{
  "tag": "ed-textarea",
  "kind": "component",
  "summary": "Textareas collect data from the user and allow multiple lines of text.",
  "status": "experimental",
  "since": "1.0",
  "docs": "https://test-apps.eurodata.de/a/eurodata-ui/docs/components/textarea/",
  "usage": "https://test-apps.eurodata.de/a/eurodata-ui/docs/components/textarea/usage/",
  "playwright": "getByTestId('…').getByRole('textbox')",
  "dependencies": [
    "ed-icon"
  ],
  "use": [
    "Genuinely multi-line, free-form text where the response may run to a sentence, a paragraph, or more — comments, descriptions, notes, message composition, and feedback",
    "Answers whose length the user cannot predict, where they need room to see and edit several lines at once",
    "A message or description field with a visible character count when the text has a length limit"
  ],
  "notFor": [
    {
      "when": "Short, single-line, bounded values such as a name, email, ZIP code, or reference number",
      "instead": "a single-line [Input](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/input)"
    },
    {
      "when": "On its own, text the user needs to format — bold, lists, headings, links, or other formatting",
      "instead": "a rich-text editor, or capture markdown and render it with the [Markdown](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/markdown) component"
    }
  ],
  "rules": [
    {
      "id": "textarea/visible-label",
      "rule": "Give every textarea in a form a short, persistent, visible label describing what it collects, and never use placeholder text as a substitute for it. Outside a form, a textarea whose surroundings already say what it is — a reply field under the thread it answers — may go without one, but never without the `aria-label` that names it then.",
      "why": "Placeholder text disappears the moment the user starts typing, so it can never be the only description of what the field expects — a user who returns to a partly filled field would have nothing left to remind them.",
      "check": "error"
    },
    {
      "id": "textarea/instructions-in-hint",
      "rule": "Put instructions the user still needs after they start typing in the hint — never rely on placeholder text to carry them."
    },
    {
      "id": "textarea/starting-height",
      "rule": "Set the starting height to the length you realistically expect — a few lines for a short comment, more for long-form content.",
      "why": "Users are not forced to resize before they begin."
    },
    {
      "id": "textarea/auto-grow",
      "rule": "Let the field expand automatically as the user types when the content length is unpredictable.",
      "why": "Long entries stay fully visible without scrolling."
    },
    {
      "id": "textarea/character-count",
      "rule": "Enable the built-in character count when there is a genuine limit, so users see how much room remains before they reach it.",
      "check": "warning"
    },
    {
      "id": "textarea/advisory-limit",
      "rule": "Decide whether the limit is enforced or advisory, and never silently cut off or discard text the user has already typed or pasted when they exceed it. Leave `maxlength` off where the user has to be told rather than cut short — the count plus a validation message warns them and lets them shorten the text themselves.",
      "why": "With `maxlength` the browser stops further typing and truncates a paste without saying so, and the count reads as characters remaining.",
      "check": "warning"
    },
    {
      "id": "textarea/min-width",
      "rule": "Keep the field at least 8.75rem (140px) wide — and comfortably wider for prose — never squeezed into a narrow column.",
      "why": "The value and the label stay legible, and short-looking limits do not justify a cramped multi-line field.",
      "check": "error"
    },
    {
      "id": "textarea/required",
      "rule": "Set `required` on mandatory fields and explain the required-marking convention once per form. Don't add your own required indicator — the label picks it up automatically."
    },
    {
      "id": "textarea/error-timing",
      "rule": "Don't add your own timing for validation errors — the component shows them only after the user has typed and left the field, or on submit. Never show an error state on page load or the instant the field receives focus, before the user has typed anything.",
      "check": "warning"
    },
    {
      "id": "textarea/specific-errors",
      "rule": "Write a specific, actionable message for each custom validation error — never a vague one like \"Invalid input\" or \"Error\". Don't write your own for the standard constraints (required, length) — the component has their messages.",
      "check": "error"
    },
    {
      "id": "textarea/readonly-not-disabled",
      "rule": "Use read-only for text the user can never change, and disabled only when it could become editable under some condition."
    },
    {
      "id": "textarea/table-edit-mode",
      "rule": "Never make every cell of a data table a permanently editable textarea — require an explicit action to enter edit mode.",
      "check": "warning"
    },
    {
      "id": "textarea/ai-suggested",
      "rule": "Use the AI-suggested state to flag a value the system pre-filled, so users can tell it apart from their own entries."
    },
    {
      "id": "textarea/default-density",
      "rule": "Keep `density` at its default. Choose `compact` or `spacious` only deliberately for a specifically tighter or looser layout, or `compact` for a control inside a [Data Grid](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/data-grid) — never to fine-tune spacing case by case.",
      "why": "The default suits standard forms and layouts, and it is the intended spacing for almost every screen.",
      "check": "warning"
    }
  ],
  "api": {
    "attributes": [
      {
        "name": "title",
        "property": "title",
        "type": "string",
        "default": "''"
      },
      {
        "name": "name",
        "property": "name",
        "type": "null | string",
        "default": "null",
        "description": "The name of the textarea, submitted as a name/value pair with form data."
      },
      {
        "name": "value",
        "property": "defaultValue",
        "type": "string",
        "description": "The default value of the form control. Primarily used for resetting the form control."
      },
      {
        "name": "density",
        "property": "density",
        "type": "'compact' | 'default' | 'spacious'",
        "default": "'default'",
        "description": "Controls the component's spacing density without affecting font-size."
      },
      {
        "name": "label",
        "property": "label",
        "type": "string",
        "default": "''",
        "description": "The textarea's label. If you need to display HTML, use the `label` slot instead."
      },
      {
        "name": "aria-label",
        "property": "ariaLabel",
        "type": "null | string",
        "default": "null",
        "description": "The textarea's accessible name for when no visible label is set. Mirrored onto the internal\ntextarea, where the textbox role lives — an aria-label left on the host alone would sit on\na role-less element and be ignored by assistive tech."
      },
      {
        "name": "placeholder",
        "property": "placeholder",
        "type": "string",
        "default": "''",
        "description": "Placeholder text to show as a hint when the input is empty."
      },
      {
        "name": "rows",
        "property": "rows",
        "type": "number",
        "default": "4",
        "description": "The number of rows to display by default."
      },
      {
        "name": "resize",
        "property": "resize",
        "type": "'auto' | 'both' | 'horizontal' | 'vertical' | 'none'",
        "default": "'vertical'",
        "description": "Controls how the textarea can be resized."
      },
      {
        "name": "readonly",
        "property": "readonly",
        "type": "boolean",
        "default": "false",
        "description": "Makes the textarea readonly."
      },
      {
        "name": "required",
        "property": "required",
        "type": "boolean",
        "default": "false",
        "description": "Makes the textarea a required field."
      },
      {
        "name": "minlength",
        "property": "minlength",
        "type": "number",
        "description": "The minimum length of input that will be considered valid."
      },
      {
        "name": "maxlength",
        "property": "maxlength",
        "type": "number",
        "description": "The maximum length of input that will be considered valid."
      },
      {
        "name": "autocapitalize",
        "property": "autocapitalize",
        "type": "'none' | 'off' | 'on' | 'sentences' | 'words' | 'characters'",
        "description": "Controls whether and how text input is automatically capitalized as it is entered by the user."
      },
      {
        "name": "autocorrect",
        "property": "autocorrect",
        "type": "boolean",
        "description": "Indicates whether the browser's autocorrect feature is on or off. When set as an attribute, use `\"off\"` or `\"on\"`.\nWhen set as a property, use `true` or `false`."
      },
      {
        "name": "autocomplete",
        "property": "autocomplete",
        "type": "string",
        "description": "Specifies what permission the browser has to provide assistance in filling out form field values. Refer to\n[this page on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) for available values."
      },
      {
        "name": "autofocus",
        "property": "autofocus",
        "type": "boolean",
        "description": "Indicates that the input should receive focus on page load."
      },
      {
        "name": "enterkeyhint",
        "property": "enterkeyhint",
        "type": "'next' | 'previous' | 'search' | 'send' | 'done' | 'enter' | 'go'",
        "description": "Used to customize the label or icon of the Enter key on virtual keyboards."
      },
      {
        "name": "spellcheck",
        "property": "spellcheck",
        "type": "boolean",
        "default": "true",
        "description": "Enables spell checking on the textarea."
      },
      {
        "name": "inputmode",
        "property": "inputmode",
        "type": "'search' | 'text' | 'numeric' | 'none' | 'email' | 'tel' | 'url' | 'decimal'",
        "description": "Tells the browser what type of data will be entered by the user, allowing it to display the appropriate virtual\nkeyboard on supportive devices."
      },
      {
        "name": "with-label",
        "property": "withLabel",
        "type": "boolean",
        "default": "false",
        "description": "Only required for SSR. Set to `true` if you're slotting in a `label` element so the server-rendered markup includes the label before the component hydrates on the client."
      },
      {
        "name": "with-hint",
        "property": "withHint",
        "type": "boolean",
        "default": "false",
        "description": "Only required for SSR. Set to `true` if you're slotting in a `hint` element so the server-rendered markup includes the hint before the component hydrates on the client."
      },
      {
        "name": "with-count",
        "property": "withCount",
        "type": "boolean",
        "default": "false",
        "description": "Shows a character count below the textarea. When `maxlength` is set, shows remaining characters instead."
      },
      {
        "name": "error",
        "property": "error",
        "type": "null | string",
        "default": "null",
        "description": "Draws an error-style input with danger colored border and icon. Set to an empty string (or use the bare attribute `<ed-input error>`) to render error styling without a visible message; submission is still blocked with a localized fallback validation message. Set to a non-empty string to additionally display that message in the message area, above the hint, and use it as the validation message. Set to `null` (the default) or remove the attribute to clear the error."
      },
      {
        "name": "warning",
        "property": "warning",
        "type": "null | string",
        "default": "null",
        "description": "Draws a warning-style input with warning colored border and icon. Set to an empty string (or use the bare attribute `<ed-input warning>`) to render warning styling without a visible message. Set to a non-empty string to additionally display that message in the message area, above the hint. Warnings do not block form submission. Set to `null` (the default) or remove the attribute to clear the warning."
      },
      {
        "name": "ai",
        "property": "ai",
        "type": "boolean",
        "default": "false",
        "description": "Draws an ai-style input with AI colored border and icon. Suppressed visually once\n`hasInteracted` flips, but the property and attribute are preserved so the styling\nreturns after `formResetCallback` clears `hasInteracted`."
      },
      {
        "name": "hint",
        "property": "hint",
        "type": "string",
        "default": "''",
        "description": "The form control's hint text. If you need to display HTML, use the `hint` slot instead."
      },
      {
        "name": "disabled",
        "property": "disabled",
        "type": "boolean",
        "description": "Disables the form control. HTML treats a control as disabled when either its own `disabled` is\nset or an ancestor `<fieldset>` is disabled, so reading this reports the combined state while\nwriting it sets only this element's own. Keeping the two apart is what lets a fieldset be\nre-enabled without clearing a disabled state the consumer set in the meantime."
      },
      {
        "name": "dir",
        "property": "dir",
        "type": "string"
      },
      {
        "name": "lang",
        "property": "lang",
        "type": "string"
      }
    ],
    "properties": [
      {
        "name": "value",
        "type": "string",
        "description": "The current value of the textarea, submitted as a name/value pair with form data. Empty is `''`,\nas on a native textarea — never `null`."
      },
      {
        "name": "form",
        "type": "HTMLFormElement | null",
        "description": "By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you\nto place the form control outside of a form and associate it with the form that has this `id`. The form must be in\nthe same document or shadow root for this to work."
      },
      {
        "name": "validationTarget",
        "type": "undefined | HTMLElement",
        "description": "Override this to change where constraint validation popups are anchored."
      }
    ],
    "methods": [
      {
        "name": "focus",
        "parameters": [
          {
            "name": "options",
            "type": "FocusOptions",
            "optional": true
          }
        ],
        "description": "Sets focus on the textarea."
      },
      {
        "name": "blur",
        "description": "Removes focus from the textarea."
      },
      {
        "name": "select",
        "description": "Selects all the text in the textarea."
      },
      {
        "name": "scrollPosition",
        "parameters": [
          {
            "name": "position",
            "type": "{ top?: number; left?: number }",
            "optional": true
          }
        ],
        "returns": "{ top: number; left: number } | undefined",
        "description": "Gets or sets the textarea's scroll position."
      },
      {
        "name": "setSelectionRange",
        "parameters": [
          {
            "name": "selectionStart",
            "type": "number"
          },
          {
            "name": "selectionEnd",
            "type": "number"
          },
          {
            "name": "selectionDirection",
            "type": "'forward' | 'backward' | 'none'"
          }
        ],
        "description": "Sets the start and end positions of the text selection (0-based)."
      },
      {
        "name": "setRangeText",
        "parameters": [
          {
            "name": "replacement",
            "type": "string"
          },
          {
            "name": "start",
            "type": "number",
            "optional": true
          },
          {
            "name": "end",
            "type": "number",
            "optional": true
          },
          {
            "name": "selectMode",
            "type": "'select' | 'start' | 'end' | 'preserve'"
          }
        ],
        "description": "Replaces a range of text with a new string."
      },
      {
        "name": "setCustomValidity",
        "parameters": [
          {
            "name": "message",
            "type": "string"
          }
        ],
        "description": "Do not use this when creating a \"Validator\". This is intended for end users of components.\nWe track manually defined custom errors so we don't clear them on accident in our validators."
      },
      {
        "name": "resetValidity",
        "description": "Reset validity is a way of removing manual custom errors and native validation."
      }
    ],
    "events": [
      {
        "name": "blur",
        "react": "onBlur",
        "description": "Emitted when the control loses focus."
      },
      {
        "name": "change",
        "react": "onChange",
        "description": "Emitted when an alteration to the control's value is committed by the user."
      },
      {
        "name": "focus",
        "react": "onFocus",
        "description": "Emitted when the control gains focus."
      },
      {
        "name": "input",
        "react": "onInput",
        "description": "Emitted when the control receives input."
      },
      {
        "name": "ed-invalid",
        "react": "onEdInvalid",
        "description": "Emitted when the form control has been checked for validity and its constraints aren't satisfied."
      }
    ],
    "slots": [
      {
        "name": "label",
        "description": "The textarea's label. Alternatively, you can use the `label` attribute."
      },
      {
        "name": "hint",
        "description": "Text that describes how to use the input. Alternatively, you can use the `hint` attribute."
      }
    ],
    "cssProperties": [],
    "parts": [
      {
        "name": "label",
        "description": "The label"
      },
      {
        "name": "message",
        "description": "The state message: an error, a warning, or the AI note."
      },
      {
        "name": "footer",
        "description": "The row below the control that holds the hint and the character count."
      },
      {
        "name": "hint",
        "description": "The hint's wrapper."
      },
      {
        "name": "base",
        "description": "The wrapper around the `<textarea>` control."
      },
      {
        "name": "textarea",
        "description": "The internal `<textarea>` control."
      },
      {
        "name": "count",
        "description": "The character count element, rendered when the `with-count` attribute is present."
      }
    ],
    "states": [
      {
        "name": "blank",
        "description": "The textarea is empty."
      },
      {
        "name": "disabled",
        "description": "The control is disabled, by its own attribute or by an ancestor fieldset."
      },
      {
        "name": "required",
        "description": "The control is required."
      },
      {
        "name": "optional",
        "description": "The control is not required."
      },
      {
        "name": "invalid",
        "description": "The value fails constraint validation, whether or not the user has touched the control yet."
      },
      {
        "name": "valid",
        "description": "The value passes constraint validation."
      },
      {
        "name": "user-invalid",
        "description": "Invalid, and the user has interacted with the control. This is the one to style for an error: it behaves like the platform's `:user-invalid`, so an untouched field is not marked wrong before the user has had a chance to fill it in."
      },
      {
        "name": "user-valid",
        "description": "Valid, and the user has interacted with the control."
      },
      {
        "name": "dirty",
        "description": "The user has interacted with the control."
      },
      {
        "name": "error",
        "description": "The `error` property is set, or the control is `user-invalid`."
      },
      {
        "name": "warning",
        "description": "The `warning` property is set."
      },
      {
        "name": "ai",
        "description": "The `ai` property is set and the user has not interacted with the control yet."
      }
    ]
  },
  "import": "import '@eurodata/eurodata-ui/dist/components/textarea/textarea.js';",
  "react": {
    "component": "EdTextarea",
    "import": "import EdTextarea from '@eurodata/eurodata-ui/dist/react/textarea/index.js';"
  }
}
