CngxDataGridAccordion
projects/ui/data-grid-accordion/data-grid-accordion.component.ts
Import#
import { CngxDataGridAccordion } from '@cngx/ui/data-grid-accordion'
Description#
Data-grid accordion group. A disclosure accordion whose header, rows, and
footer all share one grid-template-columns contract, so N arbitrary cells
align down the grid - the ceiling the accordion data-grid skin could never
reach with its fixed three slots. Hosts the headless CngxAccordion
brain via hostDirectives (so CNGX_ACCORDION and roving keyboard nav come
with it), forwards [multi] and the controlled [(openIds)] model, publishes
the column template onto the inherited --cngx-dga-columns property, and
reflects [skin] onto [data-skin]. Projects its CngxDataGridHeader,
CngxDataGridRows, and CngxDataGridFooter through a single
<ng-content />; it owns no rendering beyond providing
CNGX_DATA_GRID_ACCORDION so rows read the shared heading level.
It is a disclosure accordion, not a data grid: no role="grid", no cell edit,
no selection model, no keyboard grid navigation. It hosts the orthogonal
CngxSort atom as a second hostDirective and exposes it on
CNGX_DATA_GRID_ACCORDION as sort, so header cells become sortable with
one cngxDgaSortHeader attribute (no [cngxSortRef] plumbing) and a consumer can
bind the controlled [sortActive] / [sortDirection] inputs and read (sortChange).
For an uncontrolled grid that just needs a starting order, [initialSort]="{ active, direction }" seeds the sort once and then yields to header clicks.
It hosts the orthogonal CngxFilter atom the same way, exposed as filter:
[filterPredicate] forwards to its controlled predicate, (filterChange) re-emits,
and a projected cngxDgaFilter input two-way-binds the simple [(filterTerm)].
The group only publishes sort/filter state - the consumer still derives the
visible + ordered rows via a computed() and owns the @for; the open set is keyed
by row value so a sorted or filtered row stays open while it moves.
The column widths are declared on the header cells via col
(grow / fit / sm / md / lg); the group derives the shared template from
them, so no grid-template-columns string is needed for the common case.
<cngx-data-grid-accordion [multi]="true">
<cngx-dga-header>
<span cngxDgaCell col="sm">ID</span>
<span cngxDgaCell col="grow">Name</span>
<span cngxDgaCell col="md" align="end">Amount</span>
</cngx-dga-header>
<cngx-dga-row panelId="1">
<span cngxDgaCell>1</span>
<span cngxDgaCell primary>Alpha</span>
<span cngxDgaCell align="end">120.00</span>
Detail for row 1
</cngx-dga-row>
<cngx-dga-footer>
<span cngxDgaCell>Total</span>
</cngx-dga-footer>
</cngx-data-grid-accordion>Metadata#
Host#
Providers#
CNGX_DATA_GRID_ACCORDION- useExisting
CngxDataGridAccordion
Dependencies#
CngxFilterinject()selffilterThe hosted CngxFilter instance, exposed on CNGX_DATA_GRID_ACCORDION
as filter. [filterPredicate] forwards to its controlled predicate; consumers
read filter.predicate() (or drive addPredicate for facet filtering) and derive
the visible rows themselves. State only - the group never hides projected rows.
CngxSortinject()selfsortThe hosted CngxSort instance, exposed on CNGX_DATA_GRID_ACCORDION
so cngxDgaSortHeader cells read the shared sort with no [cngxSortRef]. It is a
hostDirective, so it lives on this element's injector; { self: true } resolves
that instance rather than an ancestor's. The group publishes it as state - the
consumer's computed() still derives the ordered rows (Ableitung preserved).
Relationships
Depends on1
Index#
Outputs
Derived State
HostBindings
Inputs#
string | undefinedRaw grid-template-columns escape hatch. Leave it unset for the common case:
the group derives the shared template from the header cells' col intents
(see resolvedColumns). Set it only when a skin needs track syntax the
col vocabulary cannot express - ch tracks, subgrid, minmax - such as the
spreadsheet skin. When set, it wins over the derived value. It holds content
columns only: the disclosure chevron rides a leading gutter outside the grid, so
it never consumes a track. Per-instance only - no app-wide config default
(unlike [skin]).
The simple text filter term, two-way bindable as [(filterTerm)]. A model()
because it is a two-way primary value the projected cngxDgaFilter input writes
(a plain input() could not be set from the slot). The group publishes it on the
context so the consumer's computed() matches it against its own row fields - the
group holds no field knowledge and does no matching (Pillar 3).
''Heading level (2-6) every row's role="heading" wrapper reflects via
aria-level. Clamped into the valid ARIA range so a stray 0/9 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 attribute binding.
clampHeadingLevel(3), { transform: (value: number | string) => clampHeadingLevel(value), }Visual skin reflected onto the [data-skin] host attribute. Resolves
input ?? CNGX_DATA_GRID_ACCORDION_CONFIG.skin: an unbound [skin] falls
back to the app-wide config default (withDataGridSkin); unset on both
leaves the base flat grid look. The skin only redirects CSS - structure,
cells, ARIA, and keyboard behaviour are identical across skins.
Outputs#
The simple text filter term, two-way bindable as [(filterTerm)]. A model()
because it is a two-way primary value the projected cngxDgaFilter input writes
(a plain input() could not be set from the slot). The group publishes it on the
context so the consumer's computed() matches it against its own row fields - the
group holds no field knowledge and does no matching (Pillar 3).
HostBindings#
| Binding | Expression |
|---|---|
[attr.data-skin] | resolvedSkin() ?? null |
[style.--cngx-dga-columns] | resolvedColumns() |
The eight opt-in visual skins for <cngx-data-grid-accordion>. Pairs with the
structural data-grid-accordion.component.css / data-grid-row.component.css
in this same entry - those own the flat base grid, the chevron, the region,
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-accordion-group>. Every skin renders the identical header / row /
region structure, cells, ARIA, and keyboard model - only the paint changes.
Each value is a CSS @scope (.cngx-data-grid-accordion[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. Every gradient from the design lab is re-mapped to a solid
--cngx-color-primary; the alternate surfaces are derived in oklab from
--cngx-color-surface toward --cngx-color-text so they track light / dark
without a fixed palette. Container / motion queries stay UNLAYERED with direct
selectors, never nested inside @scope (that breaks the token cascade).
ledger- a framed table: mono uppercase column head, zebra rows, mono right-aligned amounts, an inset primary-accent detail zone, a sum footer. Below its--cngx-dga-min-widththe grid scrolls sideways (hostoverflow-x) with every column intact rather than dropping one.spreadsheet- an Excel-style sheet: visible cell hairlines, plus a column-letter strip (A / B / C ...) and gutter row numbers BOTH derived from CSS counters - the letters count column position, the numbers count structural rows, so the consumer authors neither. Opening a row fills its gutter cell with the accent colour and the detail zone becomes a warning-tinted note cell. Below its--cngx-dga-min-widththe grid scrolls sideways rather than dropping a column.log-stream- a mono log console: timestamp / level / message columns, the row severity doubled as a 3px left edge ([data-severity]), a level badge (projectedcngx-tag), an expanded stacktracepreon a recessed surface, and a flex status footer with a live dot. Below its--cngx-dga-min-widththe grid scrolls sideways rather than dropping the timestamp.master-detail- an order/positions view: mono dimmed order number, a weighted customer name, mono right-aligned position + sum cells, and the open row held primary-tinted as the context for its detail. The detail zone is a projected sub-<table>(consumer content the skin only paints) on a recessed surface with a primary inset edge and a quiet sub-head, with a bold rule-freetfootsum. Below its--cngx-dga-min-widththe grid scrolls sideways rather than dropping a column.report- a frameless cost report: no surface frame, a3px doublerule under the column head and over the sum foot, hairline dividers between rows, mono right-aligned budget / actual money, and over-budget actual cells ([data-over]) in the danger colour. Below its--cngx-dga-min-widththe grid scrolls sideways rather than dropping a column.density- a framed task list whose row block padding and cell type ride the--cngx-dga-row-py/--cngx-dga-fshooks, transitioned so a density change animates rather than jumps. The compact / standard / spacious control is a consumer token concern (demo chrome that sets those two tokens), not a component input; the skin only frames the grid and animates the change. Below its--cngx-dga-min-widththe grid scrolls sideways rather than dropping a column.