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.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import type { ReactNode } from 'react'
  2. import { useId } from 'react'
  3. import { useContext } from 'use-context-selector'
  4. import RadioGroupContext from '../../context'
  5. import s from '../../style.module.css'
  6. import cn from '@/utils/classnames'
  7. export type IRadioProps = {
  8. className?: string
  9. labelClassName?: string
  10. children?: string | ReactNode
  11. checked?: boolean
  12. value?: string | number
  13. disabled?: boolean
  14. onChange?: (e?: IRadioProps['value']) => void
  15. }
  16. export default function Radio({
  17. className = '',
  18. labelClassName,
  19. children = '',
  20. checked,
  21. value,
  22. disabled,
  23. onChange,
  24. }: IRadioProps): React.JSX.Element {
  25. const groupContext = useContext(RadioGroupContext)
  26. const labelId = useId()
  27. const handleChange = (e: IRadioProps['value']) => {
  28. if (disabled)
  29. return
  30. onChange?.(e)
  31. groupContext?.onChange(e)
  32. }
  33. const isChecked = groupContext ? groupContext.value === value : checked
  34. const divClassName = `
  35. flex items-center py-1 relative
  36. px-7 cursor-pointer text-text-secondary rounded
  37. bg-components-option-card-option-bg hover:bg-components-option-card-option-bg-hover hover:shadow-xs
  38. `
  39. return (
  40. <div className={cn(
  41. s.label,
  42. disabled ? s.disabled : '',
  43. isChecked ? 'bg-components-option-card-option-bg-hover shadow-xs' : '',
  44. divClassName,
  45. className)}
  46. onClick={() => handleChange(value)}
  47. >
  48. {children && (
  49. <label className={
  50. cn(labelClassName, 'cursor-pointer text-sm')
  51. }
  52. id={labelId}
  53. >
  54. {children}
  55. </label>
  56. )}
  57. </div>
  58. )
  59. }