Skip to main content
cngx-src documentation

CngxAccordionGroup

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/ui/accordion/accordion-group.component.ts

Import#

import { CngxAccordionGroup } from '@cngx/ui/accordion'

Description#

Accordion organism shell. Hosts the headless CngxAccordion brain via hostDirectives - so CNGX_ACCORDION and the registration keyboard-nav come with it - forwards [multi] and the controlled [(openIds)] model, and adds [headingLevel]. Projects its CngxAccordionItem children through a single <ng-content />; the group owns no rendering beyond providing CNGX_ACCORDION_GROUP so items read the shared heading level.

<cngx-accordion-group [multi]="false" [headingLevel]="3">
  <cngx-accordion-item>
    <span cngxAccordionItemTitle>Section A</span>
    Body A
  </cngx-accordion-item>
</cngx-accordion-group>

https://cngxjs.github.io/cngx/examples/#/ui/accordion/single-open/basic https://cngxjs.github.io/cngx/examples/#/ui/accordion/multi-open/independent https://cngxjs.github.io/cngx/examples/#/ui/accordion/controlled-open/initial-open https://cngxjs.github.io/cngx/examples/#/ui/accordion/config/app-wide-labels https://cngxjs.github.io/cngx/examples/#/ui/accordion/skins/editorial

Metadata#

Host#

Providers#

CNGX_ACCORDION_GROUP
useExisting CngxAccordionGroup

Relationships

Index#

Derived State

HostBindings

Inputs#

headingLevel#
input()

Heading level (2-6) every item's role="heading" wrapper reflects via aria-level. Resolves input ?? CNGX_ACCORDION_CONFIG.headingLevel ?? 3: an unbound [headingLevel] falls back to the app-wide config default (overridden via withDefaultHeadingLevel). Clamped into the valid ARIA range so a stray 0/9 - from a binding OR the config default - can never emit an invalid aria-level. The default is clamped explicitly because Angular runs transform only on bound values, not the initial default. Coerced from string via coerceNumberProperty for template attribute binding.

default
clampHeadingLevel(this.config.headingLevel), {    transform: (value: number | string) => clampHeadingLevel(value, this.config.headingLevel),  }
input()

Visual skin reflected onto the [data-skin] host attribute. Resolves input ?? CNGX_ACCORDION_CONFIG.skin: an unbound [skin] falls back to the app-wide config default (withAccordionSkin); unset on both leaves the base flat look. The skin only redirects CSS - structure, slots, ARIA, and keyboard behaviour are identical across skins. Mirrors the tabs/stepper [skin] cascade.

HostBindings#

BindingExpression
[attr.data-skin]resolvedSkin() ?? null

The nine opt-in visual skins for <cngx-accordion-group>. Pairs with the structural accordion-group.component.css / accordion-item.component.css in this same entry - those own the flat base layout, the marker, the skeleton / refresh / error affordances, and the a11y wiring; this file owns only the per-skin paint.

Selected by the [skin] input via the [data-skin] host attribute, mirroring <cngx-tab-group>. Every skin renders the identical heading / region / marker structure, slots, ARIA, and keyboard model - only the paint changes. Each value is a CSS @scope (.cngx-accordion-group[data-skin='<name>']) block. Unlayered (this is a component styleUrl, not the Track-B cngx.css), so a [data-skin] rule overrides the flat base by specificity + source order - no @layer battle, no tokenising a layout hook just to let a layered rule win.

Reverted-hook structure (display / gap / surface box / heading grid) is set as a direct property; genuine theming stays on the --cngx-accordion-* custom properties the base still reads (padding, divider, header tint, marker, per-skin accents). Every value is a var(--cngx-*, fallback); every gradient from the design lab is re-mapped to a solid --cngx-color-primary (there is no linear / conic / radial gradient anywhere here). Motion short-circuits under prefers-reduced-motion via an unlayered @media block, never nested inside @scope.

  • editorial - a mono running index leads each row, hairline dividers, no surfaces; index + title light up primary on open / hover.
  • categorized - each item is a bordered surface card, the group stacks them with a gap, title turns primary on open.
  • plus-minus - one framed surface, items divided within, the chevron is a boxed +/- (via the --cngx-accordion-marker: plus-minus token) that fills primary on open.
  • lux - generous whitespace, large low-contrast type, a single hairline per row; title fades on hover.
  • bento - full-width tile cards stacked in a column; an icon tile leads each card and fills primary on open, a status pill trails in the meta slot and the chevron rides the outer edge.
  • section-bands - each header is an inverted full-width band, items are framed surfaces with a gap, a status chip rides the band via the meta slot.
  • timeline - a vertical rail with a per-item node that lights primary on open; rail + node are item pseudo-elements, no leading markup required.
  • severity-spine - a full-height colour spine leads each item with the priority stamped in it (a structural column, not a border).
  • primary-frame - each item is a card that gains a solid primary border and an animated primary glow on open (the re-map of the lab's rotating conic frame to a solid primary treatment).