Getting StartedInstallation and setup guides 5
LayoutWorkflow and structural layout components 7
OverlayModal and floating layer surfaces 3
FeedbackStatus, empty, progress, and loading placeholder patterns 5
FormInput and selection components 17
UtilityGeneral-purpose interface utilities 7
NavigationMenu surfaces and hierarchical actions 7

Styling contract

Style tng-form-field through host CSS variables and your own classes on projected prefix, suffix, and action elements.

Supported contract

The public styling path is the host token contract inherited from the shared input shell. Apply these vars on a class attached to <tng-form-field>.

Public host contract

css
.docs-form-field-shell {
  --tng-input-bg: var(--tng-semantic-background-surface);
  --tng-input-border: var(--tng-semantic-border-subtle);
  --tng-input-fg: var(--tng-semantic-foreground-primary);
  --tng-input-radius: 0.85rem;
  --tng-input-min-height: 2.75rem;
  --tng-input-px: 0.9rem;
  --tng-input-gap: 0.65rem;
  --tng-input-focus-ring: color-mix(in srgb, var(--tng-semantic-focus-ring) 24%, transparent);
  --tng-input-font-size: 0.96rem;
  --tng-input-line-height: 1.45;
  --tng-input-placeholder: var(--tng-semantic-foreground-muted);
}

Shell state ownership

The wrapper consumes the focus and validation states internally. If you need custom shell selectors keyed off data-focused or data-invalid, move to the headless <tng-input-group> primitive.

State ownership

html
/* <tng-form-field> exposes host tokens. */
/* Focus, invalid, disabled, and readonly attrs still live on the inner primitive group. */
/* If you need custom shell selectors keyed off those attrs, move to headless input-group. */

<tng-input-group class="docs-search-group">
  <span tngPrefix aria-hidden="true">Search</span>
  <input tngInput type="search" />
</tng-input-group>

.docs-search-group[data-focused] {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tng-semantic-focus-ring) 24%, transparent);
}

Workspace slug shell

Workspace slug shell

A projected suffix is often the reason to reach for form-field instead of the simple input component.

Workspace slug shell (Plain-CSS)

Projected content classes

Projected content classes

Theme the wrapper at the host, then style projected prefix, suffix, and action elements with your own classes.

Projected content classes

html
<div class="docs-search-shell">
  <tng-form-field>
    <span tngPrefix class="docs-search-prefix" aria-hidden="true">
      <tng-icon icon="search"></tng-icon>
    </span>
    <input tngInput type="search" placeholder="Search docs" />
    <button tngSuffix type="button" class="docs-search-action">Clear</button>
  </tng-form-field>
</div>

.docs-search-shell {
  --tng-input-border: var(--tng-semantic-border-subtle);
  --tng-input-radius: 0.85rem;
}

.docs-search-prefix { color: var(--tng-semantic-foreground-secondary); }
.docs-search-action { color: var(--tng-semantic-foreground-secondary); }

Headless escalation for shell state

The component wrapper keeps state selectors inside the primitive. Drop to headless input-group when you need custom focus or invalid selectors on the shell itself.

Headless escalation for shell state

html
/* <tng-form-field> exposes host tokens. */
/* Focus, invalid, disabled, and readonly attrs still live on the inner primitive group. */
/* If you need custom shell selectors keyed off those attrs, move to headless input-group. */

<tng-input-group class="docs-search-group">
  <span tngPrefix aria-hidden="true">Search</span>
  <input tngInput type="search" />
</tng-input-group>

.docs-search-group[data-focused] {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tng-semantic-focus-ring) 24%, transparent);
}