11import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
22import 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" ;
56import { TacoInput } from "components/tacoInput" ;
67import { Tooltip } from "components/toolTip" ;
78import { trans } from "i18n/design" ;
89import _ 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" ;
1018import Draggable from "react-draggable" ;
1119import { default as List , ListRowProps } from "react-virtualized/dist/es/List" ;
1220import styled from "styled-components" ;
1321import { CloseIcon , SearchIcon } from "icons" ;
22+ import { ANTDICON } from "icons/antIcon" ;
23+ import { Divider } from "antd-mobile" ;
1424
1525const PopupContainer = styled . div `
16- width: 408px ;
26+ width: 580px ;
1727 background: #ffffff;
1828 box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
1929 border-radius: 8px;
@@ -76,25 +86,28 @@ const IconList = styled(List)`
7686 background-color: rgba(139, 143, 163, 0.36);
7787 }
7888` ;
89+
7990const IconRow = styled . div `
8091 padding: 0 6px;
8192 display: flex;
82- align-items: center;
93+ align-items: flex-start; /* Align items to the start to allow different heights */
8394 justify-content: space-between;
8495
8596 &:last-child {
8697 gap: 8px;
8798 justify-content: flex-start;
8899 }
89100` ;
101+
90102const IconItemContainer = styled . div `
91- width: 40px;
92- height: 40px;
103+ width: 60px;
93104 display: flex;
94- align-items: center;
95- justify-content: center;
105+ flex-direction: column;
106+ align-items: center;
107+ justify-content: flex-start;
96108 cursor: pointer;
97- font-size: 20px;
109+ font-size: 28px;
110+ margin-bottom: 24px;
98111
99112 &:hover {
100113 border: 1px solid #315efb;
@@ -108,13 +121,41 @@ const IconItemContainer = styled.div`
108121 }
109122` ;
110123
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+
111140class Icon {
112141 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+ }
115149 }
116150 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+ ) ;
118159 }
119160}
120161
@@ -127,6 +168,7 @@ async function getAllIcons() {
127168 const [ { far } , { fas } ] = await Promise . all ( [
128169 import ( "@fortawesome/free-regular-svg-icons" ) ,
129170 import ( "@fortawesome/free-solid-svg-icons" ) ,
171+ // import("@fontawesome/free-brands-svg-icons"),
130172 ] ) ;
131173 const ret : Record < string , Icon > = { } ;
132174 for ( const [ type , pack ] of Object . entries ( { solid : fas , regular : far } ) ) {
@@ -144,14 +186,25 @@ async function getAllIcons() {
144186 }
145187 }
146188 }
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+ }
147196 allIcons = ret ;
148197 return ret ;
149198}
150199
151200export const iconPrefix = "/icon:" ;
152201
153202export 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+ : "" ;
155208}
156209
157210function getIconKey ( value ?: string ) {
@@ -171,7 +224,8 @@ export function useIcon(value?: string) {
171224function search (
172225 allIcons : Record < string , Icon > ,
173226 searchText : string ,
174- searchKeywords ?: Record < string , string >
227+ searchKeywords ?: Record < string , string > ,
228+ IconType ?: "OnlyAntd" | "All" | "default" | undefined
175229) {
176230 const tokens = searchText
177231 . toLowerCase ( )
@@ -182,6 +236,8 @@ function search(
182236 if ( icon . names . length === 0 ) {
183237 return false ;
184238 }
239+ if ( IconType === "OnlyAntd" && ! key . startsWith ( "antd/" ) ) return false ;
240+ if ( IconType === "default" && key . startsWith ( "antd/" ) ) return false ;
185241 let text = icon . names
186242 . flatMap ( ( name ) => [ name , searchKeywords ?. [ name ] ] )
187243 . filter ( ( t ) => t )
@@ -198,43 +254,54 @@ const IconPopup = (props: {
198254 label ?: ReactNode ;
199255 onClose : ( ) => void ;
200256 searchKeywords ?: Record < string , string > ;
257+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
201258} ) => {
202259 const [ searchText , setSearchText ] = useState ( "" ) ;
203260 const [ allIcons , setAllIcons ] = useState < Record < string , Icon > > ( { } ) ;
204261 const searchResults = useMemo (
205- ( ) => search ( allIcons , searchText , props . searchKeywords ) ,
262+ ( ) => search ( allIcons , searchText , props . searchKeywords , props . IconType ) ,
206263 [ searchText , allIcons ]
207264 ) ;
208265 const onChangeRef = useRef ( props . onChange ) ;
209266 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+ ) ;
211271 const columnNum = 8 ;
212272
213273 useEffect ( ( ) => {
214274 getAllIcons ( ) . then ( setAllIcons ) ;
215275 } , [ ] ) ;
216276
277+ const smallTextStyle = {
278+ fontSize : '8px'
279+ } ;
280+
217281 const rowRenderer = useCallback (
218282 ( p : ListRowProps ) => (
219283 < 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
233293 >
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+ ) ) }
238305 </ IconRow >
239306 ) ,
240307 [ searchResults , allIcons , onChangeIcon ]
@@ -257,9 +324,9 @@ const IconPopup = (props: {
257324 </ SearchDiv >
258325 < IconListWrapper >
259326 < IconList
260- width = { 394 }
261- height = { 312 }
262- rowHeight = { 48 }
327+ width = { 550 }
328+ height = { 400 }
329+ rowHeight = { 80 }
263330 rowCount = { Math . ceil ( searchResults . length / columnNum ) }
264331 rowRenderer = { rowRenderer }
265332 />
@@ -279,6 +346,7 @@ export const IconSelectBase = (props: {
279346 leftOffset ?: number ;
280347 parent ?: HTMLElement | null ;
281348 searchKeywords ?: Record < string , string > ;
349+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
282350} ) => {
283351 const { setVisible, parent } = props ;
284352 return (
@@ -290,7 +358,11 @@ export const IconSelectBase = (props: {
290358 onOpenChange = { setVisible }
291359 getPopupContainer = { parent ? ( ) => parent : undefined }
292360 // 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+ } }
294366 // when dragging is allowed, always re-location to avoid the popover exceeds the screen
295367 destroyTooltipOnHide
296368 content = {
@@ -299,6 +371,7 @@ export const IconSelectBase = (props: {
299371 label = { props . label }
300372 onClose = { ( ) => setVisible ?.( false ) }
301373 searchKeywords = { props . searchKeywords }
374+ IconType = { props . IconType }
302375 />
303376 }
304377 >
@@ -312,6 +385,7 @@ export const IconSelect = (props: {
312385 label ?: ReactNode ;
313386 children ?: ReactNode ;
314387 searchKeywords ?: Record < string , string > ;
388+ IconType ?: "OnlyAntd" | "All" | "default" | undefined ;
315389} ) => {
316390 const [ visible , setVisible ] = useState ( false ) ;
317391 return (
0 commit comments