Skip to content

Commit 4a06f6a

Browse files
(Icon): update markups and classnames
1 parent 436daca commit 4a06f6a

File tree

1 file changed

+66
-76
lines changed

1 file changed

+66
-76
lines changed

src/scripts/Icon.tsx

Lines changed: 66 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ import React, {
44
SVGAttributes,
55
useContext,
66
useRef,
7-
useState,
87
useEffect,
98
useCallback,
109
} from 'react';
1110
import classnames from 'classnames';
1211
import svg4everybody from 'svg4everybody';
1312
import { registerStyle, getAssetRoot } from './util';
1413
import { ComponentSettingsContext } from './ComponentSettings';
15-
import { useEventCallback } from './hooks';
1614
import { createFC } from './common';
1715

1816
svg4everybody();
@@ -222,23 +220,19 @@ function useInitComponentStyle() {
222220

223221
function getIconColor(
224222
fillColor: string | undefined,
225-
category: string | undefined,
223+
category: IconCategory,
226224
icon: string
227225
) {
228226
/* eslint-disable no-unneeded-ternary */
229-
return category === 'doctype'
230-
? null
231-
: fillColor === 'none'
227+
return fillColor === 'none'
232228
? null
233229
: fillColor
234230
? fillColor
235231
: category === 'utility'
236232
? null
237-
: category === 'custom'
238-
? icon.replace(/^custom/, 'custom-')
239-
: category === 'action' && /^new_custom/.test(icon)
233+
: category === 'action' && /^new_custom/.test(icon) // not needed for the current SLDS2 icons
240234
? icon.replace(/^new_custom/, 'custom-')
241-
: `${category ?? ''}-${(icon ?? '').replace(/_/g, '-')}`;
235+
: `${category}-${icon.replace(/_/g, '-')}`;
242236
/* eslint-enable no-unneeded-ternary */
243237
}
244238

@@ -251,14 +245,21 @@ export type IconCategory =
251245
| 'doctype'
252246
| 'standard'
253247
| 'utility';
254-
export type IconSize = 'x-small' | 'small' | 'medium' | 'large';
255-
export type IconContainer = boolean | 'default' | 'circle';
256-
export type IconTextColor = 'default' | 'warning' | 'error' | null;
248+
export type IconSize = 'xx-small' | 'x-small' | 'small' | 'medium' | 'large';
249+
export type IconContainer = 'circle';
250+
export type IconTextColor =
251+
| 'default'
252+
| 'success'
253+
| 'warning'
254+
| 'error'
255+
| 'light'
256+
| null;
257257

258258
/**
259259
*
260260
*/
261261
export type IconProps = {
262+
label?: string;
262263
containerClassName?: string;
263264
category?: IconCategory;
264265
icon: string;
@@ -290,7 +291,6 @@ const SvgIcon = forwardRef(
290291
iconColor,
291292
size = '',
292293
align,
293-
container,
294294
textColor = 'default',
295295
style,
296296
...rprops
@@ -300,10 +300,10 @@ const SvgIcon = forwardRef(
300300
'react-slds-icon',
301301
{
302302
'slds-icon': !/slds-button__icon/.test(className),
303-
[`slds-icon_${size}`]: /^(x-small|small|medium|large)$/.test(size),
303+
[`slds-icon_${size}`]: /^(xx-small|x-small|small|large)$/.test(size),
304304
[`slds-icon-text-${textColor ?? 'default'}`]:
305-
/^(default|warning|error)$/.test(textColor ?? '') && !iconColor,
306-
[`slds-icon-${iconColor ?? ''}`]: !container && iconColor,
305+
/^(default|success|warning|error|light)$/.test(textColor ?? '') &&
306+
!iconColor,
307307
'slds-m-left_x-small': align === 'right',
308308
'slds-m-right_x-small': align === 'left',
309309
},
@@ -327,18 +327,43 @@ const SvgIcon = forwardRef(
327327
}
328328
);
329329

330+
export const SvgButtonIcon = (
331+
props: {
332+
className?: string;
333+
category?: IconCategory;
334+
icon: string;
335+
} & SVGAttributes<SVGElement>
336+
) => {
337+
const {
338+
className = '',
339+
category: category_ = 'utility',
340+
icon: icon_,
341+
style,
342+
...rprops
343+
} = props;
344+
const { assetRoot = getAssetRoot() } = useContext(ComponentSettingsContext);
345+
346+
// icon and category prop should not include chars other than alphanumerics, underscore, and hyphen
347+
const icon = (icon_ ?? '').replace(/[^\w-]/g, ''); // eslint-disable-line no-param-reassign
348+
const category = (category_ ?? '').replace(/[^\w-]/g, ''); // eslint-disable-line no-param-reassign
349+
const iconUrl = `${assetRoot}/icons/${category}-sprite/svg/symbols.svg#${icon}`;
350+
return (
351+
<svg className={className} aria-hidden style={style} {...rprops}>
352+
<use xlinkHref={iconUrl} />
353+
</svg>
354+
);
355+
};
330356
/**
331357
*
332358
*/
333359
export const Icon = createFC<IconProps, { ICONS: typeof ICONS }>(
334360
(props) => {
335-
const { container, containerClassName, fillColor, ...rprops } = props;
361+
const { label, container, containerClassName, fillColor, ...rprops } =
362+
props;
336363
let { category = 'utility', icon } = props;
337364

338365
useInitComponentStyle();
339366

340-
const iconContainerRef = useRef<HTMLSpanElement | null>(null);
341-
342367
const svgIconRef = useRef<SVGSVGElement | null>(null);
343368

344369
const svgIconRefCallback = useCallback(
@@ -351,72 +376,37 @@ export const Icon = createFC<IconProps, { ICONS: typeof ICONS }>(
351376
[props.tabIndex]
352377
);
353378

354-
const [iconColor, setIconColor] = useState<string | null>(null);
355-
356-
const checkIconColor = useEventCallback(() => {
357-
if (
358-
fillColor ||
359-
category === 'doctype' ||
360-
(!fillColor && category === 'utility') ||
361-
iconColor === 'standard-default'
362-
) {
363-
return;
364-
}
365-
const el = container ? iconContainerRef.current : svgIconRef.current;
366-
if (!el) {
367-
return;
368-
}
369-
const bgColorStyle = getComputedStyle(el).backgroundColor;
370-
// if no background color set to the icon
371-
if (
372-
bgColorStyle &&
373-
/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/.test(bgColorStyle)
374-
) {
375-
setIconColor('standard-default');
376-
}
377-
});
378-
379379
useEffect(() => {
380380
svgIconRefCallback(svgIconRef.current);
381381
}, [svgIconRefCallback]);
382382

383-
useEffect(() => {
384-
checkIconColor();
385-
}, [checkIconColor]);
386-
387383
if (icon.indexOf(':') > 0) {
388384
[category, icon] = icon.split(':') as [IconCategory, string];
389385
}
390386

391-
const fillIconColor =
392-
iconColor || container ? getIconColor(fillColor, category, icon) : null;
387+
const fillIconColor = getIconColor(fillColor, category, icon);
393388

394-
const svgIcon = (
395-
<SvgIcon
396-
ref={svgIconRefCallback}
397-
{...rprops}
398-
{...{
399-
container,
400-
category,
401-
icon,
402-
iconColor: fillIconColor,
403-
}}
404-
/>
389+
const ccontainerClassName = classnames(
390+
containerClassName,
391+
'slds-icon_container',
392+
container === 'circle' ? 'slds-icon_container_circle' : null,
393+
category === 'utility' ? `slds-icon-utility-${icon}` : null,
394+
fillIconColor ? `slds-icon-${fillIconColor}` : null
395+
);
396+
return (
397+
<span className={ccontainerClassName} title={label}>
398+
<SvgIcon
399+
ref={svgIconRefCallback}
400+
{...rprops}
401+
{...{
402+
category,
403+
icon,
404+
iconColor: fillIconColor,
405+
}}
406+
/>
407+
{label ? <span className='slds-assistive-text'>{label}</span> : null}
408+
</span>
405409
);
406-
if (container) {
407-
const ccontainerClassName = classnames(
408-
containerClassName,
409-
'slds-icon_container',
410-
container === 'circle' ? 'slds-icon_container_circle' : null,
411-
fillIconColor ? `slds-icon-${fillIconColor}` : null
412-
);
413-
return (
414-
<span className={ccontainerClassName} ref={iconContainerRef}>
415-
{svgIcon}
416-
</span>
417-
);
418-
}
419-
return svgIcon;
420410
},
421411
{ ICONS }
422412
);

0 commit comments

Comments
 (0)