UNPKG

@grafana/ui

Version:
124 lines (117 loc) 4.12 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var jsxRuntime = require('react/jsx-runtime'); var css = require('@emotion/css'); var React = require('react'); var SVG = require('react-inlinesvg'); var data = require('@grafana/data'); var ThemeContext = require('../../themes/ThemeContext.cjs'); var keyframes = require('../../utils/keyframes.cjs'); var utils = require('./utils.cjs'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var SVG__default = /*#__PURE__*/_interopDefaultCompat(SVG); "use strict"; const getIconStyles = (theme) => { return { icon: css.css({ display: "inline-block", fill: "currentColor", flexShrink: 0, label: "Icon", // line-height: 0; is needed for correct icon alignment in Safari lineHeight: 0, verticalAlign: "middle" }), orange: css.css({ fill: theme.v1.palette.orange }), spin: css.css({ [theme.transitions.handleMotion("no-preference", "reduce")]: { animation: `${keyframes.spin} 2s infinite linear` } }) }; }; function useIconWorkaround(name) { const [, setForceUpdate] = React.useState(0); const isLoadingRef = React.useRef(false); const currentNameRef = React.useRef(name); const bufferedNameRef = React.useRef(null); let nameToUse = name; if (isLoadingRef.current && name !== currentNameRef.current) { nameToUse = currentNameRef.current; bufferedNameRef.current = name; } else if (!isLoadingRef.current && name !== currentNameRef.current) { currentNameRef.current = name; bufferedNameRef.current = null; isLoadingRef.current = true; } const handleLoad = React.useCallback(() => { isLoadingRef.current = false; if (bufferedNameRef.current) { currentNameRef.current = bufferedNameRef.current; bufferedNameRef.current = null; setForceUpdate((n) => n + 1); } }, []); return { nameToUse, handleLoad }; } const Icon = React.memo( React.forwardRef( ({ size = "md", type = "default", name: nameProp, className, style, title = "", ...rest }, ref) => { const styles = ThemeContext.useStyles2(getIconStyles); const { nameToUse: name, handleLoad } = useIconWorkaround(nameProp); if (!data.isIconName(name)) { console.warn("Icon component passed an invalid icon name", name); } const iconName = name === "fa fa-spinner" ? "spinner" : name; const svgSize = utils.getSvgSize(size); const svgHgt = svgSize; const svgWid = name.startsWith("gf-bar-align") ? 16 : name.startsWith("gf-interp") ? 30 : svgSize; const svgPath = utils.getIconPath(iconName, type); const composedClassName = css.cx( styles.icon, className, type === "mono" ? { [styles.orange]: name === "favorite" } : "", { [styles.spin]: iconName === "spinner" } ); return ( // @ts-expect-error react-inlinesvg@4.3.0 return type includes bigint, which isn't in @types/react@18's ReactNode. Remove when we update @types/react. /* @__PURE__ */ jsxRuntime.jsx( SVG__default.default, { "data-testid": `icon-${iconName}`, "aria-hidden": rest.tabIndex === void 0 && !title && !rest["aria-label"] && !rest["aria-labelledby"] && !rest["aria-describedby"], onLoad: handleLoad, onError: handleLoad, innerRef: ref, src: svgPath, width: svgWid, height: svgHgt, title, className: composedClassName, style, loader: /* @__PURE__ */ jsxRuntime.jsx( "svg", { className: css.cx( css.css({ width: svgWid, height: svgHgt }), composedClassName ) } ), ...rest } ) ); } ) ); Icon.displayName = "Icon"; exports.Icon = Icon; //# sourceMappingURL=Icon.cjs.map