Files
web/packages/design-system/lib/components/Icons/MaterialIcon/MaterialSymbol/MaterialSymbol.tsx
Anton Gunnarsson cbf9e7b7c2 Merged in chore/next15 (pull request #1999)
chore (SW-834): Upgrade to Next 15

* wip: apply codemod and upgrade swc plugin

* wip: design-system to react 19, fix issues from async (search)params

* wip: fix remaining issues from codemod

serverClient is now async because context use headers()
getLang is now async because it uses headers()

* Minor cleanup

* Inline react-material-symbols package

Package is seemingly not maintained any more and doesn't support
React 19. This copies the package source into `design-system`,
makes the necessary changes for 19 and export it for others to use.

* Fix missing awaits

* Disable modal exit animations

Enabling modal exit animations via isExiting prop is causing
modals to be rendered in "hidden" state and never unmount.
Seems to be an issue with react-aria-components,
see https://github.com/adobe/react-spectrum/issues/7563.
Can probably be fixed by rewriting to a solution similar to
https://react-spectrum.adobe.com/react-aria/examples/framer-modal-sheet.html

* Remove unstable cache implementation and use in memory cache locally

* Fix ref type in SelectFilter

* Use cloneElement to add key prop to element


Approved-by: Linus Flood
2025-06-02 11:11:50 +00:00

102 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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 symbols 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 symbols 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.), `<hex-color>`, `<rgb()>`, `<hsl()>` and `<hwb()>` values. */
color?: CSSProperties['color']
className?: string
style?: CSSProperties
}
export type PolymorphicMaterialSymbolProps<C extends ElementType> =
PolymorphicComponentProps<C, MaterialSymbolProps>
export const MaterialSymbol = (<C extends ElementType>(
{
icon,
onClick,
as,
weight,
fill = false,
grade,
size,
style: propStyle,
color,
className,
...props
}: PolymorphicMaterialSymbolProps<C>,
ref: Ref<C>
): 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 (
<Component
{...props}
ref={ref}
style={style}
onClick={onClick}
className={cx('material-symbols', className)}
>
{icon}
</Component>
)
}) as <C extends ElementType>(
props: PolymorphicMaterialSymbolProps<C>
) => ReactElement