{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "field-styled",
  "title": "Field essentials",
  "description": "Styled field: the essentials set. 5 decorative field variations (StackedField, FloatingField, InlineField, CardField, BorderedField) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/field-styled.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Field family: 5 form-field wrappers. Each places a label + an optional\n   description + an optional error around a control (children) and associates them\n   with ids (useId + aria-describedby + aria-invalid are written onto the cloned\n   control). Color comes ONLY from tokens: the label is foreground, the description\n   muted-foreground, the error danger, and the required asterisk danger. A static\n   layout - no animation, framer is not needed. Renders with no props too (a default\n   label + description + a real <input placeholder=\"Value\" />). */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst gap: Record<StyledSize, string> = {\n  sm: \"gap-1\",\n  md: \"gap-1.5\",\n  lg: \"gap-2\",\n  xl: \"gap-2.5\",\n}\n\nconst labelText: Record<StyledSize, string> = {\n  sm: \"text-xs\",\n  md: \"text-sm\",\n  lg: \"text-sm\",\n  xl: \"text-base\",\n}\n\nconst helpText: Record<StyledSize, string> = {\n  sm: \"text-xs\",\n  md: \"text-xs\",\n  lg: \"text-sm\",\n  xl: \"text-sm\",\n}\n\nconst controlHeight: Record<StyledSize, string> = {\n  sm: \"h-8 text-sm\",\n  md: \"h-9 text-sm\",\n  lg: \"h-10 text-base\",\n  xl: \"h-12 text-base\",\n}\n\n/* Tokenised input styling for the default control (when no children are given). */\nfunction defaultControlClass(size: StyledSize, invalid: boolean) {\n  return cn(\n    \"w-full rounded-md border bg-transparent px-3 py-1 text-foreground outline-none transition-colors placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 focus-visible:ring-[3px]\",\n    controlHeight[size],\n    invalid\n      ? \"border-danger focus-visible:border-danger focus-visible:ring-danger/25\"\n      : \"border-field-border focus-visible:border-ring focus-visible:ring-ring/50\"\n  )\n}\n\ntype BoundControlProps = {\n  id?: unknown\n  \"aria-describedby\"?: unknown\n  \"aria-invalid\"?: unknown\n}\n\n/* Clones the children (or the default input) and wires up id plus aria. */\nfunction buildControl(\n  children: React.ReactNode,\n  size: StyledSize,\n  invalid: boolean,\n  ids: { controlId: string; describedBy?: string }\n) {\n  const element = React.isValidElement(children)\n    ? (children as React.ReactElement<BoundControlProps>)\n    : (<input placeholder=\"Value\" className={defaultControlClass(size, invalid)} /> as React.ReactElement<BoundControlProps>)\n  const current = element.props\n  return React.cloneElement(element, {\n    id: current.id ?? ids.controlId,\n    \"aria-describedby\": ids.describedBy ?? current[\"aria-describedby\"],\n    \"aria-invalid\": invalid ? true : current[\"aria-invalid\"],\n  })\n}\n\ntype FieldProps = {\n  className?: string\n  size?: StyledSize\n  label?: React.ReactNode\n  description?: React.ReactNode\n  error?: React.ReactNode\n  required?: boolean\n  children?: React.ReactNode\n}\n\nconst DEFAULT_LABEL = \"Label\"\nconst DEFAULT_DESCRIPTION = \"Short help text for this field.\"\n\n/* Paylasilan id kumesi + describedby zinciri. */\nfunction useFieldIds(description: React.ReactNode, error: React.ReactNode) {\n  const base = React.useId()\n  const controlId = `${base}-control`\n  const descId = description != null && description !== false ? `${base}-desc` : undefined\n  const errorId = error != null && error !== false ? `${base}-error` : undefined\n  const describedBy = [descId, errorId].filter(Boolean).join(\" \") || undefined\n  return { controlId, descId, errorId, describedBy }\n}\n\nfunction FieldLabel({\n  htmlFor,\n  size,\n  required,\n  children,\n  className,\n}: {\n  htmlFor: string\n  size: StyledSize\n  required?: boolean\n  children: React.ReactNode\n  className?: string\n}) {\n  return (\n    <label\n      htmlFor={htmlFor}\n      data-slot=\"styled-field-label\"\n      className={cn(\"w-fit font-medium leading-none text-foreground select-none\", labelText[size], className)}\n    >\n      {children}\n      {required ? (\n        <span aria-hidden=\"true\" className=\"ml-0.5 text-danger\">\n          *\n        </span>\n      ) : null}\n    </label>\n  )\n}\n\nfunction FieldMessages({\n  size,\n  descId,\n  description,\n  errorId,\n  error,\n}: {\n  size: StyledSize\n  descId?: string\n  description: React.ReactNode\n  errorId?: string\n  error: React.ReactNode\n}) {\n  return (\n    <>\n      {description != null && description !== false ? (\n        <p id={descId} data-slot=\"styled-field-description\" className={cn(\"leading-snug text-muted-foreground\", helpText[size])}>\n          {description}\n        </p>\n      ) : null}\n      {error != null && error !== false ? (\n        <p id={errorId} data-slot=\"styled-field-error\" className={cn(\"font-medium leading-snug text-danger\", helpText[size])}>\n          {error}\n        </p>\n      ) : null}\n    </>\n  )\n}\n\n/* Stacked: etiket ustte, kontrol, altta aciklama/hata - temiz varsayilan. */\nexport function StackedField({\n  className,\n  size = \"md\",\n  label = DEFAULT_LABEL,\n  description = DEFAULT_DESCRIPTION,\n  error,\n  required,\n  children,\n}: FieldProps) {\n  const { controlId, descId, errorId, describedBy } = useFieldIds(description, error)\n  const control = buildControl(children, size, error != null && error !== false, { controlId, describedBy })\n  return (\n    <div data-slot=\"styled-field\" className={cn(\"flex w-full max-w-xs flex-col\", gap[size], className)}>\n      <FieldLabel htmlFor={controlId} size={size} required={required}>\n        {label}\n      </FieldLabel>\n      {control}\n      <FieldMessages size={size} descId={descId} description={description} errorId={errorId} error={error} />\n    </div>\n  )\n}\n\n/* Floating: the label sits on the top edge of the control (floating over the\n   border). */\nexport function FloatingField({\n  className,\n  size = \"md\",\n  label = DEFAULT_LABEL,\n  description = DEFAULT_DESCRIPTION,\n  error,\n  required,\n  children,\n}: FieldProps) {\n  const { controlId, descId, errorId, describedBy } = useFieldIds(description, error)\n  const control = buildControl(children, size, error != null && error !== false, { controlId, describedBy })\n  return (\n    <div data-slot=\"styled-field\" className={cn(\"flex w-full max-w-xs flex-col\", gap[size], className)}>\n      <div className=\"relative\">\n        <FieldLabel\n          htmlFor={controlId}\n          size={size}\n          required={required}\n          className=\"absolute -top-2 left-2.5 z-10 bg-background px-1 text-xs leading-none\"\n        >\n          {label}\n        </FieldLabel>\n        {control}\n      </div>\n      <FieldMessages size={size} descId={descId} description={description} errorId={errorId} error={error} />\n    </div>\n  )\n}\n\n/* Inline: label on the left, control on the right, one row; messages below. */\nexport function InlineField({\n  className,\n  size = \"md\",\n  label = DEFAULT_LABEL,\n  description = DEFAULT_DESCRIPTION,\n  error,\n  required,\n  children,\n}: FieldProps) {\n  const { controlId, descId, errorId, describedBy } = useFieldIds(description, error)\n  const control = buildControl(children, size, error != null && error !== false, { controlId, describedBy })\n  return (\n    <div data-slot=\"styled-field\" className={cn(\"flex w-full max-w-md flex-col\", gap[size], className)}>\n      <div className=\"flex items-center gap-3\">\n        <FieldLabel htmlFor={controlId} size={size} required={required} className=\"shrink-0\">\n          {label}\n        </FieldLabel>\n        <div className=\"min-w-0 flex-1\">{control}</div>\n      </div>\n      <FieldMessages size={size} descId={descId} description={description} errorId={errorId} error={error} />\n    </div>\n  )\n}\n\n/* Card: tum alan token kart icinde, padding'li. */\nexport function CardField({\n  className,\n  size = \"md\",\n  label = DEFAULT_LABEL,\n  description = DEFAULT_DESCRIPTION,\n  error,\n  required,\n  children,\n}: FieldProps) {\n  const { controlId, descId, errorId, describedBy } = useFieldIds(description, error)\n  const control = buildControl(children, size, error != null && error !== false, { controlId, describedBy })\n  return (\n    <div\n      data-slot=\"styled-field\"\n      className={cn(\"flex w-full max-w-xs flex-col rounded-xl border border-border bg-card p-4 text-card-foreground\", gap[size], className)}\n    >\n      <FieldLabel htmlFor={controlId} size={size} required={required}>\n        {label}\n      </FieldLabel>\n      {control}\n      <FieldMessages size={size} descId={descId} description={description} errorId={errorId} error={error} />\n    </div>\n  )\n}\n\n/* Bordered: sol tarafta token vurgu cizgisi; hata durumunda danger'a doner. */\nexport function BorderedField({\n  className,\n  size = \"md\",\n  label = DEFAULT_LABEL,\n  description = DEFAULT_DESCRIPTION,\n  error,\n  required,\n  children,\n}: FieldProps) {\n  const invalid = error != null && error !== false\n  const { controlId, descId, errorId, describedBy } = useFieldIds(description, error)\n  const control = buildControl(children, size, invalid, { controlId, describedBy })\n  return (\n    <div\n      data-slot=\"styled-field\"\n      className={cn(\n        \"flex w-full max-w-xs flex-col border-l-2 pl-3\",\n        invalid ? \"border-danger\" : \"border-primary\",\n        gap[size],\n        className\n      )}\n    >\n      <FieldLabel htmlFor={controlId} size={size} required={required}>\n        {label}\n      </FieldLabel>\n      {control}\n      <FieldMessages size={size} descId={descId} description={description} errorId={errorId} error={error} />\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/field-styled.tsx"
    }
  ],
  "categories": [
    "styled",
    "field"
  ],
  "type": "registry:component"
}