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

Imports

Primitive imports

ts
import {
  TngSelect,
  TngSelectContent,
  TngSelectIcon,
  TngSelectListbox,
  TngSelectOption,
  TngSelectOverlay,
  TngSelectTrigger,
  TngSelectValue,
} from '@tailng-ui/primitives';

Basic usage

Owned select composition

html
<section
  tngSelect
  [value]="selectedStage()"
  (valueChange)="onSelectedStageChange($event)"
>
  <button type="button" tngSelectTrigger>
    <span tngSelectValue>{{ selectedStageLabel() ?? 'Choose workflow stage' }}</span>
    <span tngSelectIcon aria-hidden="true">▾</span>
  </button>

  <div tngSelectContent class="docs-headless-selectbox-basic-content">
    <div tngSelectOverlay>
      <div
        tngSelectListbox
        [value]="selectedStage()"
        (valueChange)="onSelectedStageChange($event)"
      >
        @for (stage of workflowStages; track stage.value) {
          <div tngSelectOption [tngValue]="stage.value">{{ stage.label }}</div>
        }
      </div>
    </div>
  </div>
</section>

Select variants

The same headless select primitive rendered with an owned plain-CSS shell and a light Tailwind shell.

Workflow stage (Plain-CSS)

Workflow stage

Primitive-first single selection with an owned trigger and owned overlay rows.

Selected: In review

Behavior baseline

  • The trigger owns combobox semantics, focus, and aria-expanded.
  • The listbox bridge keeps active option state and committed value in sync.
  • Enter, Space, and pointer selection commit the active option and close the menu.
  • Use data-active, data-selected, and data-disabled for option state styling.