Stats
The <smart-stats> component renders a list of statistic cards (label/value pairs with optional previous value, change indicator, trend, icon, and action slot). It follows the Base + Standard + Wrapper pattern with an InjectionToken-based extension mechanism. The abstract StatsBaseComponent defines the shared API — optional IStatsOptions and cssClass (alias class). StatsStandardComponent is a barebones placeholder concrete implementation. StatsComponent is the public wrapper that renders StatsStandardComponent by default and accepts a custom replacement via STATS_STANDARD_COMPONENT_TOKEN.
Usage
<smart-stats [options]="options" />
Components
StatsComponent (<smart-stats>)
Main wrapper component. Renders StatsStandardComponent by default. When STATS_STANDARD_COMPONENT_TOKEN is provided, renders the injected component via NgComponentOutlet.
StatsStandardComponent (<smart-stats-standard>)
Barebones placeholder concrete implementation. Renders a wrapper <div> containing an optional <h3 class="title"> and a <dl> with one <div class="item"> per item. Each item renders an optional icon (iconTpl in <div class="icon">), label (<dt class="label">), value (<dd class="value">), optional previous value (<dd class="previous">), optional change with data-trend attribute (<dd class="change">), and optional action template (actionTpl in <div class="action">). The external cssClass is applied to the root wrapper. It does not include any visual styling — it exists solely as the default structural placeholder until a custom implementation is registered through the token.
StatsPresetComponent (<smart-stats-preset>)
Styled variation that extends StatsBaseComponent and is a drop-in replacement for StatsStandardComponent. Register it via STATS_STANDARD_COMPONENT_TOKEN to restyle every <smart-stats>, or use the <smart-stats-preset> selector directly. Renders the Preline "Three-Column Stats with Primary Accent" look: a responsive grid of stat blocks, each with an optional leading icon (iconTpl), a label heading, the big primary-accent value (with an optional inline change badge coloured by trend — green for up, red for down, gray for neutral/unset), an optional muted previousValue sub-line, and an optional actionTpl. Column count comes from options.columns (default 3); an optional options.title renders as a heading above the grid. All classes are smart:-prefixed Tailwind with explicit dark: variants. The class recipes live in preset/preset-classes.util.ts (getStatsContainerClasses, getStatsGridClasses, getStatsChangeClasses, etc.).
Because
StatsComponentrenders injected components viaNgComponentOutlet(which passes inputs by canonical name),StatsPresetComponentoverridescssClassasinput<string>('')without theclassalias. Bind it as[cssClass]when using the<smart-stats-preset>selector directly, or just passclasson<smart-stats>(the wrapper forwards it).
StatsBaseComponent (abstract)
Abstract base directive for extending custom stats implementations. Exposes options as an InputSignal<IStatsOptions | undefined> and cssClass as an InputSignal<string> (with alias class).
API
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
options | InputSignal<IStatsOptions | undefined> | - | Optional configuration (title, items, columns) |
class | InputSignal<string> | '' | External CSS classes (alias for cssClass) |
IStatsOptions
items is required. The default StatsStandardComponent consumes every property; a section is rendered only when its template/string is provided. The trend value is exposed via the data-trend attribute on <dd class="change"> for downstream styling. columns is a hint for custom implementations to lay out the grid; the default placeholder ignores it.
STATS_STANDARD_COMPONENT_TOKEN
InjectionToken that allows replacing the default StatsStandardComponent with a custom implementation. Provide a Type<StatsBaseComponent> to override.
Extending the base class
import {
ChangeDetectionStrategy,
Component,
computed,
input,
ViewEncapsulation,
} from '@angular/core';
import {
IStatsOptions,
STATS_STANDARD_COMPONENT_TOKEN,
StatsBaseComponent,
StatsComponent,
} from '@smartsoft001/angular';
@Component({
selector: 'docs-custom-stats',
template: `
<div [class]="containerClasses()" [attr.data-columns]="columns()">
@if (options()?.title) {
<h3 class="docs-stats__title">{{ options()!.title }}</h3>
}
<dl class="docs-stats__grid">
@for (item of options()?.items ?? []; track $index) {
<div
class="docs-stats__item"
[attr.aria-label]="item.ariaLabel ?? null"
>
<dt class="docs-stats__label">{{ item.label }}</dt>
<dd class="docs-stats__value">{{ item.value }}</dd>
@if (
item.previousValue !== undefined && item.previousValue !== null
) {
<dd class="docs-stats__previous">{{ item.previousValue }}</dd>
}
@if (item.change) {
<dd
class="docs-stats__change"
[attr.data-trend]="item.trend ?? null"
>
{{ item.change }}
</dd>
}
</div>
}
</dl>
</div>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomStatsComponent extends StatsBaseComponent {
// NgComponentOutlet passes 'cssClass' by canonical name, not the 'class' alias.
override cssClass = input<string>('');
columns = computed(() => this.options()?.columns ?? 3);
containerClasses = computed(() =>
['docs-stats', this.cssClass()].filter(Boolean).join(' '),
);
}
@Component({
selector: 'docs-stats-custom-example',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [StatsComponent],
// The token swaps the standard stats for the custom one everywhere below this
// component, so consumers keep writing `<smart-stats>`.
providers: [
{
provide: STATS_STANDARD_COMPONENT_TOKEN,
useValue: CustomStatsComponent,
},
],
template: `<smart-stats [options]="options" />`,
})
export class StatsCustomExampleComponent {
options: IStatsOptions = {
title: 'By the numbers',
columns: 3,
items: [
{
label: 'Accuracy rate',
value: '99.95%',
previousValue: 'in fulfilling orders',
change: '+0.4% this quarter',
trend: 'up',
},
{
label: 'Startup businesses',
value: '2,000+',
previousValue: 'partner with us',
},
{
label: 'Happy customers',
value: '85%',
previousValue: 'this year alone',
},
],
};
}
Source
The component lives in packages/shared/angular/src/lib/components/stats and is documented for Claude Code by the angular-components-stats skill.