Skip to main content
cngx-src documentation

CngxCombobox

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/forms/select/combobox/combobox.component.ts

Import#

import { CngxCombobox } from '@cngx/forms/select'

Description#

Tag-input style multi-value combobox. Inline <input role="combobox"> next to a chip strip; typing filters the panel live, Backspace-on-empty removes the trailing chip.

Stateless graph in createSelectCore; this component is a thin adapter binding the trigger template to the core's signals plus value-shape write-paths (AD dispatch, Field↔sync, search filter).

https://cngxjs.github.io/cngx/examples/#/forms/select/combobox/combobox-basic-tag-picker-with-typeahead-filter https://cngxjs.github.io/cngx/examples/#/forms/select/combobox/combobox-clearable-custom-cngxselectclearbutton https://cngxjs.github.io/cngx/examples/#/forms/select/combobox/combobox-text-summary-via-cngxcomboboxtriggerlabel

Metadata#

Host#

Providers#

CNGX_FORM_FIELD_CONTROL
useExisting CngxCombobox
CNGX_SELECT_PANEL_HOST
useExisting CngxCombobox
CNGX_SELECT_PANEL_VIEW_HOST
useExisting CngxCombobox

Relationships

Index#

Inputs#

announceChanges#boolean | null
input()

Per-instance announcer override.

default null
input()

Per-instance formatter override.

default null
ariaLabel#string | null
input()

Explicit aria-label on the trigger.

default null, { alias: 'aria-label' }
ariaLabelledBy#string | null
input()

Explicit aria-labelledby on the trigger.

default null, { alias: 'aria-labelledby' }
autofocus#boolean
input()

One-shot autofocus on first render.

default false
caretGlyph#TemplateRef | null

Replaces the built-in caret glyph. Ignored when *cngxSelectCaret is projected.

default null
chipOverflow#NonNullable

Chip-strip overflow strategy. See CngxSelectConfig.chipOverflow.

default this.config.chipOverflow,
chipRemoveAriaLabel#string
input()

A11y label prefix for the per-chip remove button.

default this.config.ariaLabels?.chipRemove ?? 'Remove'
clearable#boolean
input()

Render a clear-all button when at least one value is selected.

default false
clearButtonAriaLabel#string
input()

A11y label for the clear-all button.

default this.config.ariaLabels?.clearButton ?? 'Reset selection',
clearGlyph#TemplateRef | null

Replaces the built-in glyph inside the default clear-all button. Ignored when *cngxSelectClearButton is projected.

default null
closeOnSelect#boolean
input()

Whether activating an option closes the panel. Default false (tag-input UX).

default false

Async write handler invoked per toggle.

default null
input()

Where commitAction errors render without a *cngxSelectCommitError template.

default this.config.commitErrorDisplay
input()

Commit UX mode.

default 'optimistic'

Equality function used to match values to options. Defaults to Object.is.

default cngxSelectDefaultCompare as CngxSelectCompareFn<T>,
disabledInput#boolean
input()

Disabled state. Merges with presenter.disabled().

default false, { alias: 'disabled' }
enterKeyHint#NonNullable

Mobile enterkeyhint. Default 'enter' - Combobox commits Enter without closing the panel.

default this.config.enterKeyHint ?? 'enter',
hideCaret#boolean
input()

Hide the default dropdown caret.

default !this.config.showCaret
hideSelectionIndicator#boolean
input()

Hide the default in-panel checkmark.

default !this.config.showSelectionIndicator
idInput#string | null
input()

Custom id. Defaults to the presenter-generated ID inside form-field.

default null, { alias: 'id' }
inputMode#NonNullable

Mobile inputmode attribute. Defaults from CngxSelectConfig.inputMode.

default this.config.inputMode
label#string
input()

Accessible label for the listbox region and fallback trigger name.

default ''
loading#boolean
input()

Loading state inside the panel.

default false
input()

First-load indicator variant.

default this.config.loadingVariant
maxVisibleChips#number
input()

Max chips in 'truncate' mode.

default this.config.maxVisibleChips

Options in data-driven mode (flat or grouped).

default [] as CngxSelectOptionsInput<T>
panelClass#string | readonly string[] | null
input()

Classes applied to the panel root. Merged with the library default.

default null
panelWidth#'trigger' | number | null
input()

Panel width strategy.

default this.config.panelWidth
placeholder#string
input()

Placeholder rendered inside the input when nothing is selected.

default ''
popoverPlacement#PopoverPlacement
input()

Popover placement relative to the trigger. Per-instance input wins over CngxSelectConfig.popoverPlacement.

default this.config.popoverPlacement
input()

Subsequent-load ("refreshing") indicator variant.

default this.config.refreshingVariant
requiredInput#boolean
input()

Required state. Merges with presenter.required().

default false, { alias: 'required' }
searchDebounceMs#number
input()

Debounce for search term updates (ms).

default this.config.typeaheadDebounceInterval
input()

Custom matcher for the inline CngxListboxSearch.

default null
selectionIndicatorPosition#'before' | 'after' | null
input()

Indicator position. null → inherit config.

default null
input()

Indicator variant. null → inherit config.

default null
skeletonRowCount#number
input()

Skeleton-row count when loadingVariant === 'skeleton'.

default this.config.skeletonRowCount
skipInitial#boolean
input()

Suppress the first searchTermChange emission (hydrate-time '').

default false

Async-state source for options.

default null
tabIndex#number
input()

Tab index on the inner <input>. Defaults to 0.

default 0
values#T[]
model()

Two-way multi-value binding.

default []

Outputs#

cleared#void
output()
closed#void
output()
commitError#unknown
output()
opened#void
output()
openedChange#boolean
output()
retry#void
output()
searchTermChange#string
output()
selectionChange#CngxComboboxChange
stateChange#AsyncStatus
output()
values#T[]
model()

Two-way multi-value binding.

Instance Properties#

commitState#unknown
Readonly

Read-only view of the commit lifecycle.

this.core.commitState
disabled#unknown
Readonly
this.core.disabled
isCommitting#unknown
Readonly

true while a commit is in flight.

this.core.isCommitting
retryFn#unknown
Readonly

Callback invoked when the user clicks the default retry button.

input<(() => void) | null>(null)
selectedOptions#unknown
ProtectedReadonly
computed<CngxSelectOptionDef<T>[]>(
  () => {
    const vals = this.values();
    if (vals.length === 0) {
      return [];
    }
    // Resolve selected values against the UNFILTERED option merge so
    // chips for previously-picked values remain visible when the
    // search term hides the matching option from the listbox.
    const eq = this.compareWith();
    const out: CngxSelectOptionDef<T>[] = [];
    const flat = this.core.unfilteredFlatOptions();
    for (const v of vals) {
      const match = flat.find((o) => eq(o.value, v));
      if (match) {
        out.push(match);
      }
    }
    return out;
  },
  {
    equal: (a, b) => {
      if (a === b) {
        return true;
      }
      if (a.length !== b.length) {
        return false;
      }
      for (let i = 0; i < a.length; i++) {
        if (!Object.is(a[i], b[i])) {
          return false;
        }
      }
      return true;
    },
  },
)

Methods#

clearLocalItems#void

Reset the local buffer. Idempotent.

close#void
focus#void
focus(options?: FocusOptions)
@paramoptions?FocusOptions
isEmpty#boolean
Protected
open#void
patchData#void
patchData(item: CngxSelectOptionDef<T>)

Append a pre-built option to the local buffer. Renders in the next panel emission and silently drops once the server includes a matching value. Idempotent under compareWith.

toggle#void

HostBindings#

BindingExpression
[id]resolvedId()
[attr.aria-readonly]ariaReadonly()

Structural styles shared across the entire CngxSelect family - imported via styleUrls from every variant (CngxSelect, CngxMultiSelect, CngxCombobox, CngxTypeahead, CngxTreeSelect, CngxReorderableMultiSelect, CngxActionSelect, CngxActionMultiSelect, CngxSelectShell, and the panel components).

All variants run encapsulation: None so the rules below are global; the .cngx-select__* BEM-style class prefix is the namespace.

State modifiers

  • .cngx-option--highlighted on an option row - primary-tinted background marking the keyboard-focused row
  • [aria-disabled='true'] on an option - opacity 0.5 + cursor: not-allowed
  • .cngx-select__option--pending - cursor: progress while a row's commit is in flight
  • .cngx-select__chip-list--reordering - whole-strip cursor: grabbing while a drag is active
  • .cngx-select__chip--dragging on a chip - Trello-style lift (shadow + scale + tilt + accent fill)
  • .cngx-select__chip--drag-over on a chip - vertical drop bar painted on the leading edge via ::before

Variants

Chip-list overflow modes via data-overflow:

  • default - flex-wrap chips across multiple rows
  • data-overflow='scroll-x' - single row + horizontal scroll
  • data-overflow='truncate' - single row + clipped overflow + the .cngx-select__chip-overflow-badge count pill

Error surfaces with two layouts:

  • .cngx-select__error - column-stacked block (message + retry)
  • .cngx-select__error--inline - inline banner above the option list
  • .cngx-select__commit-error - per-commit failure banner

Slots

  • .cngx-select__panel - the floating panel surface (anchor-positioned via position-try-fallbacks)
  • .cngx-select__group-header - uppercase optgroup label
  • .cngx-select__option / .cngx-select__check - option row + the selected-state checkmark
  • .cngx-select__loading / .cngx-select__empty - inline message rows
  • .cngx-select__skeleton / .cngx-select__skeleton-row - first-load shimmer placeholders (static under prefers-reduced-motion)
  • .cngx-select__spinner-wrap / .cngx-select__spinner - first-load spinner ring
  • .cngx-select__loading-bar - first-load top-edge progress bar
  • .cngx-select__refreshing / .cngx-select__refreshing-spinner / .cngx-select__refreshing-dots - subsequent-load indicators
  • .cngx-select__option-spinner / .cngx-select__option-error - per-row commit feedback
  • .cngx-select__chip-list / .cngx-select__chip-overflow-badge - chip strip + overflow count
  • .cngx-select__chip-wrap / .cngx-select__chip-handle - reorderable chip surface + optional drag-handle glyph
  • .cngx-select__error / .cngx-select__error--inline / .cngx-select__error-message / .cngx-select__error-retry / .cngx-select__commit-error - error block, banner, and retry pieces

Inheritance

Tokens are registered top-level in @layer cngx.tokens via @property so any consumer (cngx.theme layer, app layer) can override without learning the type.

Panel surface, every primary-tinted glyph, and every danger-toned error surface delegate to the foundation so a dark-mode swap cascades through the floating panel even when anchor positioning detaches it from the trigger's DOM context:

  • --cngx-select-panel-border -> --cngx-color-border
  • --cngx-select-panel-bg -> --cngx-color-surface
  • --cngx-select-panel-color -> --cngx-color-text
  • --cngx-select-panel-shadow -> --cngx-shadow-md
  • --cngx-select-check-color -> --cngx-color-primary
  • --cngx-select-spinner-color -> --cngx-color-primary
  • --cngx-select-loading-bar-color -> --cngx-color-primary
  • --cngx-select-refreshing-color -> --cngx-color-primary
  • --cngx-select-option-spinner-color -> --cngx-color-primary
  • --cngx-select-option-error-color -> --cngx-color-danger
  • --cngx-select-error-color -> --cngx-color-danger
  • --cngx-select-chip-remove-hover-color -> --cngx-color-danger
  • --cngx-select-chip-drag-bg -> --cngx-color-primary
  • --cngx-select-chip-drop-bar-color -> --cngx-color-primary
  • --cngx-select-trigger-invalid-border-color -> --cngx-color-danger
  • --cngx-select-trigger-invalid-outline-color -> --cngx-color-danger

--cngx-select-panel-min-width is intentionally NOT registered via @property so the anchor-size(width) fallback survives when the consumer doesn't override it; registering it with any initial-value would shadow the var() fallback and break anchor positioning.

Dark mode

Three hooks swap alpha-on-black surfaces (panel shadow, option highlight, spinner track, chip-overflow tint, chip remove-hover tint, chip handle muted, chip drag shadow) plus the skeleton shimmer gradient and the option-spinner track:

  • prefers-color-scheme: dark
  • [data-color-scheme="dark"]
  • .dark class

Foundation-delegated tokens ride the foundation cascade unchanged.

Pair with

  • @cngx/themes/material/select-theme - Material 3 surface treatment across the entire family

Trigger skin for CngxCombobox - tag-input variant where the inline <input> IS the combobox's focusable element. The host carries .cngx-combobox; structural parts shared with the rest of the select family (panel frame, option rows, loading variants, chip-list flex-wrap layout, error surfaces) ride on shared/select-base.css. This file owns the role="group" wrapper, the inline <input>, the caret glyph, and the clear-all button.

State modifiers

  • :focus-within on .cngx-combobox__trigger - focus-ring outline
    • offset
  • [aria-disabled='true'] on the trigger - opacity dim + cursor: not-allowed
  • :has(> [role='combobox'][aria-invalid='true']) on the trigger - danger border + box-shadow glow at focus time (paints on the visible wrapper without a TS-side rebind since role="combobox" lives on the input)
  • .cngx-combobox__input::placeholder - muted placeholder via the shared --cngx-select-placeholder-color token
  • :hover on .cngx-combobox__clear-all - opacity 1
  • :focus-visible on the clear-all button - 2px primary outline

Slots

  • .cngx-combobox__root - display: contents host shim
  • .cngx-combobox__trigger - the bordered row
  • .cngx-combobox__input - the role="combobox" text input
  • .cngx-combobox__trigger-label - *cngxComboboxTriggerLabel slot for text summary
  • .cngx-combobox__clear-all - reset-all button
  • .cngx-combobox__caret - panel-state glyph

Inheritance

Trigger tokens delegate up the family chain:

  • --cngx-combobox-* -> --cngx-select-* -> hardcoded
  • --cngx-combobox-border -> --cngx-color-border
  • --cngx-combobox-focus-outline -> --cngx-color-primary
  • invalid surfaces fall back to --cngx-select-trigger-invalid-* -> --cngx-color-danger

Once registered via @property the inner var() steps are documentation-only; system tokens (--cngx-color-*) are the brand-wide override path.

Pair with

  • @cngx/themes/material/select-theme - Material 3 surface treatment shared across the entire select family

Index#

Surface

--cngx-select-panel-border#*
Default value 1px solid oklch(0.85 0.01 250)

Border shorthand of the dropdown panel. Falls back through --cngx-color-border. inherits: true so the :root delegating value reaches the floating panel host (anchor-positioned, may sit outside the normal DOM flow).

See: [[--cngx-color-border]]

--cngx-select-panel-bg#<color>
Default value oklch(1 0 0)

Background of the dropdown panel. Falls back through --cngx-color-surface.

See: [[--cngx-color-surface]]

--cngx-select-panel-color#*
Default value currentColor

Text color inside the panel. syntax: '*' + initial-value currentColor lets the panel inherit text color from its ancestor by default. Registering as <color> would forbid currentColor since <color> requires a computationally- independent value.

--cngx-select-panel-shadow#*
Default value 0 4px 12px oklch(0 0 0 / 0.12)

Drop-shadow shorthand. Falls back through --cngx-shadow-md. inherits: true so the :root dark-mode override (deeper shadow on dark) reaches the floating panel host.

--cngx-select-placeholder-color#<color>
Default value oklch(0 0 0 / 0.5)

Color of the placeholder text shown when no value is selected.

--cngx-select-caret-color#<color>
Default value oklch(0 0 0 / 0.5)

Color of the dropdown caret glyph shared across every variant. Muted by default to mirror the placeholder token; the Material bridge maps it to --mat-sys-on-surface-variant. inherits: true so a trigger-level override reaches the glyph element.

--cngx-select-clear-color#<color>
Default value oklch(0 0 0 / 0.5)

Color of the clear-button glyph shared across every variant. Tracks the same muted default as the caret so both trigger affordances read uniformly. inherits: true so a trigger-level override reaches the glyph element.

--cngx-combobox-border#*
Default value 1px solid oklch(0.85 0.01 250)

Border shorthand of the trigger.

--cngx-combobox-bg#<color>
Default value transparent

Background of the trigger.

--cngx-combobox-color#*
Default value currentColor

Text color of the trigger.

Layout

--cngx-select-panel-radius#*
Default value 0.25rem

Corner radius of the dropdown panel.

--cngx-select-panel-padding#*
Default value 0.25rem

Inner padding of the panel.

--cngx-select-panel-max-height#*
Default value 16rem

Maximum height before vertical scrolling kicks in.

--cngx-select-option-padding#*
Default value 0.375rem 0.5rem

Padding shorthand of each option row.

--cngx-select-option-min-height#*
Default value auto

Minimum height of an option row - defaults to auto so dense rows stay compact.

--cngx-select-option-radius#*
Default value 0.125rem

Corner radius of an option row.

--cngx-select-caret-size#*
Default value 1.25em

Font-size of the dropdown caret glyph shared across every variant.

--cngx-select-chip-gap#*
Default value 0.25rem

Gap between chips inside the trigger chip list.

--cngx-select-chip-wrap-radius#*
Default value 0.25rem

Corner radius of the reorderable chip wrap container.

--cngx-select-chip-wrap-gap#*
Default value 0.25rem

Gap between the chip body and any projected drag handle.

--cngx-combobox-min-width#*
Default value 12rem

Minimum inline size of the trigger.

--cngx-combobox-gap#*
Default value 0.375rem

Gap between the chip list, input, caret, and clear-all button.

--cngx-combobox-padding#*
Default value 0.25rem 0.375rem

Padding shorthand of the trigger.

--cngx-combobox-radius#*
Default value 0.25rem

Corner radius of the trigger.

--cngx-combobox-min-height#*
Default value 2.25rem

Minimum block size of the trigger - fits a single row of chips.

--cngx-combobox-input-flex-basis#*
Default value 4rem

Flex basis of the inline input - sets the preferred starting width before the input grows or shrinks.

--cngx-combobox-input-min-width#*
Default value 4rem

Minimum inline size of the inline input - keeps the input tappable even when chips dominate the trigger row.

State / Highlighted

--cngx-select-option-highlight-bg#<color>
Default value oklch(0.66 0.19 50 / 0.1)

Background of the keyboard-highlighted option row. Defaults to a low-alpha tint of --cngx-color-primary so the highlight reads as brand-accented without competing with selection state.

See: [[--cngx-color-primary]]

State / Selected

--cngx-select-check-color#<color>
Default value oklch(0.66 0.19 50)

Color of the selected-option checkmark glyph. Falls back through --cngx-color-primary.

See: [[--cngx-color-primary]]

State / Disabled

--cngx-select-disabled-opacity#<number>
Default value 0.5

Opacity multiplier applied when the trigger is disabled. Shared family-wide so every variant dims its disabled trigger identically.

--cngx-combobox-disabled-opacity#<number>
Default value 0.5

Opacity multiplier applied when the trigger is disabled.

State / Loading

--cngx-select-skeleton-gap#*
Default value 0.25rem

Vertical gap between skeleton placeholder rows.

--cngx-select-skeleton-padding#*
Default value 0.25rem

Padding around the skeleton placeholder block.

--cngx-select-skeleton-row-height#*
Default value 1.75rem

Height of each skeleton placeholder row.

--cngx-select-skeleton-row-radius#*
Default value 0.125rem

Corner radius of each skeleton placeholder row.

--cngx-select-spinner-padding#*
Default value 1rem

Padding around the first-load spinner wrapper.

--cngx-select-spinner-size#*
Default value 1.5rem

Diameter of the first-load spinner ring.

--cngx-select-spinner-border#*
Default value 2px solid oklch(0 0 0 / 0.15)

Track stroke of the first-load spinner ring. inherits: true so the :root dark-mode override (alpha-on-white on dark) reaches the spinner inside the floating panel.

--cngx-select-spinner-color#<color>
Default value oklch(0.66 0.19 50)

Indicator stroke of the first-load spinner ring. Falls back to --cngx-color-primary.

--cngx-select-loading-bar-height#<length>
Default value 3px

Height of the first-load loading bar.

--cngx-select-loading-bar-color#<color>
Default value oklch(0.66 0.19 50)

Color of the first-load loading bar. Falls back to --cngx-color-primary.

State / Refreshing

--cngx-select-refreshing-height#<length>
Default value 2px

Height of the subsequent-load refreshing bar.

--cngx-select-refreshing-color#<color>
Default value oklch(0.66 0.19 50)

Color of the refreshing bar gradient. Falls back to --cngx-color-primary.

--cngx-select-refreshing-spinner-padding#*
Default value 0.25rem

Padding around the refreshing spinner wrapper.

--cngx-select-refreshing-dots-gap#*
Default value 0.25rem

Gap between the three refreshing dots.

--cngx-select-refreshing-dots-padding#*
Default value 0.375rem

Padding around the refreshing dots block.

--cngx-select-refreshing-dot-size#*
Default value 0.375rem

Diameter of each refreshing dot.

--cngx-select-refreshing-dot-color#*
Default value currentColor

Color of each refreshing dot.

State / Commit

--cngx-select-option-spinner-size#*
Default value 0.875rem

Diameter of the per-row commit spinner.

--cngx-select-option-spinner-color#<color>
Default value oklch(0.66 0.19 50)

Indicator stroke of the per-row commit spinner.

--cngx-select-option-error-color#<color>
Default value oklch(0.6 0.18 25)

Glyph color of the per-row commit error indicator. Falls back to --cngx-color-danger.

--cngx-select-commit-error-padding#*
Default value 0.375rem 0.5rem

Padding of the commit error banner.

--cngx-select-commit-error-radius#*
Default value 0.125rem

Corner radius of the commit error banner.

State / Overflow

--cngx-select-chip-overflow-badge-bg#<color>
Default value oklch(0 0 0 / 0.08)

Background of the chip overflow badge shown in truncate overflow mode.

--cngx-select-chip-overflow-badge-color#<color>
Default value oklch(0 0 0 / 0.6)

Text color of the chip overflow badge.

State / Remove

--cngx-select-chip-remove-size#*
Default value 1.25rem

Hit-target diameter of the chip remove button inside a reorderable chip wrap.

--cngx-select-chip-remove-hover-bg#<color>
Default value oklch(0 0 0 / 0.12)

Background tint of the chip remove button on hover.

--cngx-select-chip-remove-hover-color#<color>
Default value oklch(0.6 0.18 25)

Foreground color of the chip remove button on hover. Falls back to --cngx-color-danger.

State / Reorder

--cngx-select-chip-handle-color#<color>
Default value oklch(0.5 0.01 250)

Color of the optional projected drag-handle glyph.

--cngx-select-chip-handle-size#*
Default value 0.75rem

Font-size of the optional projected drag-handle glyph.

State / Dragging

--cngx-select-chip-drag-shadow#*
Default value 0 8px 20px oklch(0 0 0 / 0.28)

Drop-shadow of the chip lifted into the dragging state. inherits: true so the :root dark-mode override (deeper shadow on dark) reaches the chip while it's being dragged.

--cngx-select-chip-drag-bg#<color>
Default value oklch(0.66 0.19 50)

Background of the chip lifted into the dragging state. Falls back to --cngx-color-primary.

See: [[--cngx-color-primary]]

--cngx-select-chip-drag-color#<color>
Default value oklch(1 0 0)

Text color of the chip lifted into the dragging state.

--cngx-select-chip-drag-scale#<number>
Default value 1.06

Scale multiplier of the dragging chip - Trello-style lift.

--cngx-select-chip-drag-tilt#<angle>
Default value -1.5deg

Rotation tilt applied to the dragging chip - Trello-style lift.

--cngx-select-chip-drop-bar-width#<length>
Default value 3px

Width of the drop-indicator bar between chips.

--cngx-select-chip-drop-bar-color#<color>
Default value oklch(0.66 0.19 50)

Color of the drop-indicator bar between chips. Falls back to --cngx-color-primary.

State / Error

--cngx-select-error-gap#*
Default value 0.5rem

Gap between the error message and the retry button.

--cngx-select-error-padding#*
Default value 0.5rem 0.75rem

Padding of the panel-wide error block.

--cngx-select-error-color#<color>
Default value oklch(0.6 0.18 25)

Text color of every error surface. Falls back to --cngx-color-danger.

See: [[--cngx-color-danger]]

--cngx-select-error-inline-padding#*
Default value 0.375rem 0.5rem

Padding of the inline error banner shown above the option list.

--cngx-select-error-inline-radius#*
Default value 0.125rem

Corner radius of the inline error banner.

--cngx-select-error-retry-border#*
Default value 1px solid currentColor

Border shorthand of the error retry button.

State / Trigger invalid

--cngx-select-trigger-invalid-border-color#<color>
Default value oklch(0.6 0.18 25)

Border color painted on the trigger wrapper when aria-invalid="true". Defaults track --cngx-color-danger via the delegating :root entry below.

--cngx-select-trigger-invalid-border-width#<length>
Default value 1px

Border width painted on the trigger wrapper when aria-invalid="true".

--cngx-select-trigger-invalid-outline-color#<color>
Default value oklch(0.6 0.18 25)

Outline color layered on the invalid trigger when focus is inside it. Defaults track --cngx-color-danger via the delegating :root entry below.

--cngx-select-trigger-invalid-glow#*
Default value 0 0 0 3px oklch(0.6 0.18 25 / 0.2)

Soft halo layered behind the invalid trigger at focus time. Authored as a box-shadow so it composes with any consumer-supplied focus outline.

State / Focus

--cngx-combobox-focus-outline#*
Default value 2px solid oklch(0.66 0.19 50)

Focus-ring outline shorthand applied on :focus-within. Falls back to --cngx-color-primary.

See: [[--cngx-color-primary]]

State / Clear

--cngx-combobox-clear-opacity#<number>
Default value 0.6

Resting opacity of the clear-all button.

Material theme

import { ChangeDetectionStrategy, Component, ViewEncapsulation, signal } from '@angular/core';

import { CngxCombobox, type CngxSelectOptionDef } from '@cngx/forms/select';

/**
 * `CngxCombobox` rendered against a Material 3 palette via the published
 * `@cngx/themes/material/select-theme` bridge.
 *
 * The stylesheet builds a real M3 theme: `mat.theme` emits the `--mat-sys-*`
 * system tokens, then `select.theme($theme)` routes every `--cngx-select-*`
 * token onto its Material counterpart, so the tag-input trigger, chip strip,
 * and panel surface inherit the palette with no per-instance overrides.
 * `ViewEncapsulation.None` lets the global `html` theme and the
 * `:where(cngx-combobox)` bridge rules reach both the trigger and the
 * top-layer panel.
 */
@Component({
  selector: 'app-root',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  imports: [CngxCombobox],
  styleUrl: './material-theme.component.scss',
  template: `
    <div class="demo">
      <cngx-combobox
        [label]="'Favorite colors'"
        [options]="colors"
        [(values)]="values"
        placeholder="Type to filter…"
      />
      <p class="demo__readout">Selected: {{ values().length ? values().join(', ') : '—' }}</p>
    </div>
  `,
})
export class MaterialThemeExample {
  protected readonly values = signal<string[]>([]);

  protected readonly colors: CngxSelectOptionDef<string>[] = [
    { value: 'red', label: 'Red' },
    { value: 'green', label: 'Green' },
    { value: 'blue', label: 'Blue' },
    { value: 'amber', label: 'Amber' },
    { value: 'violet', label: 'Violet' },
  ];
}
export { MaterialThemeExample as AppComponent };