Skip to main content
cngx-src documentation

CngxCheckboxGroup

cngx-checkbox-group

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/common/interactive/checkbox-group/checkbox-group.component.ts

Import#

import { CngxCheckboxGroup } from '@cngx/common/interactive'

Description#

Multi-value checkbox-group molecule. Owns a selectedValues model (the canonical multi-value source) and exposes membership derivations (allSelected, someSelected, noneSelected, selectedCount) plus the toggle-all triad (toggleAll, select, deselect) every consumer needs to wire a "select all" master checkbox to the group.

Internals lean on createSelectionController from @cngx/core/utils for membership tracking - the controller's structural-equality selected snapshot prevents downstream computed cascades from thrashing when a re-emission produces the same logical contents with a different array reference.

value is a structural alias of selectedValues so the group satisfies CngxControlValue<T[]> without owning two synchronised models - both names point to the same ModelSignal<T[]> instance.

Per Pillar 1 (Ableitung statt Verwaltung), every derived flag is a computed() - there is no manual sync between membership and the exposed flags. Per Pillar 3 (Komposition statt Konfiguration), the group composes CngxRovingTabindex as a host directive and emits no implicit children - consumers project <cngx-checkbox> instances (or any other CNGX_CONTROL_VALUE-bearing leaf) and bind each leaf's value-tracking themselves.

[allValues] is optional; when supplied, allSelected reflects "every option ticked" rather than the vacuous "every selected value is still selected" default. Consumers that wire a master checkbox pass the full option pool here so toggleAll() can select-or-clear-all per the user's mental model.

[keyFn] lets consumers with object-typed values map each value to a stable membership key (typically (v) => v.id). Without it, membership uses identity / primitive equality - which silently breaks across re-emissions when the consumer refetches array elements with the same id but new references.

[state] is an optional CngxAsyncState<unknown> input; when bound, aria-busy reflects state.status() === 'loading' reactively so AT announces the busy moment without the consumer wiring the attribute by hand.

<cngx-checkbox-group
  label="Notifications"
  [allValues]="options"
  [(selectedValues)]="picked"
>
  <cngx-checkbox
    *ngFor="let opt of options"
    [value]="opt"
  >{{ opt }}</cngx-checkbox>
</cngx-checkbox-group>

https://cngxjs.github.io/cngx/examples/#/common/interactive/checkbox/group/basic-select-all-master-projected-leaves https://cngxjs.github.io/cngx/examples/#/common/interactive/checkbox/group/disabled-cascade https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/coming-in-a-follow-up https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/reactive-forms-same-atom-just-bind-formcontrol https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/signal-forms-drop-the-atom-into-cngx-form-field

Metadata#

Host#

Providers#

CNGX_CONTROL_VALUE
useExisting CngxCheckboxGroup
CNGX_FORM_FIELD_CONTROL
useExisting CngxCheckboxGroup

Relationships

Index#

Inputs#

allValues#readonly T[] | undefined
input()
disabled#boolean
model()
default false
errorMessageId#string | null
input()

Optional id of an external error message element. The host emits aria-errormessage="<id>" only when aria-invalid="true" — symmetric with the sibling aria-invalid host binding (both gate on invalid() || errorState()). Consumers MUST render an element with the supplied id. Default null skips the attribute.

default null
invalid#boolean
model()

Bridge-writable invalid state. model<boolean> mirrors disabled so external integrations (RF/Signal-Forms bridges, custom validity adapters) can drive it without a parallel API path - consumers typically read only.

default false
keyFn#(value: T) => unknown
default (v) => v
label#string | undefined
input()
orientation#"horizontal" | "vertical"
input()
default 'vertical'
required#boolean
model()
default false
selectedValues#T[]
model()
default []

Outputs#

disabled#boolean
model()
invalid#boolean
model()

Bridge-writable invalid state. model<boolean> mirrors disabled so external integrations (RF/Signal-Forms bridges, custom validity adapters) can drive it without a parallel API path - consumers typically read only.

required#boolean
model()
selectedValues#T[]
model()

Instance Properties#

focused#unknown
Readonly
this.focusedState.asReadonly()
id#unknown
signal()Readonly
signal(nextUid('cngx-checkbox-group-')).asReadonly()
selectedCount#unknown
Readonly
this.controller.selectedCount
value#unknown
Readonly
this.selectedValues

Methods#

deselect#void
deselect(value: T)
@paramvalueT
handleFocusIn#void
Protected
handleFocusOut#void
Protected
select#void
select(value: T)
@paramvalueT
toggleAll#void

HostBindings#

BindingExpression
[attr.id]id()
[attr.aria-label]label()
[attr.aria-disabled]disabled() ? "true" : null
[attr.aria-required]required() ? "true" : null
[attr.aria-invalid]ariaInvalid() ? "true" : null
[attr.aria-errormessage]ariaInvalid() ? errorMessageId() : null
[attr.aria-busy]ariaBusy() ? "true" : null
[class.cngx-checkbox-group--horizontal]orientation() === "horizontal"

HostListeners#

EventHandler
(focusin)focusin()
(focusout)focusout()

Default visuals for CngxCheckboxGroup. The host carries .cngx-checkbox-group and frames a flex layout for projected <cngx-checkbox> children. Stacks vertically by default.

Variants

  • --horizontal - flips to a row with flex-wrap: wrap so long sets fold to additional lines

Inheritance

Gap cascades through the foundation:

  • --cngx-checkbox-group-gap -> --cngx-space-sm

Layout

--cngx-checkbox-group-gap#*
Default value 0.5rem

Gap between checkbox children. Falls back to --cngx-space-sm.