material-icon.tsx 1.2 KB

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