Skip to content

value

The value part role marks the text element that stands in for a control’s value in the design.

Why it matters

A designed text input is a stack of styled layers: a value text node, a placeholder text node, decorations, wrappers. A native <input> is one element with attributes. Collapse replaces the stack with the native control, and it is driven by annotation rather than discovery: the author marks what matters, and everything unannotated is chrome by declaration. Without value, the transform would have to guess which text node is the value.

The name is specs-native — ARIA has no vocabulary for pieces of a component, so the part vocabulary supplies one.

Emission

Scaffold

WhereWhat is emitted
The value element itselfConsumed by collapse — its text seeds the emitted control’s value; the element does not render
The resolved controlThe native control renders with that value; its own contract carries the change signal

The sibling placeholder part works the same way: consumed into the control’s placeholder attribute rather than rendered.

Unannotated descendants of a collapsing control do not render — the author declared what mattered by annotating it. Expect this and place the role accordingly: chrome that should keep rendering (icons, affordance buttons) belongs beside the collapsing container, not inside it. A bare wrapper drops silently; anything with content of its own — a text node, a glyph, an image, a composed instance — is named in a warning, as are a slot and a non-part role.

Contract

None. Like most parts, value adds no props and no handlers — it only tells the control where its value lives. The control’s own role carries the event surface: its onChange fires on every keystroke (text family) or on drag and arrow keys (slider).

The only parts that carry handlers sit beside value on a spinbutton: increment and decrement each emit a real <button> whose onClick calls stepUp() / stepDown() on the control. Both delegate to the control rather than owning behavior themselves.

How it resolves

  • Accepted only by value-bearing control concepts (textbox, password, searchbox, spinbutton, slider, textarea) — so it resolves to the component’s single value-bearing control, wherever either element sits in the layout. No tree walk, no ambiguity.
  • At most one element per part role per control: two elements both claiming value for the same control is an error naming both.
  • A value with no candidate control in its own component is valid and self-describing — it emits its own semantics but no wiring, which arrives when composed.

Platforms

EmitsBehavior a user gets
WebThe native control’s value (and placeholder)One real editable value — no phantom text layers behind the field
iOSThe text field’s bound valueVoiceOver reads the field’s current value
AndroidThe text field state’s valueTalkBack reads the field’s current value

Before and after

Without the role:

{/* … */}
<div className="ds-input-field">
<div className="ds-input-value">{p.value}</div>
<div className="ds-input-placeholder">{p.placeholder}</div>
</div>
{/* … */}

With the role (both text layers annotated):

{/* … */}
<input
className="ds-input-field"
value={value}
placeholder={p.placeholder}
onChange={handleChange}
/>
{/* … */}

See also

  • textbox — the flagship collapse consumer
  • label — lifted out of the collapse rather than consumed
  • Roles overview — how roles and the states convention fit together