@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.
- package/dist/AreaChart.svelte +6 -0
- package/dist/Button.svelte +48 -20
- package/dist/Card.svelte +6 -4
- package/dist/Checkbox.svelte +4 -0
- package/dist/Combobox.svelte +17 -6
- package/dist/DatePicker.svelte +17 -6
- package/dist/DonutChart.svelte +169 -0
- package/dist/DonutChart.svelte.d.ts +21 -0
- package/dist/DonutChart.svelte.d.ts.map +1 -0
- package/dist/Footer.svelte +124 -0
- package/dist/Footer.svelte.d.ts +21 -0
- package/dist/Footer.svelte.d.ts.map +1 -0
- package/dist/Highlight.svelte +63 -0
- package/dist/Highlight.svelte.d.ts +15 -0
- package/dist/Highlight.svelte.d.ts.map +1 -0
- package/dist/Input.svelte +34 -13
- package/dist/LanguageSelector.svelte +181 -0
- package/dist/LanguageSelector.svelte.d.ts +18 -0
- package/dist/LanguageSelector.svelte.d.ts.map +1 -0
- package/dist/Link.svelte +18 -10
- package/dist/MessageStatusBadge.svelte +11 -7
- package/dist/MessageStatusBadge.svelte.d.ts +2 -0
- package/dist/MessageStatusBadge.svelte.d.ts.map +1 -1
- package/dist/MultiSelect.svelte +17 -7
- package/dist/NumberInput.svelte +17 -6
- package/dist/OrderedList.svelte +103 -0
- package/dist/OrderedList.svelte.d.ts +17 -0
- package/dist/OrderedList.svelte.d.ts.map +1 -0
- package/dist/OverflowMenu.svelte +5 -2
- package/dist/PaginationNav.svelte +5 -2
- package/dist/PasswordInput.svelte +17 -6
- package/dist/Quote.svelte +72 -0
- package/dist/Quote.svelte.d.ts +16 -0
- package/dist/Quote.svelte.d.ts.map +1 -0
- package/dist/Radio.svelte +4 -0
- package/dist/ScatterPlot.svelte +179 -0
- package/dist/ScatterPlot.svelte.d.ts +21 -0
- package/dist/ScatterPlot.svelte.d.ts.map +1 -0
- package/dist/Search.svelte +17 -6
- package/dist/Select.svelte +21 -8
- package/dist/SkipLink.svelte +50 -0
- package/dist/SkipLink.svelte.d.ts +12 -0
- package/dist/SkipLink.svelte.d.ts.map +1 -0
- package/dist/StackedBarChart.svelte +190 -0
- package/dist/StackedBarChart.svelte.d.ts +22 -0
- package/dist/StackedBarChart.svelte.d.ts.map +1 -0
- package/dist/StreamingMessage.svelte +47 -0
- package/dist/StreamingMessage.svelte.d.ts +7 -0
- package/dist/StreamingMessage.svelte.d.ts.map +1 -1
- package/dist/Switch.svelte +5 -1
- package/dist/Tabs.svelte +21 -7
- package/dist/Textarea.svelte +36 -9
- package/dist/Tile.svelte +165 -0
- package/dist/Tile.svelte.d.ts +24 -0
- package/dist/Tile.svelte.d.ts.map +1 -0
- package/dist/Toggle.svelte +5 -1
- package/dist/Toggletip.svelte +5 -2
- package/dist/TreeView.svelte +213 -0
- package/dist/TreeView.svelte.d.ts +20 -0
- package/dist/TreeView.svelte.d.ts.map +1 -0
- package/dist/UnorderedList.svelte +4 -3
- package/dist/UnorderedList.svelte.d.ts +3 -2
- package/dist/UnorderedList.svelte.d.ts.map +1 -1
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/package.json +4 -2
|
@@ -168,11 +168,14 @@
|
|
|
168
168
|
);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/* Focus = stratégie d'anatomie partagée (outline DSFR / inset Carbon / ring base). */
|
|
171
172
|
.st-paginationNav__page:focus-visible,
|
|
172
173
|
.st-paginationNav__nav:focus-visible {
|
|
173
174
|
border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
|
|
174
|
-
|
|
175
|
-
outline:
|
|
175
|
+
outline: var(--st-component-control-anatomy-focus-outline, none);
|
|
176
|
+
outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
|
|
177
|
+
box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
|
|
178
|
+
0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
.st-paginationNav__page--active {
|
|
@@ -89,8 +89,12 @@
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
.st-field__label {
|
|
92
|
-
font-
|
|
93
|
-
font-
|
|
92
|
+
font-family: var(--st-component-field-labelTypography-family, inherit);
|
|
93
|
+
font-size: var(--st-component-field-labelTypography-size, 0.875rem);
|
|
94
|
+
font-weight: var(--st-component-field-labelTypography-weight, 600);
|
|
95
|
+
line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
|
|
96
|
+
letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
|
|
97
|
+
text-transform: var(--st-component-field-labelTypography-textTransform, none);
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
.st-field__help,
|
|
@@ -107,11 +111,15 @@
|
|
|
107
111
|
color: var(--st-component-field-errorText, var(--st-semantic-feedback-error));
|
|
108
112
|
}
|
|
109
113
|
|
|
114
|
+
/* Field box = resolved field anatomy (v1.2.0), same as Input. */
|
|
110
115
|
.st-passwordInput {
|
|
111
116
|
align-items: center;
|
|
112
|
-
background: var(--st-component-control-background, var(--st-semantic-surface-default));
|
|
113
|
-
border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
|
|
114
|
-
border-
|
|
117
|
+
background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
|
|
118
|
+
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)));
|
|
119
|
+
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)));
|
|
120
|
+
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)));
|
|
121
|
+
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)));
|
|
122
|
+
border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
|
|
115
123
|
color: var(--st-component-control-text, var(--st-semantic-text-primary));
|
|
116
124
|
display: inline-flex;
|
|
117
125
|
transition:
|
|
@@ -138,7 +146,10 @@
|
|
|
138
146
|
|
|
139
147
|
.st-passwordInput:focus-within {
|
|
140
148
|
border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
|
|
141
|
-
|
|
149
|
+
outline: var(--st-component-control-anatomy-focus-outline, none);
|
|
150
|
+
outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
|
|
151
|
+
box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
|
|
152
|
+
0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
.st-passwordInput:has([aria-invalid="true"]) {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
|
|
5
|
+
type QuoteProps = Omit<HTMLAttributes<HTMLElement>, "class" | "cite"> & {
|
|
6
|
+
/** Auteur de la citation. */
|
|
7
|
+
author?: string;
|
|
8
|
+
/** Source / référence (affichée après l'auteur). */
|
|
9
|
+
source?: string;
|
|
10
|
+
/** URL source (attribut cite du blockquote). */
|
|
11
|
+
cite?: string;
|
|
12
|
+
class?: string;
|
|
13
|
+
children?: Snippet;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
author,
|
|
18
|
+
source,
|
|
19
|
+
cite,
|
|
20
|
+
class: className,
|
|
21
|
+
children,
|
|
22
|
+
...rest
|
|
23
|
+
}: QuoteProps = $props();
|
|
24
|
+
|
|
25
|
+
const classes = () => ["st-quote", className].filter(Boolean).join(" ");
|
|
26
|
+
const hasAttribution = () => Boolean(author || source);
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<figure {...rest} class={classes()}>
|
|
30
|
+
<blockquote class="st-quote__text" {cite}>
|
|
31
|
+
{#if children}{@render children()}{/if}
|
|
32
|
+
</blockquote>
|
|
33
|
+
{#if hasAttribution()}
|
|
34
|
+
<figcaption class="st-quote__attribution">
|
|
35
|
+
{#if author}<span class="st-quote__author">{author}</span>{/if}
|
|
36
|
+
{#if source}<cite class="st-quote__source">{source}</cite>{/if}
|
|
37
|
+
</figcaption>
|
|
38
|
+
{/if}
|
|
39
|
+
</figure>
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.st-quote {
|
|
43
|
+
border-left: 4px solid var(--st-semantic-action-primary);
|
|
44
|
+
margin: 0;
|
|
45
|
+
padding: var(--st-spacing-2, 0.5rem) 0 var(--st-spacing-2, 0.5rem) var(--st-spacing-4, 1rem);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.st-quote__text {
|
|
49
|
+
color: var(--st-semantic-text-primary);
|
|
50
|
+
font-size: 1.125rem;
|
|
51
|
+
line-height: 1.6;
|
|
52
|
+
margin: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.st-quote__attribution {
|
|
56
|
+
color: var(--st-semantic-text-secondary);
|
|
57
|
+
font-size: 0.875rem;
|
|
58
|
+
margin-top: var(--st-spacing-2, 0.5rem);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.st-quote__author {
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.st-quote__author + .st-quote__source::before {
|
|
66
|
+
content: ", ";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.st-quote__source {
|
|
70
|
+
font-style: italic;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
type QuoteProps = Omit<HTMLAttributes<HTMLElement>, "class" | "cite"> & {
|
|
4
|
+
/** Auteur de la citation. */
|
|
5
|
+
author?: string;
|
|
6
|
+
/** Source / référence (affichée après l'auteur). */
|
|
7
|
+
source?: string;
|
|
8
|
+
/** URL source (attribut cite du blockquote). */
|
|
9
|
+
cite?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
};
|
|
13
|
+
declare const Quote: import("svelte").Component<QuoteProps, {}, "">;
|
|
14
|
+
type Quote = ReturnType<typeof Quote>;
|
|
15
|
+
export default Quote;
|
|
16
|
+
//# sourceMappingURL=Quote.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Quote.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Quote.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,GAAG;IACtE,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAmCJ,QAAA,MAAM,KAAK,gDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
|
package/dist/Radio.svelte
CHANGED
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
.st-choice__input {
|
|
33
|
+
/* Thématise le radio natif (couleur checked) sans markup custom — additif,
|
|
34
|
+
a11y native préservée. Le visuel custom (forme/focus par stratégie) reste
|
|
35
|
+
un item dédié (cf. backlog). */
|
|
36
|
+
accent-color: var(--st-component-selection-checkedBackground, var(--st-semantic-action-primary));
|
|
33
37
|
height: 1rem;
|
|
34
38
|
margin: 0.125rem 0 0;
|
|
35
39
|
width: 1rem;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type ScatterPlotTone =
|
|
3
|
+
| "category1" | "category2" | "category3" | "category4"
|
|
4
|
+
| "category5" | "category6" | "category7" | "category8";
|
|
5
|
+
|
|
6
|
+
export type ScatterPlotDatum = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
label?: string;
|
|
10
|
+
tone?: ScatterPlotTone;
|
|
11
|
+
};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
type ScatterPlotProps = {
|
|
16
|
+
data: ScatterPlotDatum[];
|
|
17
|
+
width?: number;
|
|
18
|
+
height?: number;
|
|
19
|
+
xLabel?: string;
|
|
20
|
+
yLabel?: string;
|
|
21
|
+
radius?: number;
|
|
22
|
+
label: string;
|
|
23
|
+
class?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
data,
|
|
28
|
+
width = 480,
|
|
29
|
+
height = 280,
|
|
30
|
+
xLabel,
|
|
31
|
+
yLabel,
|
|
32
|
+
radius = 5,
|
|
33
|
+
label,
|
|
34
|
+
class: className
|
|
35
|
+
}: ScatterPlotProps = $props();
|
|
36
|
+
|
|
37
|
+
const MARGIN = { top: 14, right: 18, bottom: 36, left: 48 };
|
|
38
|
+
|
|
39
|
+
function niceTicks(min: number, max: number, target = 5): number[] {
|
|
40
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || min === max) {
|
|
41
|
+
return [Number.isFinite(max) ? max : 0];
|
|
42
|
+
}
|
|
43
|
+
const range = max - min;
|
|
44
|
+
const rough = range / Math.max(target - 1, 1);
|
|
45
|
+
const pow = Math.pow(10, Math.floor(Math.log10(rough)));
|
|
46
|
+
const norm = rough / pow;
|
|
47
|
+
let step: number;
|
|
48
|
+
if (norm < 1.5) step = pow;
|
|
49
|
+
else if (norm < 3) step = 2 * pow;
|
|
50
|
+
else if (norm < 7) step = 5 * pow;
|
|
51
|
+
else step = 10 * pow;
|
|
52
|
+
const start = Math.floor(min / step) * step;
|
|
53
|
+
const end = Math.ceil(max / step) * step;
|
|
54
|
+
const ticks: number[] = [];
|
|
55
|
+
for (let v = start; v <= end + step / 2; v += step) ticks.push(Number(v.toFixed(10)));
|
|
56
|
+
return ticks;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function scaleLinear(v: number, d0: number, d1: number, r0: number, r1: number) {
|
|
60
|
+
if (d1 === d0) return r0;
|
|
61
|
+
return r0 + ((v - d0) * (r1 - r0)) / (d1 - d0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function fmt(v: number): string {
|
|
65
|
+
if (Math.abs(v) >= 1000) return `${(v / 1000).toFixed(v % 1000 === 0 ? 0 : 1)}k`;
|
|
66
|
+
return Number.isInteger(v) ? String(v) : v.toFixed(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let hoveredIndex: number | null = $state(null);
|
|
70
|
+
|
|
71
|
+
const TONES = ["category1","category2","category3","category4","category5","category6","category7","category8"] as const;
|
|
72
|
+
|
|
73
|
+
const scales = $derived.by(() => {
|
|
74
|
+
const xs = data.map((d) => d.x);
|
|
75
|
+
const ys = data.map((d) => d.y);
|
|
76
|
+
const xTicks = niceTicks(Math.min(...xs), Math.max(...xs));
|
|
77
|
+
const yTicks = niceTicks(Math.min(...ys), Math.max(...ys));
|
|
78
|
+
const plotW = Math.max(width - MARGIN.left - MARGIN.right, 1);
|
|
79
|
+
const plotH = Math.max(height - MARGIN.top - MARGIN.bottom, 1);
|
|
80
|
+
return {
|
|
81
|
+
xTicks, yTicks,
|
|
82
|
+
xMin: xTicks[0], xMax: xTicks[xTicks.length - 1],
|
|
83
|
+
yMin: yTicks[0], yMax: yTicks[yTicks.length - 1],
|
|
84
|
+
plotW, plotH
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const points = $derived.by(() => {
|
|
89
|
+
const { xMin, xMax, yMin, yMax, plotW, plotH } = scales;
|
|
90
|
+
return data.map((d, i) => ({
|
|
91
|
+
cx: MARGIN.left + scaleLinear(d.x, xMin, xMax, 0, plotW),
|
|
92
|
+
cy: MARGIN.top + scaleLinear(d.y, yMin, yMax, plotH, 0),
|
|
93
|
+
datum: d,
|
|
94
|
+
tone: d.tone ?? TONES[i % TONES.length]
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const classes = () => ["st-scatterPlot", className].filter(Boolean).join(" ");
|
|
99
|
+
</script>
|
|
100
|
+
|
|
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>
|
|
143
|
+
|
|
144
|
+
{#if hoveredIndex !== null && points[hoveredIndex]}
|
|
145
|
+
{@const p = points[hoveredIndex]}
|
|
146
|
+
<div class="st-scatterPlot__tooltip" role="presentation" style="left: {(p.cx / width) * 100}%; top: {(p.cy / height) * 100}%">
|
|
147
|
+
{#if p.datum.label}<span class="st-scatterPlot__tooltipLabel">{p.datum.label}</span>{/if}
|
|
148
|
+
<span class="st-scatterPlot__tooltipValue">x {p.datum.x} · y {p.datum.y}</span>
|
|
149
|
+
</div>
|
|
150
|
+
{/if}
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<style>
|
|
154
|
+
.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; }
|
|
156
|
+
.st-scatterPlot__grid { stroke: var(--st-semantic-border-subtle); stroke-dasharray: 2 3; stroke-width: 1; opacity: 0.7; }
|
|
157
|
+
.st-scatterPlot__axis { stroke: var(--st-semantic-border-subtle); stroke-width: 1; }
|
|
158
|
+
.st-scatterPlot__tick { fill: var(--st-semantic-text-secondary); font-size: 0.6875rem; }
|
|
159
|
+
.st-scatterPlot__axisLabel { fill: var(--st-semantic-text-secondary); font-size: 0.75rem; font-weight: 600; }
|
|
160
|
+
.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; }
|
|
163
|
+
.st-scatterPlot__point--category1 { fill: var(--st-semantic-data-category1); }
|
|
164
|
+
.st-scatterPlot__point--category2 { fill: var(--st-semantic-data-category2); }
|
|
165
|
+
.st-scatterPlot__point--category3 { fill: var(--st-semantic-data-category3); }
|
|
166
|
+
.st-scatterPlot__point--category4 { fill: var(--st-semantic-data-category4); }
|
|
167
|
+
.st-scatterPlot__point--category5 { fill: var(--st-semantic-data-category5); }
|
|
168
|
+
.st-scatterPlot__point--category6 { fill: var(--st-semantic-data-category6); }
|
|
169
|
+
.st-scatterPlot__point--category7 { fill: var(--st-semantic-data-category7); }
|
|
170
|
+
.st-scatterPlot__point--category8 { fill: var(--st-semantic-data-category8); }
|
|
171
|
+
.st-scatterPlot__tooltip {
|
|
172
|
+
background: var(--st-semantic-surface-inverse); border-radius: var(--st-radius-sm, 0.25rem);
|
|
173
|
+
color: var(--st-semantic-text-inverse); display: inline-flex; flex-direction: column;
|
|
174
|
+
font-size: 0.75rem; gap: 0.125rem; line-height: 1.2; padding: 0.375rem 0.5rem;
|
|
175
|
+
pointer-events: none; position: absolute; transform: translate(-50%, calc(-100% - 8px)); white-space: nowrap; z-index: 1;
|
|
176
|
+
}
|
|
177
|
+
.st-scatterPlot__tooltipLabel { font-weight: 600; }
|
|
178
|
+
.st-scatterPlot__tooltipValue { opacity: 0.85; }
|
|
179
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type ScatterPlotTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
2
|
+
export type ScatterPlotDatum = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
label?: string;
|
|
6
|
+
tone?: ScatterPlotTone;
|
|
7
|
+
};
|
|
8
|
+
type ScatterPlotProps = {
|
|
9
|
+
data: ScatterPlotDatum[];
|
|
10
|
+
width?: number;
|
|
11
|
+
height?: number;
|
|
12
|
+
xLabel?: string;
|
|
13
|
+
yLabel?: string;
|
|
14
|
+
radius?: number;
|
|
15
|
+
label: string;
|
|
16
|
+
class?: string;
|
|
17
|
+
};
|
|
18
|
+
declare const ScatterPlot: import("svelte").Component<ScatterPlotProps, {}, "">;
|
|
19
|
+
type ScatterPlot = ReturnType<typeof ScatterPlot>;
|
|
20
|
+
export default ScatterPlot;
|
|
21
|
+
//# sourceMappingURL=ScatterPlot.svelte.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/Search.svelte
CHANGED
|
@@ -87,8 +87,12 @@
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
.st-field__label {
|
|
90
|
-
font-
|
|
91
|
-
font-
|
|
90
|
+
font-family: var(--st-component-field-labelTypography-family, inherit);
|
|
91
|
+
font-size: var(--st-component-field-labelTypography-size, 0.875rem);
|
|
92
|
+
font-weight: var(--st-component-field-labelTypography-weight, 600);
|
|
93
|
+
line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
|
|
94
|
+
letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
|
|
95
|
+
text-transform: var(--st-component-field-labelTypography-textTransform, none);
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
.st-field__help,
|
|
@@ -105,11 +109,15 @@
|
|
|
105
109
|
color: var(--st-component-field-errorText, var(--st-semantic-feedback-error));
|
|
106
110
|
}
|
|
107
111
|
|
|
112
|
+
/* Field box = resolved field anatomy (v1.2.0), same as Input. */
|
|
108
113
|
.st-search {
|
|
109
114
|
align-items: center;
|
|
110
|
-
background: var(--st-component-control-background, var(--st-semantic-surface-default));
|
|
111
|
-
border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
|
|
112
|
-
border-
|
|
115
|
+
background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
|
|
116
|
+
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)));
|
|
117
|
+
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)));
|
|
118
|
+
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)));
|
|
119
|
+
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)));
|
|
120
|
+
border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
|
|
113
121
|
color: var(--st-component-control-text, var(--st-semantic-text-primary));
|
|
114
122
|
display: inline-flex;
|
|
115
123
|
transition:
|
|
@@ -136,7 +144,10 @@
|
|
|
136
144
|
|
|
137
145
|
.st-search:focus-within {
|
|
138
146
|
border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
|
|
139
|
-
|
|
147
|
+
outline: var(--st-component-control-anatomy-focus-outline, none);
|
|
148
|
+
outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
|
|
149
|
+
box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
|
|
150
|
+
0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
|
|
140
151
|
}
|
|
141
152
|
|
|
142
153
|
.st-search:has([aria-invalid="true"]) {
|
package/dist/Select.svelte
CHANGED
|
@@ -63,8 +63,12 @@
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
.st-field__label {
|
|
66
|
-
font-
|
|
67
|
-
font-
|
|
66
|
+
font-family: var(--st-component-field-labelTypography-family, inherit);
|
|
67
|
+
font-size: var(--st-component-field-labelTypography-size, 0.875rem);
|
|
68
|
+
font-weight: var(--st-component-field-labelTypography-weight, 600);
|
|
69
|
+
line-height: var(--st-component-field-labelTypography-lineHeight, 1.4);
|
|
70
|
+
letter-spacing: var(--st-component-field-labelTypography-letterSpacing, 0);
|
|
71
|
+
text-transform: var(--st-component-field-labelTypography-textTransform, none);
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
.st-field__help,
|
|
@@ -81,12 +85,19 @@
|
|
|
81
85
|
color: var(--st-component-field-errorText, var(--st-semantic-feedback-error));
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
/* Field box = resolved field anatomy (v1.2.0), same as Input. */
|
|
84
89
|
.st-select {
|
|
85
|
-
background: var(--st-component-control-background, var(--st-semantic-surface-default));
|
|
86
|
-
border: 1px solid var(--st-component-control-border, var(--st-semantic-border-subtle));
|
|
87
|
-
border-
|
|
90
|
+
background: var(--st-component-control-anatomy-field-fillBg, var(--st-component-control-background, var(--st-semantic-surface-default)));
|
|
91
|
+
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)));
|
|
92
|
+
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)));
|
|
93
|
+
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)));
|
|
94
|
+
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)));
|
|
95
|
+
border-radius: var(--st-component-control-anatomy-shape-radius, 0.375rem);
|
|
88
96
|
color: var(--st-component-control-text, var(--st-semantic-text-primary));
|
|
89
|
-
font: inherit;
|
|
97
|
+
font-family: var(--st-component-control-anatomy-typography-family, inherit);
|
|
98
|
+
font-size: var(--st-component-control-anatomy-typography-size, inherit);
|
|
99
|
+
font-weight: var(--st-component-control-anatomy-typography-weight, 400);
|
|
100
|
+
line-height: var(--st-component-control-anatomy-typography-lineHeight, 1.5);
|
|
90
101
|
min-width: 0;
|
|
91
102
|
padding: 0 2rem 0 0.75rem;
|
|
92
103
|
width: 100%;
|
|
@@ -106,8 +117,10 @@
|
|
|
106
117
|
|
|
107
118
|
.st-select:focus-visible {
|
|
108
119
|
border-color: var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
|
|
109
|
-
|
|
110
|
-
outline:
|
|
120
|
+
outline: var(--st-component-control-anatomy-focus-outline, none);
|
|
121
|
+
outline-offset: var(--st-component-control-anatomy-focus-offset, 0);
|
|
122
|
+
box-shadow: var(--st-component-control-anatomy-focus-boxShadow,
|
|
123
|
+
0 0 0 2px var(--st-component-control-focusRing, var(--st-semantic-border-interactive)));
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
.st-select[aria-invalid="true"] {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAnchorAttributes } from "svelte/elements";
|
|
4
|
+
|
|
5
|
+
type SkipLinkProps = Omit<HTMLAnchorAttributes, "class" | "href"> & {
|
|
6
|
+
/** Cible de l'ancre (id du contenu principal). */
|
|
7
|
+
href?: string;
|
|
8
|
+
class?: string;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
href = "#main-content",
|
|
14
|
+
class: className,
|
|
15
|
+
children,
|
|
16
|
+
...rest
|
|
17
|
+
}: SkipLinkProps = $props();
|
|
18
|
+
|
|
19
|
+
const classes = () => ["st-skipLink", className].filter(Boolean).join(" ");
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<a {...rest} class={classes()} {href}>
|
|
23
|
+
{#if children}{@render children()}{:else}Aller au contenu principal{/if}
|
|
24
|
+
</a>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
/* Lien d'évitement : hors écran jusqu'au focus clavier (a11y, DSFR/WCAG). */
|
|
28
|
+
.st-skipLink {
|
|
29
|
+
background: var(--st-semantic-action-primary);
|
|
30
|
+
border-radius: var(--st-radius-md, 0.375rem);
|
|
31
|
+
color: var(--st-semantic-action-primaryText, #fff);
|
|
32
|
+
font-size: 0.875rem;
|
|
33
|
+
font-weight: 600;
|
|
34
|
+
left: var(--st-spacing-2, 0.5rem);
|
|
35
|
+
padding: var(--st-spacing-2, 0.5rem) var(--st-spacing-4, 1rem);
|
|
36
|
+
position: fixed;
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
top: var(--st-spacing-2, 0.5rem);
|
|
39
|
+
transform: translateY(-150%);
|
|
40
|
+
transition: transform var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
|
|
41
|
+
z-index: var(--st-zindex-modal, 100);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.st-skipLink:focus,
|
|
45
|
+
.st-skipLink:focus-visible {
|
|
46
|
+
outline: 2px solid var(--st-semantic-border-interactive);
|
|
47
|
+
outline-offset: 2px;
|
|
48
|
+
transform: translateY(0);
|
|
49
|
+
}
|
|
50
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAnchorAttributes } from "svelte/elements";
|
|
3
|
+
type SkipLinkProps = Omit<HTMLAnchorAttributes, "class" | "href"> & {
|
|
4
|
+
/** Cible de l'ancre (id du contenu principal). */
|
|
5
|
+
href?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
};
|
|
9
|
+
declare const SkipLink: import("svelte").Component<SkipLinkProps, {}, "">;
|
|
10
|
+
type SkipLink = ReturnType<typeof SkipLink>;
|
|
11
|
+
export default SkipLink;
|
|
12
|
+
//# sourceMappingURL=SkipLink.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkipLink.svelte.d.ts","sourceRoot":"","sources":["../src/lib/SkipLink.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,KAAK,aAAa,GAAG,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,MAAM,CAAC,GAAG;IAClE,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAwBJ,QAAA,MAAM,QAAQ,mDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|