import { Tooltip } from '@components/common/form/Tooltip.js'; import { getNestedError } from '@components/common/form/utils/getNestedError.js'; import { Checkbox } from '@components/common/ui/Checkbox.js'; import { Field, FieldError, FieldLabel, FieldLegend } from '@components/common/ui/Field.js'; import { Label } from '@components/common/ui/Label.js'; import { _ } from '@evershop/evershop/lib/locale/translate/_'; import React from 'react'; import { useFormContext, RegisterOptions, FieldPath, FieldValues, Controller } from 'react-hook-form'; interface CheckboxOption { value: string | number; label: string; disabled?: boolean; } interface CheckboxFieldProps extends Omit< React.InputHTMLAttributes, 'name' | 'type' | 'defaultValue' > { name: FieldPath; label?: string; error?: string; helperText?: string; required?: boolean; validation?: RegisterOptions; options?: CheckboxOption[]; defaultValue?: boolean | (string | number)[]; direction?: 'horizontal' | 'vertical'; wrapperClassName?: string; } export function CheckboxField({ name, label, error, wrapperClassName, helperText, required, validation, options, defaultValue, direction = 'vertical', className, disabled, ...props }: CheckboxFieldProps) { const { control, formState: { errors } } = useFormContext(); const fieldError = getNestedError(name, errors, error); const fieldId = `field-${name}`; const validationRules = { ...validation, ...(required && !validation?.required && { required: _('${field} is required', { field: label || name }) }) }; const containerClass = direction === 'horizontal' ? 'checkbox-group horizontal' : 'checkbox-group'; if (!options || options.length === 0) { return (
( field.onChange(checked)} onBlur={field.onBlur} disabled={disabled} className={className} aria-invalid={fieldError !== undefined ? 'true' : 'false'} aria-describedby={ fieldError !== undefined ? `${fieldId}-error` : helperText ? `${fieldId}-helper` : undefined } /> )} /> {label && ( {label} {required && *} {helperText && } )}
{fieldError && {fieldError}}
); } return ( {label && (
<> {label} {required && *} {helperText && } (
{options.map((option, index) => { const isChecked = Array.isArray(field.value) ? field.value.includes(option.value) : false; return (
{ const currentValues = Array.isArray(field.value) ? field.value : []; if (checked) { field.onChange([...currentValues, option.value]); } else { field.onChange( currentValues.filter( (val) => val !== option.value ) ); } }} onBlur={field.onBlur} className={className} aria-invalid={fieldError ? 'true' : 'false'} aria-describedby={ fieldError ? `${fieldId}-error` : undefined } />
); })}
)} />
)} {fieldError && {fieldError}}
); }