Input

A labelled field with validation messages and value-change events.

A delivery address

Labels, values and controls align in a compact group. All values are fictional.

An edition reference

A validation message stays with its field; a locked value retains the field geometry.

Type something

The input-change event shows the current value below.

Error and disabled states

Error messages belong to the field they explain.

Give a field a visible label. A placeholder is a hint, not a label. Put the reason for an error in error, next to the field that needs attention.

AttributeTypeDefaultWhat it does
typestringtextNative input type, including email, password, number, date, month, week and time.
namestringEmptyKey in form data.
valuestringEmptyCurrent value.
labelstringEmptyVisible field label.
label-textstringEmptyTranslation key for the label.
placeholderstringEmptyHint inside an empty field.
placeholder-keystringEmptyTranslation key for the hint.
error / error-textstringEmptyLiteral error or its translation key.
disabled, readonly, requiredbooleanfalseNative field states.
variantstringdefaultdefault, filled, outlined, row (18px field in a 20px row), field (20px form control) or plain (transparent inline field).
revealablebooleanfalseShow a password visibility button; the public type stays password.
quiet-focusbooleanfalseSuppress the field focus box when its surrounding form supplies the focus treatment.
inputmodestringEmptyNative mobile keyboard hint, such as numeric.
enterkeyhintstringEmptyLabel of the touch keyboard’s return key: enter, done, go, next, previous, search or send. Text areas take it too.
liststringEmptyThe id of a <datalist> beside the field. Its options are mirrored inside the field, which a shadow root would otherwise keep from reaching them, and follow its changes.
suggestionsproperty[]Suggestions offered while typing, as strings or { value, label }; wins over list. The React Input takes it as a prop.
aria-label / aria-labelledbystringEmptyName the native field, including labels in the parent shadow root.
aria-invalidstringEmptyForward an application validation state to the native field.
aria-describedbystringEmptyCopy the referenced description into the field’s shadow root.
spellcheckstringEmptyNative spelling hint, true or false.
autocompletestringFrom typeWhat the browser may fill in, such as name, email or new-password. Without it, email, tel and url fields say so, password is current-password, and any other field is left to the browser as a native input is. off turns autofill off.

Native constraints include min, max, step, pattern, minlength and maxlength.

const field = document.querySelector('ds-input');
field.addEventListener('input-change', (event) => {
console.log(event.detail.name, event.detail.value);
});

input and change bubble through shadow boundaries once, with the host’s current value. input-change also supplies { name, value }.

The component participates in native forms through ElementInternals: a named field contributes to FormData, constraints and error affect form validity, reset restores its initial value and a disabled fieldset disables its control. checkValidity() and reportValidity() expose native validation.

Import DS1/1-root/component-tokens.css and set --ds-sf to the surface scale. The row treatment, password visibility, quiet focus and field colours are shared capabilities; configure them with attributes and --ds-input-* tokens rather than injecting styles or buttons into the shadow root.

--ds-sf is an absolute scale: 1 gives a 20px row and 14px text; 1.5 gives 30px and 21px. Shared components resolve their measures at their own host, so a nested scale does not multiply its parent’s scale. Add data-ds-surface to an ordinary layout container when its --ds-unit-based spacing should use that scale too.

<section data-ds-surface style="--ds-sf: 1.5">
<ds-input variant="field" label="Name"></ds-input>
<ds-text literal>Scaled with the field</ds-text>
</section>

Colours and typefaces inherit as usual. Resolved dimensions such as --ds-row-height and --ds-type-size-default are local to each component; set a one-off override on that host. To carry a measure through a whole subtree, use an unscaled base token (--ds-row-size, --ds-control-size, --ds-text-size, --ds-small-text-size, --ds-heading-text-size, --ds-text-leading, --ds-text-tracking, --ds-corner-size or --ds-card-corner-size). Its component computes the scaled value. Keep DS1’s default measures unless the existing product layout requires an explicit exception.

<ds-input variant="row" type="password" name="password"
aria-label="Password" autocomplete="current-password" revealable></ds-input>

input-focus and input-blur report focus changes. Call focus(), blur(), select() or setSelectionRange() on the component. selectionStart, selectionEnd and valueAsNumber expose the native field state. External HTML labels focus the field; Enter activates its form’s enabled submit button unless an application keyboard handler cancels the event.

Selecting input in a product’s component copy also copies the shared react/input.ts adapter. Register the copied components through the product’s browser entry, then import the adapter. It contains no visuals; ds-input owns the control. Registration must be browser-only in an application that renders on the server.

import { Input, type InputElement } from './design/react/input';
<Input name="name" label="Name" value={name} onChange={event => setName(event.target.value)}
required />

The adapter types the element’s words as props: label (as written) and labelText (a translation key) draw the label row, placeholderKey and errorText are the translated hint and error beside placeholder and error. The keys reach the element as label-text, placeholder-key and error-text. Textarea takes the same.

The React adapter defaults to variant="field". It supports controlled value, uncontrolled defaultValue, native hints such as autoComplete, keyboard and focus handlers, and refs typed as InputElement. Event target and currentTarget refer to the shared element. Controlled values are restored when an application rejects an edit or a form resets. React remains an optional peer dependency.

Use the input for text, email, password, number, date and time fields. File, colour, checkbox and radio inputs and composite comboboxes need their own shared controls. A combobox’s listbox and active-option relationships cannot be passed through as plain text-field attributes.

Form · Languages

Set data-ds-shape="square", "rounded" or "circular" on the page, a data-ds-surface container, or one shared control. DS1 supplies the corner shape and the button inset; the product stores the preference. Rounded uses 4px arcs, or 8px squircles where supported. Circular keeps true round ends. Every radius follows the component’s own --ds-sf, including nested scales. Without the attribute, controls use their normal DS1 defaults.

Buttons, fields, checkboxes, switches, selects and color fields share the preference. Row and plain inputs and compact menu entries retain their square edges. Multiline fields keep small 4px corners so a circular preference cannot cut into writing; --ds-textarea-radius can configure those separately. A surface can set the unscaled --ds-corner-size, --ds-corner-shape and --ds-button-inset tokens; a specific field can set --ds-input-radius. Do not inject product styles into a shared shadow root or restyle its native light-DOM frame. Preference changes do not animate corners or padding.

multiline makes the field a text area: the same labels, controlled value, selection, validation, reset and form participation across whole rows.

<label for="description">Description</label>
<ds-input multiline id="description" name="description" rows="3" required></ds-input>

rows sets the starting height in 20px rows, scaled by --ds-sf. auto-grow grows and shrinks with the content up to max-rows (default 10), then scrolls; it follows width, surface scale and loaded-font changes, so a product keeps no height measurements or resize handlers of its own. Without it, the field can be resized vertically. wrap accepts soft, hard or off. Enter inserts a newline and does not activate the surrounding form; a product’s keyboard handler may implement a deliberate send action and cancel the event. The default field variant uses the standard control treatment; variant="plain" removes the field background and border for an inline editor. --ds-textarea-height and --ds-textarea-padding configure the field through public tokens, and automatic growth takes ownership of height. In React, <Input multiline rows={3} autoGrow maxRows={8} />.