| import * as React from 'react'; |
| import { useEffect } from 'react'; |
| import { Checkbox, useStoreState, useCheckboxStore } from '@ariakit/react'; |
| import { cn } from '~/utils'; |
|
|
| const CheckboxButton = React.forwardRef< |
| HTMLInputElement, |
| { |
| icon?: React.ReactNode; |
| label: string; |
| className?: string; |
| checked?: boolean; |
| defaultChecked?: boolean; |
| isCheckedClassName?: string; |
| setValue?: (values: { |
| e?: React.ChangeEvent<HTMLInputElement>; |
| value: boolean | string; |
| }) => void; |
| } |
| >(({ icon, label, setValue, className, checked, defaultChecked, isCheckedClassName }, ref) => { |
| const checkbox = useCheckboxStore(); |
| const isChecked = useStoreState(checkbox, (state) => state?.value); |
| const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
| e.stopPropagation(); |
| if (typeof isChecked !== 'boolean') { |
| return; |
| } |
| setValue?.({ e, value: !isChecked }); |
| }; |
|
|
| |
| useEffect(() => { |
| if (checked !== undefined) { |
| checkbox.setValue(checked); |
| } |
| }, [checked, checkbox]); |
|
|
| |
| useEffect(() => { |
| if (defaultChecked !== undefined && checked === undefined) { |
| checkbox.setValue(defaultChecked); |
| } |
| }, [defaultChecked, checked, checkbox]); |
|
|
| return ( |
| <Checkbox |
| ref={ref} |
| store={checkbox} |
| onChange={onChange} |
| className={cn( |
| // Base styling from MultiSelect's selectClassName |
| 'group relative inline-flex items-center justify-center gap-1.5', |
| 'rounded-full border border-border-medium text-sm font-medium', |
| 'size-9 p-2 transition-all md:w-full md:p-3', |
| 'bg-transparent shadow-sm hover:bg-surface-hover hover:shadow-md active:shadow-inner', |
| |
| // Checked state styling |
| isChecked && isCheckedClassName && isCheckedClassName, |
| |
| // Additional custom classes |
| className, |
| )} |
| render={<button type="button" aria-label={label} />} |
| > |
| {/* Icon if provided */} |
| {icon && <span className="icon-md text-text-primary">{icon as React.JSX.Element}</span>} |
| |
| {/* Show the label on larger screens */} |
| <span className="hidden truncate md:block">{label}</span> |
| </Checkbox> |
| ); |
| }); |
|
|
| CheckboxButton.displayName = 'CheckboxButton'; |
|
|
| export default CheckboxButton; |
|
|