// @ts-ignore import Icon from '@/utils/Icon'; import { memo, type ReactNode } from 'react'; import { __ } from '@wordpress/i18n'; import * as Checkbox from '@radix-ui/react-checkbox'; interface CheckboxGroupInputProps { field: { action?: string | ReactNode; [key: string]: any; }; /** If true, the field displays an indeterminate (or overridden) state */ indeterminate?: boolean; /** Label for the group used in aria-label */ label: string; /** The current value; can be a boolean (for a single toggle) or an array for multi-selection */ value: any; /** Base id for the element */ id: string; /** Callback when the value changes */ onChange: (value: any) => void; /** If true, the field is required */ required?: boolean; /** * If a boolean is provided then it disables the whole field; if an array is provided, only the matching option(s) are disabled */ disabled?: boolean | string[]; /** A record of options in the format { optionId: optionLabel } */ options: Record; } /** * CheckboxGroupInput component * * Renders a group of checkboxes based on the options provided. * Supports a boolean mode when one option is provided as well as a load-more functionality. */ const CheckboxGroupInput = ({ field, label, value, id, onChange, required, disabled, options = {}, } : CheckboxGroupInputProps) => { // Convert incoming value to an array if not already one let valueValidated: any = value; if (!Array.isArray(valueValidated)) { valueValidated = valueValidated === '' ? [] : [valueValidated]; } const selected = Array.isArray(valueValidated) ? valueValidated : []; /** * Handles a change on an individual checkbox. * For boolean mode, simply toggles the value. * Otherwise, adds or removes the selected option. */ const handleCheckboxChange = (_checked: boolean, option: string) => { const newSelected = selected.includes('' + option) || selected.includes(parseInt(option)) ? selected.filter((item: any) => item !== '' + option && item !== parseInt(option)) : [...selected, option]; onChange(newSelected); }; /** * Determines if an option is considered checked. */ const isEnabled = (optionId: string) => { return selected.includes('' + optionId) || selected.includes(parseInt(optionId)); }; // If disabled is not an array, treat it as a boolean disabling the entire field. const allDisabled = disabled && !Array.isArray(disabled) ? disabled : false; if (Object.keys(options).length === 0) { return <>{__('No options found', 'ONBOARDING_WIZARD_TEXT_DOMAIN')}; } return (
{Object.entries(options).map(([key, optionLabel], i) => (
handleCheckboxChange(!!checked, key)} > {}} className="" />
))}
); }; export default memo(CheckboxGroupInput);