CngxCard
projects/common/card/card.component.ts
Import#
import { CngxCard } from '@cngx/common/card'
Description#
Semantic card component that adapts its host element role based on the as input.
Three archetypes:
'article'(default) - display card, no primary action'button'- the entire card is a clickable button'link'- the entire card is a navigation link
The host element is the semantic element - no inner wrapper. This eliminates double focus rings and wrapper problems for screen readers.
Action card with selection
<cngx-card as="button" [selectable]="true" [(selected)]="isSelected">
<header cngxCardHeader><h3>Patient</h3></header>
<div cngxCardBody>Details here</div>
</cngx-card>Link card
<cngx-card as="link" href="/patients/42" ariaLabel="View patient">
<img cngxCardMedia alt="Photo" />
</cngx-card>Metadata#
Host#
Index#
Derived State
HostBindings
HostListeners
Inputs#
string | undefinedAccessible label for the card. Overrides the default screen reader announcement.
"article" | "link" | "button"Semantic archetype: 'article' (display), 'button' (action), or 'link' (navigation).
'article', { alias: 'as', }Whether the card is disabled. Prevents interaction and sets aria-disabled.
falsestring | undefinedExplanation for why the card is disabled. Communicated to SR via aria-describedby.
Whether the card is in a loading state. Sets aria-busy and shows SR announcement.
falseOutputs#
HostBindings#
| Binding | Expression |
|---|---|
[attr.role] | hostRole() |
[attr.tabindex] | hostTabindex() |
[attr.href] | hostHref() |
[attr.aria-label] | ariaLabel() || null |
[attr.aria-busy] | loading() || null |
[attr.aria-selected] | interactive() && selectable() ? selected() : null |
[attr.aria-disabled] | disabled() || null |
[attr.aria-describedby] | describedByIds() |
[class.cngx-card--interactive] | interactive() |
[class.cngx-card--selected] | selected() |
[class.cngx-card--loading] | loading() |
[class.cngx-card--disabled] | disabled() |
HostListeners#
| Event | Handler |
|---|---|
(click) | click() |
(keydown.enter) | keydown.enter() |
(keydown.space) | keydown.space() |
Default visuals for CngxCard plus its slot directives. The host
carries .cngx-card; slot directives project into the nested
__media, __header, __title, __subtitle, __body,
__footer, __actions, and __badge elements.
State modifiers
--interactive- hover shadow + touch-active opacity--selected- accent border, tinted background, inset bar (non-color signal per WCAG 1.4.1)--disabled- opacity dim +pointer-events: none--loading- shimmer overlay (static fallback underprefers-reduced-motion)
Accent variants
Top stripe + tinted surface, one class per semantic intent:
--accent- neutral stripe, no tint--accent-info- info stripe, info-tinted background--accent-success- success stripe, success-tinted background--accent-warning- warning stripe, warning-tinted background--accent-danger- danger stripe, danger-tinted background--accent-neutral- neutral stripe, foundation border colour
Badge slot
.cngx-card__badge is absolutely positioned with three axes:
- Corner:
--top-end,--top-start,--bottom-end,--bottom-start - Size:
--size-sm,--size-md,--size-lg - Intent:
--intent-primary,--intent-danger,--intent-warning,--intent-success,--intent-neutral
Empty content collapses to the sm status-dot fallback regardless
of the size input.
Inheritance
Surface tokens fall back to the foundation so brand overrides propagate without per-component theming:
--cngx-card-bg->--cngx-color-surface--cngx-card-color->--cngx-color-text--cngx-card-border->--cngx-color-border--cngx-card-divider->--cngx-color-border--cngx-card-radius->--cngx-radius-lg--cngx-card-padding->--cngx-space-md--cngx-card-focus-color->--cngx-color-primary--cngx-card-selected-border->--cngx-color-primary--cngx-card-badge-*-bg->--cngx-badge-*-bg->--cngx-color-{intent}
Tinted-surface accents and the selected background use
color-mix() against the matching foundation semantic colour and
the card surface; themes only need to pin the tokens when the
runtime mix is not desired.
Dark mode
Three hooks swap the subtitle, selected background, four accent tints, and the badge ring:
prefers-color-scheme: dark[data-color-scheme="dark"].darkclass
Foundation-delegated tokens ride the foundation cascade unchanged.
Pair with
@cngx/themes/material/card-theme- Material 3 surface + elevation
Index#
State / Hover
State / Active
State / Disabled
State / Loading
Typography
Variant / Accent
Sizing
Variant / Primary
Variant / Danger
Variant / Warning
Variant / Success
Variant / Neutral
Layout
<length>120pxMinimum inline size of the card so empty cards still read as a surface.
<length>-6pxOffset of the badge slot from the card corners (negative pulls the badge half-out so it overlaps the edge).
Surface
<color>oklch(1 0 0)Card surface color. Falls back through --cngx-color-surface.
See: [[--cngx-color-surface]]
<color>oklch(0.2 0.01 290)Card text color. Falls back through --cngx-color-text.
*1px solid oklch(0.81 0.005 250)Border shorthand. Falls back through --cngx-color-border.
*2px solid oklch(1 0 0)Ring around the badge - contrasts the pill against the card
surface so the corner anchor reads as a separate element. The
:root dark-mode override swaps the colour; inherits: true so
the swap reaches the host element through the cascade.
State / Hover
*0 2px 8px 0 oklch(0 0 0 / 0.12)Drop-shadow applied on hover for .cngx-card--interactive.
State / Active
<number>0.88Opacity multiplier applied on touch-active. Only fires under
(hover: none) so it doesn't compete with the hover shadow.
State / Focus
<color>oklch(0.66 0.19 50)Focus-ring color. Falls back to --cngx-color-primary.
See: [[--cngx-color-primary]]
State / Selected
<color>oklch(0.66 0.19 50)Border color of the selected state and the inset selection bar.
Falls back to --cngx-color-primary.
See: [[--cngx-color-primary]]
<color>oklch(0.96 0.04 50)Background of the selected state. The runtime fallback uses
color-mix() against --cngx-color-primary, so this static
default only matters when a theme pins the token explicitly.
<length>3pxWidth of the inset selection bar drawn via ::before - provides
a non-color-only selection signal (WCAG 1.4.1).
State / Disabled
<number>0.5Opacity multiplier applied by .cngx-card--disabled.
State / Loading
<color>oklch(1 0 0 / 0.4)Shimmer band color for the loading overlay gradient.
<color>oklch(1 0 0 / 0.3)Static overlay shown when prefers-reduced-motion suppresses
the shimmer animation.
Typography
<color>oklch(0.36 0.02 290)Text color of the subtitle slot - muted by default.
Variant / Accent
<length>3pxWidth of the top accent stripe applied by .cngx-card--accent.
<color>transparentColor of the top accent stripe. Per-variant rules set it to the matching foundation semantic color.
<color>oklch(0.97 0.03 250)Tinted background for .cngx-card--accent-info. The runtime
fallback uses color-mix() against --cngx-color-info; this
static default only matters when a theme pins the token directly.
<color>oklch(0.97 0.04 145)Tinted background for .cngx-card--accent-success.
<color>oklch(0.97 0.04 75)Tinted background for .cngx-card--accent-warning.
<color>oklch(0.97 0.03 25)Tinted background for .cngx-card--accent-danger.
Sizing
<length>10pxDiameter (and minimum width) of the badge pill at the sm size.
Also drives the :empty status-dot fallback regardless of the
size input.
<length>22pxDiameter (and minimum width) of the badge pill at the md size.
<length>28pxDiameter (and minimum width) of the badge pill at the lg size.
<length>5pxInline padding around content-bearing badges. Zeroed by the
:empty dot fallback.
<length>999pxCorner radius. Defaults to the pill radius via --cngx-radius-pill
so the surface reads as a round indicator across all three sizes.
Variant / Primary
<color>oklch(0.66 0.19 50)Background of the primary intent. Falls back through
--cngx-badge-primary-bg then --cngx-color-primary.
See: [[--cngx-color-primary]]
Variant / Danger
<color>oklch(0.62 0.22 25)Background of the danger intent. Falls back through
--cngx-badge-error-bg then --cngx-color-danger.
See: [[--cngx-color-danger]]
Variant / Warning
<color>oklch(0.72 0.18 70)Background of the warning intent. Falls back through
--cngx-badge-warning-bg then --cngx-color-warning.
See: [[--cngx-color-warning]]
<color>oklch(0.2 0.01 250)Text colour of the warning intent.
Variant / Success
<color>oklch(0.6 0.15 145)Background of the success intent. No CngxBadge analogue -
falls straight back to --cngx-color-success.
See: [[--cngx-color-success]]
Variant / Neutral
<color>oklch(0.68 0.01 240)Background of the neutral intent. Falls back through
--cngx-badge-neutral-bg then --cngx-color-text-muted.