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 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import cn from '@/utils/classnames'
  5. import { noop } from 'lodash-es'
  6. type Props = {
  7. className?: string
  8. icon: React.ReactNode
  9. iconBgClassName?: string
  10. title: React.ReactNode
  11. description: string
  12. noRadio?: boolean
  13. isChosen?: boolean
  14. onChosen?: () => void
  15. chosenConfig?: React.ReactNode
  16. chosenConfigWrapClassName?: string
  17. }
  18. const RadioCard: FC<Props> = ({
  19. icon,
  20. iconBgClassName = 'bg-[#F5F3FF]',
  21. title,
  22. description,
  23. noRadio,
  24. isChosen,
  25. onChosen = noop,
  26. chosenConfig,
  27. chosenConfigWrapClassName,
  28. className,
  29. }) => {
  30. return (
  31. <div
  32. className={cn(
  33. 'relative cursor-pointer rounded-xl border-[0.5px] border-components-option-card-option-border bg-components-option-card-option-bg p-3',
  34. isChosen && 'border-[1.5px] bg-components-option-card-option-selected-bg',
  35. className,
  36. )}
  37. >
  38. <div className='flex gap-x-2' onClick={onChosen}>
  39. <div className={cn(iconBgClassName, 'flex size-8 shrink-0 items-center justify-center rounded-lg shadow-md')}>
  40. {icon}
  41. </div>
  42. <div className='grow'>
  43. <div className='system-sm-semibold mb-1 text-text-secondary'>{title}</div>
  44. <div className='system-xs-regular text-text-tertiary'>{description}</div>
  45. </div>
  46. {!noRadio && (
  47. <div className='absolute right-3 top-3'>
  48. <div className={cn(
  49. 'h-4 w-4 rounded-full border border-components-radio-border bg-components-radio-bg shadow-xs',
  50. isChosen && 'border-[5px] border-components-radio-border-checked',
  51. )}></div>
  52. </div>
  53. )}
  54. </div>
  55. {((isChosen && chosenConfig) || noRadio) && (
  56. <div className='mt-2 flex gap-x-2'>
  57. <div className='size-8 shrink-0'></div>
  58. <div className={cn(chosenConfigWrapClassName, 'grow')}>
  59. {chosenConfig}
  60. </div>
  61. </div>
  62. )}
  63. </div>
  64. )
  65. }
  66. export default React.memo(RadioCard)