{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "field",
  "title": "Field",
  "description": "A label, a control, and the hint or error that describes it, wired for screen readers.",
  "registryDependencies": [
    "https://creance.pages.dev/r/creance-base.json"
  ],
  "files": [
    {
      "path": "field/Field.css",
      "content": ".cr-field {\n  display: grid;\n  align-content: start;\n  gap: var(--cr-space-2);\n  color: var(--cr-color-text-default);\n  font-family: var(--cr-font-family-sans);\n}\n\n.cr-field__label {\n  font-size: var(--cr-font-size-sm);\n  font-weight: var(--cr-font-weight-semibold);\n}\n\n.cr-field[data-disabled] .cr-field__label {\n  color: var(--cr-color-text-muted);\n}\n\n.cr-field__hint {\n  color: var(--cr-color-text-muted);\n  font-size: var(--cr-font-size-xs);\n}\n\n.cr-field__error {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  color: var(--cr-color-status-failed-fg);\n  font-size: var(--cr-font-size-xs);\n}\n",
      "type": "registry:file",
      "target": "@components/creance/field/Field.css"
    },
    {
      "path": "field/Field.tsx",
      "content": "import { cloneElement, useId, type ReactElement, type ReactNode } from 'react';\nimport { cx } from '@/lib/creance/cx';\nimport { AlertIcon } from '@/lib/creance/icons';\nimport './Field.css';\n\ninterface ControlProps {\n  id?: string;\n  disabled?: boolean;\n  'aria-describedby'?: string;\n  'aria-invalid'?: boolean | 'true' | 'false';\n}\n\nexport interface FieldProps {\n  label: ReactNode;\n  /** Help that stays visible. */\n  hint?: ReactNode;\n  /** What is wrong and how to fix it. Marks the control invalid. */\n  error?: ReactNode;\n  /** One control: `Input`, `Textarea`, `Select` or your own. It receives `id`, `aria-describedby` and `aria-invalid`. */\n  children: ReactElement<ControlProps>;\n  className?: string;\n}\n\n/** A label, a control, and the hint or error that describes it, wired together for screen readers. */\nexport function Field({ label, hint, error, children, className }: FieldProps) {\n  const auto = useId();\n  const id = children.props.id ?? auto;\n  const hintId = hint ? `${id}-hint` : undefined;\n  const errorId = error ? `${id}-error` : undefined;\n  const describedBy = [children.props['aria-describedby'], errorId, hintId].filter(Boolean).join(' ') || undefined;\n\n  return (\n    <div className={cx('cr-field', className)} data-disabled={children.props.disabled || undefined}>\n      <label className=\"cr-field__label\" htmlFor={id}>\n        {label}\n      </label>\n      {cloneElement(children, {\n        id,\n        'aria-describedby': describedBy,\n        ...(error ? { 'aria-invalid': true } : {}),\n      })}\n      {error && (\n        <span id={errorId} className=\"cr-field__error\">\n          <AlertIcon />\n          {error}\n        </span>\n      )}\n      {hint && (\n        <span id={hintId} className=\"cr-field__hint\">\n          {hint}\n        </span>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/creance/field/Field.tsx"
    }
  ],
  "categories": [
    "molecule",
    "forms"
  ],
  "type": "registry:ui"
}