11import { SizeProp } from '@fortawesome/fontawesome-svg-core' ;
22import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
3- import {
4- CSSProperties ,
5- HTMLProps ,
6- PropsWithChildren ,
7- useEffect ,
8- useState ,
9- } from 'react' ;
3+ import { CSSProperties } from 'react' ;
104import styled , { css } from 'styled-components' ;
115import { CoreUITheme } from '../../style/theme' ;
12- import { Loader } from '../loader/Loader.component' ;
136import { RemoteGroup , RemoteUser } from './CustomsIcons' ;
14-
15- // Module-level cache for imported icons
16- const iconCache : Record < string , any > = { } ;
17-
18- export const iconTable = {
19- Account : 'fas faWallet' ,
20- Backend : 'fas faNetworkWired' ,
21- Tape : 'fas faTape' ,
22- 'Node-backend' : 'fas faServer' ,
23- 'Volume-backend' : 'fas faHdd' ,
24- 'Node-pdf' : 'fas faDatabase' ,
25- 'Volume-pdf' : 'fas faCompactDisc' ,
26- Network : 'fas faProjectDiagram' ,
27- Bucket : 'fas faGlassWhiskey' ,
28- 'Cloud-backend' : 'fas faCloud' ,
29- Datacenter : 'fas faWarehouse' ,
30- 'Simple-user' : 'fas faUser' ,
31- User : 'fas faUserCog' ,
32- Group : 'fas faUsers' ,
33- Alert : 'fas faBell' ,
34- Bell : 'far faBell' ,
35- 'Lat-menu' : 'fas faBars' ,
36- Dashboard : 'fas faDesktop' ,
37- Workflow : 'fas faRoute' ,
38- Expiration : 'fas faStopwatch' ,
39- Replication : 'fas faCoins' ,
40- Transition : 'fas faRocket' ,
41- Discovery : 'fas faReply' ,
42- Metrics : 'fas faChartLine' ,
43- Edit : 'fas faEdit' ,
44- Logs : 'far faFileAlt' ,
45- Lock : 'fa faLock' ,
46- 'Lock-open' : 'fa faLockOpen' ,
47- 'Create-add' : 'fas faPlus' ,
48- Delete : 'fas faTrash' ,
49- Save : 'fas faSave' ,
50- 'External-link' : 'fas faExternalLinkAlt' ,
51- Link : 'fas faLink' ,
52- Unlink : 'fas faUnlink' ,
53- Close : 'fas faTimes' ,
54- 'Dropdown-down' : 'fas faCaretDown' ,
55- 'Dropdown-up' : 'fas faCaretUp' ,
56- Search : 'fas faSearch' ,
57- More : 'fas faEllipsisV' ,
58- Info : 'fas faQuestionCircle' ,
59- Sync : 'fas faSync' ,
60- Export : 'fas faFileExport' ,
61- Copy : 'far faClone' ,
62- 'Simple-upload' : 'fas faUpload' ,
63- Upload : 'fas faFileUpload' ,
64- 'Add-plus' : 'fas faPlusSquare' ,
65- Minus : 'fas faMinus' ,
66- 'Remove-minus' : 'fas faMinusSquare' ,
67- Sort : 'fas faSort' ,
68- 'Sort-up' : 'fas faSortUp' ,
69- 'Sort-down' : 'fas faSortDown' ,
70- Calendar : 'fas faCalendarWeek' ,
71- 'Calendar-minus' : 'fas faCalendarMinus' ,
72- 'Arrow-up' : 'fas faArrowUp' ,
73- 'Arrow-down' : 'fas faArrowDown' ,
74- 'Arrow-right' : 'fas faArrowRight' ,
75- 'Arrow-left' : 'fas faArrowLeft' ,
76- 'Arrow-alt-circle-up' : 'fas faArrowAltCircleUp' ,
77- Folder : 'far faFolder' ,
78- File : 'far faFile' ,
79- 'File-invoice' : 'fas faFileInvoice' ,
80- License : 'fas faFileInvoice' ,
81- 'Deletion-marker' : 'fas faBan' ,
82- 'Map-marker' : 'fas faMapMarkerAlt' ,
83- Location : 'fas faMapMarkerAlt' ,
84- 'Info-circle' : 'fas faInfoCircle' ,
85- 'Exclamation-triangle' : 'fas faExclamationTriangle' ,
86- 'Exclamation-circle' : 'fas faExclamationCircle' ,
87- Exclamation : 'fas faExclamation' ,
88- Check : 'fas faCheck' ,
89- Protected : 'fas faShieldAlt' ,
90- 'Chevron-left' : 'fas faChevronLeft' ,
91- 'Chevron-right' : 'fas faChevronRight' ,
92- 'Chevron-down' : 'fas faChevronDown' ,
93- 'Chevron-up' : 'fas faChevronUp' ,
94- 'Angle-right' : 'fas faAngleRight' ,
95- 'Angle-double-right' : 'fas faAngleDoubleRight' ,
96- Language : 'fas faLanguage' ,
97- Theme : 'fas faPalette' ,
98- Documentation : 'fas faClipboardList' ,
99- Support : 'fas faComments' ,
100- EULA : 'fas faFileContract' ,
101- 'Log-out' : 'fas faSignOutAlt' ,
102- Hourglass : 'far faHourglass' ,
103- Pause : 'fas faPause' ,
104- 'Pause-circle' : 'far faPauseCircle' ,
105- 'Play-circle' : 'far faPlayCircle' ,
106- Upgrade : 'fas faLevelUpAlt' ,
107- Expansion : 'fas faExpandAlt' ,
108- Rebalance : 'fas faBalanceScale' ,
109- Maintenance : 'fas faHardHat' ,
110- Role : 'fas faHatCowboy' ,
111- 'Change-erasure' : 'fas faExchangeAlt' ,
112- 'Circle-health' : 'fas faCircle' ,
113- 'Circle-empty' : 'far faCircle' ,
114- 'Dot-circle' : 'fas faDotCircle' ,
115- 'Check-circle' : 'fas faCheckCircle' ,
116- 'Times-circle' : 'fas faTimesCircle' ,
117- Toolbox : 'fas faToolbox' ,
118- Cubes : 'fas faCubes' ,
119- Policy : 'fas faFileSignature' ,
120- Pen : 'fa faPen' ,
121- Pencil : 'fas faPencilAlt' ,
122- Eye : 'fas faEye' ,
123- EyeSlash : 'fas faEyeSlash' ,
124- Snowflake : 'fas faSnowflake' ,
125- Key : 'fas faKey' ,
126- Filter : 'fas faFilter' ,
127- Download : 'fas faDownload' ,
128- Certificate : 'fas faCertificate' ,
129- Redo : 'fas faRedoAlt' ,
130- Eraser : 'fas faEraser' ,
131- 'ID-card' : 'fas faIdCard' ,
132- Setting : 'fas faCog' , //TODO: Rename to Gear in FA v6 <i class="fa-sharp fa-solid fa-gear"></i>
133- Desktop : 'fas faDesktop' ,
134- Globe : 'fas faGlobe' ,
135- Satellite : 'fas faSatelliteDish' ,
136- LightMode : 'fas faSun' ,
137- DarkMode : 'fas faMoon' ,
138- News : 'fas faBullhorn' ,
139- Ring : 'fas faRing' ,
140- Stop : 'fas faStop' ,
141- Play : 'fas faPlay' ,
142- Mail : 'fas faEnvelope' ,
143- ThumbsUp : 'far faThumbsUp' ,
144- ThumbsDown : 'far faThumbsDown' ,
145- Sidebar : 'fas faColumns' ,
146- Bookopen : 'fas faBookOpen' ,
147- } ;
7+ import { iconTable } from './iconDefinitions' ;
1488
1499type IconProps = {
15010 'aria-label' ?: string ;
@@ -182,6 +42,7 @@ const IconStyled = styled(FontAwesomeIcon)`
18242
18343export type IconName = keyof typeof iconTable | keyof typeof customIcons ;
18444export type IconColor = keyof CoreUITheme ;
45+
18546type Props = {
18647 name : IconName ;
18748 size ?: SizeProp ;
@@ -193,21 +54,6 @@ type Props = {
19354 title ?: string ;
19455} ;
19556
196- const DelayedFallback = ( {
197- children,
198- ...rest
199- } : PropsWithChildren < HTMLProps < HTMLElement > > ) => {
200- const [ show , setShow ] = useState ( false ) ;
201- useEffect ( ( ) => {
202- let timeout = setTimeout ( ( ) => setShow ( true ) , 300 ) ;
203- return ( ) => {
204- clearTimeout ( timeout ) ;
205- } ;
206- } , [ ] ) ;
207-
208- return < i { ...rest } > { show && children } </ i > ;
209- } ;
210-
21157export const IconWrapper = styled . div < { size : SizeProp } > `
21258 ${ ( props ) => {
21359 const brand = props . theme ;
@@ -249,52 +95,37 @@ function NonWrappedIcon({
24995 color,
25096 ariaLabel = '' ,
25197 title,
98+ style,
25299 ...rest
253100} : Omit < Props , 'withWrapper' > ) {
254- const iconInfo = iconTable [ name ] || customIcons [ name ] ;
255- if ( ! iconInfo ) throw new Error ( `${ name } : is not a valid icon.` ) ;
256-
257- // Loaded fortawesome icon if not a custom icon
258- const [ icon , setIcon ] = useState ( ) ;
259-
260- useEffect ( ( ) => {
261- if ( customIcons [ name ] ) {
262- return ;
263- }
264-
265- const [ iconType , iconClass ] = iconInfo . split ( ' ' ) ;
266- const fontAwesomeType =
267- iconType === 'far' ? 'free-regular-svg-icons' : 'free-solid-svg-icons' ;
268- const cacheKey = `${ fontAwesomeType } /${ iconClass } ` ;
269- if ( iconCache [ cacheKey ] ) {
270- setIcon ( iconCache [ cacheKey ] ) ;
271- return ( ) => setIcon ( undefined ) ;
272- }
273-
274- // Handle FontAwesome icons with dynamic import
275- import ( `@fortawesome/${ fontAwesomeType } /${ iconClass } .js` ) . then ( ( module ) => {
276- setIcon ( module [ iconClass ] ) ;
277- iconCache [ cacheKey ] = module [ iconClass ] ;
278- } ) ;
279- return ( ) => setIcon ( undefined ) ;
280- } , [ name , iconInfo ] ) ;
281-
282- if ( ! icon && ! customIcons [ name ] ) {
101+ // Check for custom icons first
102+ const CustomIcon = customIcons [ name ] ;
103+ if ( CustomIcon ) {
283104 return (
284- < DelayedFallback aria-label = { `${ name } ${ ariaLabel } ` } >
285- < Loader size = "base" />
286- </ DelayedFallback >
105+ < CustomIcon
106+ color = { color }
107+ size = { size }
108+ title = { title }
109+ aria-label = { `${ name } ${ ariaLabel } ` }
110+ { ...rest }
111+ />
287112 ) ;
288113 }
289114
290- const IconComponent = customIcons [ name ] ?? IconStyled ;
115+ // Get FontAwesome icon from static lookup
116+ const icon = iconTable [ name ] ;
117+ if ( ! icon ) {
118+ throw new Error ( `${ name } : is not a valid icon.` ) ;
119+ }
120+
291121 return (
292- < IconComponent
122+ < IconStyled
293123 color = { color }
294124 icon = { icon }
295125 size = { size }
296126 title = { title }
297127 aria-label = { `${ name } ${ ariaLabel } ` }
128+ style = { style as React . CSSProperties & { [ key : `--fa-${string } `] : string } }
298129 { ...rest }
299130 />
300131 ) ;
@@ -312,4 +143,4 @@ function Icon({ withWrapper, ...props }: Props) {
312143 return < NonWrappedIcon { ...props } /> ;
313144}
314145
315- export { Icon } ;
146+ export { Icon , iconTable } ;
0 commit comments