Skip to content

Commit cf7acc9

Browse files
Change how icons are imported since v7 dropped dynamic import for icons.
Split icon.component.tsx in 2. One file for the component and another for the list and import of all used icons
1 parent 074c59c commit cf7acc9

File tree

2 files changed

+288
-192
lines changed

2 files changed

+288
-192
lines changed
Lines changed: 23 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,10 @@
11
import { SizeProp } from '@fortawesome/fontawesome-svg-core';
22
import { 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';
104
import styled, { css } from 'styled-components';
115
import { CoreUITheme } from '../../style/theme';
12-
import { Loader } from '../loader/Loader.component';
136
import { 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

1499
type IconProps = {
15010
'aria-label'?: string;
@@ -182,6 +42,7 @@ const IconStyled = styled(FontAwesomeIcon)`
18242

18343
export type IconName = keyof typeof iconTable | keyof typeof customIcons;
18444
export type IconColor = keyof CoreUITheme;
45+
18546
type 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-
21157
export 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

Comments
 (0)