@kanso-protocol/stat-card 0.1.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -74,7 +74,7 @@ class KpStatCardComponent {
|
|
|
74
74
|
</ng-content>
|
|
75
75
|
</div>
|
|
76
76
|
}
|
|
77
|
-
`, isInline: true, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;gap:var(--kp-stat-gap, 12px);padding:var(--kp-stat-pad, 20px);background:var(--kp-color-
|
|
77
|
+
`, isInline: true, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;gap:var(--kp-stat-gap, 12px);padding:var(--kp-stat-pad, 20px);background:var(--kp-color-surface-base);border:1px solid var(--kp-color-border-strong);border-radius:12px;font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif)}:host(.kp-stat--sm){--kp-stat-pad: 16px;--kp-stat-gap: 8px;--kp-stat-value-size: 18px;--kp-stat-label-size: 12px}:host(.kp-stat--md){--kp-stat-pad: 20px;--kp-stat-gap: 12px;--kp-stat-value-size: 24px;--kp-stat-label-size: 13px}:host(.kp-stat--lg){--kp-stat-pad: 24px;--kp-stat-gap: 16px;--kp-stat-value-size: 32px;--kp-stat-label-size: 14px}.kp-stat__header{display:flex;align-items:center;justify-content:space-between;gap:12px}.kp-stat__label{font-size:var(--kp-stat-label-size, 13px);color:var(--kp-color-text-muted);font-weight:500}.kp-stat__icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:var(--kp-color-primary-subtle-bg-rest);color:var(--kp-color-accent-primary-fg)}.kp-stat__icon .ti{font-size:18px;line-height:1}.kp-stat__value{font-size:var(--kp-stat-value-size, 24px);font-weight:600;color:var(--kp-color-text-strong);font-variant-numeric:tabular-nums;line-height:1.1}.kp-stat__trend{display:flex;align-items:center;gap:6px}.kp-stat__trend-icon{font-size:14px;line-height:1}.kp-stat__trend-value{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.kp-stat__trend-desc{font-size:12px;color:var(--kp-color-text-muted)}.kp-stat__trend[data-tone=good]{color:var(--kp-color-accent-success-fg)}.kp-stat__trend[data-tone=bad]{color:var(--kp-color-accent-danger-fg)}.kp-stat__trend[data-tone=neutral]{color:var(--kp-color-text-muted)}.kp-stat__sparkline{margin-top:4px}.kp-stat__sparkline-placeholder{height:32px;background:var(--kp-color-surface-muted);border-radius:4px}\n"], dependencies: [{ kind: "component", type: KpIconComponent, selector: "kp-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
78
78
|
}
|
|
79
79
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KpStatCardComponent, decorators: [{
|
|
80
80
|
type: Component,
|
|
@@ -107,7 +107,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
107
107
|
</ng-content>
|
|
108
108
|
</div>
|
|
109
109
|
}
|
|
110
|
-
`, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;gap:var(--kp-stat-gap, 12px);padding:var(--kp-stat-pad, 20px);background:var(--kp-color-
|
|
110
|
+
`, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;gap:var(--kp-stat-gap, 12px);padding:var(--kp-stat-pad, 20px);background:var(--kp-color-surface-base);border:1px solid var(--kp-color-border-strong);border-radius:12px;font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif)}:host(.kp-stat--sm){--kp-stat-pad: 16px;--kp-stat-gap: 8px;--kp-stat-value-size: 18px;--kp-stat-label-size: 12px}:host(.kp-stat--md){--kp-stat-pad: 20px;--kp-stat-gap: 12px;--kp-stat-value-size: 24px;--kp-stat-label-size: 13px}:host(.kp-stat--lg){--kp-stat-pad: 24px;--kp-stat-gap: 16px;--kp-stat-value-size: 32px;--kp-stat-label-size: 14px}.kp-stat__header{display:flex;align-items:center;justify-content:space-between;gap:12px}.kp-stat__label{font-size:var(--kp-stat-label-size, 13px);color:var(--kp-color-text-muted);font-weight:500}.kp-stat__icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:var(--kp-color-primary-subtle-bg-rest);color:var(--kp-color-accent-primary-fg)}.kp-stat__icon .ti{font-size:18px;line-height:1}.kp-stat__value{font-size:var(--kp-stat-value-size, 24px);font-weight:600;color:var(--kp-color-text-strong);font-variant-numeric:tabular-nums;line-height:1.1}.kp-stat__trend{display:flex;align-items:center;gap:6px}.kp-stat__trend-icon{font-size:14px;line-height:1}.kp-stat__trend-value{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.kp-stat__trend-desc{font-size:12px;color:var(--kp-color-text-muted)}.kp-stat__trend[data-tone=good]{color:var(--kp-color-accent-success-fg)}.kp-stat__trend[data-tone=bad]{color:var(--kp-color-accent-danger-fg)}.kp-stat__trend[data-tone=neutral]{color:var(--kp-color-text-muted)}.kp-stat__sparkline{margin-top:4px}.kp-stat__sparkline-placeholder{height:32px;background:var(--kp-color-surface-muted);border-radius:4px}\n"] }]
|
|
111
111
|
}], propDecorators: { size: [{
|
|
112
112
|
type: Input
|
|
113
113
|
}], label: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kanso-protocol-stat-card.mjs","sources":["../../../../../packages/patterns/stat-card/src/stat-card.component.ts","../../../../../packages/patterns/stat-card/src/kanso-protocol-stat-card.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Input,\n} from '@angular/core';\nimport { KpIconComponent } from '@kanso-protocol/icon';\n\nexport type KpStatCardSize = 'sm' | 'md' | 'lg';\nexport type KpStatTrendDirection = 'up' | 'down' | 'neutral';\n/**\n * `positive` — up = good (green), down = bad (red).\n * `negative` — up = bad (red), down = good (green) — for inverse metrics like error rate.\n */\nexport type KpStatTrendAppearance = 'positive' | 'negative';\n\n/**\n * Kanso Protocol — StatCard\n *\n * Single-metric tile with label, big value, optional icon, optional\n * trend (direction + delta + description), optional sparkline placeholder.\n * Designed to live in a dashboard grid.\n *\n * Slot: `[kpStatCardSparkline]` — drop in your real chart (e.g. recharts);\n * the placeholder shows a styled rectangle when empty.\n *\n * @example\n * <kp-stat-card label=\"Total revenue\" value=\"$12,482\" trendValue=\"+12.5%\" trendDescription=\"from last month\"/>\n */\n@Component({\n selector: 'kp-stat-card',\n imports: [KpIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses' },\n template: `\n <div class=\"kp-stat__header\">\n <span class=\"kp-stat__label\">{{ label }}</span>\n @if (showIcon && icon) {\n <span class=\"kp-stat__icon\" aria-hidden=\"true\">\n <kp-icon [name]=\"icon\" />\n </span>\n }\n </div>\n\n <span class=\"kp-stat__value\">{{ value }}</span>\n\n @if (showTrend) {\n <div class=\"kp-stat__trend\" [attr.data-tone]=\"trendTone\">\n <kp-icon class=\"kp-stat__trend-icon\" [name]=\"trendIconName\" />\n <span class=\"kp-stat__trend-value\">{{ trendValue }}</span>\n @if (trendDescription) {\n <span class=\"kp-stat__trend-desc\">{{ trendDescription }}</span>\n }\n </div>\n }\n\n @if (showSparkline) {\n <div class=\"kp-stat__sparkline\">\n <ng-content select=\"[kpStatCardSparkline]\">\n <div class=\"kp-stat__sparkline-placeholder\" aria-hidden=\"true\"></div>\n </ng-content>\n </div>\n }\n `,\n styles: [`\n :host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--kp-stat-gap, 12px);\n padding: var(--kp-stat-pad, 20px);\n background: var(--kp-color-
|
|
1
|
+
{"version":3,"file":"kanso-protocol-stat-card.mjs","sources":["../../../../../packages/patterns/stat-card/src/stat-card.component.ts","../../../../../packages/patterns/stat-card/src/kanso-protocol-stat-card.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Input,\n} from '@angular/core';\nimport { KpIconComponent } from '@kanso-protocol/icon';\n\nexport type KpStatCardSize = 'sm' | 'md' | 'lg';\nexport type KpStatTrendDirection = 'up' | 'down' | 'neutral';\n/**\n * `positive` — up = good (green), down = bad (red).\n * `negative` — up = bad (red), down = good (green) — for inverse metrics like error rate.\n */\nexport type KpStatTrendAppearance = 'positive' | 'negative';\n\n/**\n * Kanso Protocol — StatCard\n *\n * Single-metric tile with label, big value, optional icon, optional\n * trend (direction + delta + description), optional sparkline placeholder.\n * Designed to live in a dashboard grid.\n *\n * Slot: `[kpStatCardSparkline]` — drop in your real chart (e.g. recharts);\n * the placeholder shows a styled rectangle when empty.\n *\n * @example\n * <kp-stat-card label=\"Total revenue\" value=\"$12,482\" trendValue=\"+12.5%\" trendDescription=\"from last month\"/>\n */\n@Component({\n selector: 'kp-stat-card',\n imports: [KpIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses' },\n template: `\n <div class=\"kp-stat__header\">\n <span class=\"kp-stat__label\">{{ label }}</span>\n @if (showIcon && icon) {\n <span class=\"kp-stat__icon\" aria-hidden=\"true\">\n <kp-icon [name]=\"icon\" />\n </span>\n }\n </div>\n\n <span class=\"kp-stat__value\">{{ value }}</span>\n\n @if (showTrend) {\n <div class=\"kp-stat__trend\" [attr.data-tone]=\"trendTone\">\n <kp-icon class=\"kp-stat__trend-icon\" [name]=\"trendIconName\" />\n <span class=\"kp-stat__trend-value\">{{ trendValue }}</span>\n @if (trendDescription) {\n <span class=\"kp-stat__trend-desc\">{{ trendDescription }}</span>\n }\n </div>\n }\n\n @if (showSparkline) {\n <div class=\"kp-stat__sparkline\">\n <ng-content select=\"[kpStatCardSparkline]\">\n <div class=\"kp-stat__sparkline-placeholder\" aria-hidden=\"true\"></div>\n </ng-content>\n </div>\n }\n `,\n styles: [`\n :host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--kp-stat-gap, 12px);\n padding: var(--kp-stat-pad, 20px);\n background: var(--kp-color-surface-base);\n border: 1px solid var(--kp-color-border-strong);\n border-radius: 12px;\n font-family: var(--kp-font-family-sans, 'Onest', system-ui, sans-serif);\n }\n\n :host(.kp-stat--sm) { --kp-stat-pad: 16px; --kp-stat-gap: 8px; --kp-stat-value-size: 18px; --kp-stat-label-size: 12px; }\n :host(.kp-stat--md) { --kp-stat-pad: 20px; --kp-stat-gap: 12px; --kp-stat-value-size: 24px; --kp-stat-label-size: 13px; }\n :host(.kp-stat--lg) { --kp-stat-pad: 24px; --kp-stat-gap: 16px; --kp-stat-value-size: 32px; --kp-stat-label-size: 14px; }\n\n .kp-stat__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n .kp-stat__label {\n font-size: var(--kp-stat-label-size, 13px);\n color: var(--kp-color-text-muted);\n font-weight: 500;\n }\n .kp-stat__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--kp-color-primary-subtle-bg-rest);\n color: var(--kp-color-accent-primary-fg);\n }\n .kp-stat__icon .ti { font-size: 18px; line-height: 1; }\n\n .kp-stat__value {\n font-size: var(--kp-stat-value-size, 24px);\n font-weight: 600;\n color: var(--kp-color-text-strong);\n font-variant-numeric: tabular-nums;\n line-height: 1.1;\n }\n\n .kp-stat__trend {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .kp-stat__trend-icon { font-size: 14px; line-height: 1; }\n .kp-stat__trend-value { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }\n .kp-stat__trend-desc { font-size: 12px; color: var(--kp-color-text-muted); }\n .kp-stat__trend[data-tone='good'] { color: var(--kp-color-accent-success-fg); }\n .kp-stat__trend[data-tone='bad'] { color: var(--kp-color-accent-danger-fg); }\n .kp-stat__trend[data-tone='neutral'] { color: var(--kp-color-text-muted); }\n\n .kp-stat__sparkline { margin-top: 4px; }\n .kp-stat__sparkline-placeholder {\n height: 32px;\n background: var(--kp-color-surface-muted);\n border-radius: 4px;\n }\n `],\n})\nexport class KpStatCardComponent {\n @Input() size: KpStatCardSize = 'md';\n @Input() label = 'Total revenue';\n @Input() value: string | number = '$12,482';\n\n @Input() showIcon = false;\n @Input() icon: string | null = 'trending-up';\n\n @Input() showTrend = true;\n @Input() trendDirection: KpStatTrendDirection = 'up';\n @Input() trendAppearance: KpStatTrendAppearance = 'positive';\n @Input() trendValue: string | null = '+12.5%';\n @Input() trendDescription: string | null = 'from last month';\n\n @Input() showSparkline = false;\n\n get trendIconName(): string {\n if (this.trendDirection === 'up') return 'trending-up';\n if (this.trendDirection === 'down') return 'trending-down';\n return 'minus';\n }\n\n get trendTone(): 'good' | 'bad' | 'neutral' {\n if (this.trendDirection === 'neutral') return 'neutral';\n const goodWhenUp = this.trendAppearance === 'positive';\n const isUp = this.trendDirection === 'up';\n return (isUp === goodWhenUp) ? 'good' : 'bad';\n }\n\n get hostClasses(): string {\n return `kp-stat kp-stat--${this.size}`;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanso-protocol/stat-card",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/core": "^18.0.0",
|
|
7
7
|
"@angular/common": "^18.0.0",
|
|
8
|
-
"@kanso-protocol/core": "
|
|
8
|
+
"@kanso-protocol/core": ">=0.5.3"
|
|
9
9
|
},
|
|
10
10
|
"description": "Kanso Protocol — stat-card (pattern).",
|
|
11
11
|
"author": "GregNBlack",
|