1
1
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
2
2
import type { IconDefinition } from "@fortawesome/free-regular-svg-icons" ;
3
- import { default as Popover } from "antd/es/popover" ;
4
- import { ActionType } from '@rc-component/trigger/lib/interface' ;
3
+ // import type { IconDefinition as IconDefinitionBrands } from "@fortawesome/free-brands-svg-icons";
4
+ import { Popover } from "antd" ;
5
+ import { ActionType } from "@rc-component/trigger/lib/interface" ;
5
6
import { TacoInput } from "components/tacoInput" ;
6
7
import { Tooltip } from "components/toolTip" ;
7
8
import { trans } from "i18n/design" ;
8
9
import _ from "lodash" ;
9
- import { ReactNode , useEffect , useCallback , useMemo , useRef , useState } from "react" ;
10
+ import {
11
+ ReactNode ,
12
+ useEffect ,
13
+ useCallback ,
14
+ useMemo ,
15
+ useRef ,
16
+ useState ,
17
+ } from "react" ;
10
18
import Draggable from "react-draggable" ;
11
19
import { default as List , ListRowProps } from "react-virtualized/dist/es/List" ;
12
20
import styled from "styled-components" ;
13
21
import { CloseIcon , SearchIcon } from "icons" ;
22
+ import { ANTDICON } from "icons/antIcon" ;
23
+ import { Divider } from "antd-mobile" ;
14
24
15
25
const PopupContainer = styled . div `
16
- width: 408px ;
26
+ width: 580px ;
17
27
background: #ffffff;
18
28
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
19
29
border-radius: 8px;
@@ -76,25 +86,28 @@ const IconList = styled(List)`
76
86
background-color: rgba(139, 143, 163, 0.36);
77
87
}
78
88
` ;
89
+
79
90
const IconRow = styled . div `
80
91
padding: 0 6px;
81
92
display: flex;
82
- align-items: center;
93
+ align-items: flex-start; /* Align items to the start to allow different heights */
83
94
justify-content: space-between;
84
95
85
96
&:last-child {
86
97
gap: 8px;
87
98
justify-content: flex-start;
88
99
}
89
100
` ;
101
+
90
102
const IconItemContainer = styled . div `
91
- width: 40px;
92
- height: 40px;
103
+ width: 60px;
93
104
display: flex;
94
- align-items: center;
95
- justify-content: center;
105
+ flex-direction: column;
106
+ align-items: center;
107
+ justify-content: flex-start;
96
108
cursor: pointer;
97
- font-size: 20px;
109
+ font-size: 28px;
110
+ margin-bottom: 24px;
98
111
99
112
&:hover {
100
113
border: 1px solid #315efb;
@@ -108,13 +121,41 @@ const IconItemContainer = styled.div`
108
121
}
109
122
` ;
110
123
124
+ const IconWrapper = styled . div `
125
+ height: auto;
126
+ display: flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ ` ;
130
+
131
+ const IconKeyDisplay = styled . div `
132
+ font-size: 8px;
133
+ color: #8b8fa3;
134
+ margin-top: 4px; /* Space between the icon and the text */
135
+ text-align: center;
136
+ word-wrap: break-word; /* Ensure text wraps */
137
+ width: 100%; /* Ensure the container can grow */
138
+ ` ;
139
+
111
140
class Icon {
112
141
readonly title : string ;
113
- constructor ( readonly def : IconDefinition , readonly names : string [ ] ) {
114
- this . title = def . iconName . split ( "-" ) . map ( _ . upperFirst ) . join ( " " ) ;
142
+ constructor ( readonly def : IconDefinition | any , readonly names : string [ ] ) {
143
+ if ( def ?. iconName ) {
144
+ this . title = def . iconName . split ( "-" ) . map ( _ . upperFirst ) . join ( " " ) ;
145
+ } else {
146
+ this . title = names [ 0 ] . slice ( 5 ) ;
147
+ this . def = def ;
148
+ }
115
149
}
116
150
getView ( ) {
117
- return < FontAwesomeIcon icon = { this . def } style = { { width : "1em" , height : "1em" } } /> ;
151
+ if ( this . names [ 0 ] ?. startsWith ( "antd/" ) ) return this . def ;
152
+ else
153
+ return (
154
+ < FontAwesomeIcon
155
+ icon = { this . def }
156
+ style = { { width : "1em" , height : "1em" } }
157
+ />
158
+ ) ;
118
159
}
119
160
}
120
161
@@ -127,6 +168,7 @@ async function getAllIcons() {
127
168
const [ { far } , { fas } ] = await Promise . all ( [
128
169
import ( "@fortawesome/free-regular-svg-icons" ) ,
129
170
import ( "@fortawesome/free-solid-svg-icons" ) ,
171
+ // import("@fontawesome/free-brands-svg-icons"),
130
172
] ) ;
131
173
const ret : Record < string , Icon > = { } ;
132
174
for ( const [ type , pack ] of Object . entries ( { solid : fas , regular : far } ) ) {
@@ -144,14 +186,25 @@ async function getAllIcons() {
144
186
}
145
187
}
146
188
}
189
+ //append ant icon
190
+ for ( let key of Object . keys ( ANTDICON ) ) {
191
+ ret [ "antd/" + key ] = new Icon (
192
+ ANTDICON [ key . toLowerCase ( ) as keyof typeof ANTDICON ] ,
193
+ [ "antd/" + key ]
194
+ ) ;
195
+ }
147
196
allIcons = ret ;
148
197
return ret ;
149
198
}
150
199
151
200
export const iconPrefix = "/icon:" ;
152
201
153
202
export function removeQuote ( value ?: string ) {
154
- return value ? ( value . startsWith ( '"' ) && value . endsWith ( '"' ) ? value . slice ( 1 , - 1 ) : value ) : "" ;
203
+ return value
204
+ ? value . startsWith ( '"' ) && value . endsWith ( '"' )
205
+ ? value . slice ( 1 , - 1 )
206
+ : value
207
+ : "" ;
155
208
}
156
209
157
210
function getIconKey ( value ?: string ) {
@@ -171,7 +224,8 @@ export function useIcon(value?: string) {
171
224
function search (
172
225
allIcons : Record < string , Icon > ,
173
226
searchText : string ,
174
- searchKeywords ?: Record < string , string >
227
+ searchKeywords ?: Record < string , string > ,
228
+ IconType ?: "OnlyAntd" | "All" | "default" | undefined
175
229
) {
176
230
const tokens = searchText
177
231
. toLowerCase ( )
@@ -182,6 +236,8 @@ function search(
182
236
if ( icon . names . length === 0 ) {
183
237
return false ;
184
238
}
239
+ if ( IconType === "OnlyAntd" && ! key . startsWith ( "antd/" ) ) return false ;
240
+ if ( IconType === "default" && key . startsWith ( "antd/" ) ) return false ;
185
241
let text = icon . names
186
242
. flatMap ( ( name ) => [ name , searchKeywords ?. [ name ] ] )
187
243
. filter ( ( t ) => t )
@@ -198,43 +254,54 @@ const IconPopup = (props: {
198
254
label ?: ReactNode ;
199
255
onClose : ( ) => void ;
200
256
searchKeywords ?: Record < string , string > ;
257
+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
201
258
} ) => {
202
259
const [ searchText , setSearchText ] = useState ( "" ) ;
203
260
const [ allIcons , setAllIcons ] = useState < Record < string , Icon > > ( { } ) ;
204
261
const searchResults = useMemo (
205
- ( ) => search ( allIcons , searchText , props . searchKeywords ) ,
262
+ ( ) => search ( allIcons , searchText , props . searchKeywords , props . IconType ) ,
206
263
[ searchText , allIcons ]
207
264
) ;
208
265
const onChangeRef = useRef ( props . onChange ) ;
209
266
onChangeRef . current = props . onChange ;
210
- const onChangeIcon = useCallback ( ( key : string ) => onChangeRef . current ( iconPrefix + key ) , [ ] ) ;
267
+ const onChangeIcon = useCallback (
268
+ ( key : string ) => onChangeRef . current ( iconPrefix + key ) ,
269
+ [ ]
270
+ ) ;
211
271
const columnNum = 8 ;
212
272
213
273
useEffect ( ( ) => {
214
274
getAllIcons ( ) . then ( setAllIcons ) ;
215
275
} , [ ] ) ;
216
276
277
+ const smallTextStyle = {
278
+ fontSize : '8px'
279
+ } ;
280
+
217
281
const rowRenderer = useCallback (
218
282
( p : ListRowProps ) => (
219
283
< IconRow key = { p . key } style = { p . style } >
220
- { searchResults . slice ( p . index * columnNum , ( p . index + 1 ) * columnNum ) . map ( ( [ key , icon ] ) => (
221
- < Tooltip
222
- key = { key }
223
- title = { icon . title }
224
- placement = "bottom"
225
- align = { { offset : [ 0 , - 7 , 0 , 0 ] } }
226
- destroyTooltipOnHide
227
- >
228
- < IconItemContainer
229
- tabIndex = { 0 }
230
- onClick = { ( ) => {
231
- onChangeIcon ( key ) ;
232
- } }
284
+ { searchResults
285
+ . slice ( p . index * columnNum , ( p . index + 1 ) * columnNum )
286
+ . map ( ( [ key , icon ] ) => (
287
+ < Tooltip
288
+ key = { key }
289
+ title = { icon . title + ", Key: " + key }
290
+ placement = "bottom"
291
+ align = { { offset : [ 0 , - 7 , 0 , 0 ] } }
292
+ destroyTooltipOnHide
233
293
>
234
- { icon . getView ( ) }
235
- </ IconItemContainer >
236
- </ Tooltip >
237
- ) ) }
294
+ < IconItemContainer
295
+ tabIndex = { 0 }
296
+ onClick = { ( ) => {
297
+ onChangeIcon ( key ) ;
298
+ } }
299
+ >
300
+ < IconWrapper > { icon . getView ( ) } </ IconWrapper >
301
+ < IconKeyDisplay > { key } </ IconKeyDisplay >
302
+ </ IconItemContainer >
303
+ </ Tooltip >
304
+ ) ) }
238
305
</ IconRow >
239
306
) ,
240
307
[ searchResults , allIcons , onChangeIcon ]
@@ -257,9 +324,9 @@ const IconPopup = (props: {
257
324
</ SearchDiv >
258
325
< IconListWrapper >
259
326
< IconList
260
- width = { 394 }
261
- height = { 312 }
262
- rowHeight = { 48 }
327
+ width = { 550 }
328
+ height = { 400 }
329
+ rowHeight = { 80 }
263
330
rowCount = { Math . ceil ( searchResults . length / columnNum ) }
264
331
rowRenderer = { rowRenderer }
265
332
/>
@@ -279,6 +346,7 @@ export const IconSelectBase = (props: {
279
346
leftOffset ?: number ;
280
347
parent ?: HTMLElement | null ;
281
348
searchKeywords ?: Record < string , string > ;
349
+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
282
350
} ) => {
283
351
const { setVisible, parent } = props ;
284
352
return (
@@ -290,7 +358,11 @@ export const IconSelectBase = (props: {
290
358
onOpenChange = { setVisible }
291
359
getPopupContainer = { parent ? ( ) => parent : undefined }
292
360
// hide the original background when dragging the popover is allowed
293
- overlayInnerStyle = { { border : "none" , boxShadow : "none" , background : "transparent" } }
361
+ overlayInnerStyle = { {
362
+ border : "none" ,
363
+ boxShadow : "none" ,
364
+ background : "transparent" ,
365
+ } }
294
366
// when dragging is allowed, always re-location to avoid the popover exceeds the screen
295
367
destroyTooltipOnHide
296
368
content = {
@@ -299,6 +371,7 @@ export const IconSelectBase = (props: {
299
371
label = { props . label }
300
372
onClose = { ( ) => setVisible ?.( false ) }
301
373
searchKeywords = { props . searchKeywords }
374
+ IconType = { props . IconType }
302
375
/>
303
376
}
304
377
>
@@ -312,6 +385,7 @@ export const IconSelect = (props: {
312
385
label ?: ReactNode ;
313
386
children ?: ReactNode ;
314
387
searchKeywords ?: Record < string , string > ;
388
+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
315
389
} ) => {
316
390
const [ visible , setVisible ] = useState ( false ) ;
317
391
return (
0 commit comments