← All UI specs

Component contract

input

Native <input> wrapped as a design-system custom element — supports text/email/password/search/tel/url/number types, invalid+describedBy for error states, and emits dsInput with the current value on every keystroke.

Version
v1.0.0

Props

NameTypeValuesDefault
valuestring——
namestring——
typeenumtext, email, password, search, tel, url, numbertext
placeholderstring——
disabledboolean—false
requiredboolean—false
invalidboolean—false
describedBystring——
labelstring——
sizeenummd, lgmd

Events

NamePayloadCondition
dsInputstring—

Tokens

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

Accessibility

native_element
input
labeling
aria-label via the label prop (canonical) or ambient <label> wrapper (secondary, browser-computed accessible name).
keyboard
["Tab focuses","Printable characters insert at caret","Backspace/Delete edit natively","Arrow keys move caret (Up/Down step numeric value when type=number)","Enter may submit the enclosing form for type=search"]
disabled_semantics
native_disabled_attribute
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 — an <input> with no accessible name is an axe `label` violation. `placeholder` is a hint, not a label — always pair with `label`. `autocomplete` is intentionally not exposed in v1; consumers that need password-manager hints for password fields can render a native <input> for that field until the prop is added.
Raw validated JSON
{
  "name": "input",
  "version": "1.0.0",
  "props": {
    "value": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "type": {
      "type": "enum",
      "values": [
        "text",
        "email",
        "password",
        "search",
        "tel",
        "url",
        "number"
      ],
      "default": "text"
    },
    "placeholder": {
      "type": "string"
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "required": {
      "type": "boolean",
      "default": false
    },
    "invalid": {
      "type": "boolean",
      "default": false
    },
    "describedBy": {
      "type": "string"
    },
    "label": {
      "type": "string"
    },
    "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": "input",
    "labeling": "aria-label via the label prop (canonical) or ambient <label> wrapper (secondary, browser-computed accessible name).",
    "keyboard": [
      "Tab focuses",
      "Printable characters insert at caret",
      "Backspace/Delete edit natively",
      "Arrow keys move caret (Up/Down step numeric value when type=number)",
      "Enter may submit the enclosing form for type=search"
    ],
    "disabled_semantics": "native_disabled_attribute",
    "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 — an <input> with no accessible name is an axe `label` violation. `placeholder` is a hint, not a label — always pair with `label`. `autocomplete` is intentionally not exposed in v1; consumers that need password-manager hints for password fields can render a native <input> for that field until the prop is added."
  }
}
ChiralFM