material-icon.tsx 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import classNames from 'classnames'
  2. import React, { memo } from 'react'
  3. import unfilledIconTypes from '../../../fonts/material-symbols/unfilled-symbols.mjs'
  4. export type AvailableUnfilledIcon = (typeof unfilledIconTypes)[number]
  5. type BaseIconProps = React.ComponentProps<'i'> & {
  6. accessibilityLabel?: string
  7. modifier?: string
  8. size?: '2x'
  9. }
  10. type FilledIconProps = BaseIconProps & {
  11. type: string
  12. unfilled?: false
  13. }
  14. type UnfilledIconProps = BaseIconProps & {
  15. type: AvailableUnfilledIcon
  16. unfilled: true
  17. }
  18. export type IconProps = FilledIconProps | UnfilledIconProps
  19. function MaterialIcon({
  20. type,
  21. className,
  22. accessibilityLabel,
  23. modifier,
  24. size,
  25. unfilled,
  26. ...rest
  27. }: IconProps) {
  28. const iconClassName = classNames('material-symbols', className, modifier, {
  29. [`size-${size}`]: size,
  30. unfilled,
  31. })
  32. return (
  33. <>
  34. <span
  35. className={iconClassName}
  36. aria-hidden="true"
  37. translate="no"
  38. {...rest}
  39. >
  40. {type}
  41. </span>
  42. {accessibilityLabel && (
  43. <span className="visually-hidden">{accessibilityLabel}</span>
  44. )}
  45. </>
  46. )
  47. }
  48. export default memo(MaterialIcon)