{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "checkbox",
  "title": "Checkbox",
  "description": "Native ink-framed checkbox with SVG checkmark and indeterminate mixed-state line, label, hint, error, and Field context support.",
  "registryDependencies": [
    "https://frame12.dev/r/frame12-styles.json",
    "https://frame12.dev/r/field.json"
  ],
  "files": [
    {
      "path": "ui/checkbox.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { useFieldContext } from './field';\n\nexport type CheckboxDensity = 'comfortable' | 'compact';\n\nexport interface CheckboxProps\n  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n  label?: React.ReactNode;\n  hint?: React.ReactNode;\n  error?: React.ReactNode;\n  indeterminate?: boolean;\n  density?: CheckboxDensity;\n  onCheckedChange?: (checked: boolean) => void;\n  fieldClassName?: string;\n}\n\nconst useIsomorphicLayoutEffect =\n  typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n  {\n    id,\n    label,\n    hint,\n    error,\n    indeterminate = false,\n    density,\n    disabled,\n    required,\n    readOnly,\n    className = '',\n    fieldClassName = '',\n    onClick,\n    onChange,\n    onCheckedChange,\n    'aria-describedby': userDescribedBy,\n    'aria-invalid': userAriaInvalid,\n    ...rest\n  },\n  forwardedRef,\n) {\n  const fieldCtx = useFieldContext();\n  const innerRef = React.useRef<HTMLInputElement | null>(null);\n  const autoId = React.useId().replace(/:/g, '');\n  const effectiveDensity: CheckboxDensity = density ?? fieldCtx?.density ?? 'comfortable';\n  const isCompact = effectiveDensity === 'compact';\n\n  const hasOwnLabel = Boolean(label);\n  const showOwnLabel = hasOwnLabel;\n  const inputId =\n    id ||\n    (!hasOwnLabel && !fieldCtx?.isControlGroup ? fieldCtx?.id : undefined) ||\n    `f12-checkbox-${autoId}`;\n\n  const showOwnHint = Boolean(hint && !fieldCtx?.hintId);\n  const showOwnError = Boolean(error && !fieldCtx?.errorId);\n  const hintId = showOwnHint ? `${inputId}-hint` : undefined;\n  const errorId = showOwnError ? `${inputId}-error` : undefined;\n  const describedBy =\n    [userDescribedBy, fieldCtx?.describedBy, hintId, errorId].filter(Boolean).join(' ') ||\n    undefined;\n  const effectiveInvalid = error || fieldCtx?.invalid ? true : userAriaInvalid;\n  const effectiveDisabled = disabled ?? fieldCtx?.disabled;\n  const effectiveRequired = required ?? fieldCtx?.required;\n\n  const isControlledChecked = rest.checked !== undefined;\n  const [internalIndeterminate, setInternalIndeterminate] = React.useState<boolean>(() =>\n    Boolean(indeterminate),\n  );\n\n  React.useEffect(() => {\n    setInternalIndeterminate(Boolean(indeterminate));\n  }, [indeterminate]);\n\n  const effectiveIndeterminate = isControlledChecked\n    ? Boolean(indeterminate)\n    : internalIndeterminate;\n\n  const registerControlGroup = fieldCtx?.registerControlGroup;\n  const registerControlId = fieldCtx?.registerControlId;\n  useIsomorphicLayoutEffect(() => {\n    if (hasOwnLabel) {\n      registerControlGroup?.();\n    }\n    return registerControlId?.(autoId, id);\n  }, [hasOwnLabel, registerControlGroup, registerControlId, autoId, id]);\n\n  const setRefs = React.useCallback(\n    (node: HTMLInputElement | null) => {\n      innerRef.current = node;\n      if (node) {\n        node.indeterminate = effectiveIndeterminate;\n      }\n      if (typeof forwardedRef === 'function') {\n        forwardedRef(node);\n      } else if (forwardedRef) {\n        (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n      }\n    },\n    [forwardedRef, effectiveIndeterminate],\n  );\n\n  useIsomorphicLayoutEffect(() => {\n    if (innerRef.current) {\n      innerRef.current.indeterminate = effectiveIndeterminate;\n    }\n  }, [effectiveIndeterminate, rest.checked]);\n\n  React.useEffect(() => {\n    const node = innerRef.current;\n    const form = node?.form;\n    if (!form) return;\n    const handleReset = (e: Event) => {\n      const resetMixed = Boolean(indeterminate);\n      const syncNode = () => {\n        if (e.defaultPrevented) return;\n        setInternalIndeterminate(resetMixed);\n        if (innerRef.current) {\n          innerRef.current.indeterminate = resetMixed;\n          innerRef.current.classList.toggle('f12-checkbox-indeterminate', resetMixed);\n          if (resetMixed) {\n            innerRef.current.setAttribute('data-indeterminate', 'true');\n          } else {\n            innerRef.current.removeAttribute('data-indeterminate');\n          }\n        }\n      };\n      queueMicrotask(syncNode);\n      setTimeout(syncNode, 0);\n    };\n    form.addEventListener('reset', handleReset);\n    return () => {\n      form.removeEventListener('reset', handleReset);\n    };\n  }, [indeterminate]);\n\n  const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {\n    onClick?.(e);\n    if (readOnly) {\n      e.preventDefault();\n      e.currentTarget.indeterminate = effectiveIndeterminate;\n    }\n  };\n\n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    if (readOnly) {\n      e.preventDefault();\n      e.target.indeterminate = effectiveIndeterminate;\n      return;\n    }\n    if (!isControlledChecked) {\n      setInternalIndeterminate(false);\n      e.target.indeterminate = false;\n    } else {\n      e.target.indeterminate = Boolean(indeterminate);\n    }\n    onChange?.(e);\n    onCheckedChange?.(e.target.checked);\n  };\n\n  const controlRow = (\n    <div className=\"f12-check-row\" data-disabled={effectiveDisabled ? '' : undefined}>\n      <span className=\"f12-checkbox-control\">\n        <input\n          ref={setRefs}\n          id={inputId}\n          type=\"checkbox\"\n          disabled={effectiveDisabled}\n          required={effectiveRequired}\n          readOnly={readOnly}\n          aria-readonly={readOnly ? 'true' : undefined}\n          className={`f12-checkbox-input${isCompact ? ' f12-checkbox-compact' : ''}${effectiveIndeterminate ? ' f12-checkbox-indeterminate' : ''}${className ? ` ${className}` : ''}`}\n          data-indeterminate={effectiveIndeterminate ? 'true' : undefined}\n          aria-describedby={describedBy}\n          aria-invalid={effectiveInvalid}\n          onClick={handleClick}\n          onChange={handleChange}\n          {...rest}\n        />\n        <svg\n          className=\"f12-checkbox-mark\"\n          viewBox=\"0 0 16 16\"\n          fill=\"none\"\n          aria-hidden=\"true\"\n        >\n          {effectiveIndeterminate ? (\n            <line\n              className=\"f12-checkbox-mark-mixed\"\n              x1=\"3.5\"\n              y1=\"8\"\n              x2=\"12.5\"\n              y2=\"8\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2.5\"\n              strokeLinecap=\"square\"\n            />\n          ) : (\n            <polyline\n              className=\"f12-checkbox-mark-check\"\n              points=\"3.5,8.5 6.8,11.8 12.8,4.5\"\n              stroke=\"currentColor\"\n              strokeWidth=\"2.4\"\n              strokeLinecap=\"square\"\n              strokeLinejoin=\"miter\"\n            />\n          )}\n        </svg>\n      </span>\n      {showOwnLabel && (\n        <label htmlFor={inputId} className=\"f12-check-label\">\n          {label}\n          {effectiveRequired && (\n            <span className=\"f12-field-req\" aria-hidden=\"true\">\n              {' '}\n              *\n            </span>\n          )}\n        </label>\n      )}\n    </div>\n  );\n\n  if (fieldCtx && !showOwnHint && !showOwnError) {\n    return controlRow;\n  }\n\n  return (\n    <div\n      className={`f12-check-field${isCompact ? ' f12-check-field-compact' : ''}${fieldClassName ? ` ${fieldClassName}` : ''}`}\n      data-density={isCompact ? 'compact' : undefined}\n      data-disabled={effectiveDisabled ? '' : undefined}\n    >\n      {controlRow}\n      {showOwnHint && (\n        <p id={hintId} className=\"f12-hint f12-check-meta\">\n          {hint}\n        </p>\n      )}\n      {showOwnError && (\n        <p id={errorId} className=\"f12-error f12-check-meta\" role=\"alert\">\n          <span className=\"f12-error-flag\" aria-hidden=\"true\">\n            !\n          </span>\n          <span>{error}</span>\n        </p>\n      )}\n    </div>\n  );\n});\n\n(Checkbox as unknown as { f12IsCheckOrSwitch?: boolean }).f12IsCheckOrSwitch = true;\n",
      "type": "registry:ui",
      "target": "components/frame12/checkbox.tsx"
    }
  ],
  "type": "registry:ui"
}