CngxCardGrid
projects/common/card/card-grid.component.ts
Import#
import { CngxCardGrid } from '@cngx/common/card'
Description#
Responsive card grid layout with intrinsic sizing, keyboard navigation, and reason-based empty-state template selection.
Uses CSS Grid with auto-fill + minmax for intrinsic responsiveness -
no breakpoint management required.
Keyboard navigation is provided by CngxRovingTabindex as a host directive.
Arrow keys navigate between cards; Enter/Space activates.
Basic grid
<cngx-card-grid minWidth="280px">
<cngx-card>...</cngx-card>
<cngx-card>...</cngx-card>
</cngx-card-grid>With empty state
<cngx-card-grid [items]="items()" [emptyReason]="emptyReason()">
@for (item of items(); track item.id) {
<cngx-card>...</cngx-card>
}
<ng-template cngxCardGridEmpty="no-results">
<cngx-empty-state title="No results" />
</ng-template>
<ng-template cngxCardGridEmpty>
<cngx-empty-state title="Nothing here yet" />
</ng-template>
</cngx-card-grid>Metadata#
Host#
Relationships
Depends on1
Index#
Inputs#
"compact" | "default" | "comfortable"Grid density level - controls gap and card padding via CSS custom properties.
'default'EmptyReason | undefinedReason why items are empty - selects the matching cngxCardGridEmpty template.
readonly unknown[] | undefinedOptional data source. When provided and empty, the grid shows the matching empty-state template. When omitted, the grid is a pure layout tool.
Whether the grid should have role="list". Requires role="listitem" on each card.
falseBind an async state - drives loading and empty from a single source.
When set, isLoading derives from state.isFirstLoad() and
empty derives from state.isEmpty() (overrides [items]).
HostBindings#
| Binding | Expression |
|---|---|
[attr.role] | semanticList() ? "list" : null |
[attr.aria-busy] | isLoading() || null |
[style.--cngx-card-grid-min] | minWidth() |
[style.--cngx-card-grid-gap] | density() === "default" ? gap() : null |
[class.cngx-card-grid--compact] | density() === "compact" |
[class.cngx-card-grid--comfortable] | density() === "comfortable" |
Default visuals for CngxCardGrid. The host carries
.cngx-card-grid and lays its <cngx-card> children out via
auto-fill + minmax() so the column count reflows with the
viewport without a media-query ladder.
Density modifiers
--compact- tighter gap, pins--cngx-card-paddingtosmso nested cards stay in sync with the grid's rhythm--comfortable- wider gap, pins--cngx-card-paddingtolg
Reaching into --cngx-card-padding is an intentional cross-
component coupling: the density modifier owns both the gap and
the matching card-inner spacing.
Inheritance
--cngx-card-grid-gap->--cngx-space-md--cngx-card-grid-min- leaf token, no fallback chain
Index#
Layout
<length>280pxMinimum inline size of a single grid cell - auto-fill packs as
many cells as fit before reflowing.
<length>16pxGap between grid cells. Density modifiers re-pin this and the
nested --cngx-card-padding.