@deepfuture/dui-templates 1.0.0
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.
- package/README.md +214 -0
- package/all.d.ts +10 -0
- package/all.js +20 -0
- package/content/briefing-block.d.ts +36 -0
- package/content/briefing-block.js +281 -0
- package/content/empty-state.d.ts +24 -0
- package/content/empty-state.js +187 -0
- package/content/index.d.ts +5 -0
- package/content/index.js +5 -0
- package/content/numbered-insight.d.ts +30 -0
- package/content/numbered-insight.js +242 -0
- package/dashboard/index.d.ts +5 -0
- package/dashboard/index.js +5 -0
- package/dashboard/page-header.d.ts +29 -0
- package/dashboard/page-header.js +218 -0
- package/dashboard/section-panel.d.ts +41 -0
- package/dashboard/section-panel.js +393 -0
- package/data/index.d.ts +5 -0
- package/data/index.js +4 -0
- package/data/key-value.d.ts +27 -0
- package/data/key-value.js +165 -0
- package/data/market-table.d.ts +40 -0
- package/data/market-table.js +270 -0
- package/feed/activity-item.d.ts +35 -0
- package/feed/activity-item.js +278 -0
- package/feed/feed-item.d.ts +32 -0
- package/feed/feed-item.js +260 -0
- package/feed/headline-item.d.ts +27 -0
- package/feed/headline-item.js +187 -0
- package/feed/index.d.ts +6 -0
- package/feed/index.js +6 -0
- package/feed/social-post.d.ts +31 -0
- package/feed/social-post.js +268 -0
- package/media/avatar-row.d.ts +31 -0
- package/media/avatar-row.js +164 -0
- package/media/index.d.ts +7 -0
- package/media/index.js +5 -0
- package/media/media-grid.d.ts +32 -0
- package/media/media-grid.js +199 -0
- package/metrics/index.d.ts +6 -0
- package/metrics/index.js +6 -0
- package/metrics/progress-bar.d.ts +31 -0
- package/metrics/progress-bar.js +212 -0
- package/metrics/risk-gauge.d.ts +31 -0
- package/metrics/risk-gauge.js +289 -0
- package/metrics/score-item.d.ts +33 -0
- package/metrics/score-item.js +253 -0
- package/metrics/stat-card.d.ts +29 -0
- package/metrics/stat-card.js +230 -0
- package/package.json +61 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
/**
|
|
3
|
+
* `<dui-risk-gauge>` — A semicircular arc gauge with a central value,
|
|
4
|
+
* severity label, and optional trend indicator.
|
|
5
|
+
*
|
|
6
|
+
* The arc fills proportionally to `value` (0–100). The `severity` prop
|
|
7
|
+
* controls the arc color (critical, high, medium, low, info).
|
|
8
|
+
*
|
|
9
|
+
* @slot actions - Optional action buttons or links.
|
|
10
|
+
* @csspart article - The outer container.
|
|
11
|
+
* @csspart gauge - The SVG gauge area.
|
|
12
|
+
* @csspart value - The central value text.
|
|
13
|
+
* @csspart label - The metric label.
|
|
14
|
+
* @csspart trend - The trend row.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DuiRiskGauge extends LitElement {
|
|
17
|
+
#private;
|
|
18
|
+
static tagName: "dui-risk-gauge";
|
|
19
|
+
static styles: import("lit").CSSResult[];
|
|
20
|
+
/** Metric label displayed below the gauge. */
|
|
21
|
+
accessor label: string;
|
|
22
|
+
/** Gauge value (0–100). */
|
|
23
|
+
accessor value: number;
|
|
24
|
+
/** Severity level — determines arc color (critical | high | medium | low | info). */
|
|
25
|
+
accessor severity: string;
|
|
26
|
+
/** Trend text (e.g. "+5 pts", "-12%"). */
|
|
27
|
+
accessor trend: string;
|
|
28
|
+
/** Trend direction (up | down | stable). */
|
|
29
|
+
accessor trendDirection: string;
|
|
30
|
+
render(): TemplateResult;
|
|
31
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { css, html, LitElement, nothing, svg } from "lit";
|
|
36
|
+
import { property } from "lit/decorators.js";
|
|
37
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
38
|
+
/** Severity → color token mapping. */
|
|
39
|
+
const SEVERITY_COLORS = {
|
|
40
|
+
critical: "var(--destructive)",
|
|
41
|
+
high: "var(--destructive-text)",
|
|
42
|
+
medium: "var(--accent)",
|
|
43
|
+
low: "var(--accent-text)",
|
|
44
|
+
info: "var(--text-3)",
|
|
45
|
+
};
|
|
46
|
+
/** Trend direction → arrow path. */
|
|
47
|
+
const TREND_ARROWS = {
|
|
48
|
+
up: "M12 19V5M5 12l7-7 7 7",
|
|
49
|
+
down: "M12 5v14M19 12l-7 7-7-7",
|
|
50
|
+
stable: "M5 12h14",
|
|
51
|
+
};
|
|
52
|
+
const styles = css `
|
|
53
|
+
:host {
|
|
54
|
+
display: block;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
article {
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: var(--space-1);
|
|
62
|
+
padding: var(--space-3);
|
|
63
|
+
border: var(--border-width-thin) solid var(--border);
|
|
64
|
+
border-radius: var(--radius-md);
|
|
65
|
+
background: var(--surface-1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* ── Arc gauge ── */
|
|
69
|
+
.gauge {
|
|
70
|
+
position: relative;
|
|
71
|
+
width: 9rem;
|
|
72
|
+
height: 5.5rem;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: flex-end;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.gauge svg {
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: 0;
|
|
81
|
+
left: 0;
|
|
82
|
+
width: 100%;
|
|
83
|
+
height: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.center-value {
|
|
87
|
+
position: relative;
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
align-items: center;
|
|
91
|
+
gap: var(--space-0_5);
|
|
92
|
+
padding-bottom: var(--space-1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.center-number {
|
|
96
|
+
/* font-family: var(--font-mono); */
|
|
97
|
+
font-size: var(--text-2xl);
|
|
98
|
+
font-weight: var(--font-weight-bold);
|
|
99
|
+
line-height: var(--line-height-none);
|
|
100
|
+
color: var(--foreground);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.severity-label {
|
|
104
|
+
font-family: var(--font-sans);
|
|
105
|
+
font-size: var(--text-2xs);
|
|
106
|
+
font-weight: var(--font-weight-semibold);
|
|
107
|
+
letter-spacing: var(--letter-spacing-widest);
|
|
108
|
+
text-transform: uppercase;
|
|
109
|
+
line-height: var(--line-height-none);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* ── Label + trend row ── */
|
|
113
|
+
.label {
|
|
114
|
+
font-family: var(--font-sans);
|
|
115
|
+
font-size: var(--text-sm);
|
|
116
|
+
font-weight: var(--font-weight-semibold);
|
|
117
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
118
|
+
line-height: var(--line-height-snug);
|
|
119
|
+
color: var(--foreground);
|
|
120
|
+
text-align: center;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.trend-row {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: var(--space-1);
|
|
127
|
+
font-family: var(--font-sans);
|
|
128
|
+
font-size: var(--text-xs);
|
|
129
|
+
font-weight: var(--font-weight-medium);
|
|
130
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
131
|
+
line-height: var(--line-height-normal);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ── Actions ── */
|
|
135
|
+
.actions {
|
|
136
|
+
display: flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
gap: var(--space-2);
|
|
139
|
+
margin-top: var(--space-1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.actions[hidden] {
|
|
143
|
+
display: none;
|
|
144
|
+
}
|
|
145
|
+
`;
|
|
146
|
+
/**
|
|
147
|
+
* `<dui-risk-gauge>` — A semicircular arc gauge with a central value,
|
|
148
|
+
* severity label, and optional trend indicator.
|
|
149
|
+
*
|
|
150
|
+
* The arc fills proportionally to `value` (0–100). The `severity` prop
|
|
151
|
+
* controls the arc color (critical, high, medium, low, info).
|
|
152
|
+
*
|
|
153
|
+
* @slot actions - Optional action buttons or links.
|
|
154
|
+
* @csspart article - The outer container.
|
|
155
|
+
* @csspart gauge - The SVG gauge area.
|
|
156
|
+
* @csspart value - The central value text.
|
|
157
|
+
* @csspart label - The metric label.
|
|
158
|
+
* @csspart trend - The trend row.
|
|
159
|
+
*/
|
|
160
|
+
let DuiRiskGauge = (() => {
|
|
161
|
+
let _classSuper = LitElement;
|
|
162
|
+
let _label_decorators;
|
|
163
|
+
let _label_initializers = [];
|
|
164
|
+
let _label_extraInitializers = [];
|
|
165
|
+
let _value_decorators;
|
|
166
|
+
let _value_initializers = [];
|
|
167
|
+
let _value_extraInitializers = [];
|
|
168
|
+
let _severity_decorators;
|
|
169
|
+
let _severity_initializers = [];
|
|
170
|
+
let _severity_extraInitializers = [];
|
|
171
|
+
let _trend_decorators;
|
|
172
|
+
let _trend_initializers = [];
|
|
173
|
+
let _trend_extraInitializers = [];
|
|
174
|
+
let _trendDirection_decorators;
|
|
175
|
+
let _trendDirection_initializers = [];
|
|
176
|
+
let _trendDirection_extraInitializers = [];
|
|
177
|
+
return class DuiRiskGauge extends _classSuper {
|
|
178
|
+
static {
|
|
179
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
180
|
+
_label_decorators = [property()];
|
|
181
|
+
_value_decorators = [property({ type: Number })];
|
|
182
|
+
_severity_decorators = [property()];
|
|
183
|
+
_trend_decorators = [property()];
|
|
184
|
+
_trendDirection_decorators = [property({ attribute: "trend-direction" })];
|
|
185
|
+
__esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
186
|
+
__esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
|
|
187
|
+
__esDecorate(this, null, _severity_decorators, { kind: "accessor", name: "severity", static: false, private: false, access: { has: obj => "severity" in obj, get: obj => obj.severity, set: (obj, value) => { obj.severity = value; } }, metadata: _metadata }, _severity_initializers, _severity_extraInitializers);
|
|
188
|
+
__esDecorate(this, null, _trend_decorators, { kind: "accessor", name: "trend", static: false, private: false, access: { has: obj => "trend" in obj, get: obj => obj.trend, set: (obj, value) => { obj.trend = value; } }, metadata: _metadata }, _trend_initializers, _trend_extraInitializers);
|
|
189
|
+
__esDecorate(this, null, _trendDirection_decorators, { kind: "accessor", name: "trendDirection", static: false, private: false, access: { has: obj => "trendDirection" in obj, get: obj => obj.trendDirection, set: (obj, value) => { obj.trendDirection = value; } }, metadata: _metadata }, _trendDirection_initializers, _trendDirection_extraInitializers);
|
|
190
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
191
|
+
}
|
|
192
|
+
static tagName = "dui-risk-gauge";
|
|
193
|
+
static styles = [base, styles];
|
|
194
|
+
#label_accessor_storage = __runInitializers(this, _label_initializers, "");
|
|
195
|
+
/** Metric label displayed below the gauge. */
|
|
196
|
+
get label() { return this.#label_accessor_storage; }
|
|
197
|
+
set label(value) { this.#label_accessor_storage = value; }
|
|
198
|
+
#value_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _value_initializers, 0));
|
|
199
|
+
/** Gauge value (0–100). */
|
|
200
|
+
get value() { return this.#value_accessor_storage; }
|
|
201
|
+
set value(value) { this.#value_accessor_storage = value; }
|
|
202
|
+
#severity_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _severity_initializers, ""));
|
|
203
|
+
/** Severity level — determines arc color (critical | high | medium | low | info). */
|
|
204
|
+
get severity() { return this.#severity_accessor_storage; }
|
|
205
|
+
set severity(value) { this.#severity_accessor_storage = value; }
|
|
206
|
+
#trend_accessor_storage = (__runInitializers(this, _severity_extraInitializers), __runInitializers(this, _trend_initializers, ""));
|
|
207
|
+
/** Trend text (e.g. "+5 pts", "-12%"). */
|
|
208
|
+
get trend() { return this.#trend_accessor_storage; }
|
|
209
|
+
set trend(value) { this.#trend_accessor_storage = value; }
|
|
210
|
+
#trendDirection_accessor_storage = (__runInitializers(this, _trend_extraInitializers), __runInitializers(this, _trendDirection_initializers, ""));
|
|
211
|
+
/** Trend direction (up | down | stable). */
|
|
212
|
+
get trendDirection() { return this.#trendDirection_accessor_storage; }
|
|
213
|
+
set trendDirection(value) { this.#trendDirection_accessor_storage = value; }
|
|
214
|
+
#renderArc() {
|
|
215
|
+
// Semi-circle arc: 180° from left to right
|
|
216
|
+
// viewBox centers a semicircle with radius 40, stroke-width 8
|
|
217
|
+
const R = 40;
|
|
218
|
+
const CX = 50;
|
|
219
|
+
const CY = 50;
|
|
220
|
+
const circumference = Math.PI * R; // half circle
|
|
221
|
+
const clamped = Math.max(0, Math.min(100, this.value));
|
|
222
|
+
const filled = (clamped / 100) * circumference;
|
|
223
|
+
const sevColor = SEVERITY_COLORS[this.severity.toLowerCase()] ?? "var(--accent)";
|
|
224
|
+
// Arc from (10,50) to (90,50) — a semicircle
|
|
225
|
+
const arcPath = `M ${CX - R} ${CY} A ${R} ${R} 0 0 1 ${CX + R} ${CY}`;
|
|
226
|
+
return html `
|
|
227
|
+
<svg viewBox="0 0 100 55" fill="none" part="gauge">
|
|
228
|
+
${svg `
|
|
229
|
+
<!-- Track -->
|
|
230
|
+
<path d="${arcPath}" stroke="var(--border)" stroke-width="8"
|
|
231
|
+
stroke-linecap="round" fill="none" />
|
|
232
|
+
<!-- Fill -->
|
|
233
|
+
<path d="${arcPath}" stroke="${sevColor}" stroke-width="8"
|
|
234
|
+
stroke-linecap="round" fill="none"
|
|
235
|
+
stroke-dasharray="${circumference}"
|
|
236
|
+
stroke-dashoffset="${circumference - filled}" />
|
|
237
|
+
`}
|
|
238
|
+
</svg>
|
|
239
|
+
`;
|
|
240
|
+
}
|
|
241
|
+
#onSlotChange(e) {
|
|
242
|
+
const slot = e.target;
|
|
243
|
+
slot.parentElement.hidden = slot.assignedElements().length === 0;
|
|
244
|
+
}
|
|
245
|
+
render() {
|
|
246
|
+
const sevColor = SEVERITY_COLORS[this.severity.toLowerCase()] ?? "var(--accent)";
|
|
247
|
+
const trendArrow = TREND_ARROWS[this.trendDirection.toLowerCase()];
|
|
248
|
+
const trendColor = this.trendDirection === "up" ? "var(--destructive-text)"
|
|
249
|
+
: this.trendDirection === "down" ? "var(--accent-text)"
|
|
250
|
+
: "var(--text-3)";
|
|
251
|
+
return html `
|
|
252
|
+
<article part="article">
|
|
253
|
+
<div class="gauge">
|
|
254
|
+
${this.#renderArc()}
|
|
255
|
+
<div class="center-value">
|
|
256
|
+
<span class="center-number" part="value">${this.value}</span>
|
|
257
|
+
${this.severity
|
|
258
|
+
? html `<span class="severity-label" style="color: ${sevColor}">${this.severity}</span>`
|
|
259
|
+
: nothing}
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
${this.label
|
|
264
|
+
? html `<span class="label" part="label">${this.label}</span>`
|
|
265
|
+
: nothing}
|
|
266
|
+
|
|
267
|
+
${this.trend && trendArrow
|
|
268
|
+
? html `<span class="trend-row" part="trend" style="color: ${trendColor}">
|
|
269
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"
|
|
270
|
+
stroke="currentColor" stroke-width="2.5" stroke-linecap="round"
|
|
271
|
+
stroke-linejoin="round"><path d="${trendArrow}"/></svg>
|
|
272
|
+
${this.trend}
|
|
273
|
+
</span>`
|
|
274
|
+
: nothing}
|
|
275
|
+
|
|
276
|
+
<div class="actions" hidden>
|
|
277
|
+
<slot name="actions" @slotchange=${this.#onSlotChange}></slot>
|
|
278
|
+
</div>
|
|
279
|
+
</article>
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
282
|
+
constructor() {
|
|
283
|
+
super(...arguments);
|
|
284
|
+
__runInitializers(this, _trendDirection_extraInitializers);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
})();
|
|
288
|
+
export { DuiRiskGauge };
|
|
289
|
+
customElements.define(DuiRiskGauge.tagName, DuiRiskGauge);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/badge";
|
|
3
|
+
import "@deepfuture/dui-components/separator";
|
|
4
|
+
/**
|
|
5
|
+
* `<dui-score-item>` — An entity with a prominent score and optional sub-metric breakdown.
|
|
6
|
+
*
|
|
7
|
+
* Displays an entity name with an optional subtitle on the left, and a large score
|
|
8
|
+
* with an optional label on the right. Below the main row, slotted sub-metrics
|
|
9
|
+
* provide additional breakdowns.
|
|
10
|
+
*
|
|
11
|
+
* @slot sub-metrics - Additional metric breakdowns below the main row.
|
|
12
|
+
* @slot actions - Optional action buttons or links.
|
|
13
|
+
* @csspart article - The outer container.
|
|
14
|
+
* @csspart entity - The entity name.
|
|
15
|
+
* @csspart score - The score value.
|
|
16
|
+
* @csspart sub-metrics - The sub-metrics row.
|
|
17
|
+
*/
|
|
18
|
+
export declare class DuiScoreItem extends LitElement {
|
|
19
|
+
#private;
|
|
20
|
+
static tagName: "dui-score-item";
|
|
21
|
+
static styles: import("lit").CSSResult[];
|
|
22
|
+
/** Entity name (e.g. country, department, agent). */
|
|
23
|
+
accessor entity: string;
|
|
24
|
+
/** Secondary context below the entity name. */
|
|
25
|
+
accessor subtitle: string;
|
|
26
|
+
/** Prominent score value (e.g. "87", "A+", "9.4"). */
|
|
27
|
+
accessor score: string;
|
|
28
|
+
/** Label beneath the score (e.g. "Risk Score", "Rating"). */
|
|
29
|
+
accessor scoreLabel: string;
|
|
30
|
+
/** Severity level — maps to badge for optional tagging (critical | high | medium | low). */
|
|
31
|
+
accessor severity: string;
|
|
32
|
+
render(): TemplateResult;
|
|
33
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { css, html, LitElement, nothing } from "lit";
|
|
36
|
+
import { property } from "lit/decorators.js";
|
|
37
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
38
|
+
import "@deepfuture/dui-components/badge";
|
|
39
|
+
import "@deepfuture/dui-components/separator";
|
|
40
|
+
const styles = css `
|
|
41
|
+
:host {
|
|
42
|
+
display: block;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
article {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
gap: var(--space-0);
|
|
49
|
+
padding: var(--space-3);
|
|
50
|
+
border: var(--border-width-thin) solid var(--border);
|
|
51
|
+
border-radius: var(--radius-md);
|
|
52
|
+
background: var(--surface-1);
|
|
53
|
+
transition: background var(--duration-fast) ease;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
article:hover {
|
|
57
|
+
background: var(--surface-2);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ── Top row: entity + score ── */
|
|
61
|
+
.top {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: flex-start;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
gap: var(--space-3);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.entity-group {
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
gap: var(--space-0_5);
|
|
72
|
+
min-width: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.entity {
|
|
76
|
+
font-family: var(--font-sans);
|
|
77
|
+
font-size: var(--text-sm);
|
|
78
|
+
font-weight: var(--font-weight-semibold);
|
|
79
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
80
|
+
line-height: var(--line-height-snug);
|
|
81
|
+
color: var(--foreground);
|
|
82
|
+
white-space: nowrap;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
text-overflow: ellipsis;
|
|
85
|
+
min-width: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.subtitle {
|
|
89
|
+
font-family: var(--font-sans);
|
|
90
|
+
font-size: var(--text-xs);
|
|
91
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
92
|
+
line-height: var(--line-height-normal);
|
|
93
|
+
color: var(--text-2);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.score-group {
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
align-items: flex-end;
|
|
100
|
+
gap: var(--space-0_5);
|
|
101
|
+
flex-shrink: 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.score {
|
|
105
|
+
font-size: var(--text-2xl);
|
|
106
|
+
font-weight: var(--font-weight-semibold);
|
|
107
|
+
letter-spacing: var(--letter-spacing-normal);
|
|
108
|
+
line-height: var(--line-height-tight);
|
|
109
|
+
color: var(--foreground);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.score-label {
|
|
113
|
+
font-family: var(--font-sans);
|
|
114
|
+
font-size: var(--text-2xs);
|
|
115
|
+
font-weight: var(--font-weight-medium);
|
|
116
|
+
letter-spacing: var(--letter-spacing-widest);
|
|
117
|
+
text-transform: uppercase;
|
|
118
|
+
line-height: var(--line-height-normal);
|
|
119
|
+
color: var(--text-3);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* ── Sub-metrics row ── */
|
|
123
|
+
.sub-metrics {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: var(--space-3);
|
|
127
|
+
flex-wrap: wrap;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.sub-metrics[hidden] {
|
|
131
|
+
display: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ── Actions ── */
|
|
135
|
+
.actions {
|
|
136
|
+
display: flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
gap: var(--space-2);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.actions[hidden] {
|
|
142
|
+
display: none;
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
/**
|
|
146
|
+
* `<dui-score-item>` — An entity with a prominent score and optional sub-metric breakdown.
|
|
147
|
+
*
|
|
148
|
+
* Displays an entity name with an optional subtitle on the left, and a large score
|
|
149
|
+
* with an optional label on the right. Below the main row, slotted sub-metrics
|
|
150
|
+
* provide additional breakdowns.
|
|
151
|
+
*
|
|
152
|
+
* @slot sub-metrics - Additional metric breakdowns below the main row.
|
|
153
|
+
* @slot actions - Optional action buttons or links.
|
|
154
|
+
* @csspart article - The outer container.
|
|
155
|
+
* @csspart entity - The entity name.
|
|
156
|
+
* @csspart score - The score value.
|
|
157
|
+
* @csspart sub-metrics - The sub-metrics row.
|
|
158
|
+
*/
|
|
159
|
+
let DuiScoreItem = (() => {
|
|
160
|
+
let _classSuper = LitElement;
|
|
161
|
+
let _entity_decorators;
|
|
162
|
+
let _entity_initializers = [];
|
|
163
|
+
let _entity_extraInitializers = [];
|
|
164
|
+
let _subtitle_decorators;
|
|
165
|
+
let _subtitle_initializers = [];
|
|
166
|
+
let _subtitle_extraInitializers = [];
|
|
167
|
+
let _score_decorators;
|
|
168
|
+
let _score_initializers = [];
|
|
169
|
+
let _score_extraInitializers = [];
|
|
170
|
+
let _scoreLabel_decorators;
|
|
171
|
+
let _scoreLabel_initializers = [];
|
|
172
|
+
let _scoreLabel_extraInitializers = [];
|
|
173
|
+
let _severity_decorators;
|
|
174
|
+
let _severity_initializers = [];
|
|
175
|
+
let _severity_extraInitializers = [];
|
|
176
|
+
return class DuiScoreItem extends _classSuper {
|
|
177
|
+
static {
|
|
178
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
179
|
+
_entity_decorators = [property()];
|
|
180
|
+
_subtitle_decorators = [property()];
|
|
181
|
+
_score_decorators = [property()];
|
|
182
|
+
_scoreLabel_decorators = [property({ attribute: "score-label" })];
|
|
183
|
+
_severity_decorators = [property()];
|
|
184
|
+
__esDecorate(this, null, _entity_decorators, { kind: "accessor", name: "entity", static: false, private: false, access: { has: obj => "entity" in obj, get: obj => obj.entity, set: (obj, value) => { obj.entity = value; } }, metadata: _metadata }, _entity_initializers, _entity_extraInitializers);
|
|
185
|
+
__esDecorate(this, null, _subtitle_decorators, { kind: "accessor", name: "subtitle", static: false, private: false, access: { has: obj => "subtitle" in obj, get: obj => obj.subtitle, set: (obj, value) => { obj.subtitle = value; } }, metadata: _metadata }, _subtitle_initializers, _subtitle_extraInitializers);
|
|
186
|
+
__esDecorate(this, null, _score_decorators, { kind: "accessor", name: "score", static: false, private: false, access: { has: obj => "score" in obj, get: obj => obj.score, set: (obj, value) => { obj.score = value; } }, metadata: _metadata }, _score_initializers, _score_extraInitializers);
|
|
187
|
+
__esDecorate(this, null, _scoreLabel_decorators, { kind: "accessor", name: "scoreLabel", static: false, private: false, access: { has: obj => "scoreLabel" in obj, get: obj => obj.scoreLabel, set: (obj, value) => { obj.scoreLabel = value; } }, metadata: _metadata }, _scoreLabel_initializers, _scoreLabel_extraInitializers);
|
|
188
|
+
__esDecorate(this, null, _severity_decorators, { kind: "accessor", name: "severity", static: false, private: false, access: { has: obj => "severity" in obj, get: obj => obj.severity, set: (obj, value) => { obj.severity = value; } }, metadata: _metadata }, _severity_initializers, _severity_extraInitializers);
|
|
189
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
190
|
+
}
|
|
191
|
+
static tagName = "dui-score-item";
|
|
192
|
+
static styles = [base, styles];
|
|
193
|
+
#entity_accessor_storage = __runInitializers(this, _entity_initializers, "");
|
|
194
|
+
/** Entity name (e.g. country, department, agent). */
|
|
195
|
+
get entity() { return this.#entity_accessor_storage; }
|
|
196
|
+
set entity(value) { this.#entity_accessor_storage = value; }
|
|
197
|
+
#subtitle_accessor_storage = (__runInitializers(this, _entity_extraInitializers), __runInitializers(this, _subtitle_initializers, ""));
|
|
198
|
+
/** Secondary context below the entity name. */
|
|
199
|
+
get subtitle() { return this.#subtitle_accessor_storage; }
|
|
200
|
+
set subtitle(value) { this.#subtitle_accessor_storage = value; }
|
|
201
|
+
#score_accessor_storage = (__runInitializers(this, _subtitle_extraInitializers), __runInitializers(this, _score_initializers, ""));
|
|
202
|
+
/** Prominent score value (e.g. "87", "A+", "9.4"). */
|
|
203
|
+
get score() { return this.#score_accessor_storage; }
|
|
204
|
+
set score(value) { this.#score_accessor_storage = value; }
|
|
205
|
+
#scoreLabel_accessor_storage = (__runInitializers(this, _score_extraInitializers), __runInitializers(this, _scoreLabel_initializers, ""));
|
|
206
|
+
/** Label beneath the score (e.g. "Risk Score", "Rating"). */
|
|
207
|
+
get scoreLabel() { return this.#scoreLabel_accessor_storage; }
|
|
208
|
+
set scoreLabel(value) { this.#scoreLabel_accessor_storage = value; }
|
|
209
|
+
#severity_accessor_storage = (__runInitializers(this, _scoreLabel_extraInitializers), __runInitializers(this, _severity_initializers, ""));
|
|
210
|
+
/** Severity level — maps to badge for optional tagging (critical | high | medium | low). */
|
|
211
|
+
get severity() { return this.#severity_accessor_storage; }
|
|
212
|
+
set severity(value) { this.#severity_accessor_storage = value; }
|
|
213
|
+
#onSlotChange(e) {
|
|
214
|
+
const slot = e.target;
|
|
215
|
+
slot.parentElement.hidden = slot.assignedElements().length === 0;
|
|
216
|
+
}
|
|
217
|
+
render() {
|
|
218
|
+
return html `
|
|
219
|
+
<article part="article">
|
|
220
|
+
<div class="top">
|
|
221
|
+
<div class="entity-group">
|
|
222
|
+
<span class="entity" part="entity">${this.entity}</span>
|
|
223
|
+
${this.subtitle
|
|
224
|
+
? html `<span class="subtitle">${this.subtitle}</span>`
|
|
225
|
+
: nothing}
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<div class="score-group">
|
|
229
|
+
<span class="score" part="score">${this.score}</span>
|
|
230
|
+
${this.scoreLabel
|
|
231
|
+
? html `<span class="score-label">${this.scoreLabel}</span>`
|
|
232
|
+
: nothing}
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div class="sub-metrics" part="sub-metrics" hidden>
|
|
237
|
+
<slot name="sub-metrics" @slotchange=${this.#onSlotChange}></slot>
|
|
238
|
+
</div>
|
|
239
|
+
|
|
240
|
+
<div class="actions" hidden>
|
|
241
|
+
<slot name="actions" @slotchange=${this.#onSlotChange}></slot>
|
|
242
|
+
</div>
|
|
243
|
+
</article>
|
|
244
|
+
`;
|
|
245
|
+
}
|
|
246
|
+
constructor() {
|
|
247
|
+
super(...arguments);
|
|
248
|
+
__runInitializers(this, _severity_extraInitializers);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
})();
|
|
252
|
+
export { DuiScoreItem };
|
|
253
|
+
customElements.define(DuiScoreItem.tagName, DuiScoreItem);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/icon";
|
|
3
|
+
/**
|
|
4
|
+
* `<dui-stat-card>` — A single metric card displaying a label, prominent value,
|
|
5
|
+
* optional trend indicator, and description text.
|
|
6
|
+
*
|
|
7
|
+
* @slot actions - Optional action buttons or links.
|
|
8
|
+
* @csspart article - The outer container.
|
|
9
|
+
* @csspart label - The metric label.
|
|
10
|
+
* @csspart value - The metric value.
|
|
11
|
+
* @csspart trend - The trend indicator.
|
|
12
|
+
* @csspart description - The description text.
|
|
13
|
+
*/
|
|
14
|
+
export declare class DuiStatCard extends LitElement {
|
|
15
|
+
#private;
|
|
16
|
+
static tagName: "dui-stat-card";
|
|
17
|
+
static styles: import("lit").CSSResult[];
|
|
18
|
+
/** Metric label (e.g. "Total Events", "Response Time"). */
|
|
19
|
+
accessor label: string;
|
|
20
|
+
/** Primary metric value (e.g. "1,284", "$42.5K", "99.9%"). */
|
|
21
|
+
accessor value: string;
|
|
22
|
+
/** Trend text (e.g. "+12%", "-3.2%", "0%"). */
|
|
23
|
+
accessor trend: string;
|
|
24
|
+
/** Trend direction — determines arrow and color (up | down | stable). */
|
|
25
|
+
accessor trendDirection: string;
|
|
26
|
+
/** Supporting context text. */
|
|
27
|
+
accessor description: string;
|
|
28
|
+
render(): TemplateResult;
|
|
29
|
+
}
|