Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: jZonG <jzongcode@gmail.com>
64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import { useId } from 'react'
|
|
import { useContext } from 'use-context-selector'
|
|
import RadioGroupContext from '../../context'
|
|
import s from '../../style.module.css'
|
|
import cn from '@/utils/classnames'
|
|
|
|
export type IRadioProps = {
|
|
className?: string
|
|
labelClassName?: string
|
|
children?: string | ReactNode
|
|
checked?: boolean
|
|
value?: string | number
|
|
disabled?: boolean
|
|
onChange?: (e?: IRadioProps['value']) => void
|
|
}
|
|
|
|
export default function Radio({
|
|
className = '',
|
|
labelClassName,
|
|
children = '',
|
|
checked,
|
|
value,
|
|
disabled,
|
|
onChange,
|
|
}: IRadioProps): React.JSX.Element {
|
|
const groupContext = useContext(RadioGroupContext)
|
|
const labelId = useId()
|
|
const handleChange = (e: IRadioProps['value']) => {
|
|
if (disabled)
|
|
return
|
|
|
|
onChange?.(e)
|
|
groupContext?.onChange(e)
|
|
}
|
|
|
|
const isChecked = groupContext ? groupContext.value === value : checked
|
|
const divClassName = `
|
|
flex items-center py-1 relative
|
|
px-7 cursor-pointer hover:bg-gray-200 rounded
|
|
`
|
|
|
|
return (
|
|
<div className={cn(
|
|
s.label,
|
|
disabled ? s.disabled : '',
|
|
isChecked ? 'bg-white shadow' : '',
|
|
divClassName,
|
|
className)}
|
|
onClick={() => handleChange(value)}
|
|
>
|
|
{children && (
|
|
<label className={
|
|
cn(labelClassName, 'cursor-pointer text-sm')
|
|
}
|
|
id={labelId}
|
|
>
|
|
{children}
|
|
</label>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|