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
102 lines
3.0 KiB
TypeScript
102 lines
3.0 KiB
TypeScript
// 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.), `<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
|