{
  "name": "textarea",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "textarea.tsx",
      "content": "\"use client\";\r\n\r\nimport { createVariants, css, themeVars as theme } from \"@yugnex/core\";\r\nimport { forwardRef, useId, type ReactNode, type TextareaHTMLAttributes } from \"react\";\r\n\r\nconst textareaVariants = createVariants({\r\n  base: {\r\n    display: \"block\",\r\n    width: \"100%\",\r\n    minHeight: \"5rem\",\r\n    borderRadius: theme.radius.md,\r\n    border: `1px solid ${theme.color.input}`,\r\n    backgroundColor: theme.color.background,\r\n    color: theme.color.foreground,\r\n    fontFamily: theme.fontFamily.sans,\r\n    fontSize: theme.fontSize.sm,\r\n    lineHeight: theme.lineHeight.base,\r\n    padding: `${theme.space[2]} ${theme.space[3]}`,\r\n    resize: \"vertical\",\r\n    transitionProperty: \"border-color, box-shadow\",\r\n    transitionDuration: theme.duration.fast,\r\n    transitionTimingFunction: theme.easing.standard,\r\n    \"&::placeholder\": { color: theme.color.mutedForeground },\r\n    \"&:focus-visible\": {\r\n      outline: \"none\",\r\n      borderColor: theme.color.ring,\r\n      boxShadow: `0 0 0 3px ${theme.color.accent}`,\r\n    },\r\n    \"&:disabled\": { opacity: 0.5, cursor: \"not-allowed\", resize: \"none\" },\r\n  },\r\n  variants: {\r\n    invalid: {\r\n      true: { borderColor: theme.color.destructive },\r\n    },\r\n  },\r\n});\r\n\r\nconst labelClass = css({\r\n  display: \"block\",\r\n  marginBottom: theme.space[1.5],\r\n  fontSize: theme.fontSize.sm,\r\n  fontWeight: theme.fontWeight.medium,\r\n  color: theme.color.foreground,\r\n});\r\n\r\nconst helpClass = css({\r\n  marginTop: theme.space[1.5],\r\n  fontSize: theme.fontSize.xs,\r\n  color: theme.color.mutedForeground,\r\n});\r\n\r\nconst errorClass = css({\r\n  marginTop: theme.space[1.5],\r\n  fontSize: theme.fontSize.xs,\r\n  color: theme.color.destructive,\r\n});\r\n\r\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\r\n  label?: ReactNode;\r\n  description?: ReactNode;\r\n  error?: ReactNode;\r\n}\r\n\r\n/** A multiline text field with label, description, and error states wired up for accessibility. */\r\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\r\n  { label, description, error, id, className, ...props },\r\n  ref,\r\n) {\r\n  const generatedId = useId();\r\n  const fieldId = id ?? generatedId;\r\n  const descriptionId = description ? `${fieldId}-description` : undefined;\r\n  const errorId = error ? `${fieldId}-error` : undefined;\r\n  const describedBy = [descriptionId, errorId].filter(Boolean).join(\" \") || undefined;\r\n\r\n  return (\r\n    <div>\r\n      {label ? (\r\n        <label className={labelClass} htmlFor={fieldId}>\r\n          {label}\r\n        </label>\r\n      ) : null}\r\n      <textarea\r\n        ref={ref}\r\n        id={fieldId}\r\n        className={textareaVariants({ invalid: error ? \"true\" : undefined, className })}\r\n        aria-invalid={Boolean(error) || undefined}\r\n        aria-describedby={describedBy}\r\n        {...props}\r\n      />\r\n      {description ? (\r\n        <p id={descriptionId} className={helpClass}>\r\n          {description}\r\n        </p>\r\n      ) : null}\r\n      {error ? (\r\n        <p id={errorId} className={errorClass} role=\"alert\">\r\n          {error}\r\n        </p>\r\n      ) : null}\r\n    </div>\r\n  );\r\n});\r\n",
      "type": "registry:component"
    }
  ]
}