{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "textarea-styled",
  "title": "Textarea essentials",
  "description": "Styled textarea: the essentials set. 5 decorative textarea variations (UnderlineTextarea, FloatTextarea, GlowTextarea, FilledTextarea, CountTextarea) 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/textarea-styled.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Textarea family: 5 decorative multi-line text fields. Color comes ONLY from\n   tokens. Size = min-height. The focus effects are CSS (focus-within / peer) +\n   token transitions; the transform-based ones are protected with motion-reduce.\n   Each one wraps a real <textarea> and passes through all the native props. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst height: Record<StyledSize, string> = {\n  sm: \"min-h-16 text-sm\",\n  md: \"min-h-20 text-sm\",\n  lg: \"min-h-24 text-base\",\n  xl: \"min-h-28 text-base\",\n}\n\nconst fieldBase =\n  \"w-full resize-y bg-transparent text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n\ntype Props = React.ComponentProps<\"textarea\"> & { size?: StyledSize }\n\n/* Underline: no frame, with a token line growing from the center along the bottom\n   on focus. */\nexport function UnderlineTextarea({ className, size = \"md\", ...props }: Props) {\n  return (\n    <span data-slot=\"styled-textarea\" className={cn(\"relative flex w-72 max-w-full flex-col border-b border-border\", height[size], className)}>\n      <textarea {...props} className={cn(fieldBase, \"peer flex-1 px-1 py-1.5\", height[size])} />\n      <span className=\"pointer-events-none absolute inset-x-0 bottom-[-1px] h-0.5 origin-center scale-x-0 bg-primary transition-transform duration-(--motion-base) ease-(--motion-ease) peer-focus:scale-x-100 motion-reduce:transition-none\" />\n    </span>\n  )\n}\n\n/* Float: odakta / dolu iken yukari suzulen etiket (placeholder=\" \" + peer). */\nexport function FloatTextarea({ className, size = \"md\", id, ...props }: Props) {\n  const autoId = React.useId()\n  const areaId = id ?? autoId\n  return (\n    <span data-slot=\"styled-textarea\" className={cn(\"relative flex w-72 max-w-full flex-col rounded-lg border border-border px-3 pt-5 pb-2\", height[size], className)}>\n      <textarea id={areaId} placeholder=\" \" {...props} className={cn(fieldBase, \"peer flex-1\", height[size])} />\n      <label\n        htmlFor={areaId}\n        className=\"pointer-events-none absolute left-3 top-4 bg-background px-1 text-muted-foreground transition-all duration-(--motion-base) peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:text-primary peer-[:not(:placeholder-shown)]:top-0 peer-[:not(:placeholder-shown)]:-translate-y-1/2 peer-[:not(:placeholder-shown)]:text-xs motion-reduce:transition-none\"\n      >\n        Label\n      </label>\n    </span>\n  )\n}\n\n/* Glow: odakta token isima halkasi (focus-within box-shadow). */\nexport function GlowTextarea({ className, size = \"md\", ...props }: Props) {\n  return (\n    <span\n      data-slot=\"styled-textarea\"\n      className={cn(\n        \"relative flex w-72 max-w-full flex-col rounded-lg border border-border px-3 py-2 transition-shadow duration-(--motion-base) focus-within:border-info focus-within:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-info)_25%,transparent)]\",\n        height[size],\n        className\n      )}\n    >\n      <textarea {...props} className={cn(fieldBase, \"flex-1\", height[size])} />\n    </span>\n  )\n}\n\n/* Filled: dolu yuzey + odakta alttan token vurgu cizgisi. */\nexport function FilledTextarea({ className, size = \"md\", ...props }: Props) {\n  return (\n    <span data-slot=\"styled-textarea\" className={cn(\"relative flex w-72 max-w-full flex-col overflow-hidden rounded-t-lg border-b border-border bg-surface-2 px-3 py-2\", height[size], className)}>\n      <textarea {...props} className={cn(fieldBase, \"peer flex-1\", height[size])} />\n      <span className=\"pointer-events-none absolute inset-x-0 bottom-[-1px] h-0.5 origin-center scale-x-0 bg-primary transition-transform duration-(--motion-base) ease-(--motion-ease) peer-focus:scale-x-100 motion-reduce:transition-none\" />\n    </span>\n  )\n}\n\n/* Count: kosede canli karakter sayaci; value uzunlugunu okur, maxLength alir. */\nexport function CountTextarea({ className, size = \"md\", value, defaultValue, maxLength, onChange, ...props }: Props) {\n  const initial = String(value ?? defaultValue ?? \"\").length\n  const [count, setCount] = React.useState(initial)\n\n  React.useEffect(() => {\n    if (value !== undefined) setCount(String(value).length)\n  }, [value])\n\n  function handleChange(event: React.ChangeEvent<HTMLTextAreaElement>) {\n    setCount(event.target.value.length)\n    onChange?.(event)\n  }\n\n  return (\n    <span data-slot=\"styled-textarea\" className={cn(\"relative flex w-72 max-w-full flex-col rounded-lg border border-border px-3 pt-2 pb-6 transition-colors focus-within:border-primary\", height[size], className)}>\n      <textarea\n        value={value}\n        defaultValue={defaultValue}\n        maxLength={maxLength}\n        onChange={handleChange}\n        {...props}\n        className={cn(fieldBase, \"flex-1\", height[size])}\n      />\n      <span className=\"pointer-events-none absolute bottom-1.5 right-3 text-xs tabular-nums text-muted-foreground\">\n        {maxLength ? `${count}/${maxLength}` : count}\n      </span>\n    </span>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/textarea-styled.tsx"
    }
  ],
  "categories": [
    "styled",
    "textarea"
  ],
  "type": "registry:component"
}