import type * as React from 'react'; import type { CheckboxProps, CheckedState } from '../checkbox/types.js'; import type { PrimitivePropsWithRef } from '../utils/primitive.js'; /** @internal One registered {@link CheckboxGroupItem}, as the root sees it. */ export interface CheckboxGroupItemEntry { value: string; disabled: boolean; /** The item's DOM id — the consumer's own when they set one — for the select-all's `aria-controls`. */ id: string; } /** @internal Shared state distributed from {@link CheckboxGroup} to its parts via context. */ export interface CheckboxGroupContextValue { name?: string | undefined; /** The group's `form` id, forwarded to every item's hidden input. */ form?: string | undefined; value: string[]; disabled: boolean; /** Group-level `readOnly`, carried by each item as `aria-readonly`. */ readOnly: boolean; /** Group-level `required`, carried by each item as `aria-required`. */ required: boolean; /** Cap on how many items may be checked, or `undefined` for no cap. */ max?: number | undefined; /** Whether the cap is reached, so unchecked items announce `aria-disabled` without leaving the tab order. */ maxReached: boolean; /** The group's `useId`, from which an item with no id of its own derives one. */ baseId: string; /** Space-separated ids of every item, for the select-all's `aria-controls`. */ itemIds: string; /** Tri-state of the select-all parent, derived from the enabled items. */ selectAllChecked: CheckedState; /** Adds or removes one item's value. */ toggleItem: (value: string, checked: boolean) => void; /** Checks every enabled item, or clears them all when they already are. */ toggleAll: () => void; /** Registers an item for the whole duration of its mount; returns its unregister. */ registerItem: (value: string, disabled: boolean, id: string) => () => void; } /** One entry of {@link CheckboxGroupProps.options} — a single checkbox. */ export interface CheckboxGroupOption { /** Unique identifier added to or removed from the group's `value`. */ value: string; /** Text rendered inside the derived `CheckboxGroupItem`. */ label: React.ReactNode; /** * Disables this item alone, and excludes it from select-all. * @default false */ disabled?: boolean | undefined; } /** Props for the {@link CheckboxGroup} root. */ export interface CheckboxGroupProps extends Omit, 'defaultValue'> { /** * The checkboxes the group renders, one derived `CheckboxGroupItem` per entry, ignored when `children` is given. * @default undefined — nothing is derived; compose the items as `children`. */ options?: CheckboxGroupOption[] | undefined; /** * Checked item values for controlled usage, paired with `onValueChange`. * @default undefined — uncontrolled, tracks its own value internally. */ value?: string[] | undefined; /** * Initially checked item values, for uncontrolled usage. * @default [] — nothing checked. */ defaultValue?: string[] | undefined; /** * Fires with the new value array whenever the selection changes, controlled or not. * @default undefined — no-op if omitted. */ onValueChange?: ((value: string[]) => void) | undefined; /** * Name for native form participation: each item renders a hidden input * under this name, so `formData.getAll(name)` returns every checked value. * @default undefined — no hidden inputs rendered. */ name?: string | undefined; /** * Marks the group as required — at least one item must be checked — exposed as `aria-required` on every {@link CheckboxGroupItem} rather than the `role="group"` root. * @default false */ required?: boolean | undefined; /** * Id of the `
` that owns this group, forwarded to every item's hidden input, for a group rendered outside that form. * @default undefined — the group belongs to its nearest ancestor ``, if any. */ form?: string | undefined; /** * Disables every item in the group, and the select-all parent. * @default false */ disabled?: boolean | undefined; /** * Freezes the selection without freezing the group: every item keeps its tab stop and gains `aria-readonly`, and nothing responds to Space or click. * @default false */ readOnly?: boolean | undefined; /** * Caps how many items may be checked at once; unchecked items past the cap gain `aria-disabled` and `data-max-reached` but keep their tab stop. * @default undefined — no cap. */ max?: number | undefined; /** * Marks the group as invalid, exposed as `aria-invalid`/`data-invalid` on * the `role="group"` root. * @default false */ invalid?: boolean | undefined; /** * Size rung the skin scales the boxes by, fed to every derived item. * @default undefined — the skin's own default size. */ size?: 'sm' | 'md' | 'lg' | (string & {}) | undefined; } /** * Props for a single {@link CheckboxGroupItem}, omitting group-level state like `required`, `readOnly`, `invalid`, and `form`. */ export interface CheckboxGroupItemProps extends Omit { /** Unique identifier added to or removed from the group's `value`. */ value: string; /** * Disables this item alone, excluding it from select-all's counting and toggling. * @default false */ disabled?: boolean | undefined; } /** * Props for the {@link CheckboxGroupSelectAll} tri-state parent, taking only `disabled` since its state is entirely derived from the group. */ export interface CheckboxGroupSelectAllProps extends Omit { /** * Disables the parent alone; the group-level `disabled` also disables it. * @default false */ disabled?: boolean | undefined; }