material-icon.tsx 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import classNames from 'classnames'
  2. import React from 'react'
  3. import { bsVersion } from '@/features/utils/bootstrap-5'
  4. // NOTE: When updating this list, make sure to update the bundled .woff2
  5. // file as well. See details in material-symbols.css
  6. export type AvailableUnfilledIcon =
  7. | 'description'
  8. | 'forum'
  9. | 'integration_instructions'
  10. | 'rate_review'
  11. | 'report'
  12. type BaseIconProps = React.ComponentProps<'i'> & {
  13. accessibilityLabel?: string
  14. modifier?: string
  15. size?: '2x'
  16. }
  17. type FilledIconProps = BaseIconProps & {
  18. type: string
  19. unfilled?: false
  20. }
  21. type UnfilledIconProps = BaseIconProps & {
  22. type: AvailableUnfilledIcon
  23. unfilled: true
  24. }
  25. type IconProps = FilledIconProps | UnfilledIconProps
  26. function MaterialIcon({
  27. type,
  28. className,
  29. accessibilityLabel,
  30. modifier,
  31. size,
  32. unfilled,
  33. ...rest
  34. }: IconProps) {
  35. const iconClassName = classNames('material-symbols', className, modifier, {
  36. [`size-${size}`]: size,
  37. unfilled,
  38. })
  39. return (
  40. <>
  41. <span className={iconClassName} aria-hidden="true" {...rest}>
  42. {type}
  43. </span>
  44. {accessibilityLabel && (
  45. <span className={bsVersion({ bs5: 'visually-hidden', bs3: 'sr-only' })}>
  46. {accessibilityLabel}
  47. </span>
  48. )}
  49. </>
  50. )
  51. }
  52. export default MaterialIcon