← 全部 UI 规范

组件契约

textarea

原生 <textarea>,封装为设计系统的自定义元素——带 rows prop 的多行文本框,用 invalid+describedBy 表示错误状态,并在每次按键时触发 dsInput 事件。

版本
v1.0.0

Props

名称类型取值默认值
valuestring——
namestring——
placeholderstring——
disabledboolean—false
requiredboolean—false
invalidboolean—false
describedBystring——
labelstring——
rowsnumber—3
sizeenummd, lgmd

事件

名称载荷条件
dsInputstring—

Token

spacing
primitive.spacing.sm, primitive.spacing.md, primitive.spacing.lg, primitive.spacing.xl
radius
primitive.radius.sm, primitive.radius.md
font
primitive.font.family, primitive.font.size-md

无障碍

native_element
textarea
labeling
aria-label via the label prop (canonical) or ambient <label> wrapper (secondary, browser-computed accessible name).
keyboard
["Tab focuses (does not insert a tab character by default)","Enter inserts a newline (does not submit the enclosing form)","Printable characters insert at caret","Backspace/Delete edit natively","Arrow keys move caret"]
disabled_semantics
native_disabled_attribute (also disables the resize handle in our CSS)
error_semantics
aria-invalid (from `invalid` prop) + aria-describedby (from `describedBy` prop, expected to point at a light-DOM node id containing the error message)
required_semantics
aria-required (from `required` prop); visual asterisk is the consumer's responsibility
notes
label prop is REQUIRED for WCAG conformance — a <textarea> with no accessible name is an axe `label` violation. `placeholder` is a hint, not a label — always pair with `label`. Native vertical resize is kept enabled (`resize: vertical`); consumers that need a pinned height can override with `resize: none`.
经过校验的原始 JSON
{
  "name": "textarea",
  "version": "1.0.0",
  "props": {
    "value": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "placeholder": {
      "type": "string"
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "required": {
      "type": "boolean",
      "default": false
    },
    "invalid": {
      "type": "boolean",
      "default": false
    },
    "describedBy": {
      "type": "string"
    },
    "label": {
      "type": "string"
    },
    "rows": {
      "type": "number",
      "default": 3
    },
    "size": {
      "type": "enum",
      "values": [
        "md",
        "lg"
      ],
      "default": "md"
    }
  },
  "events": {
    "dsInput": {
      "payload": "string"
    }
  },
  "tokens_used": {
    "spacing": [
      "primitive.spacing.sm",
      "primitive.spacing.md",
      "primitive.spacing.lg",
      "primitive.spacing.xl"
    ],
    "radius": [
      "primitive.radius.sm",
      "primitive.radius.md"
    ],
    "font": [
      "primitive.font.family",
      "primitive.font.size-md"
    ]
  },
  "a11y": {
    "native_element": "textarea",
    "labeling": "aria-label via the label prop (canonical) or ambient <label> wrapper (secondary, browser-computed accessible name).",
    "keyboard": [
      "Tab focuses (does not insert a tab character by default)",
      "Enter inserts a newline (does not submit the enclosing form)",
      "Printable characters insert at caret",
      "Backspace/Delete edit natively",
      "Arrow keys move caret"
    ],
    "disabled_semantics": "native_disabled_attribute (also disables the resize handle in our CSS)",
    "error_semantics": "aria-invalid (from `invalid` prop) + aria-describedby (from `describedBy` prop, expected to point at a light-DOM node id containing the error message)",
    "required_semantics": "aria-required (from `required` prop); visual asterisk is the consumer's responsibility",
    "notes": "label prop is REQUIRED for WCAG conformance — a <textarea> with no accessible name is an axe `label` violation. `placeholder` is a hint, not a label — always pair with `label`. Native vertical resize is kept enabled (`resize: vertical`); consumers that need a pinned height can override with `resize: none`."
  }
}
ChiralFM