@sentropic/design-system-svelte 0.10.3 → 0.10.4

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.
Files changed (87) hide show
  1. package/dist/AreaChart.svelte +38 -26
  2. package/dist/AreaChart.svelte.d.ts.map +1 -1
  3. package/dist/BackToTop.svelte +157 -0
  4. package/dist/BackToTop.svelte.d.ts +14 -0
  5. package/dist/BackToTop.svelte.d.ts.map +1 -0
  6. package/dist/BarChart.svelte +38 -39
  7. package/dist/BarChart.svelte.d.ts.map +1 -1
  8. package/dist/Card.svelte +2 -0
  9. package/dist/ChartDataList.svelte +33 -0
  10. package/dist/ChartDataList.svelte.d.ts +9 -0
  11. package/dist/ChartDataList.svelte.d.ts.map +1 -0
  12. package/dist/ChatComposer.svelte +20 -3
  13. package/dist/ChatComposer.svelte.d.ts +6 -30
  14. package/dist/ChatComposer.svelte.d.ts.map +1 -1
  15. package/dist/Checkbox.svelte +4 -0
  16. package/dist/Combobox.svelte +1 -1
  17. package/dist/ContentSwitcher.svelte +1 -0
  18. package/dist/DataTable.svelte +4 -1
  19. package/dist/DatePicker.svelte +1 -1
  20. package/dist/DisplaySettings.svelte +210 -0
  21. package/dist/DisplaySettings.svelte.d.ts +24 -0
  22. package/dist/DisplaySettings.svelte.d.ts.map +1 -0
  23. package/dist/DonutChart.svelte +44 -29
  24. package/dist/DonutChart.svelte.d.ts.map +1 -1
  25. package/dist/Dropdown.svelte +1 -1
  26. package/dist/FileUploader.svelte +2 -2
  27. package/dist/ForceGraph.svelte +428 -26
  28. package/dist/ForceGraph.svelte.d.ts +27 -0
  29. package/dist/ForceGraph.svelte.d.ts.map +1 -1
  30. package/dist/GraphLegend.svelte +142 -0
  31. package/dist/GraphLegend.svelte.d.ts +12 -0
  32. package/dist/GraphLegend.svelte.d.ts.map +1 -0
  33. package/dist/Header.svelte +2 -1
  34. package/dist/IconButton.svelte +1 -1
  35. package/dist/InlineLoading.svelte +10 -1
  36. package/dist/InlineLoading.svelte.d.ts.map +1 -1
  37. package/dist/Input.svelte +3 -2
  38. package/dist/LanguageSelector.svelte +2 -1
  39. package/dist/LineChart.svelte +38 -26
  40. package/dist/LineChart.svelte.d.ts.map +1 -1
  41. package/dist/Link.svelte +7 -1
  42. package/dist/MediaContent.svelte +124 -0
  43. package/dist/MediaContent.svelte.d.ts +22 -0
  44. package/dist/MediaContent.svelte.d.ts.map +1 -0
  45. package/dist/Menu.svelte +56 -3
  46. package/dist/Menu.svelte.d.ts.map +1 -1
  47. package/dist/MessageStatusBadge.svelte +1 -1
  48. package/dist/MultiSelect.svelte +2 -2
  49. package/dist/Notification.svelte +150 -0
  50. package/dist/Notification.svelte.d.ts +17 -0
  51. package/dist/Notification.svelte.d.ts.map +1 -0
  52. package/dist/NumberInput.svelte +1 -0
  53. package/dist/OverflowMenu.svelte +84 -13
  54. package/dist/OverflowMenu.svelte.d.ts.map +1 -1
  55. package/dist/Pagination.svelte +7 -0
  56. package/dist/PaginationNav.svelte +2 -2
  57. package/dist/ProgressIndicator.svelte +13 -1
  58. package/dist/ProgressIndicator.svelte.d.ts +1 -0
  59. package/dist/ProgressIndicator.svelte.d.ts.map +1 -1
  60. package/dist/Radio.svelte +7 -3
  61. package/dist/ScatterPlot.svelte +64 -45
  62. package/dist/ScatterPlot.svelte.d.ts.map +1 -1
  63. package/dist/Search.svelte +6 -3
  64. package/dist/Select.svelte +8 -2
  65. package/dist/SideNav.svelte +6 -0
  66. package/dist/StackedBarChart.svelte +51 -30
  67. package/dist/StackedBarChart.svelte.d.ts.map +1 -1
  68. package/dist/StreamingMessage.svelte +2 -2
  69. package/dist/Switch.svelte +4 -0
  70. package/dist/Table.svelte +4 -1
  71. package/dist/TableOfContents.svelte +109 -0
  72. package/dist/TableOfContents.svelte.d.ts +16 -0
  73. package/dist/TableOfContents.svelte.d.ts.map +1 -0
  74. package/dist/Tag.svelte +1 -1
  75. package/dist/Textarea.svelte +3 -2
  76. package/dist/Tile.svelte +4 -0
  77. package/dist/TileGroup.svelte +4 -0
  78. package/dist/Toggle.svelte +4 -0
  79. package/dist/Toggletip.svelte +1 -1
  80. package/dist/Transcription.svelte +135 -0
  81. package/dist/Transcription.svelte.d.ts +19 -0
  82. package/dist/Transcription.svelte.d.ts.map +1 -0
  83. package/dist/TreeView.svelte +2 -2
  84. package/dist/index.d.ts +12 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +8 -0
  87. package/package.json +1 -1
@@ -0,0 +1,142 @@
1
+ <script lang="ts" module>
2
+ // Re-export types so GraphLegend can be used standalone without importing from ForceGraph.
3
+ export type { ForceGraphLegendEntry, ForceGraphNodeShape, ForceGraphTone } from "./ForceGraph.svelte";
4
+ </script>
5
+
6
+ <script lang="ts">
7
+ import { nodeShapePath } from "./ForceGraph.svelte";
8
+ import type { ForceGraphLegendEntry } from "./ForceGraph.svelte";
9
+
10
+ type GraphLegendProps = {
11
+ entries: ForceGraphLegendEntry[];
12
+ /** Optional heading shown above entries. */
13
+ title?: string;
14
+ class?: string;
15
+ };
16
+
17
+ let { entries, title, class: className }: GraphLegendProps = $props();
18
+
19
+ const classes = () =>
20
+ ["st-graphLegend", className].filter(Boolean).join(" ");
21
+ </script>
22
+
23
+ <div class={classes()} aria-label={title ?? "Graph legend"}>
24
+ {#if title}
25
+ <p class="st-graphLegend__title">{title}</p>
26
+ {/if}
27
+ <ul class="st-graphLegend__list" role="list">
28
+ {#each entries as entry}
29
+ {@const swatchPath = entry.shape !== undefined ? nodeShapePath(entry.shape, 7) : null}
30
+ {@const swatchTone = entry.tone ?? "category1"}
31
+ <li class="st-graphLegend__entry">
32
+ {#if entry.shape !== undefined}
33
+ <svg
34
+ class="st-graphLegend__swatch"
35
+ viewBox="-8 -8 16 16"
36
+ width="16"
37
+ height="16"
38
+ aria-hidden="true"
39
+ >
40
+ {#if swatchPath}
41
+ <path
42
+ d={swatchPath}
43
+ class="st-graphLegend__shape st-graphLegend__shape--{swatchTone}"
44
+ />
45
+ {:else}
46
+ <circle
47
+ r="7"
48
+ class="st-graphLegend__shape st-graphLegend__shape--{swatchTone}"
49
+ />
50
+ {/if}
51
+ </svg>
52
+ {:else}
53
+ <svg
54
+ class="st-graphLegend__swatch"
55
+ viewBox="0 0 16 8"
56
+ width="16"
57
+ height="8"
58
+ aria-hidden="true"
59
+ >
60
+ <line
61
+ x1="0"
62
+ y1="4"
63
+ x2="16"
64
+ y2="4"
65
+ class="st-graphLegend__edge"
66
+ class:st-graphLegend__edge--weak={entry.weak}
67
+ />
68
+ </svg>
69
+ {/if}
70
+ <span class="st-graphLegend__label">{entry.label}</span>
71
+ </li>
72
+ {/each}
73
+ </ul>
74
+ </div>
75
+
76
+ <style>
77
+ .st-graphLegend {
78
+ background: var(--st-semantic-surface-overlay, rgba(0,0,0,0.45));
79
+ border-radius: var(--st-radius-sm, 0.25rem);
80
+ color: var(--st-semantic-text-inverse, #fff);
81
+ display: inline-flex;
82
+ flex-direction: column;
83
+ font-size: 0.6875rem;
84
+ gap: 0.25rem;
85
+ padding: 0.375rem 0.5rem;
86
+ }
87
+
88
+ .st-graphLegend__title {
89
+ font-size: 0.625rem;
90
+ font-weight: 600;
91
+ letter-spacing: 0.04em;
92
+ margin: 0 0 0.125rem;
93
+ opacity: 0.75;
94
+ text-transform: uppercase;
95
+ }
96
+
97
+ .st-graphLegend__list {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 0.25rem;
101
+ list-style: none;
102
+ margin: 0;
103
+ padding: 0;
104
+ }
105
+
106
+ .st-graphLegend__entry {
107
+ align-items: center;
108
+ display: flex;
109
+ gap: 0.375rem;
110
+ }
111
+
112
+ .st-graphLegend__swatch { flex-shrink: 0; }
113
+
114
+ .st-graphLegend__label { white-space: nowrap; }
115
+
116
+ .st-graphLegend__shape {
117
+ fill-opacity: 0.9;
118
+ stroke: var(--st-semantic-surface-default, #fff);
119
+ stroke-width: 1;
120
+ }
121
+
122
+ .st-graphLegend__shape--category1 { fill: var(--st-semantic-data-category1); }
123
+ .st-graphLegend__shape--category2 { fill: var(--st-semantic-data-category2); }
124
+ .st-graphLegend__shape--category3 { fill: var(--st-semantic-data-category3); }
125
+ .st-graphLegend__shape--category4 { fill: var(--st-semantic-data-category4); }
126
+ .st-graphLegend__shape--category5 { fill: var(--st-semantic-data-category5); }
127
+ .st-graphLegend__shape--category6 { fill: var(--st-semantic-data-category6); }
128
+ .st-graphLegend__shape--category7 { fill: var(--st-semantic-data-category7); }
129
+ .st-graphLegend__shape--category8 { fill: var(--st-semantic-data-category8); }
130
+
131
+ .st-graphLegend__edge {
132
+ stroke: var(--st-semantic-border-strong, #888);
133
+ stroke-width: 1.5;
134
+ opacity: 0.8;
135
+ }
136
+
137
+ .st-graphLegend__edge--weak {
138
+ stroke: var(--st-semantic-border-subtle, #aaa);
139
+ stroke-dasharray: 3 3;
140
+ opacity: 0.65;
141
+ }
142
+ </style>
@@ -0,0 +1,12 @@
1
+ export type { ForceGraphLegendEntry, ForceGraphNodeShape, ForceGraphTone } from "./ForceGraph.svelte";
2
+ import type { ForceGraphLegendEntry } from "./ForceGraph.svelte";
3
+ type GraphLegendProps = {
4
+ entries: ForceGraphLegendEntry[];
5
+ /** Optional heading shown above entries. */
6
+ title?: string;
7
+ class?: string;
8
+ };
9
+ declare const GraphLegend: import("svelte").Component<GraphLegendProps, {}, "">;
10
+ type GraphLegend = ReturnType<typeof GraphLegend>;
11
+ export default GraphLegend;
12
+ //# sourceMappingURL=GraphLegend.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphLegend.svelte.d.ts","sourceRoot":"","sources":["../src/lib/GraphLegend.svelte.ts"],"names":[],"mappings":"AAIE,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIxG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,KAAK,gBAAgB,GAAG;IACtB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA8CJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -256,6 +256,7 @@
256
256
 
257
257
  .st-header__account-trigger:hover,
258
258
  .st-header__account-trigger:focus-visible {
259
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
259
260
  border-color: var(--st-semantic-border-interactive, var(--st-semantic-action-primary));
260
261
  outline: none;
261
262
  }
@@ -350,7 +351,7 @@
350
351
 
351
352
  .st-header__signin:hover,
352
353
  .st-header__signin:focus-visible {
353
- background: var(--st-semantic-surface-subtle, #f1f5f9);
354
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
354
355
  outline: none;
355
356
  }
356
357
  </style>
@@ -83,7 +83,7 @@
83
83
  }
84
84
 
85
85
  .st-iconButton:hover:not(:disabled) {
86
- background: var(--st-component-iconButton-hoverBackground, var(--st-semantic-surface-subtle));
86
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
87
87
  }
88
88
 
89
89
  .st-iconButton--secondary:hover:not(:disabled) {
@@ -8,10 +8,18 @@
8
8
  class?: string;
9
9
  };
10
10
 
11
+ const FALLBACK_LABELS = {
12
+ active: "Loading",
13
+ success: "Completed",
14
+ error: "Error",
15
+ inactive: "Inactive"
16
+ } as const;
17
+
11
18
  let {
12
19
  label,
13
20
  status = "active",
14
21
  class: className,
22
+ "aria-label": ariaLabel,
15
23
  ...rest
16
24
  }: InlineLoadingProps = $props();
17
25
 
@@ -19,9 +27,10 @@
19
27
  ["st-inlineLoading", `st-inlineLoading--${status}`, className].filter(Boolean).join(" ");
20
28
 
21
29
  const role = () => (status === "error" ? "alert" : "status");
30
+ const accessibleLabel = () => ariaLabel ?? (label ? undefined : FALLBACK_LABELS[status]);
22
31
  </script>
23
32
 
24
- <div {...rest} class={classes()} role={role()} aria-live="polite">
33
+ <div {...rest} class={classes()} role={role()} aria-label={accessibleLabel()} aria-live="polite">
25
34
  <span class="st-inlineLoading__icon" aria-hidden="true">
26
35
  {#if status === "active"}
27
36
  <span class="st-inlineLoading__spinner">
@@ -1 +1 @@
1
- {"version":3,"file":"InlineLoading.svelte.d.ts","sourceRoot":"","sources":["../src/lib/InlineLoading.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAsCJ,QAAA,MAAM,aAAa,wDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"InlineLoading.svelte.d.ts","sourceRoot":"","sources":["../src/lib/InlineLoading.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA+CJ,QAAA,MAAM,aAAa,wDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
package/dist/Input.svelte CHANGED
@@ -96,8 +96,8 @@
96
96
  corners → the base Sent Tech field stays a uniform rounded box. */
97
97
  border-top-left-radius: var(--st-component-control-anatomy-field-radiusTop, var(--st-component-control-anatomy-shape-radius, 0.375rem));
98
98
  border-top-right-radius: var(--st-component-control-anatomy-field-radiusTop, var(--st-component-control-anatomy-shape-radius, 0.375rem));
99
- border-bottom-right-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
100
- border-bottom-left-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
99
+ border-bottom-right-radius: var(--st-component-control-anatomy-field-radiusBottom, var(--st-component-control-anatomy-shape-radius, 0.375rem));
100
+ border-bottom-left-radius: var(--st-component-control-anatomy-field-radiusBottom, var(--st-component-control-anatomy-shape-radius, 0.375rem));
101
101
  /* Bottom rule as a box-shadow inset (anatomy v1.3.0, real DSFR/Carbon
102
102
  technique) instead of a border-bottom — keeps the box height honest.
103
103
  Fallback = none → the base boxed field draws its rule via the 4 borders. */
@@ -136,6 +136,7 @@
136
136
  }
137
137
 
138
138
  .st-control:hover:not(:disabled) {
139
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
139
140
  border-color: var(--st-component-control-hoverBorder, var(--st-semantic-border-strong));
140
141
  }
141
142
 
@@ -104,6 +104,7 @@
104
104
  }
105
105
 
106
106
  .st-languageSelector__trigger:hover:not(:disabled) {
107
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
107
108
  border-color: var(--st-component-control-hoverBorder, var(--st-semantic-border-strong));
108
109
  }
109
110
 
@@ -164,7 +165,7 @@
164
165
  }
165
166
 
166
167
  .st-languageSelector__option:hover {
167
- background: var(--st-semantic-surface-subtle);
168
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
168
169
  color: var(--st-semantic-text-primary);
169
170
  }
170
171
 
@@ -16,6 +16,8 @@
16
16
  </script>
17
17
 
18
18
  <script lang="ts">
19
+ import ChartDataList from "./ChartDataList.svelte";
20
+
19
21
  type LineChartProps = {
20
22
  data: LineChartDatum[];
21
23
  width?: number;
@@ -128,6 +130,8 @@
128
130
  });
129
131
  });
130
132
 
133
+ const dataValueItems = $derived(data.map((d) => `${d.x}: ${d.y}`));
134
+
131
135
  function buildLinearPath(pts: { x: number; y: number }[]): string {
132
136
  return pts.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
133
137
  }
@@ -190,26 +194,39 @@
190
194
  return entries;
191
195
  });
192
196
 
193
- function handleEnter(i: number) {
194
- hoveredIndex = i;
195
- }
196
197
  function handleLeave() {
197
198
  hoveredIndex = null;
198
199
  }
200
+ function handleVisualPointerMove(event: PointerEvent) {
201
+ const target = event.target;
202
+ if (!(target instanceof Element)) {
203
+ hoveredIndex = null;
204
+ return;
205
+ }
206
+ const index = Number(target.getAttribute("data-chart-index"));
207
+ hoveredIndex = Number.isInteger(index) ? index : null;
208
+ }
199
209
 
200
210
  const classes = () =>
201
211
  ["st-lineChart", `st-lineChart--${tone}`, className].filter(Boolean).join(" ");
202
212
  </script>
203
213
 
204
- <div class={classes()} role="img" aria-label={label}>
205
- <svg
206
- viewBox="0 0 {width} {height}"
207
- preserveAspectRatio="xMidYMid meet"
208
- width="100%"
209
- height="100%"
210
- focusable="false"
211
- aria-hidden="true"
214
+ <div class={classes()}>
215
+ <div
216
+ class="st-lineChart__visual"
217
+ role="img"
218
+ aria-label={label}
219
+ onpointermove={handleVisualPointerMove}
220
+ onpointerleave={handleLeave}
212
221
  >
222
+ <svg
223
+ viewBox="0 0 {width} {height}"
224
+ preserveAspectRatio="xMidYMid meet"
225
+ width="100%"
226
+ height="100%"
227
+ focusable="false"
228
+ aria-hidden="true"
229
+ >
213
230
  <!-- gridlines + Y axis ticks -->
214
231
  {#each gridLines as g (g.value)}
215
232
  <line
@@ -278,16 +295,13 @@
278
295
  cx={p.x}
279
296
  cy={p.y}
280
297
  r="4"
281
- tabindex="0"
282
- role="img"
283
- aria-label="{p.datum.x}: {p.datum.y}"
284
- onmouseenter={() => handleEnter(p.index)}
285
- onmouseleave={handleLeave}
286
- onfocus={() => handleEnter(p.index)}
287
- onblur={handleLeave}
298
+ data-chart-index={p.index}
288
299
  />
289
300
  {/each}
290
- </svg>
301
+ </svg>
302
+ </div>
303
+
304
+ <ChartDataList {label} items={dataValueItems} />
291
305
 
292
306
  {#if hoveredIndex !== null && points[hoveredIndex]}
293
307
  {@const p = points[hoveredIndex]}
@@ -325,6 +339,10 @@
325
339
  overflow: visible;
326
340
  }
327
341
 
342
+ .st-lineChart__visual {
343
+ display: block;
344
+ }
345
+
328
346
  .st-lineChart__grid {
329
347
  stroke: var(--st-component-lineChart-gridStroke, var(--st-semantic-border-subtle));
330
348
  stroke-dasharray: 2 3;
@@ -360,16 +378,10 @@
360
378
  transition: r 120ms ease;
361
379
  }
362
380
 
363
- .st-lineChart__dot:hover,
364
- .st-lineChart__dot:focus-visible {
381
+ .st-lineChart__dot:hover {
365
382
  r: 5.5;
366
383
  }
367
384
 
368
- .st-lineChart__dot:focus-visible {
369
- outline: 2px solid var(--st-semantic-border-interactive);
370
- outline-offset: 1px;
371
- }
372
-
373
385
  .st-lineChart__tooltip {
374
386
  background: var(--st-component-lineChart-tooltipBackground, var(--st-semantic-surface-inverse));
375
387
  border-radius: var(--st-radius-sm, 0.25rem);
@@ -1 +1 @@
1
- {"version":3,"file":"LineChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/LineChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAkOJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"LineChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/LineChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAMF,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA+OJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
package/dist/Link.svelte CHANGED
@@ -67,6 +67,9 @@
67
67
  text-decoration: var(--st-component-link-anatomy-typography-textDecoration, underline);
68
68
  text-decoration-thickness: var(--st-component-link-anatomy-typography-decorationThickness, auto);
69
69
  text-underline-offset: var(--st-component-link-anatomy-typography-decorationOffset, 0.18em);
70
+ transition-property: color, text-decoration-thickness, text-underline-offset;
71
+ transition-duration: var(--st-motion-normal, 180ms);
72
+ transition-timing-function: var(--st-motion-easing, cubic-bezier(0.4, 0, 0.2, 1));
70
73
  }
71
74
 
72
75
  .st-link--standalone {
@@ -83,8 +86,11 @@
83
86
  color: var(--st-component-link-anatomy-states-hover-text, var(--st-component-link-hoverText, var(--st-semantic-action-primary)));
84
87
  /* Anatomy v1.1.0: hover decoration sourced from states.hover.decoration
85
88
  (= link typography textDecorationHover). Carbon: none → underline; DSFR/base:
86
- underline → underline (no-op). The DSFR animated underline stays an escape. */
89
+ underline → underline (no-op). The DSFR animated underline now
90
+ transitions thickness/offset via anatomy-hover vars when provided. */
87
91
  text-decoration-line: var(--st-component-link-anatomy-states-hover-decoration, underline);
92
+ text-decoration-thickness: var(--st-component-link-anatomy-typography-decorationThicknessHover, var(--st-component-link-anatomy-typography-decorationThickness, auto));
93
+ text-underline-offset: var(--st-component-link-anatomy-typography-decorationOffsetHover, var(--st-component-link-anatomy-typography-decorationOffset, 0.18em));
88
94
  }
89
95
 
90
96
  /* Focus = shared mixin. --st-radius-* fixed to the valid `sm` token (was the
@@ -0,0 +1,124 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type MediaKind = "image" | "video";
6
+
7
+ type MediaContentProps = Omit<HTMLAttributes<HTMLElement>, "children" | "class"> & {
8
+ title?: string;
9
+ caption?: string;
10
+ byline?: string;
11
+ media?: string;
12
+ mediaAlt?: string;
13
+ mediaKind?: MediaKind;
14
+ mediaControls?: boolean;
15
+ aspectRatio?: string;
16
+ mediaCaptions?: string;
17
+ mediaCaptionsLabel?: string;
18
+ mediaCaptionsLang?: string;
19
+ class?: string;
20
+ children?: Snippet;
21
+ };
22
+
23
+ let {
24
+ title,
25
+ caption,
26
+ byline,
27
+ media,
28
+ mediaAlt = "",
29
+ mediaKind = "image",
30
+ mediaControls = true,
31
+ aspectRatio = "16/9",
32
+ mediaCaptions,
33
+ mediaCaptionsLabel = "Français",
34
+ mediaCaptionsLang = "fr",
35
+ class: className,
36
+ children,
37
+ ...rest
38
+ }: MediaContentProps = $props();
39
+
40
+ const defaultCaptions = "data:text/vtt,WEBVTT";
41
+
42
+ const hasMedia = () => Boolean(media?.trim());
43
+ const classes = () => ["st-mediaContent", className].filter(Boolean).join(" ");
44
+ </script>
45
+
46
+ <figure class={classes()} {...rest}>
47
+ <div class="st-mediaContent__media" style={`--st-mediaContent-ratio:${aspectRatio}`}>
48
+ {#if hasMedia()}
49
+ {#if mediaKind === "video"}
50
+ <video controls={mediaControls} src={media} aria-label={title || "Contenu média"} preload="metadata">
51
+ <track
52
+ kind="captions"
53
+ src={mediaCaptions ?? defaultCaptions}
54
+ srclang={mediaCaptionsLang}
55
+ label={mediaCaptionsLabel}
56
+ default
57
+ />
58
+ </video>
59
+ {:else}
60
+ <img src={media} alt={mediaAlt} loading="lazy" decoding="async" />
61
+ {/if}
62
+ {:else}
63
+ {@render children?.()}
64
+ {/if}
65
+ </div>
66
+
67
+ {#if title || caption || byline}
68
+ <figcaption class="st-mediaContent__caption">
69
+ {#if title}
70
+ <p class="st-mediaContent__title">{title}</p>
71
+ {/if}
72
+ {#if caption}
73
+ <p>{caption}</p>
74
+ {/if}
75
+ {#if byline}
76
+ <p class="st-mediaContent__byline">{byline}</p>
77
+ {/if}
78
+ </figcaption>
79
+ {/if}
80
+ </figure>
81
+
82
+ <style>
83
+ .st-mediaContent {
84
+ border: 1px solid var(--st-semantic-border-subtle);
85
+ border-radius: 0.5rem;
86
+ margin: 0;
87
+ overflow: hidden;
88
+ }
89
+
90
+ .st-mediaContent__media {
91
+ aspect-ratio: var(--st-mediaContent-ratio);
92
+ background: var(--st-semantic-surface-subtle);
93
+ overflow: hidden;
94
+ }
95
+
96
+ .st-mediaContent__media > :global(img),
97
+ .st-mediaContent__media > :global(video) {
98
+ block-size: 100%;
99
+ inline-size: 100%;
100
+ object-fit: cover;
101
+ display: block;
102
+ }
103
+
104
+ .st-mediaContent__caption {
105
+ background: var(--st-semantic-surface-primary);
106
+ color: var(--st-semantic-text-primary);
107
+ font-size: 0.875rem;
108
+ padding: 0.6rem 0.75rem;
109
+ }
110
+
111
+ .st-mediaContent__title {
112
+ color: var(--st-semantic-text-primary);
113
+ font-weight: 600;
114
+ margin: 0;
115
+ }
116
+
117
+ .st-mediaContent__caption p {
118
+ margin: 0.25rem 0 0;
119
+ }
120
+
121
+ .st-mediaContent__byline {
122
+ color: var(--st-semantic-text-secondary);
123
+ }
124
+ </style>
@@ -0,0 +1,22 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ type MediaKind = "image" | "video";
4
+ type MediaContentProps = Omit<HTMLAttributes<HTMLElement>, "children" | "class"> & {
5
+ title?: string;
6
+ caption?: string;
7
+ byline?: string;
8
+ media?: string;
9
+ mediaAlt?: string;
10
+ mediaKind?: MediaKind;
11
+ mediaControls?: boolean;
12
+ aspectRatio?: string;
13
+ mediaCaptions?: string;
14
+ mediaCaptionsLabel?: string;
15
+ mediaCaptionsLang?: string;
16
+ class?: string;
17
+ children?: Snippet;
18
+ };
19
+ declare const MediaContent: import("svelte").Component<MediaContentProps, {}, "">;
20
+ type MediaContent = ReturnType<typeof MediaContent>;
21
+ export default MediaContent;
22
+ //# sourceMappingURL=MediaContent.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaContent.svelte.d.ts","sourceRoot":"","sources":["../src/lib/MediaContent.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnC,KAAK,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAgEJ,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
package/dist/Menu.svelte CHANGED
@@ -62,6 +62,26 @@
62
62
  }: MenuProps = $props();
63
63
 
64
64
  let host: HTMLDivElement | undefined = $state();
65
+ function getFocusableItems(): HTMLButtonElement[] {
66
+ return Array.from(
67
+ host?.querySelectorAll<HTMLButtonElement>('[role="menuitem"]:not(:disabled)') ?? []
68
+ );
69
+ }
70
+
71
+ function moveIndex(index: number, size: number, step: number) {
72
+ if (size <= 0) return 0;
73
+ return ((index + step) % size + size) % size;
74
+ }
75
+
76
+ function focusAt(index: number) {
77
+ const focusable = getFocusableItems();
78
+ if (!focusable.length) return;
79
+ const target = moveIndex(index, focusable.length, 0);
80
+ focusable.forEach((button, idx) => {
81
+ button.tabIndex = idx === target ? 0 : -1;
82
+ });
83
+ focusable[target]?.focus();
84
+ }
65
85
 
66
86
  const classes = () =>
67
87
  ["st-menu", dense ? "st-menu--dense" : null, className].filter(Boolean).join(" ");
@@ -76,6 +96,35 @@
76
96
  return item.kind === undefined || item.kind === "item";
77
97
  }
78
98
 
99
+ function onItemKeyDown(event: KeyboardEvent, item: MenuActionItem) {
100
+ const focusable = getFocusableItems();
101
+ const current = focusable.indexOf(event.currentTarget as HTMLButtonElement);
102
+ if (event.key === "ArrowDown") {
103
+ event.preventDefault();
104
+ focusAt(current + 1);
105
+ return;
106
+ }
107
+ if (event.key === "ArrowUp") {
108
+ event.preventDefault();
109
+ focusAt(current - 1);
110
+ return;
111
+ }
112
+ if (event.key === "Home") {
113
+ event.preventDefault();
114
+ focusAt(0);
115
+ return;
116
+ }
117
+ if (event.key === "End") {
118
+ event.preventDefault();
119
+ focusAt(focusable.length - 1);
120
+ return;
121
+ }
122
+ if (event.key === "Enter" || event.key === " ") {
123
+ event.preventDefault();
124
+ if (!item.disabled) selectItem(item);
125
+ }
126
+ }
127
+
79
128
  function onWindowKeydown(event: KeyboardEvent) {
80
129
  if (event.key === "Escape" && open && dismissOnSelect) {
81
130
  event.preventDefault();
@@ -105,6 +154,7 @@
105
154
  aria-disabled={item.disabled ? "true" : undefined}
106
155
  disabled={item.disabled}
107
156
  onclick={() => selectItem(item)}
157
+ onkeydown={(event) => onItemKeyDown(event, item)}
108
158
  >
109
159
  {#if Icon}
110
160
  <span class="st-menu__itemIcon" aria-hidden="true">
@@ -163,7 +213,7 @@
163
213
 
164
214
  .st-menu__item:hover:not(:disabled),
165
215
  .st-menu__item:focus-visible {
166
- background: var(--st-component-menu-itemHoverBackground, var(--st-semantic-surface-subtle));
216
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
167
217
  outline: none;
168
218
  }
169
219
 
@@ -173,12 +223,15 @@
173
223
  }
174
224
 
175
225
  .st-menu__item--danger {
176
- color: var(--st-component-menu-dangerText, var(--st-semantic-feedback-error, #b91c1c));
226
+ color: var(--st-component-menu-dangerText, var(--st-semantic-feedback-error));
177
227
  }
178
228
 
179
229
  .st-menu__item--danger:hover:not(:disabled),
180
230
  .st-menu__item--danger:focus-visible {
181
- background: var(--st-component-menu-dangerHoverBackground, rgba(185, 28, 28, 0.08));
231
+ background: var(
232
+ --st-component-menu-dangerHoverBackground,
233
+ var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle))
234
+ );
182
235
  }
183
236
 
184
237
  .st-menu__itemIcon {
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Menu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAS1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AA8EJ,QAAA,MAAM,IAAI,kCAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Menu.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Menu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAS1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AA+HJ,QAAA,MAAM,IAAI,kCAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -41,7 +41,7 @@
41
41
  </Tag>
42
42
 
43
43
  <style>
44
- .st-messageStatusBadge {
44
+ :global(.st-messageStatusBadge) {
45
45
  align-items: center;
46
46
  text-transform: none;
47
47
  }