@sentropic/design-system-svelte 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/AreaChart.svelte +6 -0
  2. package/dist/Button.svelte +48 -20
  3. package/dist/Card.svelte +6 -4
  4. package/dist/Checkbox.svelte +4 -0
  5. package/dist/Combobox.svelte +17 -6
  6. package/dist/DatePicker.svelte +17 -6
  7. package/dist/DonutChart.svelte +169 -0
  8. package/dist/DonutChart.svelte.d.ts +21 -0
  9. package/dist/DonutChart.svelte.d.ts.map +1 -0
  10. package/dist/Footer.svelte +124 -0
  11. package/dist/Footer.svelte.d.ts +21 -0
  12. package/dist/Footer.svelte.d.ts.map +1 -0
  13. package/dist/Highlight.svelte +63 -0
  14. package/dist/Highlight.svelte.d.ts +15 -0
  15. package/dist/Highlight.svelte.d.ts.map +1 -0
  16. package/dist/Input.svelte +34 -13
  17. package/dist/LanguageSelector.svelte +181 -0
  18. package/dist/LanguageSelector.svelte.d.ts +18 -0
  19. package/dist/LanguageSelector.svelte.d.ts.map +1 -0
  20. package/dist/Link.svelte +18 -10
  21. package/dist/MessageStatusBadge.svelte +11 -7
  22. package/dist/MessageStatusBadge.svelte.d.ts +2 -0
  23. package/dist/MessageStatusBadge.svelte.d.ts.map +1 -1
  24. package/dist/MultiSelect.svelte +17 -7
  25. package/dist/NumberInput.svelte +17 -6
  26. package/dist/OrderedList.svelte +103 -0
  27. package/dist/OrderedList.svelte.d.ts +17 -0
  28. package/dist/OrderedList.svelte.d.ts.map +1 -0
  29. package/dist/OverflowMenu.svelte +5 -2
  30. package/dist/PaginationNav.svelte +5 -2
  31. package/dist/PasswordInput.svelte +17 -6
  32. package/dist/Quote.svelte +72 -0
  33. package/dist/Quote.svelte.d.ts +16 -0
  34. package/dist/Quote.svelte.d.ts.map +1 -0
  35. package/dist/Radio.svelte +4 -0
  36. package/dist/ScatterPlot.svelte +179 -0
  37. package/dist/ScatterPlot.svelte.d.ts +21 -0
  38. package/dist/ScatterPlot.svelte.d.ts.map +1 -0
  39. package/dist/Search.svelte +17 -6
  40. package/dist/Select.svelte +21 -8
  41. package/dist/SkipLink.svelte +50 -0
  42. package/dist/SkipLink.svelte.d.ts +12 -0
  43. package/dist/SkipLink.svelte.d.ts.map +1 -0
  44. package/dist/StackedBarChart.svelte +190 -0
  45. package/dist/StackedBarChart.svelte.d.ts +22 -0
  46. package/dist/StackedBarChart.svelte.d.ts.map +1 -0
  47. package/dist/StreamingMessage.svelte +47 -0
  48. package/dist/StreamingMessage.svelte.d.ts +7 -0
  49. package/dist/StreamingMessage.svelte.d.ts.map +1 -1
  50. package/dist/Switch.svelte +5 -1
  51. package/dist/Tabs.svelte +21 -7
  52. package/dist/Textarea.svelte +36 -9
  53. package/dist/Tile.svelte +165 -0
  54. package/dist/Tile.svelte.d.ts +24 -0
  55. package/dist/Tile.svelte.d.ts.map +1 -0
  56. package/dist/Toggle.svelte +5 -1
  57. package/dist/Toggletip.svelte +5 -2
  58. package/dist/TreeView.svelte +213 -0
  59. package/dist/TreeView.svelte.d.ts +20 -0
  60. package/dist/TreeView.svelte.d.ts.map +1 -0
  61. package/dist/UnorderedList.svelte +4 -3
  62. package/dist/UnorderedList.svelte.d.ts +3 -2
  63. package/dist/UnorderedList.svelte.d.ts.map +1 -1
  64. package/dist/index.d.ts +19 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +11 -0
  67. package/package.json +4 -2
@@ -0,0 +1,15 @@
1
+ export type HighlightTone = "neutral" | "info" | "success" | "warning" | "error";
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ type HighlightProps = Omit<HTMLAttributes<HTMLElement>, "class" | "title"> & {
5
+ /** Tonalité de l'encart (couleur d'accent). */
6
+ tone?: HighlightTone;
7
+ /** Titre optionnel de la mise en avant. */
8
+ title?: string;
9
+ class?: string;
10
+ children?: Snippet;
11
+ };
12
+ declare const Highlight: import("svelte").Component<HighlightProps, {}, "">;
13
+ type Highlight = ReturnType<typeof Highlight>;
14
+ export default Highlight;
15
+ //# sourceMappingURL=Highlight.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Highlight.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Highlight.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAGnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG;IAC3E,+CAA+C;IAC/C,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA4BJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
package/dist/Input.svelte CHANGED
@@ -58,8 +58,12 @@
58
58
  }
59
59
 
60
60
  .st-field__label {
61
- font-size: 0.875rem;
62
- font-weight: 600;
61
+ font-family: var(--st-component-field-labelTypography-family, inherit);
62
+ font-size: var(--st-component-field-labelTypography-size, 0.875rem);
63
+ font-weight: var(--st-component-field-labelTypography-weight, 600);
64
+ line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
65
+ letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
66
+ text-transform: var(--st-component-field-labelTypography-textTransform, none);
63
67
  }
64
68
 
65
69
  .st-field__help,
@@ -77,13 +81,26 @@
77
81
  }
78
82
 
79
83
  .st-control {
80
- background: var(--st-component-control-background, var(--st-semantic-surface-default));
81
- border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
82
- border-radius: var(--st-component-control-radius, 0.375rem);
84
+ /* Field style (anatomy v1.2.0): the background fill + per-side borders come
85
+ from the resolved `field` anatomy. outline (base) = surface.default fill +
86
+ 4 equal borders; filled-underline (DSFR/Carbon) = filled bg + bottom rule
87
+ only (top/right/left = none). Fallbacks reproduce the prior boxed look. */
88
+ background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
89
+ border-top: var(--st-component-control-anatomy-field-borderTop, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
90
+ border-right: var(--st-component-control-anatomy-field-borderRight, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
91
+ border-bottom: var(--st-component-control-anatomy-field-borderBottom, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
92
+ border-left: var(--st-component-control-anatomy-field-borderLeft, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
93
+ border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
83
94
  color: var(--st-component-control-text, var(--st-semantic-text-primary));
84
- font: inherit;
95
+ font-family: var(--st-component-control-anatomy-typography-family, inherit);
96
+ font-size: var(--st-component-control-anatomy-typography-size, inherit);
97
+ font-weight: var(--st-component-control-anatomy-typography-weight, 400);
98
+ line-height: var(--st-component-control-anatomy-typography-lineHeight, 1.5);
85
99
  min-width: 0;
86
- padding: 0 0.75rem;
100
+ /* Inputs use the SM inline padding (denser than buttons) — base = 0.75rem. */
101
+ padding: var(--st-component-control-anatomy-density-md-paddingBlock, 0)
102
+ var(--st-component-control-anatomy-density-sm-paddingInline, 0.75rem);
103
+ cursor: var(--st-cursor-text, text);
87
104
  transition:
88
105
  border-color var(--st-motion-fast, 120ms) var(--st-motion-easing, ease),
89
106
  box-shadow var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
@@ -91,15 +108,15 @@
91
108
  }
92
109
 
93
110
  .st-control--sm {
94
- min-height: var(--st-component-control-smHeight, 2rem);
111
+ min-height: var(--st-component-control-anatomy-density-sm-controlHeight, var(--st-component-control-smHeight, 2rem));
95
112
  }
96
113
 
97
114
  .st-control--md {
98
- min-height: var(--st-component-control-mdHeight, 2.5rem);
115
+ min-height: var(--st-component-control-anatomy-density-md-controlHeight, var(--st-component-control-mdHeight, 2.5rem));
99
116
  }
100
117
 
101
118
  .st-control--lg {
102
- min-height: var(--st-component-control-lgHeight, 3rem);
119
+ min-height: var(--st-component-control-anatomy-density-lg-controlHeight, var(--st-component-control-lgHeight, 3rem));
103
120
  }
104
121
 
105
122
  .st-control::placeholder {
@@ -110,10 +127,14 @@
110
127
  border-color: var(--st-component-control-hoverBorder, var(--st-semantic-border-strong));
111
128
  }
112
129
 
130
+ /* Focus = shared mixin. Base/DSFR use outline; Carbon uses inset box-shadow.
131
+ The border-color change is the field's own affordance and stays. */
113
132
  .st-control:focus-visible {
114
133
  border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
115
- box-shadow: 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
116
- outline: none;
134
+ outline: var(--st-component-control-anatomy-focus-outline, none);
135
+ outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
136
+ box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
137
+ 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
117
138
  }
118
139
 
119
140
  .st-control[aria-invalid="true"] {
@@ -123,6 +144,6 @@
123
144
  .st-control:disabled {
124
145
  background: var(--st-component-control-disabledBackground, var(--st-semantic-surface-subtle));
125
146
  color: var(--st-component-control-disabledText, var(--st-semantic-text-muted));
126
- cursor: not-allowed;
147
+ cursor: var(--st-cursor-disabled, not-allowed);
127
148
  }
128
149
  </style>
@@ -0,0 +1,181 @@
1
+ <script lang="ts" module>
2
+ export interface LanguageOption {
3
+ value: string;
4
+ label: string;
5
+ }
6
+ </script>
7
+
8
+ <script lang="ts">
9
+ type LanguageSelectorProps = {
10
+ /** Code de langue courant (bindable). */
11
+ value?: string;
12
+ options: LanguageOption[];
13
+ /** aria-label du déclencheur. */
14
+ label?: string;
15
+ disabled?: boolean;
16
+ class?: string;
17
+ onchange?: (value: string) => void;
18
+ };
19
+
20
+ let {
21
+ value = $bindable<string>(""),
22
+ options,
23
+ label = "Choisir la langue",
24
+ disabled = false,
25
+ class: className,
26
+ onchange
27
+ }: LanguageSelectorProps = $props();
28
+
29
+ let open = $state(false);
30
+ let root: HTMLDivElement | undefined = $state();
31
+
32
+ const current = $derived(options.find((o) => o.value === value) ?? options[0]);
33
+ const classes = () => ["st-languageSelector", className].filter(Boolean).join(" ");
34
+
35
+ function choose(next: string) {
36
+ value = next;
37
+ open = false;
38
+ onchange?.(next);
39
+ }
40
+ </script>
41
+
42
+ <svelte:window
43
+ onclick={(e) => {
44
+ if (open && root && e.target instanceof Node && !root.contains(e.target)) open = false;
45
+ }}
46
+ onkeydown={(e) => {
47
+ if (e.key === "Escape") open = false;
48
+ }}
49
+ />
50
+
51
+ <div class={classes()} bind:this={root}>
52
+ <button
53
+ type="button"
54
+ class="st-languageSelector__trigger"
55
+ aria-haspopup="listbox"
56
+ aria-expanded={open}
57
+ aria-label={label}
58
+ {disabled}
59
+ onclick={() => (open = !open)}
60
+ >
61
+ <span class="st-languageSelector__current">{current?.label ?? value}</span>
62
+ <span class="st-languageSelector__caret" class:st-languageSelector__caret--open={open} aria-hidden="true"></span>
63
+ </button>
64
+
65
+ {#if open}
66
+ <ul class="st-languageSelector__menu" role="listbox" aria-label={label}>
67
+ {#each options as option (option.value)}
68
+ <li>
69
+ <button
70
+ type="button"
71
+ class="st-languageSelector__option"
72
+ class:st-languageSelector__option--active={option.value === value}
73
+ role="option"
74
+ aria-selected={option.value === value}
75
+ onclick={() => choose(option.value)}
76
+ >
77
+ <span class="st-languageSelector__check" aria-hidden="true">{option.value === value ? "✓" : ""}</span>
78
+ {option.label}
79
+ </button>
80
+ </li>
81
+ {/each}
82
+ </ul>
83
+ {/if}
84
+ </div>
85
+
86
+ <style>
87
+ .st-languageSelector {
88
+ display: inline-block;
89
+ position: relative;
90
+ }
91
+
92
+ .st-languageSelector__trigger {
93
+ align-items: center;
94
+ background: var(--st-component-control-background, var(--st-semantic-surface-default));
95
+ border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
96
+ border-radius: var(--st-radius-md, 0.375rem);
97
+ color: var(--st-semantic-text-primary);
98
+ cursor: pointer;
99
+ display: inline-flex;
100
+ font: inherit;
101
+ font-size: 0.85rem;
102
+ gap: var(--st-spacing-2, 0.5rem);
103
+ padding: 0.35rem 0.6rem;
104
+ }
105
+
106
+ .st-languageSelector__trigger:hover:not(:disabled) {
107
+ border-color: var(--st-component-control-hoverBorder, var(--st-semantic-border-strong));
108
+ }
109
+
110
+ .st-languageSelector__trigger:focus-visible {
111
+ border-color: var(--st-semantic-border-interactive);
112
+ box-shadow: 0 0 0 2px var(--st-semantic-border-interactive);
113
+ outline: none;
114
+ }
115
+
116
+ .st-languageSelector__trigger:disabled {
117
+ cursor: not-allowed;
118
+ opacity: 0.55;
119
+ }
120
+
121
+ .st-languageSelector__caret {
122
+ border-left: 4px solid transparent;
123
+ border-right: 4px solid transparent;
124
+ border-top: 5px solid currentColor;
125
+ display: inline-block;
126
+ transition: transform var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
127
+ }
128
+
129
+ .st-languageSelector__caret--open {
130
+ transform: rotate(180deg);
131
+ }
132
+
133
+ .st-languageSelector__menu {
134
+ background: var(--st-component-menu-background, var(--st-semantic-surface-raised));
135
+ border: 1px solid var(--st-component-menu-border, var(--st-semantic-border-subtle));
136
+ border-radius: var(--st-radius-md, 0.375rem);
137
+ box-shadow: var(--st-shadow-medium, 0 8px 24px rgb(15 23 42 / 0.12));
138
+ display: flex;
139
+ flex-direction: column;
140
+ gap: 0.1rem;
141
+ list-style: none;
142
+ margin: 0.25rem 0 0;
143
+ min-width: 9rem;
144
+ padding: 0.25rem;
145
+ position: absolute;
146
+ right: 0;
147
+ z-index: var(--st-zindex-overlay, 80);
148
+ }
149
+
150
+ .st-languageSelector__option {
151
+ align-items: center;
152
+ background: transparent;
153
+ border: 0;
154
+ border-radius: var(--st-radius-sm, 0.25rem);
155
+ color: var(--st-semantic-text-secondary);
156
+ cursor: pointer;
157
+ display: flex;
158
+ font: inherit;
159
+ font-size: 0.85rem;
160
+ gap: 0.4rem;
161
+ padding: 0.35rem 0.5rem;
162
+ text-align: left;
163
+ width: 100%;
164
+ }
165
+
166
+ .st-languageSelector__option:hover {
167
+ background: var(--st-semantic-surface-subtle);
168
+ color: var(--st-semantic-text-primary);
169
+ }
170
+
171
+ .st-languageSelector__option--active {
172
+ color: var(--st-semantic-action-primary);
173
+ font-weight: 600;
174
+ }
175
+
176
+ .st-languageSelector__check {
177
+ display: inline-flex;
178
+ justify-content: center;
179
+ width: 0.75rem;
180
+ }
181
+ </style>
@@ -0,0 +1,18 @@
1
+ export interface LanguageOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ type LanguageSelectorProps = {
6
+ /** Code de langue courant (bindable). */
7
+ value?: string;
8
+ options: LanguageOption[];
9
+ /** aria-label du déclencheur. */
10
+ label?: string;
11
+ disabled?: boolean;
12
+ class?: string;
13
+ onchange?: (value: string) => void;
14
+ };
15
+ declare const LanguageSelector: import("svelte").Component<LanguageSelectorProps, {}, "value">;
16
+ type LanguageSelector = ReturnType<typeof LanguageSelector>;
17
+ export default LanguageSelector;
18
+ //# sourceMappingURL=LanguageSelector.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LanguageSelector.svelte.d.ts","sourceRoot":"","sources":["../src/lib/LanguageSelector.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,KAAK,qBAAqB,GAAG;IAC3B,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AA0DJ,QAAA,MAAM,gBAAgB,gEAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
package/dist/Link.svelte CHANGED
@@ -57,9 +57,10 @@
57
57
  <style>
58
58
  .st-link {
59
59
  color: var(--st-component-link-text, var(--st-semantic-text-link));
60
- cursor: pointer;
61
- text-decoration: underline;
62
- text-underline-offset: 0.18em;
60
+ cursor: var(--st-cursor-interactive, pointer);
61
+ text-decoration: var(--st-component-link-anatomy-typography-textDecoration, underline);
62
+ text-decoration-thickness: var(--st-component-link-anatomy-typography-decorationThickness, auto);
63
+ text-underline-offset: var(--st-component-link-anatomy-typography-decorationOffset, 0.18em);
63
64
  }
64
65
 
65
66
  .st-link--standalone {
@@ -73,18 +74,25 @@
73
74
  }
74
75
 
75
76
  .st-link:hover {
76
- color: var(--st-component-link-hoverText, var(--st-semantic-action-primary));
77
+ color: var(--st-component-link-anatomy-states-hover-text, var(--st-component-link-hoverText, var(--st-semantic-action-primary)));
78
+ /* Anatomy v1.1.0: hover decoration sourced from states.hover.decoration
79
+ (= link typography textDecorationHover). Carbon: none → underline; DSFR/base:
80
+ underline → underline (no-op). The DSFR animated underline stays an escape. */
81
+ text-decoration-line: var(--st-component-link-anatomy-states-hover-decoration, underline);
77
82
  }
78
83
 
84
+ /* Focus = shared mixin. --st-radius-* fixed to the valid `sm` token (was the
85
+ phantom --st-radius-small). */
79
86
  .st-link:focus-visible {
80
- border-radius: var(--st-radius-small, 0.375rem);
81
- outline: 2px solid var(--st-component-link-focusRing, var(--st-semantic-border-interactive));
82
- outline-offset: 2px;
87
+ border-radius: var(--st-component-link-anatomy-shape-radius, var(--st-radius-sm, 0.25rem));
88
+ outline: var(--st-component-link-anatomy-focus-outline, 2px solid var(--st-semantic-border-interactive));
89
+ outline-offset: var(--st-component-link-anatomy-focus-offset, 2px);
90
+ box-shadow: var(--st-component-link-anatomy-focus-boxShadow, none);
83
91
  }
84
92
 
85
93
  .st-link--disabled {
86
- color: var(--st-component-link-disabledText, var(--st-semantic-text-muted));
87
- cursor: not-allowed;
88
- text-decoration: none;
94
+ color: var(--st-component-link-anatomy-states-disabled-text, var(--st-component-link-disabledText, var(--st-semantic-text-muted)));
95
+ cursor: var(--st-cursor-disabled, not-allowed);
96
+ text-decoration: var(--st-component-link-anatomy-states-disabled-decoration, none);
89
97
  }
90
98
  </style>
@@ -8,10 +8,19 @@
8
8
  type MessageStatusBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
9
9
  status: ChatMessageStatus;
10
10
  tone?: StatusTone;
11
+ /** Surcharge i18n des libellés par statut (défaut : libellés FR). */
12
+ labels?: Partial<Record<ChatMessageStatus, string>>;
11
13
  class?: string;
12
14
  };
13
15
 
14
- let { status, tone, class: className, ...rest }: MessageStatusBadgeProps = $props();
16
+ let { status, tone, labels, class: className, ...rest }: MessageStatusBadgeProps = $props();
17
+
18
+ const DEFAULT_LABELS: Record<ChatMessageStatus, string> = {
19
+ pending: "En attente",
20
+ processing: "En cours",
21
+ completed: "Terminé",
22
+ failed: "Échec"
23
+ };
15
24
 
16
25
  const mappedTone = () => {
17
26
  if (tone) return tone;
@@ -21,12 +30,7 @@
21
30
  return "warning";
22
31
  };
23
32
 
24
- const label = () => {
25
- if (status === "pending") return "En attente";
26
- if (status === "processing") return "En cours";
27
- if (status === "completed") return "Terminé";
28
- return "Échec";
29
- };
33
+ const label = () => labels?.[status] ?? DEFAULT_LABELS[status];
30
34
 
31
35
  const classes = () => ["st-messageStatusBadge", className].filter(Boolean).join(" ");
32
36
  </script>
@@ -4,6 +4,8 @@ type StatusTone = "neutral" | "success" | "warning" | "error" | "info";
4
4
  type MessageStatusBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
5
5
  status: ChatMessageStatus;
6
6
  tone?: StatusTone;
7
+ /** Surcharge i18n des libellés par statut (défaut : libellés FR). */
8
+ labels?: Partial<Record<ChatMessageStatus, string>>;
7
9
  class?: string;
8
10
  };
9
11
  declare const MessageStatusBadge: import("svelte").Component<MessageStatusBadgeProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageStatusBadge.svelte.d.ts","sourceRoot":"","sources":["../src/lib/MessageStatusBadge.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvE,KAAK,uBAAuB,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,GAAG;IACjF,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAqCJ,QAAA,MAAM,kBAAkB,6DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"MessageStatusBadge.svelte.d.ts","sourceRoot":"","sources":["../src/lib/MessageStatusBadge.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvE,KAAK,uBAAuB,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,GAAG;IACjF,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAuCJ,QAAA,MAAM,kBAAkB,6DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -197,8 +197,12 @@
197
197
  }
198
198
 
199
199
  .st-field__label {
200
- font-size: 0.875rem;
201
- font-weight: 600;
200
+ font-family: var(--st-component-field-labelTypography-family, inherit);
201
+ font-size: var(--st-component-field-labelTypography-size, 0.875rem);
202
+ font-weight: var(--st-component-field-labelTypography-weight, 600);
203
+ line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
204
+ letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
205
+ text-transform: var(--st-component-field-labelTypography-textTransform, none);
202
206
  }
203
207
 
204
208
  .st-field__help,
@@ -244,11 +248,15 @@
244
248
  min-height: var(--st-component-control-lgHeight, 3rem);
245
249
  }
246
250
 
251
+ /* Field box = resolved field anatomy (v1.2.0), same as Input. */
247
252
  .st-multiSelect__trigger {
248
253
  align-items: center;
249
- background: var(--st-component-control-background, var(--st-semantic-surface-default));
250
- border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
251
- border-radius: var(--st-component-control-radius, 0.375rem);
254
+ background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
255
+ border-top: var(--st-component-control-anatomy-field-borderTop, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
256
+ border-right: var(--st-component-control-anatomy-field-borderRight, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
257
+ border-bottom: var(--st-component-control-anatomy-field-borderBottom, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
258
+ border-left: var(--st-component-control-anatomy-field-borderLeft, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
259
+ border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
252
260
  color: var(--st-component-control-text, var(--st-semantic-text-primary));
253
261
  cursor: pointer;
254
262
  display: flex;
@@ -268,8 +276,10 @@
268
276
 
269
277
  .st-multiSelect__trigger:focus-visible {
270
278
  border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
271
- box-shadow: 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
272
- outline: none;
279
+ outline: var(--st-component-control-anatomy-focus-outline, none);
280
+ outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
281
+ box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
282
+ 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
273
283
  }
274
284
 
275
285
  .st-multiSelect[data-invalid="true"] .st-multiSelect__trigger {
@@ -126,8 +126,12 @@
126
126
  }
127
127
 
128
128
  .st-field__label {
129
- font-size: 0.875rem;
130
- font-weight: 600;
129
+ font-family: var(--st-component-field-labelTypography-family, inherit);
130
+ font-size: var(--st-component-field-labelTypography-size, 0.875rem);
131
+ font-weight: var(--st-component-field-labelTypography-weight, 600);
132
+ line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
133
+ letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
134
+ text-transform: var(--st-component-field-labelTypography-textTransform, none);
131
135
  }
132
136
 
133
137
  .st-field__help,
@@ -144,11 +148,15 @@
144
148
  color: var(--st-component-field-errorText, var(--st-semantic-feedback-error));
145
149
  }
146
150
 
151
+ /* Field box = resolved field anatomy (v1.2.0), same as Input. */
147
152
  .st-numberInput {
148
153
  align-items: stretch;
149
- background: var(--st-component-control-background, var(--st-semantic-surface-default));
150
- border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
151
- border-radius: var(--st-component-control-radius, 0.375rem);
154
+ background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
155
+ border-top: var(--st-component-control-anatomy-field-borderTop, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
156
+ border-right: var(--st-component-control-anatomy-field-borderRight, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
157
+ border-bottom: var(--st-component-control-anatomy-field-borderBottom, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
158
+ border-left: var(--st-component-control-anatomy-field-borderLeft, var(--st-component-control-anatomy-shape-borderWidth, 1px) var(--st-component-control-anatomy-shape-borderStyle, solid) var(--st-component-control-border, var(--st-semantic-border-subtle)));
159
+ border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
152
160
  color: var(--st-component-control-text, var(--st-semantic-text-primary));
153
161
  display: inline-flex;
154
162
  overflow: hidden;
@@ -176,7 +184,10 @@
176
184
 
177
185
  .st-numberInput:focus-within {
178
186
  border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
179
- box-shadow: 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
187
+ outline: var(--st-component-control-anatomy-focus-outline, none);
188
+ outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
189
+ box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
190
+ 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
180
191
  }
181
192
 
182
193
  .st-numberInput:has([aria-invalid="true"]) {
@@ -0,0 +1,103 @@
1
+ <script lang="ts" module>
2
+ import type { Snippet } from "svelte";
3
+
4
+ export type OrderedListInput = string | OrderedListItem;
5
+
6
+ export interface OrderedListItem {
7
+ content: string | Snippet;
8
+ /** Sous-items : chaînes ou objets (normalisés au rendu). */
9
+ children?: OrderedListInput[];
10
+ }
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ import type { HTMLAttributes } from "svelte/elements";
15
+
16
+ type OrderedListProps = Omit<HTMLAttributes<HTMLOListElement>, "class"> & {
17
+ items: OrderedListInput[];
18
+ nested?: boolean;
19
+ class?: string;
20
+ };
21
+
22
+ let {
23
+ items,
24
+ nested = false,
25
+ class: className,
26
+ ...rest
27
+ }: OrderedListProps = $props();
28
+
29
+ const classes = () =>
30
+ ["st-orderedList", nested ? "st-orderedList--nested" : null, className]
31
+ .filter(Boolean)
32
+ .join(" ");
33
+
34
+ function normalize(item: OrderedListInput): OrderedListItem {
35
+ if (typeof item === "string") return { content: item };
36
+ return item;
37
+ }
38
+
39
+ function isSnippet(value: string | Snippet): value is Snippet {
40
+ return typeof value === "function";
41
+ }
42
+ </script>
43
+
44
+ <ol {...rest} class={classes()}>
45
+ {#each items as raw, index (index)}
46
+ {@const item = normalize(raw)}
47
+ <li class="st-orderedList__item">
48
+ {#if isSnippet(item.content)}
49
+ {@render item.content()}
50
+ {:else}
51
+ {item.content}
52
+ {/if}
53
+ {#if item.children && item.children.length > 0}
54
+ <ol class="st-orderedList st-orderedList--nested">
55
+ {#each item.children as childRaw, childIndex (childIndex)}
56
+ {@const child = normalize(childRaw)}
57
+ <li class="st-orderedList__item">
58
+ {#if isSnippet(child.content)}
59
+ {@render child.content()}
60
+ {:else}
61
+ {child.content}
62
+ {/if}
63
+ </li>
64
+ {/each}
65
+ </ol>
66
+ {/if}
67
+ </li>
68
+ {/each}
69
+ </ol>
70
+
71
+ <style>
72
+ .st-orderedList {
73
+ color: var(--st-semantic-text-primary);
74
+ counter-reset: st-ol;
75
+ display: grid;
76
+ gap: var(--st-spacing-1, 0.25rem);
77
+ list-style: none;
78
+ margin: 0;
79
+ padding: 0;
80
+ }
81
+
82
+ .st-orderedList--nested {
83
+ margin-block-start: var(--st-spacing-1, 0.25rem);
84
+ margin-inline-start: var(--st-spacing-4, 1rem);
85
+ }
86
+
87
+ .st-orderedList__item {
88
+ counter-increment: st-ol;
89
+ line-height: 1.5;
90
+ padding-inline-start: var(--st-spacing-8, 2rem);
91
+ position: relative;
92
+ }
93
+
94
+ .st-orderedList__item::before {
95
+ color: var(--st-semantic-text-secondary);
96
+ content: counter(st-ol) ".";
97
+ font-variant-numeric: tabular-nums;
98
+ inset-inline-start: 0;
99
+ position: absolute;
100
+ text-align: end;
101
+ width: var(--st-spacing-6, 1.5rem);
102
+ }
103
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from "svelte";
2
+ export type OrderedListInput = string | OrderedListItem;
3
+ export interface OrderedListItem {
4
+ content: string | Snippet;
5
+ /** Sous-items : chaînes ou objets (normalisés au rendu). */
6
+ children?: OrderedListInput[];
7
+ }
8
+ import type { HTMLAttributes } from "svelte/elements";
9
+ type OrderedListProps = Omit<HTMLAttributes<HTMLOListElement>, "class"> & {
10
+ items: OrderedListInput[];
11
+ nested?: boolean;
12
+ class?: string;
13
+ };
14
+ declare const OrderedList: import("svelte").Component<OrderedListProps, {}, "">;
15
+ type OrderedList = ReturnType<typeof OrderedList>;
16
+ export default OrderedList;
17
+ //# sourceMappingURL=OrderedList.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderedList.svelte.d.ts","sourceRoot":"","sources":["../src/lib/OrderedList.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,eAAe,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,GAAG;IACxE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA4DJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -180,10 +180,13 @@
180
180
  );
181
181
  }
182
182
 
183
+ /* Focus = stratégie d'anatomie partagée (outline DSFR / inset Carbon / ring base). */
183
184
  .st-overflowMenu__trigger:focus-visible {
184
185
  border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
185
- box-shadow: 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
186
- outline: none;
186
+ outline: var(--st-component-control-anatomy-focus-outline, none);
187
+ outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
188
+ box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
189
+ 0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
187
190
  }
188
191
 
189
192
  .st-overflowMenu__trigger[aria-expanded="true"] {