Getting StartedInstall and bootstrap headless foundations 4
LayoutHeadless structural primitives for expandable and container patterns 6
OverlayHeadless modal and floating layer behavior 3
FeedbackHeadless notification and status communication patterns 5
FormHeadless input and selection contracts 17
UtilityReusable action, identity, and clipboard behavior 6
NavigationHeadless trails, trees, menus, and command surfaces 7

Styling contract

Style listbox states through public attributes and option hooks instead of relying on internal DOM assumptions.

The focus ring belongs on [tngListbox]. Option rows expose active and selected state visually, but they stay out of the sequential tab order.

CSS contract table

SelectorApplied onPurpose
[tngListbox]Listbox hostContainer layout, keyboard focus ring, and Tab-stop ownership.
[tngOption]Option hostTypography, spacing, and surface states.
[tngOption][data-active]Option hostKeyboard-active visual state.
[tngOption][data-selected]Option hostSelected item styling.
[tngOption][data-disabled]Option hostDisabled affordance and interaction cue.

State selectors

listbox.states.css

css
[tngListbox]:focus {
  border-color: var(--tng-semantic-accent-brand);
}

[tngOption][data-active] {
  border-color: var(--tng-semantic-accent-brand);
}

[tngOption][data-selected] {
  background: color-mix(in srgb, var(--tng-semantic-accent-brand) 15%, transparent);
}

[tngOption][data-disabled] {
  cursor: not-allowed;
  opacity: 0.56;
}

Example shells

listbox.contract.css

css
.project-listbox {
  border: 1px solid var(--tng-semantic-border-subtle);
  border-radius: 0.8rem;
  display: grid;
  gap: 0.45rem;
  outline: none;
  padding: 0.7rem;
}

.project-listbox:focus {
  border-color: var(--tng-semantic-accent-brand);
}

.project-listbox [data-selected] {
  background: color-mix(in srgb, var(--tng-semantic-accent-brand) 15%, transparent);
}

.project-listbox [data-active] {
  border-color: var(--tng-semantic-accent-brand);
}

.project-listbox [data-disabled] {
  cursor: not-allowed;
  opacity: 0.56;
}