@sentropic/design-system-svelte 0.34.0 → 0.34.21
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/dist/AppChrome.svelte +660 -0
- package/dist/AppChrome.svelte.d.ts +74 -0
- package/dist/AppChrome.svelte.d.ts.map +1 -0
- package/dist/AppChrome.test.d.ts +2 -0
- package/dist/AppChrome.test.d.ts.map +1 -0
- package/dist/AppChrome.test.js +122 -0
- package/dist/AppHeader.svelte +159 -1
- package/dist/AppHeader.svelte.d.ts +18 -1
- package/dist/AppHeader.svelte.d.ts.map +1 -1
- package/dist/ArcDiagramChart.svelte +380 -0
- package/dist/ArcDiagramChart.svelte.d.ts +43 -0
- package/dist/ArcDiagramChart.svelte.d.ts.map +1 -0
- package/dist/AreaRangeChart.svelte +487 -0
- package/dist/AreaRangeChart.svelte.d.ts +38 -0
- package/dist/AreaRangeChart.svelte.d.ts.map +1 -0
- package/dist/AreaSplineRangeChart.svelte +478 -0
- package/dist/AreaSplineRangeChart.svelte.d.ts +37 -0
- package/dist/AreaSplineRangeChart.svelte.d.ts.map +1 -0
- package/dist/BellCurveChart.svelte +487 -0
- package/dist/BellCurveChart.svelte.d.ts +40 -0
- package/dist/BellCurveChart.svelte.d.ts.map +1 -0
- package/dist/Calendar.svelte +11 -0
- package/dist/ChatThread.svelte +32 -1
- package/dist/ChatThread.svelte.d.ts +14 -0
- package/dist/ChatThread.svelte.d.ts.map +1 -1
- package/dist/ColumnPyramidChart.svelte +332 -0
- package/dist/ColumnPyramidChart.svelte.d.ts +35 -0
- package/dist/ColumnPyramidChart.svelte.d.ts.map +1 -0
- package/dist/ColumnRangeChart.svelte +432 -0
- package/dist/ColumnRangeChart.svelte.d.ts +42 -0
- package/dist/ColumnRangeChart.svelte.d.ts.map +1 -0
- package/dist/Combobox.svelte +3 -0
- package/dist/ConfigItemCard.svelte +303 -0
- package/dist/ConfigItemCard.svelte.d.ts +37 -0
- package/dist/ConfigItemCard.svelte.d.ts.map +1 -0
- package/dist/ContentSwitcher.svelte +1 -1
- package/dist/DatePicker.svelte +3 -0
- package/dist/DependencyWheelChart.svelte +413 -0
- package/dist/DependencyWheelChart.svelte.d.ts +42 -0
- package/dist/DependencyWheelChart.svelte.d.ts.map +1 -0
- package/dist/DumbbellChart.svelte +403 -0
- package/dist/DumbbellChart.svelte.d.ts +44 -0
- package/dist/DumbbellChart.svelte.d.ts.map +1 -0
- package/dist/ErrorBarChart.svelte +428 -0
- package/dist/ErrorBarChart.svelte.d.ts +40 -0
- package/dist/ErrorBarChart.svelte.d.ts.map +1 -0
- package/dist/FieldCard.svelte +220 -0
- package/dist/FieldCard.svelte.d.ts +28 -0
- package/dist/FieldCard.svelte.d.ts.map +1 -0
- package/dist/GanttChart.svelte +410 -0
- package/dist/GanttChart.svelte.d.ts +39 -0
- package/dist/GanttChart.svelte.d.ts.map +1 -0
- package/dist/HLCChart.svelte +330 -0
- package/dist/HLCChart.svelte.d.ts +32 -0
- package/dist/HLCChart.svelte.d.ts.map +1 -0
- package/dist/HeikinAshiChart.svelte +365 -0
- package/dist/HeikinAshiChart.svelte.d.ts +37 -0
- package/dist/HeikinAshiChart.svelte.d.ts.map +1 -0
- package/dist/HollowCandlestickChart.svelte +357 -0
- package/dist/HollowCandlestickChart.svelte.d.ts +34 -0
- package/dist/HollowCandlestickChart.svelte.d.ts.map +1 -0
- package/dist/Input.svelte +3 -0
- package/dist/ItemChart.svelte +389 -0
- package/dist/ItemChart.svelte.d.ts +67 -0
- package/dist/ItemChart.svelte.d.ts.map +1 -0
- package/dist/LollipopChart.svelte +1 -1
- package/dist/MultiSelect.svelte +3 -0
- package/dist/NumberInput.svelte +3 -0
- package/dist/OHLCChart.svelte +343 -0
- package/dist/OHLCChart.svelte.d.ts +33 -0
- package/dist/OHLCChart.svelte.d.ts.map +1 -0
- package/dist/OrganizationChart.svelte +284 -0
- package/dist/OrganizationChart.svelte.d.ts +19 -0
- package/dist/OrganizationChart.svelte.d.ts.map +1 -0
- package/dist/PasswordInput.svelte +3 -0
- package/dist/PolygonChart.svelte +189 -0
- package/dist/PolygonChart.svelte.d.ts +17 -0
- package/dist/PolygonChart.svelte.d.ts.map +1 -0
- package/dist/ScoreCard.svelte +172 -0
- package/dist/ScoreCard.svelte.d.ts +27 -0
- package/dist/ScoreCard.svelte.d.ts.map +1 -0
- package/dist/Search.svelte +7 -5
- package/dist/Select.svelte +3 -0
- package/dist/StreamgraphChart.svelte +283 -0
- package/dist/StreamgraphChart.svelte.d.ts +23 -0
- package/dist/StreamgraphChart.svelte.d.ts.map +1 -0
- package/dist/StreamingMessage.svelte +44 -2
- package/dist/StreamingMessage.svelte.d.ts +18 -1
- package/dist/StreamingMessage.svelte.d.ts.map +1 -1
- package/dist/TileMapChart.svelte +314 -0
- package/dist/TileMapChart.svelte.d.ts +45 -0
- package/dist/TileMapChart.svelte.d.ts.map +1 -0
- package/dist/TimePicker.svelte +3 -0
- package/dist/TimelineChart.svelte +362 -0
- package/dist/TimelineChart.svelte.d.ts +22 -0
- package/dist/TimelineChart.svelte.d.ts.map +1 -0
- package/dist/TreegraphChart.svelte +281 -0
- package/dist/TreegraphChart.svelte.d.ts +19 -0
- package/dist/TreegraphChart.svelte.d.ts.map +1 -0
- package/dist/VariablePieChart.svelte +313 -0
- package/dist/VariablePieChart.svelte.d.ts +52 -0
- package/dist/VariablePieChart.svelte.d.ts.map +1 -0
- package/dist/VennChart.svelte +348 -0
- package/dist/VennChart.svelte.d.ts +72 -0
- package/dist/VennChart.svelte.d.ts.map +1 -0
- package/dist/WordCloudChart.svelte +279 -0
- package/dist/WordCloudChart.svelte.d.ts +18 -0
- package/dist/WordCloudChart.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -0
- package/package.json +5 -3
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type StreamgraphChartTone =
|
|
3
|
+
| "category1" | "category2" | "category3" | "category4"
|
|
4
|
+
| "category5" | "category6" | "category7" | "category8";
|
|
5
|
+
|
|
6
|
+
// Une série pour un point d'abscisse : un libellé + sa valeur.
|
|
7
|
+
export type StreamgraphChartSeriesValue = {
|
|
8
|
+
label: string;
|
|
9
|
+
value: number;
|
|
10
|
+
tone?: StreamgraphChartTone;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Un point sur l'axe X (catégorie / temps) avec ses séries empilées.
|
|
14
|
+
export type StreamgraphChartDatum = {
|
|
15
|
+
category: string;
|
|
16
|
+
values: StreamgraphChartSeriesValue[];
|
|
17
|
+
};
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
import ChartDataList from "./ChartDataList.svelte";
|
|
22
|
+
|
|
23
|
+
type StreamgraphChartProps = {
|
|
24
|
+
data: StreamgraphChartDatum[];
|
|
25
|
+
width?: number;
|
|
26
|
+
height?: number;
|
|
27
|
+
label: string;
|
|
28
|
+
smooth?: boolean;
|
|
29
|
+
showLegend?: boolean;
|
|
30
|
+
class?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let {
|
|
34
|
+
data = [],
|
|
35
|
+
width = 480,
|
|
36
|
+
height = 240,
|
|
37
|
+
label,
|
|
38
|
+
smooth = true,
|
|
39
|
+
showLegend = true,
|
|
40
|
+
class: className
|
|
41
|
+
}: StreamgraphChartProps = $props();
|
|
42
|
+
|
|
43
|
+
const MARGIN = { top: 12, right: 16, bottom: 32, left: 16 };
|
|
44
|
+
const TONES = ["category1","category2","category3","category4","category5","category6","category7","category8"] as const;
|
|
45
|
+
|
|
46
|
+
const scaleLinear = (v: number, d0: number, d1: number, r0: number, r1: number) =>
|
|
47
|
+
d1 === d0 ? r0 : r0 + ((v - d0) * (r1 - r0)) / (d1 - d0);
|
|
48
|
+
|
|
49
|
+
function buildLinearPath(pts: { x: number; y: number }[]): string {
|
|
50
|
+
return pts.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function buildSmoothPath(pts: { x: number; y: number }[]): string {
|
|
54
|
+
if (pts.length < 2) return buildLinearPath(pts);
|
|
55
|
+
const t = 0.18;
|
|
56
|
+
let d = `M${pts[0].x.toFixed(2)},${pts[0].y.toFixed(2)}`;
|
|
57
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
58
|
+
const p0 = pts[i - 1] ?? pts[i];
|
|
59
|
+
const p1 = pts[i];
|
|
60
|
+
const p2 = pts[i + 1];
|
|
61
|
+
const p3 = pts[i + 2] ?? p2;
|
|
62
|
+
const c1x = p1.x + (p2.x - p0.x) * t;
|
|
63
|
+
const c1y = p1.y + (p2.y - p0.y) * t;
|
|
64
|
+
const c2x = p2.x - (p3.x - p1.x) * t;
|
|
65
|
+
const c2y = p2.y - (p3.y - p1.y) * t;
|
|
66
|
+
d += ` C${c1x.toFixed(2)},${c1y.toFixed(2)} ${c2x.toFixed(2)},${c2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
|
|
67
|
+
}
|
|
68
|
+
return d;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Valeur non-finie ou négative → 0 (le streamgraph empile des grandeurs ≥ 0).
|
|
72
|
+
const safeValue = (v: number) => (Number.isFinite(v) && v > 0 ? v : 0);
|
|
73
|
+
|
|
74
|
+
const plotWidth = $derived(Math.max(width - MARGIN.left - MARGIN.right, 1));
|
|
75
|
+
const plotHeight = $derived(Math.max(height - MARGIN.top - MARGIN.bottom, 1));
|
|
76
|
+
|
|
77
|
+
// Ordre stable des séries (1re apparition) + ton associé.
|
|
78
|
+
const series = $derived.by(() => {
|
|
79
|
+
const seen = new Map<string, StreamgraphChartTone>();
|
|
80
|
+
data.forEach((d) =>
|
|
81
|
+
d.values.forEach((sv, i) => {
|
|
82
|
+
if (!seen.has(sv.label)) seen.set(sv.label, sv.tone ?? TONES[seen.size % TONES.length]);
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
return [...seen.entries()].map(([seriesLabel, tone]) => ({ seriesLabel, tone }));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Échelle Y symétrique : demi-amplitude = max des sommes empilées / 2.
|
|
89
|
+
const halfMax = $derived.by(() => {
|
|
90
|
+
let max = 0;
|
|
91
|
+
for (const d of data) {
|
|
92
|
+
let sum = 0;
|
|
93
|
+
for (const sv of d.values) sum += safeValue(sv.value);
|
|
94
|
+
if (sum > max) max = sum;
|
|
95
|
+
}
|
|
96
|
+
return max / 2 || 1;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Pour chaque x : abscisse en px + bornes basse/haute (px) par série,
|
|
100
|
+
// baseline « wiggle » centrée (pile centrée autour de 0 ⇒ baseline = -somme/2).
|
|
101
|
+
const layout = $derived.by(() => {
|
|
102
|
+
const n = data.length;
|
|
103
|
+
const xs = data.map((_, i) => {
|
|
104
|
+
const denom = Math.max(n - 1, 1);
|
|
105
|
+
const xRatio = n === 1 ? 0.5 : i / denom;
|
|
106
|
+
return MARGIN.left + xRatio * plotWidth;
|
|
107
|
+
});
|
|
108
|
+
const midY = MARGIN.top + plotHeight / 2;
|
|
109
|
+
// valToY : une grandeur signée (par rapport au centre) → coordonnée px.
|
|
110
|
+
const valToY = (signed: number) => midY - scaleLinear(signed, 0, halfMax, 0, plotHeight / 2);
|
|
111
|
+
|
|
112
|
+
// bands[seriesIndex][xIndex] = { x, top, bottom } en px.
|
|
113
|
+
const bands = series.map(() => [] as { x: number; top: number; bottom: number }[]);
|
|
114
|
+
data.forEach((d, xi) => {
|
|
115
|
+
const total = d.values.reduce((s, sv) => s + safeValue(sv.value), 0);
|
|
116
|
+
let acc = -total / 2; // baseline centrée
|
|
117
|
+
series.forEach((s, si) => {
|
|
118
|
+
const sv = d.values.find((v) => v.label === s.seriesLabel);
|
|
119
|
+
const v = sv ? safeValue(sv.value) : 0;
|
|
120
|
+
const lower = acc;
|
|
121
|
+
const upper = acc + v;
|
|
122
|
+
acc = upper;
|
|
123
|
+
bands[si].push({ x: xs[xi], top: valToY(upper), bottom: valToY(lower) });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
return { xs, bands };
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Aire fermée par série (haut gauche→droite, puis bas droite→gauche).
|
|
130
|
+
const areas = $derived.by(() =>
|
|
131
|
+
series.map((s, si) => {
|
|
132
|
+
const band = layout.bands[si];
|
|
133
|
+
if (!band || band.length === 0) return { tone: s.tone, seriesLabel: s.seriesLabel, d: "" };
|
|
134
|
+
const topPts = band.map((b) => ({ x: b.x, y: b.top }));
|
|
135
|
+
const bottomPts = band.map((b) => ({ x: b.x, y: b.bottom })).reverse();
|
|
136
|
+
const topPath = smooth ? buildSmoothPath(topPts) : buildLinearPath(topPts);
|
|
137
|
+
const bottomPath = (smooth ? buildSmoothPath(bottomPts) : buildLinearPath(bottomPts)).replace(/^M/, "L");
|
|
138
|
+
return { tone: s.tone, seriesLabel: s.seriesLabel, d: `${topPath} ${bottomPath} Z` };
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// Étiquettes d'axe X : jusqu'à 5 catégories réparties.
|
|
143
|
+
const xTickEntries = $derived.by(() => {
|
|
144
|
+
const n = data.length;
|
|
145
|
+
if (n === 0) return [] as { x: number; label: string }[];
|
|
146
|
+
const target = Math.min(5, n);
|
|
147
|
+
const stride = Math.max(1, Math.round((n - 1) / (target - 1 || 1)));
|
|
148
|
+
const entries: { x: number; label: string }[] = [];
|
|
149
|
+
for (let i = 0; i < n; i += stride) entries.push({ x: layout.xs[i], label: data[i].category });
|
|
150
|
+
const lastIdx = n - 1;
|
|
151
|
+
if (entries[entries.length - 1]?.label !== data[lastIdx].category) {
|
|
152
|
+
entries.push({ x: layout.xs[lastIdx], label: data[lastIdx].category });
|
|
153
|
+
}
|
|
154
|
+
return entries;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Liste accessible : total par série + total global.
|
|
158
|
+
const dataValueItems = $derived.by(() => {
|
|
159
|
+
const items = series.map((s) => {
|
|
160
|
+
const total = data.reduce((sum, d) => {
|
|
161
|
+
const sv = d.values.find((v) => v.label === s.seriesLabel);
|
|
162
|
+
return sum + (sv ? safeValue(sv.value) : 0);
|
|
163
|
+
}, 0);
|
|
164
|
+
return `${s.seriesLabel}: ${total}`;
|
|
165
|
+
});
|
|
166
|
+
const grand = data.reduce((sum, d) => sum + d.values.reduce((s, sv) => s + safeValue(sv.value), 0), 0);
|
|
167
|
+
if (series.length > 0) items.push(`Total: ${grand}`);
|
|
168
|
+
return items;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
let hovered: number | null = $state(null);
|
|
172
|
+
|
|
173
|
+
function handleVisualPointerMove(event: PointerEvent) {
|
|
174
|
+
const target = event.target;
|
|
175
|
+
if (!(target instanceof Element)) {
|
|
176
|
+
hovered = null;
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const si = Number(target.getAttribute("data-series-index"));
|
|
180
|
+
hovered = Number.isInteger(si) ? si : null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const tooltip = $derived.by(() => {
|
|
184
|
+
if (hovered === null || !series[hovered]) return null;
|
|
185
|
+
const s = series[hovered];
|
|
186
|
+
const band = layout.bands[hovered];
|
|
187
|
+
if (!band || band.length === 0) return null;
|
|
188
|
+
const mid = band[Math.floor(band.length / 2)];
|
|
189
|
+
const total = data.reduce((sum, d) => {
|
|
190
|
+
const sv = d.values.find((v) => v.label === s.seriesLabel);
|
|
191
|
+
return sum + (sv ? safeValue(sv.value) : 0);
|
|
192
|
+
}, 0);
|
|
193
|
+
return { label: s.seriesLabel, value: total, cx: mid.x, cy: (mid.top + mid.bottom) / 2 };
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const classes = () => ["st-streamgraphChart", className].filter(Boolean).join(" ");
|
|
197
|
+
</script>
|
|
198
|
+
|
|
199
|
+
<div class={classes()}>
|
|
200
|
+
<div
|
|
201
|
+
class="st-streamgraphChart__visual"
|
|
202
|
+
role="img"
|
|
203
|
+
aria-label={label}
|
|
204
|
+
onpointermove={handleVisualPointerMove}
|
|
205
|
+
onpointerleave={() => (hovered = null)}
|
|
206
|
+
>
|
|
207
|
+
<svg viewBox="0 0 {width} {height}" preserveAspectRatio="xMidYMid meet" width="100%" height="100%" focusable="false" aria-hidden="true">
|
|
208
|
+
<line class="st-streamgraphChart__axis" x1={MARGIN.left} x2={width - MARGIN.right} y1={height - MARGIN.bottom} y2={height - MARGIN.bottom} />
|
|
209
|
+
|
|
210
|
+
{#each xTickEntries as tick, i (i)}
|
|
211
|
+
<text class="st-streamgraphChart__tickLabel" x={tick.x} y={height - MARGIN.bottom + 16} text-anchor="middle">{tick.label}</text>
|
|
212
|
+
{/each}
|
|
213
|
+
|
|
214
|
+
{#each areas as area, si (area.seriesLabel)}
|
|
215
|
+
{#if area.d}
|
|
216
|
+
<path
|
|
217
|
+
class="st-streamgraphChart__area st-streamgraphChart__area--{area.tone}"
|
|
218
|
+
class:st-streamgraphChart__area--dim={hovered !== null && hovered !== si}
|
|
219
|
+
d={area.d}
|
|
220
|
+
data-series-index={si}
|
|
221
|
+
/>
|
|
222
|
+
{/if}
|
|
223
|
+
{/each}
|
|
224
|
+
</svg>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<ChartDataList {label} items={dataValueItems} />
|
|
228
|
+
|
|
229
|
+
{#if tooltip}
|
|
230
|
+
<div class="st-streamgraphChart__tooltip" role="presentation" style="left: {(tooltip.cx / width) * 100}%; top: {(tooltip.cy / height) * 100}%">
|
|
231
|
+
<span class="st-streamgraphChart__tooltipLabel">{tooltip.label}</span>
|
|
232
|
+
<span class="st-streamgraphChart__tooltipValue">{tooltip.value}</span>
|
|
233
|
+
</div>
|
|
234
|
+
{/if}
|
|
235
|
+
|
|
236
|
+
{#if showLegend && series.length > 0}
|
|
237
|
+
<ul class="st-streamgraphChart__legend">
|
|
238
|
+
{#each series as item (item.seriesLabel)}
|
|
239
|
+
<li class="st-streamgraphChart__legendItem">
|
|
240
|
+
<span class="st-streamgraphChart__legendSwatch st-streamgraphChart__legendSwatch--{item.tone}" aria-hidden="true"></span>
|
|
241
|
+
{item.seriesLabel}
|
|
242
|
+
</li>
|
|
243
|
+
{/each}
|
|
244
|
+
</ul>
|
|
245
|
+
{/if}
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
<style>
|
|
249
|
+
.st-streamgraphChart { color: var(--st-semantic-text-secondary); display: block; font-family: inherit; position: relative; width: 100%; }
|
|
250
|
+
.st-streamgraphChart svg, .st-streamgraphChart__visual { display: block; overflow: visible; }
|
|
251
|
+
.st-streamgraphChart__axis { stroke: var(--st-semantic-border-subtle); stroke-width: 1; }
|
|
252
|
+
.st-streamgraphChart__tickLabel { fill: var(--st-semantic-text-secondary); font-size: 0.6875rem; }
|
|
253
|
+
.st-streamgraphChart__area { cursor: pointer; stroke: var(--st-semantic-surface-default, #fff); stroke-width: 0.75; transition: opacity 120ms ease; }
|
|
254
|
+
.st-streamgraphChart__area--dim { opacity: 0.4; }
|
|
255
|
+
.st-streamgraphChart__area--category1 { fill: var(--st-semantic-data-category1); }
|
|
256
|
+
.st-streamgraphChart__area--category2 { fill: var(--st-semantic-data-category2); }
|
|
257
|
+
.st-streamgraphChart__area--category3 { fill: var(--st-semantic-data-category3); }
|
|
258
|
+
.st-streamgraphChart__area--category4 { fill: var(--st-semantic-data-category4); }
|
|
259
|
+
.st-streamgraphChart__area--category5 { fill: var(--st-semantic-data-category5); }
|
|
260
|
+
.st-streamgraphChart__area--category6 { fill: var(--st-semantic-data-category6); }
|
|
261
|
+
.st-streamgraphChart__area--category7 { fill: var(--st-semantic-data-category7); }
|
|
262
|
+
.st-streamgraphChart__area--category8 { fill: var(--st-semantic-data-category8); }
|
|
263
|
+
@media (prefers-reduced-motion: reduce) { .st-streamgraphChart__area { transition: none; } }
|
|
264
|
+
.st-streamgraphChart__tooltip {
|
|
265
|
+
background: var(--st-semantic-surface-inverse); border-radius: var(--st-radius-sm, 0.25rem);
|
|
266
|
+
color: var(--st-semantic-text-inverse); display: inline-flex; flex-direction: column; font-size: 0.75rem;
|
|
267
|
+
gap: 0.125rem; line-height: 1.2; padding: 0.375rem 0.5rem; pointer-events: none; position: absolute;
|
|
268
|
+
transform: translate(-50%, calc(-100% - 8px)); white-space: nowrap; z-index: 1;
|
|
269
|
+
}
|
|
270
|
+
.st-streamgraphChart__tooltipLabel { font-weight: 600; }
|
|
271
|
+
.st-streamgraphChart__tooltipValue { opacity: 0.85; }
|
|
272
|
+
.st-streamgraphChart__legend { display: flex; flex-wrap: wrap; gap: 0.75rem; list-style: none; margin: 0.5rem 0 0; padding: 0; }
|
|
273
|
+
.st-streamgraphChart__legendItem { align-items: center; color: var(--st-semantic-text-secondary); display: inline-flex; font-size: 0.75rem; gap: 0.35rem; }
|
|
274
|
+
.st-streamgraphChart__legendSwatch { border-radius: 2px; height: 0.7rem; width: 0.7rem; }
|
|
275
|
+
.st-streamgraphChart__legendSwatch--category1 { background: var(--st-semantic-data-category1); }
|
|
276
|
+
.st-streamgraphChart__legendSwatch--category2 { background: var(--st-semantic-data-category2); }
|
|
277
|
+
.st-streamgraphChart__legendSwatch--category3 { background: var(--st-semantic-data-category3); }
|
|
278
|
+
.st-streamgraphChart__legendSwatch--category4 { background: var(--st-semantic-data-category4); }
|
|
279
|
+
.st-streamgraphChart__legendSwatch--category5 { background: var(--st-semantic-data-category5); }
|
|
280
|
+
.st-streamgraphChart__legendSwatch--category6 { background: var(--st-semantic-data-category6); }
|
|
281
|
+
.st-streamgraphChart__legendSwatch--category7 { background: var(--st-semantic-data-category7); }
|
|
282
|
+
.st-streamgraphChart__legendSwatch--category8 { background: var(--st-semantic-data-category8); }
|
|
283
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type StreamgraphChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
2
|
+
export type StreamgraphChartSeriesValue = {
|
|
3
|
+
label: string;
|
|
4
|
+
value: number;
|
|
5
|
+
tone?: StreamgraphChartTone;
|
|
6
|
+
};
|
|
7
|
+
export type StreamgraphChartDatum = {
|
|
8
|
+
category: string;
|
|
9
|
+
values: StreamgraphChartSeriesValue[];
|
|
10
|
+
};
|
|
11
|
+
type StreamgraphChartProps = {
|
|
12
|
+
data: StreamgraphChartDatum[];
|
|
13
|
+
width?: number;
|
|
14
|
+
height?: number;
|
|
15
|
+
label: string;
|
|
16
|
+
smooth?: boolean;
|
|
17
|
+
showLegend?: boolean;
|
|
18
|
+
class?: string;
|
|
19
|
+
};
|
|
20
|
+
declare const StreamgraphChart: import("svelte").Component<StreamgraphChartProps, {}, "">;
|
|
21
|
+
type StreamgraphChart = ReturnType<typeof StreamgraphChart>;
|
|
22
|
+
export default StreamgraphChart;
|
|
23
|
+
//# sourceMappingURL=StreamgraphChart.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamgraphChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/StreamgraphChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,oBAAoB,GAC5B,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GACrD,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAG1D,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;CAC7B,CAAC;AAGF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,2BAA2B,EAAE,CAAC;CACvC,CAAC;AAMF,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,qBAAqB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAuNJ,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -34,6 +34,18 @@
|
|
|
34
34
|
|
|
35
35
|
export type StreamingMessageMode = "live" | "passive";
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Simple data-driven event shape (cross-framework parity with React/Vue
|
|
39
|
+
* ports). Distinguished from the rich event-stream shape by the absence of a
|
|
40
|
+
* `type` discriminant.
|
|
41
|
+
*/
|
|
42
|
+
export type StreamingMessageSimpleEvent = {
|
|
43
|
+
id: string;
|
|
44
|
+
label: string;
|
|
45
|
+
text?: string;
|
|
46
|
+
status?: ChatMessageStatus;
|
|
47
|
+
};
|
|
48
|
+
|
|
37
49
|
type ToolCallState = {
|
|
38
50
|
toolCallId: string;
|
|
39
51
|
toolName: string;
|
|
@@ -48,8 +60,14 @@
|
|
|
48
60
|
status?: ChatMessageStatus;
|
|
49
61
|
streamId?: string;
|
|
50
62
|
initialEvents?: StreamingMessageEvent[];
|
|
51
|
-
events?: StreamingMessageEvent[];
|
|
63
|
+
events?: StreamingMessageEvent[] | StreamingMessageSimpleEvent[];
|
|
52
64
|
finalContent?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Plain message body (cross-framework parity with React/Vue ports). When
|
|
67
|
+
* provided, it is used as the rendered content (equivalent to
|
|
68
|
+
* `finalContent`). The canonical event-stream API still works.
|
|
69
|
+
*/
|
|
70
|
+
text?: string;
|
|
53
71
|
mode?: StreamingMessageMode;
|
|
54
72
|
placeholder?: string;
|
|
55
73
|
showTrail?: boolean;
|
|
@@ -65,6 +83,7 @@
|
|
|
65
83
|
initialEvents = [],
|
|
66
84
|
events = [],
|
|
67
85
|
finalContent,
|
|
86
|
+
text,
|
|
68
87
|
mode = "live",
|
|
69
88
|
placeholder = "Streaming en cours…",
|
|
70
89
|
showTrail = true,
|
|
@@ -76,10 +95,25 @@
|
|
|
76
95
|
|
|
77
96
|
const classes = () => ["st-streamingMessage", className].filter(Boolean).join(" ");
|
|
78
97
|
|
|
79
|
-
|
|
98
|
+
// A simple event lacks the `type` discriminant of the rich stream shape.
|
|
99
|
+
const isSimpleEvent = (
|
|
100
|
+
event: StreamingMessageEvent | StreamingMessageSimpleEvent
|
|
101
|
+
): event is StreamingMessageSimpleEvent =>
|
|
102
|
+
event != null && typeof event === "object" && !("type" in event);
|
|
103
|
+
|
|
104
|
+
const simpleEvents = (): StreamingMessageSimpleEvent[] =>
|
|
105
|
+
(events as Array<StreamingMessageEvent | StreamingMessageSimpleEvent>).filter(isSimpleEvent);
|
|
106
|
+
|
|
107
|
+
const richEvents = (): StreamingMessageEvent[] =>
|
|
108
|
+
(events as Array<StreamingMessageEvent | StreamingMessageSimpleEvent>).filter(
|
|
109
|
+
(event): event is StreamingMessageEvent => !isSimpleEvent(event)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const mergedEvents = () => [...initialEvents, ...richEvents()];
|
|
80
113
|
|
|
81
114
|
const resolvedContent = () => {
|
|
82
115
|
if (finalContent) return finalContent;
|
|
116
|
+
if (text) return text;
|
|
83
117
|
return mergedEvents()
|
|
84
118
|
.filter((event) => event.type === "message.delta")
|
|
85
119
|
.map((event) => event.delta)
|
|
@@ -242,6 +276,14 @@
|
|
|
242
276
|
</ul>
|
|
243
277
|
</details>
|
|
244
278
|
{/if}
|
|
279
|
+
|
|
280
|
+
{#if simpleEvents().length > 0}
|
|
281
|
+
<ul class="st-streamingMessage__trailList">
|
|
282
|
+
{#each simpleEvents() as event (event.id)}
|
|
283
|
+
<li>{event.label}</li>
|
|
284
|
+
{/each}
|
|
285
|
+
</ul>
|
|
286
|
+
{/if}
|
|
245
287
|
</ChatMessage>
|
|
246
288
|
|
|
247
289
|
<style>
|
|
@@ -38,13 +38,30 @@ export type StreamingMessageEvent = {
|
|
|
38
38
|
messageId?: string;
|
|
39
39
|
};
|
|
40
40
|
export type StreamingMessageMode = "live" | "passive";
|
|
41
|
+
/**
|
|
42
|
+
* Simple data-driven event shape (cross-framework parity with React/Vue
|
|
43
|
+
* ports). Distinguished from the rich event-stream shape by the absence of a
|
|
44
|
+
* `type` discriminant.
|
|
45
|
+
*/
|
|
46
|
+
export type StreamingMessageSimpleEvent = {
|
|
47
|
+
id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
text?: string;
|
|
50
|
+
status?: ChatMessageStatus;
|
|
51
|
+
};
|
|
41
52
|
type StreamingMessageProps = Omit<HTMLAttributes<HTMLElement>, "class" | "children" | "role"> & {
|
|
42
53
|
role?: ChatMessageRole;
|
|
43
54
|
status?: ChatMessageStatus;
|
|
44
55
|
streamId?: string;
|
|
45
56
|
initialEvents?: StreamingMessageEvent[];
|
|
46
|
-
events?: StreamingMessageEvent[];
|
|
57
|
+
events?: StreamingMessageEvent[] | StreamingMessageSimpleEvent[];
|
|
47
58
|
finalContent?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Plain message body (cross-framework parity with React/Vue ports). When
|
|
61
|
+
* provided, it is used as the rendered content (equivalent to
|
|
62
|
+
* `finalContent`). The canonical event-stream API still works.
|
|
63
|
+
*/
|
|
64
|
+
text?: string;
|
|
48
65
|
mode?: StreamingMessageMode;
|
|
49
66
|
placeholder?: string;
|
|
50
67
|
showTrail?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StreamingMessage.svelte.d.ts","sourceRoot":"","sources":["../src/lib/StreamingMessage.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAoB,EAChB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"StreamingMessage.svelte.d.ts","sourceRoot":"","sources":["../src/lib/StreamingMessage.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAoB,EAChB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B,CAAC;AAQF,KAAK,qBAAqB,GAAG,IAAI,CAC/B,cAAc,CAAC,WAAW,CAAC,EAC3B,OAAO,GAAG,UAAU,GAAG,MAAM,CAC9B,GAAG;IACF,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACxC,MAAM,CAAC,EAAE,qBAAqB,EAAE,GAAG,2BAA2B,EAAE,CAAC;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAyNJ,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|