/* eslint-disable @typescript-eslint/no-explicit-any */ import { cx } from '@fuel-ui/css'; import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; import type { ReactElement } from 'react'; import { Fragment, cloneElement, useMemo } from 'react'; import { createStyle, useStore, useStyles } from '~/hooks/useStore'; import { Components } from '~/utils/components-list'; import { _unstable_createComponent, _unstable_createEl, createPolymorphicComponent, } from '../../utils'; import type { IconDef, Icons } from './defs'; const ICON_URL = '/icons.svg'; function getIconUrl() { try { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore if (__STORYBOOK_FUEL_UI__) return ICON_URL; return useStore.getState().iconUrl; } catch (e) { return useStore.getState().iconUrl; } } const _Icon = _unstable_createComponent(Components.Icon, (props) => { const store = useStore(); const iconUrl = useMemo(() => getIconUrl(), [store.iconUrl]); const { as = 'i', label: initialLabel, inline, icon, color, className, wrapperClassName, css, size = 18, stroke = 1.5, svgProps, ...rest } = props; const iconProps = { 'aria-hidden': true, className: cx('fuel_Icon', `fuel_Icon-${icon}`, className), focusable: false, strokeWidth: String(stroke), }; let label = initialLabel || rest['aria-label']; if (!label && typeof icon === 'string') { label = `Icon ${icon}`; } if (!label && (icon as ReactElement)?.props?.icon) { label = `Icon ${(icon as ReactElement).props?.icon}`; } const classes = useStyles(styles, { ...rest, css: { display: inline ? 'inline-flex' : 'flex', ...(color && { color: `$${color}` }), ...css, }, }); const elementProps = { ...rest, role: 'img', 'aria-label': label, className: cx(wrapperClassName, classes.root.className), } as any; const children = useMemo(() => { if (typeof icon === 'string') { return ( <> {label || icon} ); } return cloneElement(icon as ReactElement, elementProps); }, [store.iconUrl, icon]); return typeof icon === 'string' ? _unstable_createEl(as, elementProps, children) : _unstable_createEl(Fragment, {}, children); }); export const Icon = createPolymorphicComponent(_Icon); Icon.id = 'Icon'; Icon.is = (icon: Icons) => icon; const styles = createStyle(Components.Icon, { root: { is: ['centered'], '&, & *': { bg: 'transparent !important', }, }, });