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
| Name | Type | Values | Default |
|---|---|---|---|
| value | string | — | — |
| name | string | — | — |
| type | enum | text, email, password, search, tel, url, number | text |
| placeholder | string | — | — |
| disabled | boolean | — | false |
| required | boolean | — | false |
| invalid | boolean | — | false |
| describedBy | string | — | — |
| label | string | — | — |
| size | enum | md, lg | md |
Events
| Name | Payload | Condition |
|---|---|---|
| dsInput | string | — |
Tokens
- spacing
- sm, md, lg, xl
- radius
- sm, md
- font
- family, 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": [
"sm",
"md",
"lg",
"xl"
],
"radius": [
"sm",
"md"
],
"font": [
"family",
"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."
}
}