@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
@@ -346,7 +346,7 @@
346
346
  }
347
347
 
348
348
  .st-multiSelect__tagRemove:hover:not(:disabled) {
349
- background: color-mix(in srgb, currentColor 18%, transparent);
349
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
350
350
  }
351
351
 
352
352
  .st-multiSelect__tagRemove:focus-visible {
@@ -426,7 +426,7 @@
426
426
  .st-multiSelect__option:hover:not(:disabled),
427
427
  .st-multiSelect__option:focus-visible {
428
428
  background: var(
429
- --st-component-dropdown-optionHoverBackground,
429
+ --st-component-control-hoverBackground,
430
430
  var(--st-semantic-surface-subtle)
431
431
  );
432
432
  outline: none;
@@ -0,0 +1,150 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type NotificationProps = Omit<HTMLAttributes<HTMLElement>, "class"> & {
6
+ tone?: "info" | "success" | "warning" | "error";
7
+ title: string;
8
+ message?: string;
9
+ dismissible?: boolean;
10
+ dismissLabel?: string;
11
+ onDismiss?: () => void;
12
+ class?: string;
13
+ actions?: Snippet;
14
+ children?: Snippet;
15
+ };
16
+
17
+ let {
18
+ tone = "info",
19
+ title,
20
+ message,
21
+ dismissible = false,
22
+ dismissLabel = "Dismiss",
23
+ onDismiss,
24
+ class: className,
25
+ actions,
26
+ children,
27
+ ...rest
28
+ }: NotificationProps = $props();
29
+
30
+ const classes = () =>
31
+ ["st-notification", `st-notification--${tone}`, className].filter(Boolean).join(" ");
32
+
33
+ const canDismiss = () => dismissible && typeof onDismiss === "function";
34
+ const role = () => (tone === "error" ? "alert" : "status");
35
+
36
+ const onDismissClick = () => onDismiss?.();
37
+ </script>
38
+
39
+ <section {...rest} class={classes()} role={role()}>
40
+ <div class="st-notification__content">
41
+ <h2 class="st-notification__title">{title}</h2>
42
+ {#if message}
43
+ <p class="st-notification__message">{message}</p>
44
+ {/if}
45
+ {@render children?.()}
46
+ </div>
47
+ <div class="st-notification__meta">
48
+ {#if actions}
49
+ <div class="st-notification__actions">
50
+ {@render actions()}
51
+ </div>
52
+ {/if}
53
+ {#if canDismiss()}
54
+ <button
55
+ type="button"
56
+ class="st-notification__close"
57
+ aria-label={dismissLabel}
58
+ title={dismissLabel}
59
+ onclick={onDismissClick}
60
+ >
61
+ ×
62
+ </button>
63
+ {/if}
64
+ </div>
65
+ </section>
66
+
67
+ <style>
68
+ .st-notification {
69
+ background: var(--st-component-notification-background, var(--st-semantic-surface-raised));
70
+ border: 1px solid var(--st-component-notification-border, var(--st-semantic-border-subtle));
71
+ border-left-width: var(--st-component-notification-accentWidth, 0.25rem);
72
+ border-left-style: solid;
73
+ border-left-color: var(--st-component-notification-accent, var(--st-semantic-feedback-info));
74
+ border-radius: 0;
75
+ color: var(--st-component-notification-text, var(--st-semantic-text-primary));
76
+ display: flex;
77
+ gap: var(--st-spacing-4, 1rem);
78
+ justify-content: space-between;
79
+ padding: var(--st-spacing-4, 1rem);
80
+ width: min(100%, 32rem);
81
+ }
82
+
83
+ .st-notification--info {
84
+ --st-component-notification-accent: var(--st-component-notification-infoAccent, var(--st-semantic-feedback-info));
85
+ }
86
+
87
+ .st-notification--success {
88
+ --st-component-notification-accent: var(--st-component-notification-successAccent, var(--st-semantic-feedback-success));
89
+ }
90
+
91
+ .st-notification--warning {
92
+ --st-component-notification-accent: var(--st-component-notification-warningAccent, var(--st-semantic-feedback-warning));
93
+ }
94
+
95
+ .st-notification--error {
96
+ --st-component-notification-accent: var(--st-component-notification-errorAccent, var(--st-semantic-feedback-error));
97
+ }
98
+
99
+ .st-notification__content {
100
+ display: grid;
101
+ gap: 0.25rem;
102
+ flex: 1;
103
+ min-width: 0;
104
+ }
105
+
106
+ .st-notification__title {
107
+ font-size: 0.9375rem;
108
+ margin: 0;
109
+ }
110
+
111
+ .st-notification__message {
112
+ color: var(--st-semantic-text-secondary);
113
+ font-size: 0.875rem;
114
+ line-height: 1.5;
115
+ margin: 0;
116
+ }
117
+
118
+ .st-notification__meta {
119
+ align-items: start;
120
+ display: flex;
121
+ flex-shrink: 0;
122
+ gap: 0.5rem;
123
+ }
124
+
125
+ .st-notification__actions {
126
+ align-items: start;
127
+ display: flex;
128
+ gap: var(--st-spacing-2, 0.5rem);
129
+ }
130
+
131
+ .st-notification__close {
132
+ align-items: center;
133
+ background: transparent;
134
+ border: 1px solid var(--st-semantic-border-subtle);
135
+ border-radius: var(--st-border-radius-full, 999px);
136
+ color: var(--st-semantic-text-secondary);
137
+ cursor: var(--st-cursor-interactive, pointer);
138
+ display: inline-flex;
139
+ font-size: 0.875rem;
140
+ height: 1.75rem;
141
+ justify-content: center;
142
+ min-width: 1.75rem;
143
+ padding: 0;
144
+ width: 1.75rem;
145
+ }
146
+
147
+ .st-notification__close:hover {
148
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
149
+ }
150
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ type NotificationProps = Omit<HTMLAttributes<HTMLElement>, "class"> & {
4
+ tone?: "info" | "success" | "warning" | "error";
5
+ title: string;
6
+ message?: string;
7
+ dismissible?: boolean;
8
+ dismissLabel?: string;
9
+ onDismiss?: () => void;
10
+ class?: string;
11
+ actions?: Snippet;
12
+ children?: Snippet;
13
+ };
14
+ declare const Notification: import("svelte").Component<NotificationProps, {}, "">;
15
+ type Notification = ReturnType<typeof Notification>;
16
+ export default Notification;
17
+ //# sourceMappingURL=Notification.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Notification.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Notification.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAAG;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAsDJ,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -217,6 +217,7 @@
217
217
  }
218
218
 
219
219
  .st-numberInput__control[type="number"] {
220
+ appearance: textfield;
220
221
  -moz-appearance: textfield;
221
222
  }
222
223
 
@@ -38,6 +38,7 @@
38
38
  <script lang="ts">
39
39
  import { Ellipsis } from "@lucide/svelte";
40
40
  import type { HTMLAttributes } from "svelte/elements";
41
+ import { tick } from "svelte";
41
42
 
42
43
  type OverflowMenuProps = Omit<HTMLAttributes<HTMLDivElement>, "class" | "onselect"> & {
43
44
  items: OverflowMenuItem[];
@@ -63,6 +64,35 @@
63
64
  }: OverflowMenuProps = $props();
64
65
 
65
66
  let host: HTMLDivElement | undefined = $state();
67
+ let list: HTMLUListElement | undefined = $state();
68
+
69
+ function getFocusableItems(): HTMLButtonElement[] {
70
+ return Array.from(
71
+ list?.querySelectorAll<HTMLButtonElement>('[role="menuitem"]:not(:disabled)') ?? []
72
+ );
73
+ }
74
+
75
+ function moveIndex(index: number, size: number, step: number) {
76
+ if (size <= 0) return 0;
77
+ return ((index + step) % size + size) % size;
78
+ }
79
+
80
+ function focusAt(index: number) {
81
+ const focusable = getFocusableItems();
82
+ if (!focusable.length) return;
83
+ const target = moveIndex(index, focusable.length, 0);
84
+ focusable.forEach((button, idx) => {
85
+ button.tabIndex = idx === target ? 0 : -1;
86
+ });
87
+ focusable[target]?.focus();
88
+ }
89
+
90
+ function openAndFocus() {
91
+ open = true;
92
+ tick().then(() => {
93
+ focusAt(0);
94
+ });
95
+ }
66
96
 
67
97
  const classes = () =>
68
98
  [
@@ -71,11 +101,15 @@
71
101
  dense ? "st-overflowMenu--dense" : null,
72
102
  className
73
103
  ]
74
- .filter(Boolean)
75
- .join(" ");
104
+ .filter(Boolean)
105
+ .join(" ");
76
106
 
77
107
  function toggle() {
78
- open = !open;
108
+ if (open) {
109
+ close();
110
+ } else {
111
+ openAndFocus();
112
+ }
79
113
  }
80
114
 
81
115
  function close() {
@@ -105,6 +139,46 @@
105
139
  const target = event.target as Node | null;
106
140
  if (host && target && !host.contains(target)) close();
107
141
  }
142
+
143
+ function onTriggerKeyDown(event: KeyboardEvent) {
144
+ if (!["ArrowDown", "Enter", " "].includes(event.key)) return;
145
+ event.preventDefault();
146
+ if (open) {
147
+ focusAt(0);
148
+ } else {
149
+ openAndFocus();
150
+ }
151
+ }
152
+
153
+ function onItemKeyDown(event: KeyboardEvent, item: OverflowMenuActionItem) {
154
+ const focusable = getFocusableItems();
155
+ const current = focusable.indexOf(event.currentTarget as HTMLButtonElement);
156
+ if (event.key === "ArrowDown") {
157
+ event.preventDefault();
158
+ focusAt(current + 1);
159
+ return;
160
+ }
161
+ if (event.key === "ArrowUp") {
162
+ event.preventDefault();
163
+ focusAt(current - 1);
164
+ return;
165
+ }
166
+ if (event.key === "Home") {
167
+ event.preventDefault();
168
+ focusAt(0);
169
+ return;
170
+ }
171
+ if (event.key === "End") {
172
+ event.preventDefault();
173
+ focusAt(focusable.length - 1);
174
+ return;
175
+ }
176
+ if (item.disabled) return;
177
+ if (event.key === "Enter" || event.key === " ") {
178
+ event.preventDefault();
179
+ selectItem(item);
180
+ }
181
+ }
108
182
  </script>
109
183
 
110
184
  <svelte:window onkeydown={onWindowKeydown} onpointerdown={onWindowPointerDown} />
@@ -117,11 +191,12 @@
117
191
  aria-expanded={open ? "true" : "false"}
118
192
  aria-label={triggerLabel}
119
193
  onclick={toggle}
194
+ onkeydown={onTriggerKeyDown}
120
195
  >
121
196
  <Ellipsis size={18} strokeWidth={2.25} aria-hidden="true" />
122
197
  </button>
123
198
  {#if open}
124
- <ul class="st-overflowMenu__list" role="menu" aria-label={label}>
199
+ <ul bind:this={list} class="st-overflowMenu__list" role="menu" aria-label={label}>
125
200
  {#each items as item, index (index)}
126
201
  {#if isAction(item)}
127
202
  {@const Icon = item.icon}
@@ -133,7 +208,9 @@
133
208
  role="menuitem"
134
209
  aria-disabled={item.disabled ? "true" : undefined}
135
210
  disabled={item.disabled}
211
+ tabindex={-1}
136
212
  onclick={() => selectItem(item)}
213
+ onkeydown={(event) => onItemKeyDown(event, item)}
137
214
  >
138
215
  {#if Icon}
139
216
  <span class="st-overflowMenu__itemIcon" aria-hidden="true">
@@ -174,10 +251,7 @@
174
251
  }
175
252
 
176
253
  .st-overflowMenu__trigger:hover {
177
- background: var(
178
- --st-component-overflowMenu-triggerHoverBackground,
179
- var(--st-semantic-surface-subtle)
180
- );
254
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
181
255
  }
182
256
 
183
257
  /* Focus = stratégie d'anatomie partagée (outline DSFR / inset Carbon / ring base). */
@@ -190,10 +264,7 @@
190
264
  }
191
265
 
192
266
  .st-overflowMenu__trigger[aria-expanded="true"] {
193
- background: var(
194
- --st-component-overflowMenu-triggerHoverBackground,
195
- var(--st-semantic-surface-subtle)
196
- );
267
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
197
268
  }
198
269
 
199
270
  .st-overflowMenu__list {
@@ -257,7 +328,7 @@
257
328
 
258
329
  .st-overflowMenu__item:hover:not(:disabled),
259
330
  .st-overflowMenu__item:focus-visible {
260
- background: var(--st-component-menu-itemHoverBackground, var(--st-semantic-surface-subtle));
331
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
261
332
  outline: none;
262
333
  }
263
334
 
@@ -1 +1 @@
1
- {"version":3,"file":"OverflowMenu.svelte.d.ts","sourceRoot":"","sources":["../src/lib/OverflowMenu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,qBAAqB,GAAG;IAClC,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,gBAAgB,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,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,gBAAgB,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GACxB,sBAAsB,GACtB,uBAAuB,GACvB,qBAAqB,CAAC;AAI5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IACpF,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AAoGJ,QAAA,MAAM,YAAY,0CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"OverflowMenu.svelte.d.ts","sourceRoot":"","sources":["../src/lib/OverflowMenu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,qBAAqB,GAAG;IAClC,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,gBAAgB,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,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,gBAAgB,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GACxB,sBAAsB,GACtB,uBAAuB,GACvB,qBAAqB,CAAC;AAI5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IACpF,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AA8KJ,QAAA,MAAM,YAAY,0CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -85,6 +85,13 @@
85
85
  font-weight: var(--st-component-pagination-activeWeight, inherit);
86
86
  }
87
87
 
88
+ .st-pagination button:hover:not(:disabled) {
89
+ background: var(
90
+ --st-component-control-hoverBackground,
91
+ var(--st-component-pagination-hoverBackground, var(--st-semantic-surface-subtle))
92
+ );
93
+ }
94
+
88
95
  .st-pagination button:disabled {
89
96
  color: var(--st-component-pagination-disabledText, var(--st-semantic-text-muted));
90
97
  cursor: not-allowed;
@@ -163,8 +163,8 @@
163
163
  .st-paginationNav__page:hover:not(:disabled),
164
164
  .st-paginationNav__nav:hover:not(:disabled) {
165
165
  background: var(
166
- --st-component-paginationNav-hoverBackground,
167
- var(--st-semantic-surface-subtle)
166
+ --st-component-control-hoverBackground,
167
+ var(--st-component-paginationNav-hoverBackground, var(--st-semantic-surface-subtle))
168
168
  );
169
169
  }
170
170
 
@@ -22,13 +22,23 @@
22
22
  items: ProgressIndicatorItem[];
23
23
  vertical?: boolean;
24
24
  label?: string;
25
+ statusLabels?: Partial<Record<ProgressIndicatorStatus, string>>;
25
26
  class?: string;
26
27
  };
27
28
 
29
+ const DEFAULT_STATUS_LABELS: Record<ProgressIndicatorStatus, string> = {
30
+ complete: "Complete",
31
+ current: "Current",
32
+ upcoming: "Upcoming",
33
+ invalid: "Invalid",
34
+ disabled: "Disabled"
35
+ };
36
+
28
37
  let {
29
38
  items,
30
39
  vertical = false,
31
40
  label = "Progress",
41
+ statusLabels,
32
42
  class: className,
33
43
  ...rest
34
44
  }: ProgressIndicatorProps = $props();
@@ -44,6 +54,8 @@
44
54
 
45
55
  const resolvedStatus = (item: ProgressIndicatorItem): ProgressIndicatorStatus =>
46
56
  item.status ?? "upcoming";
57
+ const indicatorLabel = (item: ProgressIndicatorItem, status: ProgressIndicatorStatus) =>
58
+ `${statusLabels?.[status] ?? DEFAULT_STATUS_LABELS[status]}: ${item.label}`;
47
59
  </script>
48
60
 
49
61
  <ol {...rest} class={classes()} aria-label={label}>
@@ -54,7 +66,7 @@
54
66
  class={["st-progressIndicator__step", `st-progressIndicator__step--${status}`].join(" ")}
55
67
  aria-current={status === "current" ? "step" : undefined}
56
68
  >
57
- <span class="st-progressIndicator__indicator" aria-hidden="true">
69
+ <span class="st-progressIndicator__indicator" role="img" aria-label={indicatorLabel(item, status)}>
58
70
  <span class="st-progressIndicator__circle">
59
71
  {#if status === "complete"}
60
72
  <Check size={14} strokeWidth={2} aria-hidden="true" />
@@ -10,6 +10,7 @@ type ProgressIndicatorProps = Omit<HTMLAttributes<HTMLOListElement>, "class"> &
10
10
  items: ProgressIndicatorItem[];
11
11
  vertical?: boolean;
12
12
  label?: string;
13
+ statusLabels?: Partial<Record<ProgressIndicatorStatus, string>>;
13
14
  class?: string;
14
15
  };
15
16
  declare const ProgressIndicator: import("svelte").Component<ProgressIndicatorProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressIndicator.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ProgressIndicator.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,uBAAuB,GAC/B,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,CAAC;AAEf,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAClC;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,GAAG;IAC9E,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAgEJ,QAAA,MAAM,iBAAiB,4DAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"ProgressIndicator.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ProgressIndicator.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,uBAAuB,GAC/B,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,CAAC;AAEf,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAClC;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,GAAG;IAC9E,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA2EJ,QAAA,MAAM,iBAAiB,4DAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
package/dist/Radio.svelte CHANGED
@@ -12,8 +12,8 @@
12
12
  const classes = () => ["st-choice", "st-choice--radio", className].filter(Boolean).join(" ");
13
13
  </script>
14
14
 
15
- <label class={classes()}>
16
- <input {...rest} class="st-choice__input" type="radio" aria-invalid={invalid ? "true" : undefined} />
15
+ <label class={classes()} data-invalid={invalid ? "true" : undefined}>
16
+ <input {...rest} class="st-choice__input" type="radio" />
17
17
  <span class="st-choice__content">
18
18
  <span class="st-choice__label">{label}</span>
19
19
  {#if helperText}<span class="st-choice__help">{helperText}</span>{/if}
@@ -48,7 +48,11 @@
48
48
  0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
49
49
  }
50
50
 
51
- .st-choice__input[aria-invalid="true"] {
51
+ .st-choice:hover .st-choice__input {
52
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
53
+ }
54
+
55
+ .st-choice[data-invalid="true"] .st-choice__input {
52
56
  accent-color: var(--st-component-control-invalidBorder, var(--st-semantic-feedback-error));
53
57
  outline-color: var(--st-component-control-invalidBorder, var(--st-semantic-feedback-error));
54
58
  }
@@ -12,6 +12,8 @@
12
12
  </script>
13
13
 
14
14
  <script lang="ts">
15
+ import ChartDataList from "./ChartDataList.svelte";
16
+
15
17
  type ScatterPlotProps = {
16
18
  data: ScatterPlotDatum[];
17
19
  width?: number;
@@ -95,51 +97,69 @@
95
97
  }));
96
98
  });
97
99
 
100
+ const dataValueItems = $derived(
101
+ data.map((d) => (d.label ? `${d.label}: x ${d.x}, y ${d.y}` : `x ${d.x}, y ${d.y}`))
102
+ );
103
+
104
+ function handleVisualPointerMove(event: PointerEvent) {
105
+ const target = event.target;
106
+ if (!(target instanceof Element)) {
107
+ hoveredIndex = null;
108
+ return;
109
+ }
110
+ const index = Number(target.getAttribute("data-chart-index"));
111
+ hoveredIndex = Number.isInteger(index) ? index : null;
112
+ }
113
+
98
114
  const classes = () => ["st-scatterPlot", className].filter(Boolean).join(" ");
99
115
  </script>
100
116
 
101
- <div class={classes()} role="img" aria-label={label}>
102
- <svg viewBox="0 0 {width} {height}" preserveAspectRatio="xMidYMid meet" width="100%" height="100%" focusable="false" aria-hidden="true">
103
- <!-- gridlines + ticks Y -->
104
- {#each scales.yTicks as t (t)}
105
- {@const y = MARGIN.top + scaleLinear(t, scales.yMin, scales.yMax, scales.plotH, 0)}
106
- <line class="st-scatterPlot__grid" x1={MARGIN.left} x2={width - MARGIN.right} y1={y} y2={y} />
107
- <text class="st-scatterPlot__tick" x={MARGIN.left - 6} y={y} text-anchor="end" dominant-baseline="middle">{fmt(t)}</text>
108
- {/each}
109
- <!-- ticks X -->
110
- {#each scales.xTicks as t (t)}
111
- {@const x = MARGIN.left + scaleLinear(t, scales.xMin, scales.xMax, 0, scales.plotW)}
112
- <text class="st-scatterPlot__tick" x={x} y={height - MARGIN.bottom + 16} text-anchor="middle">{fmt(t)}</text>
113
- {/each}
114
-
115
- <!-- axes -->
116
- <line class="st-scatterPlot__axis" x1={MARGIN.left} x2={MARGIN.left} y1={MARGIN.top} y2={height - MARGIN.bottom} />
117
- <line class="st-scatterPlot__axis" x1={MARGIN.left} x2={width - MARGIN.right} y1={height - MARGIN.bottom} y2={height - MARGIN.bottom} />
118
-
119
- {#if xLabel}
120
- <text class="st-scatterPlot__axisLabel" x={MARGIN.left + scales.plotW / 2} y={height - 4} text-anchor="middle">{xLabel}</text>
121
- {/if}
122
- {#if yLabel}
123
- <text class="st-scatterPlot__axisLabel" x={12} y={MARGIN.top + scales.plotH / 2} text-anchor="middle" transform="rotate(-90 12 {MARGIN.top + scales.plotH / 2})">{yLabel}</text>
124
- {/if}
125
-
126
- <!-- points -->
127
- {#each points as p, i (i)}
128
- <circle
129
- class="st-scatterPlot__point st-scatterPlot__point--{p.tone}"
130
- cx={p.cx}
131
- cy={p.cy}
132
- r={radius}
133
- tabindex="0"
134
- role="img"
135
- aria-label="{p.datum.label ? p.datum.label + ': ' : ''}x {p.datum.x}, y {p.datum.y}"
136
- onmouseenter={() => (hoveredIndex = i)}
137
- onmouseleave={() => (hoveredIndex = null)}
138
- onfocus={() => (hoveredIndex = i)}
139
- onblur={() => (hoveredIndex = null)}
140
- />
141
- {/each}
142
- </svg>
117
+ <div class={classes()}>
118
+ <div
119
+ class="st-scatterPlot__visual"
120
+ role="img"
121
+ aria-label={label}
122
+ onpointermove={handleVisualPointerMove}
123
+ onpointerleave={() => (hoveredIndex = null)}
124
+ >
125
+ <svg viewBox="0 0 {width} {height}" preserveAspectRatio="xMidYMid meet" width="100%" height="100%" focusable="false" aria-hidden="true">
126
+ <!-- gridlines + ticks Y -->
127
+ {#each scales.yTicks as t (t)}
128
+ {@const y = MARGIN.top + scaleLinear(t, scales.yMin, scales.yMax, scales.plotH, 0)}
129
+ <line class="st-scatterPlot__grid" x1={MARGIN.left} x2={width - MARGIN.right} y1={y} y2={y} />
130
+ <text class="st-scatterPlot__tick" x={MARGIN.left - 6} y={y} text-anchor="end" dominant-baseline="middle">{fmt(t)}</text>
131
+ {/each}
132
+ <!-- ticks X -->
133
+ {#each scales.xTicks as t (t)}
134
+ {@const x = MARGIN.left + scaleLinear(t, scales.xMin, scales.xMax, 0, scales.plotW)}
135
+ <text class="st-scatterPlot__tick" x={x} y={height - MARGIN.bottom + 16} text-anchor="middle">{fmt(t)}</text>
136
+ {/each}
137
+
138
+ <!-- axes -->
139
+ <line class="st-scatterPlot__axis" x1={MARGIN.left} x2={MARGIN.left} y1={MARGIN.top} y2={height - MARGIN.bottom} />
140
+ <line class="st-scatterPlot__axis" x1={MARGIN.left} x2={width - MARGIN.right} y1={height - MARGIN.bottom} y2={height - MARGIN.bottom} />
141
+
142
+ {#if xLabel}
143
+ <text class="st-scatterPlot__axisLabel" x={MARGIN.left + scales.plotW / 2} y={height - 4} text-anchor="middle">{xLabel}</text>
144
+ {/if}
145
+ {#if yLabel}
146
+ <text class="st-scatterPlot__axisLabel" x={12} y={MARGIN.top + scales.plotH / 2} text-anchor="middle" transform="rotate(-90 12 {MARGIN.top + scales.plotH / 2})">{yLabel}</text>
147
+ {/if}
148
+
149
+ <!-- points -->
150
+ {#each points as p, i (i)}
151
+ <circle
152
+ class="st-scatterPlot__point st-scatterPlot__point--{p.tone}"
153
+ cx={p.cx}
154
+ cy={p.cy}
155
+ r={radius}
156
+ data-chart-index={i}
157
+ />
158
+ {/each}
159
+ </svg>
160
+ </div>
161
+
162
+ <ChartDataList {label} items={dataValueItems} />
143
163
 
144
164
  {#if hoveredIndex !== null && points[hoveredIndex]}
145
165
  {@const p = points[hoveredIndex]}
@@ -152,14 +172,13 @@
152
172
 
153
173
  <style>
154
174
  .st-scatterPlot { color: var(--st-semantic-text-secondary); display: block; font-family: inherit; position: relative; width: 100%; }
155
- .st-scatterPlot svg { display: block; overflow: visible; }
175
+ .st-scatterPlot svg, .st-scatterPlot__visual { display: block; overflow: visible; }
156
176
  .st-scatterPlot__grid { stroke: var(--st-semantic-border-subtle); stroke-dasharray: 2 3; stroke-width: 1; opacity: 0.7; }
157
177
  .st-scatterPlot__axis { stroke: var(--st-semantic-border-subtle); stroke-width: 1; }
158
178
  .st-scatterPlot__tick { fill: var(--st-semantic-text-secondary); font-size: 0.6875rem; }
159
179
  .st-scatterPlot__axisLabel { fill: var(--st-semantic-text-secondary); font-size: 0.75rem; font-weight: 600; }
160
180
  .st-scatterPlot__point { cursor: pointer; fill-opacity: 0.85; transition: fill-opacity 120ms ease, r 120ms ease; }
161
- .st-scatterPlot__point:hover, .st-scatterPlot__point:focus-visible { fill-opacity: 1; }
162
- .st-scatterPlot__point:focus-visible { outline: 2px solid var(--st-semantic-border-interactive); outline-offset: 1px; }
181
+ .st-scatterPlot__point:hover { fill-opacity: 1; }
163
182
  .st-scatterPlot__point--category1 { fill: var(--st-semantic-data-category1); }
164
183
  .st-scatterPlot__point--category2 { fill: var(--st-semantic-data-category2); }
165
184
  .st-scatterPlot__point--category3 { fill: var(--st-semantic-data-category3); }
@@ -1 +1 @@
1
- {"version":3,"file":"ScatterPlot.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ScatterPlot.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,eAAe,GACvB,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GACrD,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA6HJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ScatterPlot.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ScatterPlot.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,eAAe,GACvB,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GACrD,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB,CAAC;AAMF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAgJJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -121,14 +121,17 @@
121
121
  the Input field box); bottom corners keep the field shape radius. */
122
122
  border-top-left-radius: var(--st-component-control-anatomy-field-radiusTop, var(--st-component-control-anatomy-shape-radius, 0.375rem));
123
123
  border-top-right-radius: var(--st-component-control-anatomy-field-radiusTop, var(--st-component-control-anatomy-shape-radius, 0.375rem));
124
- border-bottom-right-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
125
- border-bottom-left-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
124
+ border-bottom-right-radius: var(--st-component-control-anatomy-field-radiusBottom, var(--st-component-control-anatomy-shape-radius, 0.375rem));
125
+ border-bottom-left-radius: var(--st-component-control-anatomy-field-radiusBottom, var(--st-component-control-anatomy-shape-radius, 0.375rem));
126
126
  color: var(--st-component-control-text, var(--st-semantic-text-primary));
127
127
  display: inline-flex;
128
128
  /* P-D: field-box padding + input typography per theme. Default = the prior
129
129
  render (0 padding on the wrapper, inherited 16px / `normal` typography);
130
130
  DSFR pads 8/16px, Carbon 0/40px to match the measured reference input. */
131
- padding: var(--st-component-search-paddingBlock, 0) var(--st-component-search-paddingInline, 0);
131
+ padding: var(--st-component-search-paddingBlock, 0)
132
+ var(--st-component-search-paddingRight, var(--st-component-search-paddingInline, 0))
133
+ var(--st-component-search-paddingBlock, 0)
134
+ var(--st-component-search-paddingLeft, var(--st-component-search-paddingInline, 0));
132
135
  font-size: var(--st-component-search-fontSize, 1rem);
133
136
  line-height: var(--st-component-search-lineHeight, normal);
134
137
  letter-spacing: var(--st-component-search-letterSpacing, normal);