// This is adapted from https://github.com/edjonesdev/react-material-symbols // since it doesn't support React 19 and is not maintained anymore. // We should probably move to a different solution in the future. import type { ElementType, CSSProperties, ReactElement, Ref } from "react" import type { MaterialSymbolWeight, PolymorphicComponentProps, SymbolCodepoints, } from "./types" import { cx } from "class-variance-authority" export type { MaterialSymbolWeight, SymbolCodepoints } from "./types" export type MaterialSymbolProps = { /** Required. The name of the icon to render. */ icon: SymbolCodepoints /** Default `false`. * * Fill gives you the ability to modify the default icon style. A single icon can render both unfilled and filled states. */ fill?: boolean /** Weight defines the symbol’s stroke weight, with a range of weights between thin (100) and heavy (900). Weight can also affect the overall size of the symbol. */ weight?: MaterialSymbolWeight /** Weight and grade affect a symbol’s thickness. Adjustments to grade are more granular than adjustments to weight and have a small impact on the size of the symbol. */ grade?: number /** Default `'inherit'`. * * Size defines the icon width and height in pixels. For the image to look the same at different sizes, the stroke weight (thickness) changes as the icon size scales. */ size?: number /** Default `'inherit'` * * Color accepts key values (`'red'`, `'blue'`, `'indigo'`, etc.), ``, ``, `` and `` values. */ color?: CSSProperties["color"] className?: string style?: CSSProperties } export type PolymorphicMaterialSymbolProps = PolymorphicComponentProps export const MaterialSymbol = (( { icon, onClick, as, weight, fill = false, grade, size, style: propStyle, color, className, ...props }: PolymorphicMaterialSymbolProps, ref: Ref ): ReactElement => { const Component = onClick !== undefined ? "button" : ((as as ElementType) ?? "span") const style = { color, ...propStyle } if (fill) style.fontVariationSettings = [style.fontVariationSettings, '"FILL" 1'] .filter(Boolean) .join(", ") if (weight) style.fontVariationSettings = [ style.fontVariationSettings, `"wght" ${weight}`, ] .filter(Boolean) .join(", ") if (grade) style.fontVariationSettings = [ style.fontVariationSettings, `"GRAD" ${grade}`, ] .filter(Boolean) .join(", ") if (size) { style.fontVariationSettings = [ style.fontVariationSettings, `"opsz" ${size}`, ] .filter(Boolean) .join(", ") style.fontSize = size } return ( {icon} ) }) as ( props: PolymorphicMaterialSymbolProps ) => ReactElement