{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "checkbox", "title": "Integrated Checkbox", "description": "Thin labeled Checkbox wrapper with optional description, accessible ID and ARIA wiring, delegated controlled or uncontrolled state, and native form behavior.", "registryDependencies": [ "checkbox" ], "files": [ { "path": "registry/ui/checkbox.tsx", "content": "\"use client\";\n\nimport type { ClassValue } from \"clsx\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { Checkbox as CheckboxControl } from \"@/components/ui/checkbox\";\nimport { cn } from \"@/lib/utils\";\n\nconst WHITESPACE_PATTERN = /\\s+/;\n\ntype CheckboxControlProps = ComponentProps;\n\ninterface CheckboxOwnedProps {\n /** Semantic and structural keys owned by the primitive and Compose layer. */\n \"aria-checked\"?: never;\n \"aria-disabled\"?: never;\n \"aria-readonly\"?: never;\n \"aria-required\"?: never;\n children?: never;\n /** Class override for the visible Checkbox control. */\n className?: ClassValue;\n dangerouslySetInnerHTML?: never;\n /** The primitive slot marker is owned by the Compose component. */\n \"data-slot\"?: never;\n /** Optional supporting content announced after the label. */\n description?: ReactNode;\n /** Class override for the description content. */\n descriptionClassName?: ClassValue;\n indeterminate?: never;\n /** Required caller-owned content that names the checkbox. */\n label: ReactNode;\n /** Class override for the label content. */\n labelClassName?: ClassValue;\n nativeButton?: never;\n /** Class override for the outer option layout. */\n optionClassName?: ClassValue;\n parent?: never;\n render?: never;\n role?: never;\n}\n\nexport interface CheckboxProps\n extends Omit,\n CheckboxOwnedProps {}\n\nconst hasNode = (node: ReactNode): boolean =>\n node !== null && node !== undefined && typeof node !== \"boolean\";\n\nconst mergeIds = (...values: (string | undefined)[]): string | undefined => {\n const tokens = values\n .flatMap((value) => value?.split(WHITESPACE_PATTERN) ?? [])\n .filter(Boolean);\n const merged = [...new Set(tokens)].join(\" \");\n\n return merged || undefined;\n};\n\nexport const Checkbox = ({\n \"aria-checked\": _ignoredAriaChecked,\n \"aria-disabled\": _ignoredAriaDisabled,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-readonly\": _ignoredAriaReadonly,\n \"aria-required\": _ignoredAriaRequired,\n className,\n children: _ignoredChildren,\n \"data-slot\": _ignoredDataSlot,\n dangerouslySetInnerHTML: _ignoredDangerouslySetInnerHTML,\n description,\n descriptionClassName,\n id,\n indeterminate: _ignoredIndeterminate,\n label,\n labelClassName,\n nativeButton: _ignoredNativeButton,\n optionClassName,\n parent: _ignoredParent,\n render: _ignoredRender,\n role: _ignoredRole,\n ...controlProps\n}: CheckboxProps) => {\n const autoId = useId();\n const controlId = id ?? `${autoId}-control`;\n const labelId = `${autoId}-label`;\n const descriptionId = `${autoId}-description`;\n const hasLabel = hasNode(label);\n const hasDescription = hasNode(description);\n const mergedLabelledBy = mergeIds(\n hasLabel ? labelId : undefined,\n ariaLabelledBy\n );\n const blockDescriptionAsLabel =\n hasDescription && !hasLabel && mergedLabelledBy === undefined;\n\n return (\n
\n \n {hasLabel || hasDescription ? (\n \n ) : null}\n
\n );\n};\n\nexport default Checkbox;\n", "type": "registry:component", "target": "components/easy/checkbox.tsx" } ], "type": "registry:component" }