@sentropic/design-system-react 0.10.0 → 0.12.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/ComboChart.d.ts +27 -0
- package/dist/ComboChart.d.ts.map +1 -0
- package/dist/ComboChart.js +189 -0
- package/dist/ComboChart.js.map +1 -0
- package/dist/FunnelChart.d.ts +20 -0
- package/dist/FunnelChart.d.ts.map +1 -0
- package/dist/FunnelChart.js +117 -0
- package/dist/FunnelChart.js.map +1 -0
- package/dist/GaugeChart.d.ts +35 -0
- package/dist/GaugeChart.d.ts.map +1 -0
- package/dist/GaugeChart.js +115 -0
- package/dist/GaugeChart.js.map +1 -0
- package/dist/KpiCard.d.ts +45 -0
- package/dist/KpiCard.d.ts.map +1 -0
- package/dist/KpiCard.js +67 -0
- package/dist/KpiCard.js.map +1 -0
- package/dist/SelectableList.d.ts +41 -0
- package/dist/SelectableList.d.ts.map +1 -0
- package/dist/SelectableList.js +156 -0
- package/dist/SelectableList.js.map +1 -0
- package/dist/SelectableRow.d.ts +107 -0
- package/dist/SelectableRow.d.ts.map +1 -0
- package/dist/SelectableRow.js +93 -0
- package/dist/SelectableRow.js.map +1 -0
- package/dist/TreemapChart.d.ts +25 -0
- package/dist/TreemapChart.d.ts.map +1 -0
- package/dist/TreemapChart.js +179 -0
- package/dist/TreemapChart.js.map +1 -0
- package/dist/WaterfallChart.d.ts +18 -0
- package/dist/WaterfallChart.d.ts.map +1 -0
- package/dist/WaterfallChart.js +133 -0
- package/dist/WaterfallChart.js.map +1 -0
- package/dist/catalog.d.ts +33 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +176 -5
- package/dist/catalog.js.map +1 -1
- package/dist/chartContrast.d.ts +6 -0
- package/dist/chartContrast.d.ts.map +1 -0
- package/dist/chartContrast.js +59 -0
- package/dist/chartContrast.js.map +1 -0
- package/dist/chartScale.d.ts +6 -0
- package/dist/chartScale.d.ts.map +1 -1
- package/dist/chartScale.js +41 -0
- package/dist/chartScale.js.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/styles.css +869 -2
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type KpiCardSize = "sm" | "md" | "lg";
|
|
3
|
+
export type KpiCardTrend = "up" | "down" | "flat";
|
|
4
|
+
export type KpiCardFormat = "number" | "currency" | "percent";
|
|
5
|
+
export type KpiCardDeltaFormat = "percent" | "absolute";
|
|
6
|
+
export type KpiCardTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
7
|
+
export type KpiCardProps = Omit<React.HTMLAttributes<HTMLElement>, "className"> & {
|
|
8
|
+
/**
|
|
9
|
+
* Valeur principale affichée en grand. Le formatage `format` ne s'applique
|
|
10
|
+
* qu'aux `number` (un `string` est rendu verbatim).
|
|
11
|
+
*
|
|
12
|
+
* Pour `format="percent"`, `Intl.NumberFormat` multiplie par 100 : passez une
|
|
13
|
+
* **fraction** (0–1). Ex. `0.42` → « 42 % », et non `42` (qui donnerait « 4 200 % »).
|
|
14
|
+
*/
|
|
15
|
+
value: number | string;
|
|
16
|
+
/** Étiquette de l'indicateur (ex. « Revenu mensuel »). */
|
|
17
|
+
label: string;
|
|
18
|
+
/**
|
|
19
|
+
* Variation par rapport à la période précédente.
|
|
20
|
+
*
|
|
21
|
+
* En `deltaFormat="percent"` (défaut), la valeur est multipliée par 100 :
|
|
22
|
+
* passez une **fraction** (ex. `0.12` → « +12 % »).
|
|
23
|
+
*/
|
|
24
|
+
delta?: number;
|
|
25
|
+
/** Comment exprimer le delta : en pourcentage ou en valeur absolue. */
|
|
26
|
+
deltaFormat?: KpiCardDeltaFormat;
|
|
27
|
+
/** Tendance ; déduite du signe du delta si absente. */
|
|
28
|
+
trend?: KpiCardTrend;
|
|
29
|
+
/** Formatage de la valeur principale via Intl.NumberFormat. */
|
|
30
|
+
format?: KpiCardFormat;
|
|
31
|
+
/** Unité suffixée à la valeur (ex. « ms », « €/mois »). */
|
|
32
|
+
unit?: string;
|
|
33
|
+
/** Code devise ISO 4217 pour format="currency" (défaut EUR). */
|
|
34
|
+
currency?: string;
|
|
35
|
+
/** Locale BCP 47 pour le formatage des nombres (défaut undefined = locale du runtime). */
|
|
36
|
+
locale?: string;
|
|
37
|
+
/** Mini-graphique de tendance optionnel. */
|
|
38
|
+
sparkline?: number[];
|
|
39
|
+
size?: KpiCardSize;
|
|
40
|
+
/** Couleur catégorielle pour l'accent (pastille discrète près de l'étiquette). */
|
|
41
|
+
tone?: KpiCardTone;
|
|
42
|
+
className?: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function KpiCard({ value, label, delta, deltaFormat, trend, format, unit, currency, locale, sparkline, size, tone, className, ...rest }: KpiCardProps): import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
//# sourceMappingURL=KpiCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KpiCard.d.ts","sourceRoot":"","sources":["../src/KpiCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7C,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,CAAC;AACxD,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,GAAG;IAChF;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,uDAAuD;IACvD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,kFAAkF;IAClF,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,KAAK,EACL,KAAK,EACL,WAAuB,EACvB,KAAK,EACL,MAAiB,EACjB,IAAI,EACJ,QAAgB,EAChB,MAAM,EACN,SAAS,EACT,IAAW,EACX,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACR,EAAE,YAAY,2CAgId"}
|
package/dist/KpiCard.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { classNames } from "./classNames.js";
|
|
4
|
+
import { Sparkline } from "./Sparkline.js";
|
|
5
|
+
export function KpiCard({ value, label, delta, deltaFormat = "percent", trend, format = "number", unit, currency = "EUR", locale, sparkline, size = "md", tone, className, ...rest }) {
|
|
6
|
+
const resolvedTrend = trend ?? (delta == null ? undefined : delta > 0 ? "up" : delta < 0 ? "down" : "flat");
|
|
7
|
+
const formattedValue = (() => {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
// Intl rend "NaN"/"∞" pour les valeurs non finies : préférer un tiret cadratin.
|
|
12
|
+
if (!Number.isFinite(value)) {
|
|
13
|
+
return "—";
|
|
14
|
+
}
|
|
15
|
+
if (format === "currency") {
|
|
16
|
+
try {
|
|
17
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(value);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Code devise invalide → repli sur un nombre brut plutôt qu'une exception.
|
|
21
|
+
return new Intl.NumberFormat(locale).format(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (format === "percent") {
|
|
25
|
+
return new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 2 }).format(value);
|
|
26
|
+
}
|
|
27
|
+
return new Intl.NumberFormat(locale).format(value);
|
|
28
|
+
})();
|
|
29
|
+
const formattedDelta = (() => {
|
|
30
|
+
if (delta == null || !Number.isFinite(delta)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const sign = delta > 0 ? "+" : "";
|
|
34
|
+
if (deltaFormat === "percent") {
|
|
35
|
+
const pct = new Intl.NumberFormat(locale, {
|
|
36
|
+
style: "percent",
|
|
37
|
+
maximumFractionDigits: 1,
|
|
38
|
+
}).format(delta);
|
|
39
|
+
return `${sign}${pct}`;
|
|
40
|
+
}
|
|
41
|
+
return `${sign}${new Intl.NumberFormat(locale).format(delta)}`;
|
|
42
|
+
})();
|
|
43
|
+
/** Le sparkline emprunte la couleur sémantique de la tendance. */
|
|
44
|
+
const sparklineTone = resolvedTrend === "up" ? "success" : resolvedTrend === "down" ? "error" : "neutral";
|
|
45
|
+
const arrow = resolvedTrend === "up"
|
|
46
|
+
? "M3 8.5 7 4l4 4.5"
|
|
47
|
+
: resolvedTrend === "down"
|
|
48
|
+
? "M3 5.5 7 10l4-4.5"
|
|
49
|
+
: "M3 7h8";
|
|
50
|
+
const trendLabel = resolvedTrend === "up"
|
|
51
|
+
? "en hausse"
|
|
52
|
+
: resolvedTrend === "down"
|
|
53
|
+
? "en baisse"
|
|
54
|
+
: resolvedTrend === "flat"
|
|
55
|
+
? "stable"
|
|
56
|
+
: undefined;
|
|
57
|
+
const ariaLabel = [
|
|
58
|
+
label,
|
|
59
|
+
formattedValue,
|
|
60
|
+
unit,
|
|
61
|
+
formattedDelta && `${formattedDelta} ${trendLabel ?? ""}`.trim(),
|
|
62
|
+
]
|
|
63
|
+
.filter(Boolean)
|
|
64
|
+
.join(", ");
|
|
65
|
+
return (_jsxs("article", { ...rest, className: classNames("st-kpiCard", `st-kpiCard--${size}`, tone && `st-kpiCard--${tone}`, tone && "st-kpiCard--toned", className), role: "group", "aria-label": ariaLabel, children: [_jsxs("p", { className: "st-kpiCard__label", children: [tone ? _jsx("span", { className: "st-kpiCard__swatch", "aria-hidden": "true" }) : null, label] }), _jsxs("p", { className: "st-kpiCard__value", children: [_jsx("span", { className: "st-kpiCard__number", children: formattedValue }), unit ? _jsx("span", { className: "st-kpiCard__unit", children: unit }) : null] }), formattedDelta || sparkline ? (_jsxs("div", { className: "st-kpiCard__footer", children: [formattedDelta ? (_jsxs("span", { className: `st-kpiCard__delta st-kpiCard__delta--${resolvedTrend ?? "flat"}`, "aria-hidden": "true", children: [_jsx("svg", { className: "st-kpiCard__arrow", width: "14", height: "14", viewBox: "0 0 14 14", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: arrow, fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) }), _jsx("span", { className: "st-kpiCard__deltaValue", children: formattedDelta })] })) : null, sparkline && sparkline.length > 0 ? (_jsx(Sparkline, { className: "st-kpiCard__sparkline", data: sparkline, tone: sparklineTone, area: true })) : null] })) : null] }));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=KpiCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KpiCard.js","sourceRoot":"","sources":["../src/KpiCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type SelectableListProps = Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> & {
|
|
3
|
+
/** Accessible name for the listbox (required for SR users). */
|
|
4
|
+
label?: string;
|
|
5
|
+
/** References the id of an external visible label (alternative to `label`). */
|
|
6
|
+
labelledby?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Allow more than one selected row. Adds aria-multiselectable and toggles
|
|
9
|
+
* each row independently. Defaults to false (single-select).
|
|
10
|
+
*/
|
|
11
|
+
multiple?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Selected value(s). Controlled when provided. For single-select pass a
|
|
14
|
+
* string (or null); for multiple pass a string[]. When omitted the list is
|
|
15
|
+
* uncontrolled and keeps its own internal selection.
|
|
16
|
+
*/
|
|
17
|
+
value?: string | string[] | null;
|
|
18
|
+
/**
|
|
19
|
+
* Fired with the new selection on every change. Receives a string|null for
|
|
20
|
+
* single-select and a string[] for multiple. Required for the controlled
|
|
21
|
+
* pattern; also fires for uncontrolled lists.
|
|
22
|
+
*/
|
|
23
|
+
onChange?: (value: string | string[] | null) => void;
|
|
24
|
+
children?: React.ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Accessible listbox that owns selection + a roving tabindex for its
|
|
29
|
+
* {@link SelectableRow} children. Arrow / Home / End move focus (roving),
|
|
30
|
+
* Space / Enter / click toggle the focused row. Single-select by default;
|
|
31
|
+
* `multiple` toggles rows independently. Controlled via `value`/`onChange`,
|
|
32
|
+
* otherwise it keeps its own internal selection. Pilots each child row through
|
|
33
|
+
* a STABLE React context (so a row's registration effect never re-runs in a
|
|
34
|
+
* loop) plus a `version` counter the rows read to recompute role / tabindex /
|
|
35
|
+
* aria-selected on every selection / focus / registry change.
|
|
36
|
+
*/
|
|
37
|
+
export declare function SelectableList({ label, labelledby, multiple, value, onChange, children, className, ...rest }: SelectableListProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare namespace SelectableList {
|
|
39
|
+
var displayName: string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=SelectableList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectableList.d.ts","sourceRoot":"","sources":["../src/SelectableList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX,GAAG;IACF,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkBF;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,EACV,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,mBAAmB,2CA4IrB;yBArJe,cAAc"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { classNames } from "./classNames.js";
|
|
4
|
+
import { SelectableListContext, SelectableListVersionContext, } from "./SelectableRow.js";
|
|
5
|
+
function toSet(v) {
|
|
6
|
+
if (v == null)
|
|
7
|
+
return new Set();
|
|
8
|
+
return new Set(Array.isArray(v) ? v : [v]);
|
|
9
|
+
}
|
|
10
|
+
function sortByDom(list) {
|
|
11
|
+
return [...list].sort((a, b) => {
|
|
12
|
+
const pos = a.el.compareDocumentPosition(b.el);
|
|
13
|
+
if (pos & Node.DOCUMENT_POSITION_FOLLOWING)
|
|
14
|
+
return -1;
|
|
15
|
+
if (pos & Node.DOCUMENT_POSITION_PRECEDING)
|
|
16
|
+
return 1;
|
|
17
|
+
return 0;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Accessible listbox that owns selection + a roving tabindex for its
|
|
22
|
+
* {@link SelectableRow} children. Arrow / Home / End move focus (roving),
|
|
23
|
+
* Space / Enter / click toggle the focused row. Single-select by default;
|
|
24
|
+
* `multiple` toggles rows independently. Controlled via `value`/`onChange`,
|
|
25
|
+
* otherwise it keeps its own internal selection. Pilots each child row through
|
|
26
|
+
* a STABLE React context (so a row's registration effect never re-runs in a
|
|
27
|
+
* loop) plus a `version` counter the rows read to recompute role / tabindex /
|
|
28
|
+
* aria-selected on every selection / focus / registry change.
|
|
29
|
+
*/
|
|
30
|
+
export function SelectableList({ label, labelledby, multiple = false, value, onChange, children, className, ...rest }) {
|
|
31
|
+
// Controlled when the consumer passes `value` (including null).
|
|
32
|
+
const controlled = value !== undefined;
|
|
33
|
+
// --- Mutable state lives in refs (read by the STABLE context methods); a
|
|
34
|
+
// `version` counter drives re-renders so rows recompute their derived
|
|
35
|
+
// attributes. This keeps the context object identity-stable, which is what
|
|
36
|
+
// prevents the rows' registration effect from re-running in a loop. ------
|
|
37
|
+
const entriesRef = React.useRef([]);
|
|
38
|
+
const tabStopRef = React.useRef(null);
|
|
39
|
+
const internalRef = React.useRef(new Set());
|
|
40
|
+
// `version` is provided to rows so they re-render on every selection / focus /
|
|
41
|
+
// registry change (the actions context stays identity-stable).
|
|
42
|
+
const [version, force] = React.useReducer((n) => n + 1, 0);
|
|
43
|
+
const bump = React.useCallback(() => force(), []);
|
|
44
|
+
// Latest controlled inputs, read by stable callbacks without stale closures.
|
|
45
|
+
const controlledRef = React.useRef(controlled);
|
|
46
|
+
controlledRef.current = controlled;
|
|
47
|
+
const valueRef = React.useRef(value);
|
|
48
|
+
valueRef.current = value;
|
|
49
|
+
const multipleRef = React.useRef(multiple);
|
|
50
|
+
multipleRef.current = multiple;
|
|
51
|
+
const onChangeRef = React.useRef(onChange);
|
|
52
|
+
onChangeRef.current = onChange;
|
|
53
|
+
function currentSelection() {
|
|
54
|
+
return controlledRef.current ? toSet(valueRef.current) : internalRef.current;
|
|
55
|
+
}
|
|
56
|
+
// Default roving stop = first registered (DOM-ordered) row when none focused.
|
|
57
|
+
function effectiveTabStop() {
|
|
58
|
+
return tabStopRef.current ?? entriesRef.current[0]?.el ?? null;
|
|
59
|
+
}
|
|
60
|
+
function valueOf(el) {
|
|
61
|
+
return entriesRef.current.find((e) => e.el === el)?.value;
|
|
62
|
+
}
|
|
63
|
+
// Stable context methods — created ONCE so the context object never changes
|
|
64
|
+
// identity. They read mutable state from refs and bump the version to re-render.
|
|
65
|
+
const context = React.useMemo(() => {
|
|
66
|
+
const register = (el, rowValue) => {
|
|
67
|
+
entriesRef.current = sortByDom([
|
|
68
|
+
...entriesRef.current.filter((e) => e.el !== el),
|
|
69
|
+
{ el, value: rowValue },
|
|
70
|
+
]);
|
|
71
|
+
bump();
|
|
72
|
+
return () => {
|
|
73
|
+
entriesRef.current = entriesRef.current.filter((e) => e.el !== el);
|
|
74
|
+
if (tabStopRef.current === el)
|
|
75
|
+
tabStopRef.current = null;
|
|
76
|
+
bump();
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const isSelected = (el) => {
|
|
80
|
+
const v = valueOf(el);
|
|
81
|
+
return v !== undefined && currentSelection().has(v);
|
|
82
|
+
};
|
|
83
|
+
const isTabStop = (el) => el === effectiveTabStop();
|
|
84
|
+
const emit = (next) => {
|
|
85
|
+
if (!controlledRef.current)
|
|
86
|
+
internalRef.current = next;
|
|
87
|
+
if (multipleRef.current)
|
|
88
|
+
onChangeRef.current?.([...next]);
|
|
89
|
+
else
|
|
90
|
+
onChangeRef.current?.(next.size ? [...next][0] : null);
|
|
91
|
+
bump();
|
|
92
|
+
};
|
|
93
|
+
const activate = (el) => {
|
|
94
|
+
const v = valueOf(el);
|
|
95
|
+
if (v === undefined)
|
|
96
|
+
return;
|
|
97
|
+
const current = currentSelection();
|
|
98
|
+
let next;
|
|
99
|
+
if (multipleRef.current) {
|
|
100
|
+
next = new Set(current);
|
|
101
|
+
if (next.has(v))
|
|
102
|
+
next.delete(v);
|
|
103
|
+
else
|
|
104
|
+
next.add(v);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Single-select toggles off when re-activating the selected row.
|
|
108
|
+
next = current.has(v) && current.size === 1 ? new Set() : new Set([v]);
|
|
109
|
+
}
|
|
110
|
+
emit(next);
|
|
111
|
+
};
|
|
112
|
+
const focusRow = (el) => {
|
|
113
|
+
tabStopRef.current = el;
|
|
114
|
+
bump();
|
|
115
|
+
};
|
|
116
|
+
const navigate = (el, key) => {
|
|
117
|
+
const list = entriesRef.current;
|
|
118
|
+
if (list.length === 0)
|
|
119
|
+
return;
|
|
120
|
+
const idx = list.findIndex((e) => e.el === el);
|
|
121
|
+
if (idx === -1)
|
|
122
|
+
return;
|
|
123
|
+
let targetIdx = idx;
|
|
124
|
+
if (key === "ArrowDown" || key === "ArrowRight")
|
|
125
|
+
targetIdx = idx + 1;
|
|
126
|
+
else if (key === "ArrowUp" || key === "ArrowLeft")
|
|
127
|
+
targetIdx = idx - 1;
|
|
128
|
+
else if (key === "Home")
|
|
129
|
+
targetIdx = 0;
|
|
130
|
+
else if (key === "End")
|
|
131
|
+
targetIdx = list.length - 1;
|
|
132
|
+
// Clamp (no wrap) so Home/End and arrows stay within bounds.
|
|
133
|
+
targetIdx = Math.max(0, Math.min(list.length - 1, targetIdx));
|
|
134
|
+
const target = list[targetIdx]?.el;
|
|
135
|
+
if (target) {
|
|
136
|
+
tabStopRef.current = target;
|
|
137
|
+
target.focus();
|
|
138
|
+
bump();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
managed: true,
|
|
143
|
+
itemRole: "option",
|
|
144
|
+
register,
|
|
145
|
+
isSelected,
|
|
146
|
+
isTabStop,
|
|
147
|
+
activate,
|
|
148
|
+
focusRow,
|
|
149
|
+
navigate,
|
|
150
|
+
};
|
|
151
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
152
|
+
}, [bump]);
|
|
153
|
+
return (_jsx("div", { ...rest, className: classNames("st-selectableList", className), role: "listbox", "aria-label": labelledby ? undefined : label, "aria-labelledby": labelledby, "aria-multiselectable": multiple ? "true" : undefined, children: _jsx(SelectableListContext.Provider, { value: context, children: _jsx(SelectableListVersionContext.Provider, { value: version, children: children }) }) }));
|
|
154
|
+
}
|
|
155
|
+
SelectableList.displayName = "SelectableList";
|
|
156
|
+
//# sourceMappingURL=SelectableList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectableList.js","sourceRoot":"","sources":["../src/SelectableList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Shared context between {@link SelectableList} and its {@link SelectableRow}
|
|
4
|
+
* children. The list owns selection + the roving tabindex and exposes the
|
|
5
|
+
* getters/callbacks the rows read to derive their own `role` / `tabindex` /
|
|
6
|
+
* `aria-selected`. When a row is used STANDALONE (no provider) the context is
|
|
7
|
+
* null and the row falls back to its own `role` / `tabindex` / selection state.
|
|
8
|
+
*/
|
|
9
|
+
export type SelectableListContextValue = {
|
|
10
|
+
/** True when the list manages selection/roving for its rows. */
|
|
11
|
+
readonly managed: true;
|
|
12
|
+
/** listbox role for the wrapper → rows are "option". */
|
|
13
|
+
readonly itemRole: "option";
|
|
14
|
+
/** Register a row element; returns an unregister callback. */
|
|
15
|
+
register: (el: HTMLElement, value: string | undefined) => () => void;
|
|
16
|
+
/** Is the row with this element currently selected? */
|
|
17
|
+
isSelected: (el: HTMLElement) => boolean;
|
|
18
|
+
/** Should the row with this element be the roving-tabindex stop (tabindex 0)? */
|
|
19
|
+
isTabStop: (el: HTMLElement) => boolean;
|
|
20
|
+
/** Row was activated (click / Space / Enter). The list toggles selection. */
|
|
21
|
+
activate: (el: HTMLElement) => void;
|
|
22
|
+
/** Row received focus → becomes the roving tab stop. */
|
|
23
|
+
focusRow: (el: HTMLElement) => void;
|
|
24
|
+
/** Arrow / Home / End navigation from a row. */
|
|
25
|
+
navigate: (el: HTMLElement, key: string) => void;
|
|
26
|
+
};
|
|
27
|
+
export declare const SelectableListContext: React.Context<SelectableListContextValue | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Changing version context, bumped by the list on every selection / focus /
|
|
30
|
+
* registry change. Rows read it during render so they re-render and recompute
|
|
31
|
+
* their derived attributes. Kept SEPARATE from {@link SelectableListContext} so
|
|
32
|
+
* the actions context stays identity-stable (a row's registration effect must
|
|
33
|
+
* not re-run — and re-register — in a loop).
|
|
34
|
+
*/
|
|
35
|
+
export declare const SelectableListVersionContext: React.Context<number>;
|
|
36
|
+
export type SelectableRowProps = Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect"> & {
|
|
37
|
+
/**
|
|
38
|
+
* Selected state. Honoured when the row is used STANDALONE; inside a
|
|
39
|
+
* {@link SelectableList} the list is the source of truth and drives the
|
|
40
|
+
* selected styling, so this prop is ignored for managed rows.
|
|
41
|
+
*/
|
|
42
|
+
selected?: boolean;
|
|
43
|
+
/** Notified on every toggle with the new selected state (standalone rows). */
|
|
44
|
+
onSelect?: (selected: boolean) => void;
|
|
45
|
+
/** Non-interactive when true. */
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
/** Stable value, surfaced as `data-value` and used by the list for `value`. */
|
|
48
|
+
value?: string;
|
|
49
|
+
/**
|
|
50
|
+
* ARIA role for the standalone row. Defaults to "option" so a lone row still
|
|
51
|
+
* reads as a selectable item. Inside a list the role is forced to "option".
|
|
52
|
+
*/
|
|
53
|
+
role?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Opt-in left accent bar on the selected state. Off by default so the
|
|
56
|
+
* selected item is a calm tinted surface + accented text (two signals only).
|
|
57
|
+
*/
|
|
58
|
+
accentBar?: boolean;
|
|
59
|
+
/** Leading content (icon / avatar). */
|
|
60
|
+
leading?: React.ReactNode;
|
|
61
|
+
/** Trailing content (meta / icon). */
|
|
62
|
+
trailing?: React.ReactNode;
|
|
63
|
+
/** Main content. */
|
|
64
|
+
children?: React.ReactNode;
|
|
65
|
+
className?: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Compact, full-width selectable list/rail row. By DEFAULT the selected state
|
|
69
|
+
* is two calm signals — a tinted surface + accented text — deliberately NOT the
|
|
70
|
+
* off-theme "boudin box" it replaces, and NOT a reflow-causing font-weight
|
|
71
|
+
* bump. The fine left accent bar is OPT-IN via the `accentBar` prop. Focus is an
|
|
72
|
+
* EXTERNAL offset outline. role="option" + aria-selected, keyboard-activatable
|
|
73
|
+
* (Enter / Space), inert when disabled. Inside a {@link SelectableList} the list
|
|
74
|
+
* (via context) owns selection and the roving tabindex.
|
|
75
|
+
*/
|
|
76
|
+
export declare const SelectableRow: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect"> & {
|
|
77
|
+
/**
|
|
78
|
+
* Selected state. Honoured when the row is used STANDALONE; inside a
|
|
79
|
+
* {@link SelectableList} the list is the source of truth and drives the
|
|
80
|
+
* selected styling, so this prop is ignored for managed rows.
|
|
81
|
+
*/
|
|
82
|
+
selected?: boolean;
|
|
83
|
+
/** Notified on every toggle with the new selected state (standalone rows). */
|
|
84
|
+
onSelect?: (selected: boolean) => void;
|
|
85
|
+
/** Non-interactive when true. */
|
|
86
|
+
disabled?: boolean;
|
|
87
|
+
/** Stable value, surfaced as `data-value` and used by the list for `value`. */
|
|
88
|
+
value?: string;
|
|
89
|
+
/**
|
|
90
|
+
* ARIA role for the standalone row. Defaults to "option" so a lone row still
|
|
91
|
+
* reads as a selectable item. Inside a list the role is forced to "option".
|
|
92
|
+
*/
|
|
93
|
+
role?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Opt-in left accent bar on the selected state. Off by default so the
|
|
96
|
+
* selected item is a calm tinted surface + accented text (two signals only).
|
|
97
|
+
*/
|
|
98
|
+
accentBar?: boolean;
|
|
99
|
+
/** Leading content (icon / avatar). */
|
|
100
|
+
leading?: React.ReactNode;
|
|
101
|
+
/** Trailing content (meta / icon). */
|
|
102
|
+
trailing?: React.ReactNode;
|
|
103
|
+
/** Main content. */
|
|
104
|
+
children?: React.ReactNode;
|
|
105
|
+
className?: string;
|
|
106
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
107
|
+
//# sourceMappingURL=SelectableRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectableRow.d.ts","sourceRoot":"","sources":["../src/SelectableRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,IAAI,CAAC;IACrE,uDAAuD;IACvD,UAAU,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACzC,iFAAiF;IACjF,SAAS,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,wDAAwD;IACxD,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,gDAAgD;IAChD,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,qBAAqB,kDAC4B,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,uBAAyB,CAAC;AAEnE,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX,GAAG;IACF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,oBAAoB;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa;IAxCxB;;;;OAIG;eACQ,OAAO;IAClB,8EAA8E;eACnE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;IACtC,iCAAiC;eACtB,OAAO;IAClB,+EAA+E;YACvE,MAAM;IACd;;;OAGG;WACI,MAAM;IACb;;;OAGG;gBACS,OAAO;IACnB,uCAAuC;cAC7B,KAAK,CAAC,SAAS;IACzB,sCAAsC;eAC3B,KAAK,CAAC,SAAS;IAC1B,oBAAoB;eACT,KAAK,CAAC,SAAS;gBACd,MAAM;wCAmInB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { classNames } from "./classNames.js";
|
|
4
|
+
export const SelectableListContext = React.createContext(null);
|
|
5
|
+
/**
|
|
6
|
+
* Changing version context, bumped by the list on every selection / focus /
|
|
7
|
+
* registry change. Rows read it during render so they re-render and recompute
|
|
8
|
+
* their derived attributes. Kept SEPARATE from {@link SelectableListContext} so
|
|
9
|
+
* the actions context stays identity-stable (a row's registration effect must
|
|
10
|
+
* not re-run — and re-register — in a loop).
|
|
11
|
+
*/
|
|
12
|
+
export const SelectableListVersionContext = React.createContext(0);
|
|
13
|
+
/**
|
|
14
|
+
* Compact, full-width selectable list/rail row. By DEFAULT the selected state
|
|
15
|
+
* is two calm signals — a tinted surface + accented text — deliberately NOT the
|
|
16
|
+
* off-theme "boudin box" it replaces, and NOT a reflow-causing font-weight
|
|
17
|
+
* bump. The fine left accent bar is OPT-IN via the `accentBar` prop. Focus is an
|
|
18
|
+
* EXTERNAL offset outline. role="option" + aria-selected, keyboard-activatable
|
|
19
|
+
* (Enter / Space), inert when disabled. Inside a {@link SelectableList} the list
|
|
20
|
+
* (via context) owns selection and the roving tabindex.
|
|
21
|
+
*/
|
|
22
|
+
export const SelectableRow = React.forwardRef(({ selected = false, onSelect, disabled = false, value, role = "option", accentBar = false, leading, trailing, children, className, ...rest }, ref) => {
|
|
23
|
+
const list = React.useContext(SelectableListContext);
|
|
24
|
+
// Subscribe to the list's version so this row re-renders (and recomputes
|
|
25
|
+
// role / tabindex / aria-selected) on every selection / focus / registry
|
|
26
|
+
// change. The value itself is unused — reading the context is the subscription.
|
|
27
|
+
React.useContext(SelectableListVersionContext);
|
|
28
|
+
const innerRef = React.useRef(null);
|
|
29
|
+
// Merge the forwarded ref with our own so the list can register the element.
|
|
30
|
+
const setRef = React.useCallback((el) => {
|
|
31
|
+
innerRef.current = el;
|
|
32
|
+
if (typeof ref === "function")
|
|
33
|
+
ref(el);
|
|
34
|
+
else if (ref)
|
|
35
|
+
ref.current = el;
|
|
36
|
+
}, [ref]);
|
|
37
|
+
// Register with the parent list (if any) so it can order rows for arrow nav
|
|
38
|
+
// and compute the roving tab stop. Re-registers if value changes.
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
const el = innerRef.current;
|
|
41
|
+
if (!list || !el || disabled)
|
|
42
|
+
return;
|
|
43
|
+
return list.register(el, value);
|
|
44
|
+
}, [list, value, disabled]);
|
|
45
|
+
// Subscribe to list re-renders so managed rows recompute selected/tabstop.
|
|
46
|
+
// The list bumps this version on every selection / focus change.
|
|
47
|
+
const el = innerRef.current;
|
|
48
|
+
const isSelected = list && el ? list.isSelected(el) : selected;
|
|
49
|
+
const effectiveRole = list ? list.itemRole : role;
|
|
50
|
+
const tabIndex = disabled ? -1 : list && el ? (list.isTabStop(el) ? 0 : -1) : 0;
|
|
51
|
+
function activate() {
|
|
52
|
+
if (disabled)
|
|
53
|
+
return;
|
|
54
|
+
const node = innerRef.current;
|
|
55
|
+
if (list && node) {
|
|
56
|
+
list.activate(node);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
onSelect?.(!selected);
|
|
60
|
+
}
|
|
61
|
+
function handleKeyDown(e) {
|
|
62
|
+
if (disabled)
|
|
63
|
+
return;
|
|
64
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
activate();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Roving navigation is owned by the list; forward the relevant keys.
|
|
70
|
+
const node = innerRef.current;
|
|
71
|
+
if (list &&
|
|
72
|
+
node &&
|
|
73
|
+
(e.key === "ArrowDown" ||
|
|
74
|
+
e.key === "ArrowUp" ||
|
|
75
|
+
e.key === "ArrowLeft" ||
|
|
76
|
+
e.key === "ArrowRight" ||
|
|
77
|
+
e.key === "Home" ||
|
|
78
|
+
e.key === "End")) {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
list.navigate(node, e.key);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function handleFocus() {
|
|
84
|
+
if (disabled)
|
|
85
|
+
return;
|
|
86
|
+
const node = innerRef.current;
|
|
87
|
+
if (list && node)
|
|
88
|
+
list.focusRow(node);
|
|
89
|
+
}
|
|
90
|
+
return (_jsxs("div", { ...rest, ref: setRef, className: classNames("st-selectableRow", isSelected && "st-selectableRow--selected", disabled && "st-selectableRow--disabled", accentBar && "st-selectableRow--accentBar", className), role: effectiveRole, "aria-selected": effectiveRole === "option" ? isSelected : undefined, "aria-disabled": disabled ? "true" : undefined, "data-value": value, tabIndex: tabIndex, onClick: activate, onKeyDown: handleKeyDown, onFocus: handleFocus, children: [leading != null ? (_jsx("span", { className: "st-selectableRow__leading", children: leading })) : null, _jsx("span", { className: "st-selectableRow__content", children: children }), trailing != null ? (_jsx("span", { className: "st-selectableRow__trailing", children: trailing })) : null] }));
|
|
91
|
+
});
|
|
92
|
+
SelectableRow.displayName = "SelectableRow";
|
|
93
|
+
//# sourceMappingURL=SelectableRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectableRow.js","sourceRoot":"","sources":["../src/SelectableRow.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type TreemapChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
3
|
+
export type TreemapChartDatum = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
tone?: TreemapChartTone;
|
|
7
|
+
children?: TreemapChartDatum[];
|
|
8
|
+
};
|
|
9
|
+
export type TreemapTiling = "squarified";
|
|
10
|
+
export type TreemapChartProps = Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
11
|
+
/** Données hiérarchiques : 1 ou 2 niveaux. Un nœud avec `children` est subdivisé. */
|
|
12
|
+
data: TreemapChartDatum[];
|
|
13
|
+
/** Algorithme de pavage (squarified uniquement pour l'instant). */
|
|
14
|
+
tiling?: TreemapTiling;
|
|
15
|
+
/** Affiche les labels dans les rectangles suffisamment grands. */
|
|
16
|
+
showLabels?: boolean;
|
|
17
|
+
/** Affiche une légende sous le graphique. */
|
|
18
|
+
legend?: boolean;
|
|
19
|
+
width?: number;
|
|
20
|
+
height?: number;
|
|
21
|
+
label: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function TreemapChart({ data, tiling, showLabels, legend, width, height, label, className, ...rest }: TreemapChartProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=TreemapChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreemapChart.d.ts","sourceRoot":"","sources":["../src/TreemapChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG;IACxF,qFAAqF;IACrF,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,mEAAmE;IACnE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAqHF,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAqB,EACrB,UAAiB,EACjB,MAAc,EACd,KAAW,EACX,MAAY,EACZ,KAAK,EACL,SAAS,EACT,GAAG,IAAI,EACR,EAAE,iBAAiB,2CAqLnB"}
|