Skip to main content
cngx-src documentation

CngxFilterBuilder

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/forms/filter-builder/filter-builder.component.ts

Import#

import { CngxFilterBuilder } from '@cngx/forms/filter-builder'

Description#

Recursive query-builder component. Brain lives entirely in CngxFilterBuilderPresenter (host directive). This component is the thin render shell: hosts the slot contentChildren and mounts the body resolved through CNGX_FILTER_BUILDER_BODY_HOST (default CngxFilterBuilderBody). State-driven UI (loading / error / refreshing) is the consumer's concern - wrap with <cngx-async-container [state]>. The live-region announcer is bound here so AT updates stay outside the body's recursive render path.

https://cngxjs.github.io/cngx/examples/#/forms/filter-builder/basic-two-way-binding-json-inspection https://cngxjs.github.io/cngx/examples/#/forms/filter-builder/filter-builder-async-state/loading-error-content-branches-via-cngx-async-container https://cngxjs.github.io/cngx/examples/#/forms/filter-builder/filter-builder-json/builder-json https://cngxjs.github.io/cngx/examples/#/forms/filter-builder/seeded-tree-and-or-composition

Metadata#

Host#

Dependencies#

CNGX_FILTER_BUILDER_BODY_HOSTinject()bodyType

Relationships

Index#

Instance Properties#

addFilterButtonSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderAddFilterButton)
addGroupButtonSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderAddGroupButton)
emptySlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderEmpty)
expressionTemplateSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderExpressionTemplate)
groupTemplateSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderGroupTemplate)
logicToggleSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderLogicToggle)
negationToggleSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderNegationToggle)
removeButtonSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderRemoveButton)
templates#unknown
ProtectedReadonly
injectFilterBuilderTemplateRegistry({
  empty: this.emptySlot,
  expressionTemplate: this.expressionTemplateSlot,
  groupTemplate: this.groupTemplateSlot,
  addFilterButton: this.addFilterButtonSlot,
  addGroupButton: this.addGroupButtonSlot,
  removeButton: this.removeButtonSlot,
  logicToggle: this.logicToggleSlot,
  negationToggle: this.negationToggleSlot,
  valueEditor: this.valueEditorSlot,
})
valueEditorSlot#unknown
contentChild()ProtectedReadonly
contentChild(CngxFilterBuilderValueEditor)

HostBindings#

BindingExpression
[attr.aria-disabled]ariaDisabled()

Default visuals for CngxFilterBuilder. The host cngx-filter-builder owns the outer container, group rails, indent / border accents, action-button row, and the empty-state typography. Group-row children (cngx-filter-row, cngx-filter-expression-row) are display: contents wrappers that delegate their flex layout back to the .cngx-filter-builder__expression class declared here. Surfaces stay neutral - borders track --cngx-color-border, the remove-button error tone tracks --cngx-color-danger, no primary-flavored defaults at this layer.

State modifiers

  • .cngx-filter-builder__action-button:hover / :focus-visible - alpha-on-black hover tint (alpha-on-white in dark mode)
  • .cngx-filter-builder__action-button:focus-visible - 2px currentColor outline, 2px offset
  • .cngx-filter-builder__action-button[disabled] - 0.5 opacity dim, not-allowed cursor

Variants

  • .cngx-filter-group-root - root group, no indent / no left rail
  • :not(.cngx-filter-group-root) - nested groups pick up the indent and the left rail
  • .cngx-filter-group-negated - dashed border-style on the group container, reads as "exclusion" without changing the color
  • .cngx-filter-builder__action-button--remove - destructive foreground sourced from the danger chain

Slots

  • cngx-filter-builder - host, padding + background + foreground
  • .cngx-filter-builder__sr - screen-reader-only live region
  • .cngx-filter-builder__group - group container, gap + padding + border + radius
  • .cngx-filter-builder__expression - row inner flex row, gap + wrap, aligned center
  • .cngx-filter-builder__actions - action-button row, flex + gap + wrap
  • .cngx-filter-builder__empty - empty-state typography, italic + muted foreground
  • .cngx-filter-builder__action-button - inline-flex button, border + radius + transitions on background / border
  • .cngx-filter-builder__action-glyph - inline-flex glyph slot, sized via --cngx-filter-builder-action-glyph-size
  • .cngx-filter-builder__logic-toggle - logic-toggle row, gap

Inheritance

Surface tokens delegate to the foundation so a brand change propagates without per-component theming:

  • --cngx-filter-builder-border-color -> --cngx-color-border
  • --cngx-filter-builder-action-border -> --cngx-color-border
  • --cngx-filter-builder-group-border -> 1px solid var(--cngx-color-border)
  • --cngx-filter-builder-rail -> 2px solid var(--cngx-color-border)
  • --cngx-filter-builder-action-remove-fg -> --cngx-filter-builder-error-fg -> --cngx-color-danger
  • --cngx-filter-builder-error-fg -> --cngx-color-danger

Layout / sizing / motion tokens stay structural (no foundation delegate). --cngx-filter-builder-action-button borders carry the group-border color through the same delegating chain so a single --cngx-color-border swap retints the whole surface.

Dark mode

Three hooks lift the alpha-on-black hover tint to alpha-on-white and invert the muted empty-state foreground from dim dark gray to soft light gray so secondary information keeps its weight:

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

Foundation-delegated tokens (group border, rail, remove-tone) ride the foundation cascade unchanged.

Index#

Layout

--cngx-filter-builder-padding#*
Default value 0.5rem

Padding shorthand around the outer builder container.

--cngx-filter-builder-gap#*
Default value 0.5rem

Gap between sibling rows / actions / logic-toggle items.

--cngx-filter-builder-group-padding#*
Default value 0.5rem

Padding shorthand inside each group container.

--cngx-filter-builder-radius#*
Default value 0.375rem

Corner radius of group containers and action buttons.

--cngx-filter-builder-indent#*
Default value 1.25rem

Indent applied to nested (non-root) groups so the hierarchy reads visually.

--cngx-filter-builder-empty-padding#*
Default value 0.75rem

Padding shorthand of the empty-state slot.

--cngx-filter-builder-action-gap#*
Default value 0.25rem

Gap between an action button's glyph and its label.

--cngx-filter-builder-action-padding#*
Default value 0.25rem 0.625rem

Padding shorthand of an action button.

--cngx-filter-builder-action-radius#*
Default value 0.375rem

Corner radius of an action button.

--cngx-filter-builder-action-glyph-size#*
Default value 1em

Font-size of the action-button glyph slot.

Surface

--cngx-filter-builder-bg#<color>
Default value transparent

Background of the outer builder container.

--cngx-filter-builder-fg#*
Default value currentColor

Foreground text color of the builder.

--cngx-filter-builder-group-border#*
Default value 1px solid oklch(0.87 0 0)

Border shorthand of each group container. inherits: true so the :root delegating value reaches nested group containers.

--cngx-filter-builder-border-color#<color>
Default value oklch(0.87 0 0)

Border color of group containers and the action-button stroke. Falls back through --cngx-color-border. inherits: true so a :root override flows into the builder host.

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

--cngx-filter-builder-rail#*
Default value 2px solid oklch(0.87 0 0)

Left rail border shorthand for nested groups. inherits: true so the :root delegating value reaches nested rails.

--cngx-filter-builder-action-fg#*
Default value currentColor

Text color of an action button.

--cngx-filter-builder-action-bg#<color>
Default value transparent

Background of an action button at rest.

--cngx-filter-builder-action-border-width#<length>
Default value 1px

Border width of an action button.

--cngx-filter-builder-action-border#<color>
Default value oklch(0.82 0 0)

Border color of an action button. inherits: true so a :root delegating value reaches the button inside the builder host.

Variant / Negated

--cngx-filter-builder-negated-border-style#*
Default value dashed

Border-style applied to negated groups — dashed reads as "exclusion" without changing the color.

State / Empty

--cngx-filter-builder-empty-fg#<color>
Default value oklch(0.45 0 0)

Text color of the empty-state slot — muted by default. inherits: true so the :root dark-mode override reaches the empty slot inside the builder host.

Typography

--cngx-filter-builder-action-font-size#*
Default value 0.875rem

Font-size of an action button's label.

State / Hover

--cngx-filter-builder-action-hover-bg#<color>
Default value oklch(0 0 0 / 0.04)

Background tint applied on hover / focus-visible of an action button. inherits: true so the :root dark-mode override (alpha-on-white in dark) reaches the button.

State / Focus

--cngx-filter-builder-focus-outline#*
Default value 2px solid currentColor

Focus-ring outline shorthand applied to action buttons.

--cngx-filter-builder-focus-outline-offset#<length>
Default value 2px

Outline offset of the focus ring.

State / Disabled

--cngx-filter-builder-action-disabled-opacity#<number>
Default value 0.5

Opacity multiplier applied to disabled action buttons.

Variant / Remove

--cngx-filter-builder-action-remove-fg#<color>
Default value oklch(0.55 0.18 25)

Foreground color of the destructive remove button. Falls back through --cngx-filter-builder-error-fg and then --cngx-color-danger.

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

State / Error

--cngx-filter-builder-error-fg#<color>
Default value oklch(0.55 0.18 25)

Error-tone foreground shared across the builder's error states. Falls back through --cngx-color-danger.