You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.tsx 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. 'use client'
  2. import React from 'react'
  3. import type { FC } from 'react'
  4. import { init } from 'emoji-mart'
  5. import data from '@emoji-mart/data'
  6. import { cva } from 'class-variance-authority'
  7. import type { AppIconType } from '@/types/app'
  8. import classNames from '@/utils/classnames'
  9. init({ data })
  10. export type AppIconProps = {
  11. size?: 'xs' | 'tiny' | 'small' | 'medium' | 'large' | 'xl' | 'xxl'
  12. rounded?: boolean
  13. iconType?: AppIconType | null
  14. icon?: string
  15. background?: string | null
  16. imageUrl?: string | null
  17. className?: string
  18. innerIcon?: React.ReactNode
  19. coverElement?: React.ReactNode
  20. onClick?: () => void
  21. }
  22. const appIconVariants = cva(
  23. 'flex items-center justify-center relative text-lg rounded-lg grow-0 shrink-0 overflow-hidden leading-none',
  24. {
  25. variants: {
  26. size: {
  27. xs: 'w-4 h-4 text-xs',
  28. tiny: 'w-6 h-6 text-base',
  29. small: 'w-8 h-8 text-xl',
  30. medium: 'w-9 h-9 text-[22px]',
  31. large: 'w-10 h-10 text-[24px]',
  32. xl: 'w-12 h-12 text-[28px]',
  33. xxl: 'w-14 h-14 text-[32px]',
  34. },
  35. rounded: {
  36. true: 'rounded-full',
  37. },
  38. },
  39. defaultVariants: {
  40. size: 'medium',
  41. rounded: false,
  42. },
  43. })
  44. const AppIcon: FC<AppIconProps> = ({
  45. size = 'medium',
  46. rounded = false,
  47. iconType,
  48. icon,
  49. background,
  50. imageUrl,
  51. className,
  52. innerIcon,
  53. coverElement,
  54. onClick,
  55. }) => {
  56. const isValidImageIcon = iconType === 'image' && imageUrl
  57. return <span
  58. className={classNames(appIconVariants({ size, rounded }), className)}
  59. style={{ background: isValidImageIcon ? undefined : (background || '#FFEAD5') }}
  60. onClick={onClick}
  61. >
  62. {isValidImageIcon
  63. ? <img src={imageUrl} className="h-full w-full" alt="app icon" />
  64. : (innerIcon || ((icon && icon !== '') ? <em-emoji id={icon} /> : <em-emoji id='🤖' />))
  65. }
  66. {coverElement}
  67. </span>
  68. }
  69. export default React.memo(AppIcon)