@sia-ui/react-web 0.4.0 → 0.5.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/CHANGELOG.md +53 -0
- package/README.md +129 -74
- package/dist/index.cjs +472 -363
- package/dist/index.css +303 -233
- package/dist/index.d.cts +81 -9
- package/dist/index.d.ts +81 -9
- package/dist/index.js +473 -366
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -296,7 +296,8 @@ var Drawer = React.forwardRef(
|
|
|
296
296
|
isOpen,
|
|
297
297
|
phase: state,
|
|
298
298
|
open: doOpen,
|
|
299
|
-
close: doClose
|
|
299
|
+
close: doClose,
|
|
300
|
+
toggle
|
|
300
301
|
} = headless.useDisclosureState({
|
|
301
302
|
...open !== void 0 ? { open } : {},
|
|
302
303
|
defaultOpen,
|
|
@@ -305,15 +306,17 @@ var Drawer = React.forwardRef(
|
|
|
305
306
|
});
|
|
306
307
|
const drawerRef = React.useRef(null);
|
|
307
308
|
const zIndexRef = React.useRef(null);
|
|
309
|
+
const fermer = React.useRef(doClose);
|
|
310
|
+
fermer.current = doClose;
|
|
308
311
|
React.useImperativeHandle(
|
|
309
312
|
ref,
|
|
310
313
|
() => ({
|
|
311
314
|
open: doOpen,
|
|
312
315
|
close: doClose,
|
|
313
|
-
toggle
|
|
316
|
+
toggle,
|
|
314
317
|
isOpen: () => isOpen
|
|
315
318
|
}),
|
|
316
|
-
[isOpen,
|
|
319
|
+
[isOpen, doOpen, doClose, toggle]
|
|
317
320
|
);
|
|
318
321
|
React.useEffect(() => {
|
|
319
322
|
if (!isOpen) return;
|
|
@@ -330,7 +333,7 @@ var Drawer = React.forwardRef(
|
|
|
330
333
|
const onKeyDown = (e) => {
|
|
331
334
|
if (!closeOnEsc || e.key !== "Escape") return;
|
|
332
335
|
if (headless.overlayStack.isTop(zIndexRef.current)) {
|
|
333
|
-
|
|
336
|
+
fermer.current();
|
|
334
337
|
}
|
|
335
338
|
};
|
|
336
339
|
window.addEventListener("keydown", onKeyDown);
|
|
@@ -2040,9 +2043,9 @@ function Calendar({
|
|
|
2040
2043
|
if (mode === void 0) setPanelMode(next);
|
|
2041
2044
|
onPanelChange?.(monthIso(controlledMonth), next);
|
|
2042
2045
|
};
|
|
2043
|
-
const isDisabled = (date) => Boolean(
|
|
2046
|
+
const isDisabled = React.useCallback((date) => Boolean(
|
|
2044
2047
|
disabledDate?.(date) || validRange && (date < validRange[0] || date > validRange[1])
|
|
2045
|
-
);
|
|
2048
|
+
), [disabledDate, validRange]);
|
|
2046
2049
|
const selectDate = (date) => {
|
|
2047
2050
|
if (isDisabled(date)) return;
|
|
2048
2051
|
if (selectionMode === "range") {
|
|
@@ -2076,7 +2079,7 @@ function Calendar({
|
|
|
2076
2079
|
...rangeEdge ? { rangeEdge } : {}
|
|
2077
2080
|
};
|
|
2078
2081
|
});
|
|
2079
|
-
}, [year, monthIndex, firstDayOfWeek,
|
|
2082
|
+
}, [year, monthIndex, firstDayOfWeek, isDisabled, currentValue, currentRange.start, currentRange.end]);
|
|
2080
2083
|
const weekdays = Array.from({ length: 7 }, (_, index) => new Intl.DateTimeFormat(locale, { weekday: "short" }).format(new Date(2024, 0, 7 + firstDayOfWeek + index)));
|
|
2081
2084
|
const monthName = new Intl.DateTimeFormat(locale, { month: "long" }).format(controlledMonth);
|
|
2082
2085
|
const updateFromString = (next) => setMonth(parseMonth(next));
|
|
@@ -2723,6 +2726,8 @@ function Timer({ duration = 6e4, initialValue = 0, direction = "down", running =
|
|
|
2723
2726
|
const initial = direction === "down" ? duration : initialValue;
|
|
2724
2727
|
const [value, setValue] = React.useState(initial);
|
|
2725
2728
|
const finishCalled = React.useRef(false);
|
|
2729
|
+
const latest = React.useRef({ value, onChange, onFinish });
|
|
2730
|
+
latest.current = { value, onChange, onFinish };
|
|
2726
2731
|
React.useEffect(() => {
|
|
2727
2732
|
setValue(direction === "down" ? duration : initialValue);
|
|
2728
2733
|
finishCalled.current = false;
|
|
@@ -2730,15 +2735,15 @@ function Timer({ duration = 6e4, initialValue = 0, direction = "down", running =
|
|
|
2730
2735
|
React.useEffect(() => {
|
|
2731
2736
|
if (!running) return;
|
|
2732
2737
|
const startedAt = Date.now();
|
|
2733
|
-
const base = value;
|
|
2738
|
+
const base = latest.current.value;
|
|
2734
2739
|
const update = () => {
|
|
2735
2740
|
const elapsed = Date.now() - startedAt;
|
|
2736
2741
|
const next = direction === "down" ? Math.max(0, base - elapsed) : base + elapsed;
|
|
2737
2742
|
setValue(next);
|
|
2738
|
-
onChange?.(next);
|
|
2743
|
+
latest.current.onChange?.(next);
|
|
2739
2744
|
if (direction === "down" && next === 0 && !finishCalled.current) {
|
|
2740
2745
|
finishCalled.current = true;
|
|
2741
|
-
onFinish?.();
|
|
2746
|
+
latest.current.onFinish?.();
|
|
2742
2747
|
}
|
|
2743
2748
|
};
|
|
2744
2749
|
update();
|
|
@@ -2760,6 +2765,270 @@ function PageHeader({ title, description, eyebrow, actions, className }) {
|
|
|
2760
2765
|
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-page-header__actions", children: actions })
|
|
2761
2766
|
] });
|
|
2762
2767
|
}
|
|
2768
|
+
function optionsFromChildren(children) {
|
|
2769
|
+
return React.Children.toArray(children).flatMap((child) => {
|
|
2770
|
+
if (!React.isValidElement(child))
|
|
2771
|
+
return [];
|
|
2772
|
+
const value = child.props.value;
|
|
2773
|
+
if (value === void 0) return [];
|
|
2774
|
+
return [{
|
|
2775
|
+
value: String(value),
|
|
2776
|
+
label: child.props.children,
|
|
2777
|
+
...child.props.disabled !== void 0 ? { disabled: child.props.disabled } : {}
|
|
2778
|
+
}];
|
|
2779
|
+
});
|
|
2780
|
+
}
|
|
2781
|
+
function optionText(option) {
|
|
2782
|
+
return [option.label, option.description, ...option.keywords ?? []].map((value) => typeof value === "string" || typeof value === "number" ? String(value) : "").join(" ");
|
|
2783
|
+
}
|
|
2784
|
+
var Select = React.forwardRef(function Select2({
|
|
2785
|
+
id,
|
|
2786
|
+
name,
|
|
2787
|
+
options,
|
|
2788
|
+
children,
|
|
2789
|
+
value,
|
|
2790
|
+
defaultValue = "",
|
|
2791
|
+
onValueChange,
|
|
2792
|
+
placeholder = "S\xE9lectionner",
|
|
2793
|
+
searchable = false,
|
|
2794
|
+
searchPlaceholder = "Rechercher...",
|
|
2795
|
+
fetcher,
|
|
2796
|
+
debounce = 250,
|
|
2797
|
+
loadingText = "Chargement des options...",
|
|
2798
|
+
emptyText = "Aucun r\xE9sultat",
|
|
2799
|
+
errorText = "Impossible de charger les options",
|
|
2800
|
+
clearable = false,
|
|
2801
|
+
disabled = false,
|
|
2802
|
+
invalid = false,
|
|
2803
|
+
required = false,
|
|
2804
|
+
placement = "bottom-start",
|
|
2805
|
+
renderValue,
|
|
2806
|
+
variant = "default",
|
|
2807
|
+
className,
|
|
2808
|
+
"aria-invalid": ariaInvalid,
|
|
2809
|
+
"aria-required": ariaRequired,
|
|
2810
|
+
...ariaProps
|
|
2811
|
+
}, forwardedRef) {
|
|
2812
|
+
const generatedId = React.useId();
|
|
2813
|
+
const controlId = id ?? `sia-select-${generatedId.replace(/:/g, "")}`;
|
|
2814
|
+
const listboxId = `${controlId}-listbox`;
|
|
2815
|
+
const triggerRef = React.useRef(null);
|
|
2816
|
+
const searchRef = React.useRef(null);
|
|
2817
|
+
const staticOptions = React.useMemo(
|
|
2818
|
+
() => options ?? optionsFromChildren(children),
|
|
2819
|
+
[children, options]
|
|
2820
|
+
);
|
|
2821
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
2822
|
+
const [open, setOpen] = React.useState(false);
|
|
2823
|
+
const [query, setQuery] = React.useState("");
|
|
2824
|
+
const [remoteOptions, setRemoteOptions] = React.useState([]);
|
|
2825
|
+
const [selectedRemoteOption, setSelectedRemoteOption] = React.useState();
|
|
2826
|
+
const [loading, setLoading] = React.useState(false);
|
|
2827
|
+
const [loadError, setLoadError] = React.useState(false);
|
|
2828
|
+
const [activeIndex, setActiveIndex] = React.useState(-1);
|
|
2829
|
+
const currentValue = value ?? internalValue;
|
|
2830
|
+
const sourceOptions = fetcher ? remoteOptions : staticOptions;
|
|
2831
|
+
const visibleOptions = React.useMemo(() => {
|
|
2832
|
+
if (fetcher) return sourceOptions;
|
|
2833
|
+
const needle = query.trim();
|
|
2834
|
+
return needle ? sourceOptions.filter((option) => utils.looseIncludes(optionText(option), needle)) : sourceOptions;
|
|
2835
|
+
}, [fetcher, query, sourceOptions]);
|
|
2836
|
+
const selectedOption = [...staticOptions, ...remoteOptions].find(
|
|
2837
|
+
(option) => option.value === currentValue
|
|
2838
|
+
) ?? (selectedRemoteOption?.value === currentValue ? selectedRemoteOption : void 0);
|
|
2839
|
+
React.useEffect(() => {
|
|
2840
|
+
if (!open || !fetcher) return;
|
|
2841
|
+
const controller = new AbortController();
|
|
2842
|
+
const timeout = window.setTimeout(async () => {
|
|
2843
|
+
setLoading(true);
|
|
2844
|
+
setLoadError(false);
|
|
2845
|
+
try {
|
|
2846
|
+
const nextOptions = await fetcher(query, controller.signal);
|
|
2847
|
+
if (!controller.signal.aborted) setRemoteOptions(nextOptions);
|
|
2848
|
+
} catch {
|
|
2849
|
+
if (!controller.signal.aborted) setLoadError(true);
|
|
2850
|
+
} finally {
|
|
2851
|
+
if (!controller.signal.aborted) setLoading(false);
|
|
2852
|
+
}
|
|
2853
|
+
}, debounce);
|
|
2854
|
+
return () => {
|
|
2855
|
+
window.clearTimeout(timeout);
|
|
2856
|
+
controller.abort();
|
|
2857
|
+
};
|
|
2858
|
+
}, [debounce, fetcher, open, query]);
|
|
2859
|
+
React.useEffect(() => {
|
|
2860
|
+
if (!open) return;
|
|
2861
|
+
const selected = visibleOptions.findIndex((option) => option.value === currentValue);
|
|
2862
|
+
setActiveIndex(selected >= 0 ? selected : visibleOptions.findIndex((option) => !option.disabled));
|
|
2863
|
+
if (searchable || fetcher) window.setTimeout(() => searchRef.current?.focus(), 0);
|
|
2864
|
+
}, [currentValue, fetcher, open, searchable, visibleOptions]);
|
|
2865
|
+
const setTriggerRef = (node) => {
|
|
2866
|
+
triggerRef.current = node;
|
|
2867
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2868
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
2869
|
+
};
|
|
2870
|
+
const changeValue = (nextValue, option) => {
|
|
2871
|
+
if (value === void 0) setInternalValue(nextValue);
|
|
2872
|
+
onValueChange?.(nextValue, option);
|
|
2873
|
+
};
|
|
2874
|
+
const choose = (option) => {
|
|
2875
|
+
if (option.disabled) return;
|
|
2876
|
+
if (fetcher) setSelectedRemoteOption(option);
|
|
2877
|
+
changeValue(option.value, option);
|
|
2878
|
+
setOpen(false);
|
|
2879
|
+
setQuery("");
|
|
2880
|
+
window.setTimeout(() => triggerRef.current?.focus(), 0);
|
|
2881
|
+
};
|
|
2882
|
+
const moveActive = (direction) => {
|
|
2883
|
+
if (!visibleOptions.length) return;
|
|
2884
|
+
let next = activeIndex;
|
|
2885
|
+
for (let count = 0; count < visibleOptions.length; count += 1) {
|
|
2886
|
+
next = (next + direction + visibleOptions.length) % visibleOptions.length;
|
|
2887
|
+
if (!visibleOptions[next]?.disabled) break;
|
|
2888
|
+
}
|
|
2889
|
+
setActiveIndex(next);
|
|
2890
|
+
};
|
|
2891
|
+
const handleKeyDown = (event) => {
|
|
2892
|
+
if (["ArrowDown", "ArrowUp"].includes(event.key)) {
|
|
2893
|
+
event.preventDefault();
|
|
2894
|
+
if (!open) setOpen(true);
|
|
2895
|
+
else moveActive(event.key === "ArrowDown" ? 1 : -1);
|
|
2896
|
+
return;
|
|
2897
|
+
}
|
|
2898
|
+
if (event.key === "Home" && open) {
|
|
2899
|
+
event.preventDefault();
|
|
2900
|
+
setActiveIndex(visibleOptions.findIndex((option) => !option.disabled));
|
|
2901
|
+
} else if (event.key === "End" && open) {
|
|
2902
|
+
event.preventDefault();
|
|
2903
|
+
for (let index = visibleOptions.length - 1; index >= 0; index -= 1) {
|
|
2904
|
+
if (!visibleOptions[index]?.disabled) {
|
|
2905
|
+
setActiveIndex(index);
|
|
2906
|
+
break;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
} else if (event.key === "Enter" && open && activeIndex >= 0) {
|
|
2910
|
+
event.preventDefault();
|
|
2911
|
+
const active = visibleOptions[activeIndex];
|
|
2912
|
+
if (active) choose(active);
|
|
2913
|
+
} else if (event.key === "Escape" && open) {
|
|
2914
|
+
event.preventDefault();
|
|
2915
|
+
setOpen(false);
|
|
2916
|
+
triggerRef.current?.focus();
|
|
2917
|
+
} else if (!open && clearable && currentValue && ["Backspace", "Delete"].includes(event.key)) {
|
|
2918
|
+
event.preventDefault();
|
|
2919
|
+
changeValue("");
|
|
2920
|
+
}
|
|
2921
|
+
};
|
|
2922
|
+
const showSearch = searchable || Boolean(fetcher);
|
|
2923
|
+
const activeOption = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
|
|
2924
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2925
|
+
"div",
|
|
2926
|
+
{
|
|
2927
|
+
className: utils.cn(
|
|
2928
|
+
"sia-select",
|
|
2929
|
+
variant === "embedded" && "sia-select--embedded",
|
|
2930
|
+
disabled && "sia-select--disabled",
|
|
2931
|
+
className
|
|
2932
|
+
),
|
|
2933
|
+
children: [
|
|
2934
|
+
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: currentValue }),
|
|
2935
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2936
|
+
"button",
|
|
2937
|
+
{
|
|
2938
|
+
ref: setTriggerRef,
|
|
2939
|
+
id: controlId,
|
|
2940
|
+
type: "button",
|
|
2941
|
+
className: utils.cn("sia-select__trigger", invalid && "sia-select__trigger--invalid"),
|
|
2942
|
+
role: "combobox",
|
|
2943
|
+
"aria-haspopup": "listbox",
|
|
2944
|
+
"aria-expanded": open,
|
|
2945
|
+
"aria-controls": listboxId,
|
|
2946
|
+
"aria-activedescendant": open && activeOption ? `${listboxId}-${activeIndex}` : void 0,
|
|
2947
|
+
"aria-invalid": ariaInvalid ?? (invalid || void 0),
|
|
2948
|
+
"aria-required": ariaRequired ?? (required || void 0),
|
|
2949
|
+
disabled,
|
|
2950
|
+
onClick: () => setOpen((current) => !current),
|
|
2951
|
+
onKeyDown: handleKeyDown,
|
|
2952
|
+
...ariaProps,
|
|
2953
|
+
children: [
|
|
2954
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("sia-select__value", !selectedOption && "sia-select__placeholder"), children: renderValue ? renderValue(selectedOption) : selectedOption?.label ?? placeholder }),
|
|
2955
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-select__actions", children: [
|
|
2956
|
+
clearable && currentValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2957
|
+
"span",
|
|
2958
|
+
{
|
|
2959
|
+
className: "sia-select__clear",
|
|
2960
|
+
"aria-hidden": "true",
|
|
2961
|
+
title: "Effacer la s\xE9lection",
|
|
2962
|
+
onClick: (event) => {
|
|
2963
|
+
event.stopPropagation();
|
|
2964
|
+
changeValue("");
|
|
2965
|
+
},
|
|
2966
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
2967
|
+
}
|
|
2968
|
+
),
|
|
2969
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "sia-select__chevron", "aria-hidden": "true" })
|
|
2970
|
+
] })
|
|
2971
|
+
]
|
|
2972
|
+
}
|
|
2973
|
+
),
|
|
2974
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2975
|
+
Overlay,
|
|
2976
|
+
{
|
|
2977
|
+
open,
|
|
2978
|
+
anchorRef: triggerRef,
|
|
2979
|
+
onOpenChange: setOpen,
|
|
2980
|
+
placement,
|
|
2981
|
+
matchAnchorWidth: true,
|
|
2982
|
+
className: "sia-select__overlay",
|
|
2983
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-select__panel", onKeyDown: handleKeyDown, children: [
|
|
2984
|
+
showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-select__search-wrap", children: [
|
|
2985
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { "aria-hidden": "true" }),
|
|
2986
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2987
|
+
"input",
|
|
2988
|
+
{
|
|
2989
|
+
ref: searchRef,
|
|
2990
|
+
className: "sia-select__search",
|
|
2991
|
+
value: query,
|
|
2992
|
+
placeholder: searchPlaceholder,
|
|
2993
|
+
"aria-label": searchPlaceholder,
|
|
2994
|
+
onChange: (event) => setQuery(event.target.value)
|
|
2995
|
+
}
|
|
2996
|
+
),
|
|
2997
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "xs", label: "Chargement" })
|
|
2998
|
+
] }),
|
|
2999
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: listboxId, role: "listbox", "aria-busy": loading || void 0, className: "sia-select__options", children: loading && !visibleOptions.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status", children: loadingText }) : loadError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status sia-select__status--error", children: errorText }) : !visibleOptions.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status", children: emptyText }) : visibleOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3000
|
+
"button",
|
|
3001
|
+
{
|
|
3002
|
+
id: `${listboxId}-${index}`,
|
|
3003
|
+
type: "button",
|
|
3004
|
+
role: "option",
|
|
3005
|
+
"aria-selected": currentValue === option.value,
|
|
3006
|
+
disabled: option.disabled,
|
|
3007
|
+
className: utils.cn(
|
|
3008
|
+
"sia-select__option",
|
|
3009
|
+
index === activeIndex && "sia-select__option--active"
|
|
3010
|
+
),
|
|
3011
|
+
onMouseEnter: () => setActiveIndex(index),
|
|
3012
|
+
onClick: () => choose(option),
|
|
3013
|
+
children: [
|
|
3014
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-select__option-content", children: [
|
|
3015
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label }),
|
|
3016
|
+
option.description && /* @__PURE__ */ jsxRuntime.jsx("small", { children: option.description })
|
|
3017
|
+
] }),
|
|
3018
|
+
currentValue === option.value && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { "aria-hidden": "true" })
|
|
3019
|
+
]
|
|
3020
|
+
},
|
|
3021
|
+
option.value
|
|
3022
|
+
)) })
|
|
3023
|
+
] })
|
|
3024
|
+
}
|
|
3025
|
+
)
|
|
3026
|
+
]
|
|
3027
|
+
}
|
|
3028
|
+
);
|
|
3029
|
+
});
|
|
3030
|
+
Select.displayName = "Select";
|
|
3031
|
+
var DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];
|
|
2763
3032
|
function Pagination({
|
|
2764
3033
|
page,
|
|
2765
3034
|
totalPages,
|
|
@@ -2770,6 +3039,11 @@ function Pagination({
|
|
|
2770
3039
|
jumpTo = false,
|
|
2771
3040
|
showTotal = false,
|
|
2772
3041
|
compact = false,
|
|
3042
|
+
pageSize,
|
|
3043
|
+
onPageSizeChange,
|
|
3044
|
+
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
3045
|
+
pageSizeLabel,
|
|
3046
|
+
renderPageSize,
|
|
2773
3047
|
ariaLabel,
|
|
2774
3048
|
className
|
|
2775
3049
|
}) {
|
|
@@ -2780,8 +3054,17 @@ function Pagination({
|
|
|
2780
3054
|
const current = Math.min(Math.max(page, 1), Math.max(totalPages, 1));
|
|
2781
3055
|
const [draft, setDraft] = React.useState(String(current));
|
|
2782
3056
|
React.useEffect(() => setDraft(String(current)), [current]);
|
|
2783
|
-
|
|
2784
|
-
|
|
3057
|
+
const tailles = React.useMemo(() => {
|
|
3058
|
+
if (pageSize === void 0 || pageSizeOptions.includes(pageSize)) {
|
|
3059
|
+
return pageSizeOptions;
|
|
3060
|
+
}
|
|
3061
|
+
return [...pageSizeOptions, pageSize].sort((a, b) => a - b);
|
|
3062
|
+
}, [pageSize, pageSizeOptions]);
|
|
3063
|
+
const choixTaille = pageSize !== void 0 && onPageSizeChange && tailles.length > 0;
|
|
3064
|
+
const plusieursPages = totalPages > 1;
|
|
3065
|
+
const tailleLibelle = pageSizeLabel ?? locale.perPage;
|
|
3066
|
+
if (!plusieursPages && !choixTaille) return null;
|
|
3067
|
+
const items = plusieursPages ? headless.paginationItems(current, totalPages, siblingCount) : [];
|
|
2785
3068
|
const jump = (event) => {
|
|
2786
3069
|
event.preventDefault();
|
|
2787
3070
|
const asked = Number(draft);
|
|
@@ -2801,71 +3084,97 @@ function Pagination({
|
|
|
2801
3084
|
),
|
|
2802
3085
|
"aria-label": ariaLabel ?? "Pagination",
|
|
2803
3086
|
children: [
|
|
2804
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2805
|
-
|
|
2806
|
-
{
|
|
2807
|
-
type: "button",
|
|
2808
|
-
className: "sia-pagination__step",
|
|
2809
|
-
disabled: current === 1,
|
|
2810
|
-
"aria-label": previousLabel,
|
|
2811
|
-
onClick: () => onPageChange(current - 1),
|
|
2812
|
-
children: [
|
|
2813
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
|
|
2814
|
-
!compact && /* @__PURE__ */ jsxRuntime.jsx("span", { children: previousLabel })
|
|
2815
|
-
]
|
|
2816
|
-
}
|
|
2817
|
-
),
|
|
2818
|
-
items.map(
|
|
2819
|
-
(item) => typeof item === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3087
|
+
plusieursPages && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-pagination__pages", children: [
|
|
3088
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2820
3089
|
"button",
|
|
2821
3090
|
{
|
|
2822
3091
|
type: "button",
|
|
2823
|
-
className: "sia-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2832
|
-
"button",
|
|
2833
|
-
{
|
|
2834
|
-
type: "button",
|
|
2835
|
-
className: "sia-pagination__step",
|
|
2836
|
-
disabled: current === totalPages,
|
|
2837
|
-
"aria-label": nextLabel,
|
|
2838
|
-
onClick: () => onPageChange(current + 1),
|
|
2839
|
-
children: [
|
|
2840
|
-
!compact && /* @__PURE__ */ jsxRuntime.jsx("span", { children: nextLabel }),
|
|
2841
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
2842
|
-
]
|
|
2843
|
-
}
|
|
2844
|
-
),
|
|
2845
|
-
showTotal && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-pagination__total", children: [
|
|
2846
|
-
locale.page,
|
|
2847
|
-
" ",
|
|
2848
|
-
current,
|
|
2849
|
-
" / ",
|
|
2850
|
-
totalPages
|
|
2851
|
-
] }),
|
|
2852
|
-
jumpTo && /* @__PURE__ */ jsxRuntime.jsxs("form", { className: "sia-pagination__jump", onSubmit: jump, children: [
|
|
2853
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: jumpId, children: locale.goToPage }),
|
|
2854
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2855
|
-
"input",
|
|
2856
|
-
{
|
|
2857
|
-
id: jumpId,
|
|
2858
|
-
type: "text",
|
|
2859
|
-
inputMode: "numeric",
|
|
2860
|
-
value: draft,
|
|
2861
|
-
"aria-label": locale.goToPage,
|
|
2862
|
-
onChange: (event) => setDraft(event.target.value.replace(/\D/g, "")),
|
|
2863
|
-
onBlur: jump
|
|
3092
|
+
className: "sia-pagination__step",
|
|
3093
|
+
disabled: current === 1,
|
|
3094
|
+
"aria-label": previousLabel,
|
|
3095
|
+
onClick: () => onPageChange(current - 1),
|
|
3096
|
+
children: [
|
|
3097
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
|
|
3098
|
+
!compact && /* @__PURE__ */ jsxRuntime.jsx("span", { children: previousLabel })
|
|
3099
|
+
]
|
|
2864
3100
|
}
|
|
2865
3101
|
),
|
|
2866
|
-
|
|
2867
|
-
"
|
|
3102
|
+
items.map(
|
|
3103
|
+
(item) => typeof item === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3104
|
+
"button",
|
|
3105
|
+
{
|
|
3106
|
+
type: "button",
|
|
3107
|
+
className: "sia-pagination__page",
|
|
3108
|
+
"aria-current": item === current ? "page" : void 0,
|
|
3109
|
+
onClick: () => onPageChange(item),
|
|
3110
|
+
children: item
|
|
3111
|
+
},
|
|
3112
|
+
item
|
|
3113
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-pagination__gap", "aria-hidden": "true", children: "\u2026" }, item)
|
|
3114
|
+
),
|
|
3115
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3116
|
+
"button",
|
|
3117
|
+
{
|
|
3118
|
+
type: "button",
|
|
3119
|
+
className: "sia-pagination__step",
|
|
3120
|
+
disabled: current === totalPages,
|
|
3121
|
+
"aria-label": nextLabel,
|
|
3122
|
+
onClick: () => onPageChange(current + 1),
|
|
3123
|
+
children: [
|
|
3124
|
+
!compact && /* @__PURE__ */ jsxRuntime.jsx("span", { children: nextLabel }),
|
|
3125
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
3126
|
+
]
|
|
3127
|
+
}
|
|
3128
|
+
)
|
|
3129
|
+
] }),
|
|
3130
|
+
(choixTaille || plusieursPages && (showTotal || jumpTo)) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-pagination__settings", children: [
|
|
3131
|
+
plusieursPages && showTotal && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-pagination__total", children: [
|
|
3132
|
+
locale.page,
|
|
3133
|
+
" ",
|
|
3134
|
+
current,
|
|
3135
|
+
" / ",
|
|
2868
3136
|
totalPages
|
|
3137
|
+
] }),
|
|
3138
|
+
choixTaille && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-pagination__size", children: renderPageSize ? renderPageSize({
|
|
3139
|
+
pageSize,
|
|
3140
|
+
options: tailles,
|
|
3141
|
+
onChange: onPageSizeChange,
|
|
3142
|
+
label: tailleLibelle
|
|
3143
|
+
}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3144
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: tailleLibelle }),
|
|
3145
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3146
|
+
Select,
|
|
3147
|
+
{
|
|
3148
|
+
variant: "embedded",
|
|
3149
|
+
"aria-label": tailleLibelle,
|
|
3150
|
+
placement: "top-end",
|
|
3151
|
+
value: String(pageSize),
|
|
3152
|
+
options: tailles.map((taille) => ({
|
|
3153
|
+
value: String(taille),
|
|
3154
|
+
label: String(taille)
|
|
3155
|
+
})),
|
|
3156
|
+
onValueChange: (valeur) => onPageSizeChange(Number(valeur))
|
|
3157
|
+
}
|
|
3158
|
+
)
|
|
3159
|
+
] }) }),
|
|
3160
|
+
plusieursPages && jumpTo && /* @__PURE__ */ jsxRuntime.jsxs("form", { className: "sia-pagination__jump", onSubmit: jump, children: [
|
|
3161
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: jumpId, children: locale.goToPage }),
|
|
3162
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3163
|
+
"input",
|
|
3164
|
+
{
|
|
3165
|
+
id: jumpId,
|
|
3166
|
+
type: "text",
|
|
3167
|
+
inputMode: "numeric",
|
|
3168
|
+
value: draft,
|
|
3169
|
+
"aria-label": locale.goToPage,
|
|
3170
|
+
onChange: (event) => setDraft(event.target.value.replace(/\D/g, "")),
|
|
3171
|
+
onBlur: jump
|
|
3172
|
+
}
|
|
3173
|
+
),
|
|
3174
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-pagination__jump-total", "aria-hidden": "true", children: [
|
|
3175
|
+
"/ ",
|
|
3176
|
+
totalPages
|
|
3177
|
+
] })
|
|
2869
3178
|
] })
|
|
2870
3179
|
] })
|
|
2871
3180
|
]
|
|
@@ -3151,6 +3460,7 @@ function DataTable({
|
|
|
3151
3460
|
searchKeys,
|
|
3152
3461
|
searchPlaceholder,
|
|
3153
3462
|
onSearch,
|
|
3463
|
+
searchDelay = 0,
|
|
3154
3464
|
layout = "auto",
|
|
3155
3465
|
maxHeight,
|
|
3156
3466
|
stickyHeader = false,
|
|
@@ -3269,9 +3579,10 @@ function DataTable({
|
|
|
3269
3579
|
{
|
|
3270
3580
|
value: recherche,
|
|
3271
3581
|
placeholder: searchPlaceholder ?? locale.search,
|
|
3582
|
+
...onSearch && searchDelay > 0 ? { onSearch, searchDelay } : {},
|
|
3272
3583
|
onValueChange: (v) => {
|
|
3273
3584
|
setRecherche(v);
|
|
3274
|
-
onSearch?.(v);
|
|
3585
|
+
if (searchDelay <= 0) onSearch?.(v);
|
|
3275
3586
|
}
|
|
3276
3587
|
}
|
|
3277
3588
|
),
|
|
@@ -4064,255 +4375,6 @@ function DateTimePicker({ value, defaultValue = { date: "", time: "" }, onValueC
|
|
|
4064
4375
|
/* @__PURE__ */ jsxRuntime.jsx(TimePicker, { ...timeProps, value: current.time, minuteStep, secondStep, showSeconds, hourFormat, needConfirm, tone, ...stateProps, "aria-label": "Heure", onValueChange: (time) => update({ ...current, time }) })
|
|
4065
4376
|
] });
|
|
4066
4377
|
}
|
|
4067
|
-
function optionsFromChildren(children) {
|
|
4068
|
-
return React.Children.toArray(children).flatMap((child) => {
|
|
4069
|
-
if (!React.isValidElement(child))
|
|
4070
|
-
return [];
|
|
4071
|
-
const value = child.props.value;
|
|
4072
|
-
if (value === void 0) return [];
|
|
4073
|
-
return [{
|
|
4074
|
-
value: String(value),
|
|
4075
|
-
label: child.props.children,
|
|
4076
|
-
...child.props.disabled !== void 0 ? { disabled: child.props.disabled } : {}
|
|
4077
|
-
}];
|
|
4078
|
-
});
|
|
4079
|
-
}
|
|
4080
|
-
function optionText(option) {
|
|
4081
|
-
return [option.label, option.description, ...option.keywords ?? []].map((value) => typeof value === "string" || typeof value === "number" ? String(value) : "").join(" ").toLocaleLowerCase();
|
|
4082
|
-
}
|
|
4083
|
-
var Select = React.forwardRef(function Select2({
|
|
4084
|
-
id,
|
|
4085
|
-
name,
|
|
4086
|
-
options,
|
|
4087
|
-
children,
|
|
4088
|
-
value,
|
|
4089
|
-
defaultValue = "",
|
|
4090
|
-
onValueChange,
|
|
4091
|
-
placeholder = "S\xE9lectionner",
|
|
4092
|
-
searchable = false,
|
|
4093
|
-
searchPlaceholder = "Rechercher...",
|
|
4094
|
-
fetcher,
|
|
4095
|
-
debounce = 250,
|
|
4096
|
-
loadingText = "Chargement des options...",
|
|
4097
|
-
emptyText = "Aucun r\xE9sultat",
|
|
4098
|
-
errorText = "Impossible de charger les options",
|
|
4099
|
-
clearable = false,
|
|
4100
|
-
disabled = false,
|
|
4101
|
-
invalid = false,
|
|
4102
|
-
required = false,
|
|
4103
|
-
placement = "bottom-start",
|
|
4104
|
-
className,
|
|
4105
|
-
"aria-invalid": ariaInvalid,
|
|
4106
|
-
"aria-required": ariaRequired,
|
|
4107
|
-
...ariaProps
|
|
4108
|
-
}, forwardedRef) {
|
|
4109
|
-
const generatedId = React.useId();
|
|
4110
|
-
const controlId = id ?? `sia-select-${generatedId.replace(/:/g, "")}`;
|
|
4111
|
-
const listboxId = `${controlId}-listbox`;
|
|
4112
|
-
const triggerRef = React.useRef(null);
|
|
4113
|
-
const searchRef = React.useRef(null);
|
|
4114
|
-
const staticOptions = React.useMemo(
|
|
4115
|
-
() => options ?? optionsFromChildren(children),
|
|
4116
|
-
[children, options]
|
|
4117
|
-
);
|
|
4118
|
-
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
4119
|
-
const [open, setOpen] = React.useState(false);
|
|
4120
|
-
const [query, setQuery] = React.useState("");
|
|
4121
|
-
const [remoteOptions, setRemoteOptions] = React.useState([]);
|
|
4122
|
-
const [selectedRemoteOption, setSelectedRemoteOption] = React.useState();
|
|
4123
|
-
const [loading, setLoading] = React.useState(false);
|
|
4124
|
-
const [loadError, setLoadError] = React.useState(false);
|
|
4125
|
-
const [activeIndex, setActiveIndex] = React.useState(-1);
|
|
4126
|
-
const currentValue = value ?? internalValue;
|
|
4127
|
-
const sourceOptions = fetcher ? remoteOptions : staticOptions;
|
|
4128
|
-
const visibleOptions = React.useMemo(() => {
|
|
4129
|
-
if (fetcher) return sourceOptions;
|
|
4130
|
-
const needle = query.trim().toLocaleLowerCase();
|
|
4131
|
-
return needle ? sourceOptions.filter((option) => optionText(option).includes(needle)) : sourceOptions;
|
|
4132
|
-
}, [fetcher, query, sourceOptions]);
|
|
4133
|
-
const selectedOption = [...staticOptions, ...remoteOptions].find(
|
|
4134
|
-
(option) => option.value === currentValue
|
|
4135
|
-
) ?? (selectedRemoteOption?.value === currentValue ? selectedRemoteOption : void 0);
|
|
4136
|
-
React.useEffect(() => {
|
|
4137
|
-
if (!open || !fetcher) return;
|
|
4138
|
-
const controller = new AbortController();
|
|
4139
|
-
const timeout = window.setTimeout(async () => {
|
|
4140
|
-
setLoading(true);
|
|
4141
|
-
setLoadError(false);
|
|
4142
|
-
try {
|
|
4143
|
-
const nextOptions = await fetcher(query, controller.signal);
|
|
4144
|
-
if (!controller.signal.aborted) setRemoteOptions(nextOptions);
|
|
4145
|
-
} catch {
|
|
4146
|
-
if (!controller.signal.aborted) setLoadError(true);
|
|
4147
|
-
} finally {
|
|
4148
|
-
if (!controller.signal.aborted) setLoading(false);
|
|
4149
|
-
}
|
|
4150
|
-
}, debounce);
|
|
4151
|
-
return () => {
|
|
4152
|
-
window.clearTimeout(timeout);
|
|
4153
|
-
controller.abort();
|
|
4154
|
-
};
|
|
4155
|
-
}, [debounce, fetcher, open, query]);
|
|
4156
|
-
React.useEffect(() => {
|
|
4157
|
-
if (!open) return;
|
|
4158
|
-
setActiveIndex(visibleOptions.findIndex((option) => option.value === currentValue));
|
|
4159
|
-
if (searchable || fetcher) window.setTimeout(() => searchRef.current?.focus(), 0);
|
|
4160
|
-
}, [currentValue, fetcher, open, searchable, visibleOptions]);
|
|
4161
|
-
const setTriggerRef = (node) => {
|
|
4162
|
-
triggerRef.current = node;
|
|
4163
|
-
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
4164
|
-
else if (forwardedRef) forwardedRef.current = node;
|
|
4165
|
-
};
|
|
4166
|
-
const changeValue = (nextValue, option) => {
|
|
4167
|
-
if (value === void 0) setInternalValue(nextValue);
|
|
4168
|
-
onValueChange?.(nextValue, option);
|
|
4169
|
-
};
|
|
4170
|
-
const choose = (option) => {
|
|
4171
|
-
if (option.disabled) return;
|
|
4172
|
-
if (fetcher) setSelectedRemoteOption(option);
|
|
4173
|
-
changeValue(option.value, option);
|
|
4174
|
-
setOpen(false);
|
|
4175
|
-
setQuery("");
|
|
4176
|
-
window.setTimeout(() => triggerRef.current?.focus(), 0);
|
|
4177
|
-
};
|
|
4178
|
-
const moveActive = (direction) => {
|
|
4179
|
-
if (!visibleOptions.length) return;
|
|
4180
|
-
let next = activeIndex;
|
|
4181
|
-
for (let count = 0; count < visibleOptions.length; count += 1) {
|
|
4182
|
-
next = (next + direction + visibleOptions.length) % visibleOptions.length;
|
|
4183
|
-
if (!visibleOptions[next]?.disabled) break;
|
|
4184
|
-
}
|
|
4185
|
-
setActiveIndex(next);
|
|
4186
|
-
};
|
|
4187
|
-
const handleKeyDown = (event) => {
|
|
4188
|
-
if (["ArrowDown", "ArrowUp"].includes(event.key)) {
|
|
4189
|
-
event.preventDefault();
|
|
4190
|
-
if (!open) setOpen(true);
|
|
4191
|
-
else moveActive(event.key === "ArrowDown" ? 1 : -1);
|
|
4192
|
-
return;
|
|
4193
|
-
}
|
|
4194
|
-
if (event.key === "Home" && open) {
|
|
4195
|
-
event.preventDefault();
|
|
4196
|
-
setActiveIndex(visibleOptions.findIndex((option) => !option.disabled));
|
|
4197
|
-
} else if (event.key === "End" && open) {
|
|
4198
|
-
event.preventDefault();
|
|
4199
|
-
for (let index = visibleOptions.length - 1; index >= 0; index -= 1) {
|
|
4200
|
-
if (!visibleOptions[index]?.disabled) {
|
|
4201
|
-
setActiveIndex(index);
|
|
4202
|
-
break;
|
|
4203
|
-
}
|
|
4204
|
-
}
|
|
4205
|
-
} else if (event.key === "Enter" && open && activeIndex >= 0) {
|
|
4206
|
-
event.preventDefault();
|
|
4207
|
-
const active = visibleOptions[activeIndex];
|
|
4208
|
-
if (active) choose(active);
|
|
4209
|
-
} else if (event.key === "Escape" && open) {
|
|
4210
|
-
event.preventDefault();
|
|
4211
|
-
setOpen(false);
|
|
4212
|
-
triggerRef.current?.focus();
|
|
4213
|
-
} else if (!open && clearable && currentValue && ["Backspace", "Delete"].includes(event.key)) {
|
|
4214
|
-
event.preventDefault();
|
|
4215
|
-
changeValue("");
|
|
4216
|
-
}
|
|
4217
|
-
};
|
|
4218
|
-
const showSearch = searchable || Boolean(fetcher);
|
|
4219
|
-
const activeOption = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
|
|
4220
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("sia-select", disabled && "sia-select--disabled", className), children: [
|
|
4221
|
-
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: currentValue }),
|
|
4222
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4223
|
-
"button",
|
|
4224
|
-
{
|
|
4225
|
-
ref: setTriggerRef,
|
|
4226
|
-
id: controlId,
|
|
4227
|
-
type: "button",
|
|
4228
|
-
className: utils.cn("sia-select__trigger", invalid && "sia-select__trigger--invalid"),
|
|
4229
|
-
role: "combobox",
|
|
4230
|
-
"aria-haspopup": "listbox",
|
|
4231
|
-
"aria-expanded": open,
|
|
4232
|
-
"aria-controls": listboxId,
|
|
4233
|
-
"aria-activedescendant": open && activeOption ? `${listboxId}-${activeIndex}` : void 0,
|
|
4234
|
-
"aria-invalid": ariaInvalid ?? (invalid || void 0),
|
|
4235
|
-
"aria-required": ariaRequired ?? (required || void 0),
|
|
4236
|
-
disabled,
|
|
4237
|
-
onClick: () => setOpen((current) => !current),
|
|
4238
|
-
onKeyDown: handleKeyDown,
|
|
4239
|
-
...ariaProps,
|
|
4240
|
-
children: [
|
|
4241
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("sia-select__value", !selectedOption && "sia-select__placeholder"), children: selectedOption?.label ?? placeholder }),
|
|
4242
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-select__actions", children: [
|
|
4243
|
-
clearable && currentValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4244
|
-
"span",
|
|
4245
|
-
{
|
|
4246
|
-
className: "sia-select__clear",
|
|
4247
|
-
"aria-hidden": "true",
|
|
4248
|
-
title: "Effacer la s\xE9lection",
|
|
4249
|
-
onClick: (event) => {
|
|
4250
|
-
event.stopPropagation();
|
|
4251
|
-
changeValue("");
|
|
4252
|
-
},
|
|
4253
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
4254
|
-
}
|
|
4255
|
-
),
|
|
4256
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "sia-select__chevron", "aria-hidden": "true" })
|
|
4257
|
-
] })
|
|
4258
|
-
]
|
|
4259
|
-
}
|
|
4260
|
-
),
|
|
4261
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4262
|
-
Overlay,
|
|
4263
|
-
{
|
|
4264
|
-
open,
|
|
4265
|
-
anchorRef: triggerRef,
|
|
4266
|
-
onOpenChange: setOpen,
|
|
4267
|
-
placement,
|
|
4268
|
-
matchAnchorWidth: true,
|
|
4269
|
-
className: "sia-select__overlay",
|
|
4270
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-select__panel", onKeyDown: handleKeyDown, children: [
|
|
4271
|
-
showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-select__search-wrap", children: [
|
|
4272
|
-
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { "aria-hidden": "true" }),
|
|
4273
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4274
|
-
"input",
|
|
4275
|
-
{
|
|
4276
|
-
ref: searchRef,
|
|
4277
|
-
className: "sia-select__search",
|
|
4278
|
-
value: query,
|
|
4279
|
-
placeholder: searchPlaceholder,
|
|
4280
|
-
"aria-label": searchPlaceholder,
|
|
4281
|
-
onChange: (event) => setQuery(event.target.value)
|
|
4282
|
-
}
|
|
4283
|
-
),
|
|
4284
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "xs", label: "Chargement" })
|
|
4285
|
-
] }),
|
|
4286
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { id: listboxId, role: "listbox", "aria-busy": loading || void 0, className: "sia-select__options", children: loading && !visibleOptions.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status", children: loadingText }) : loadError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status sia-select__status--error", children: errorText }) : !visibleOptions.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-select__status", children: emptyText }) : visibleOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4287
|
-
"button",
|
|
4288
|
-
{
|
|
4289
|
-
id: `${listboxId}-${index}`,
|
|
4290
|
-
type: "button",
|
|
4291
|
-
role: "option",
|
|
4292
|
-
"aria-selected": currentValue === option.value,
|
|
4293
|
-
disabled: option.disabled,
|
|
4294
|
-
className: utils.cn(
|
|
4295
|
-
"sia-select__option",
|
|
4296
|
-
index === activeIndex && "sia-select__option--active"
|
|
4297
|
-
),
|
|
4298
|
-
onMouseEnter: () => setActiveIndex(index),
|
|
4299
|
-
onClick: () => choose(option),
|
|
4300
|
-
children: [
|
|
4301
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-select__option-content", children: [
|
|
4302
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label }),
|
|
4303
|
-
option.description && /* @__PURE__ */ jsxRuntime.jsx("small", { children: option.description })
|
|
4304
|
-
] }),
|
|
4305
|
-
currentValue === option.value && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { "aria-hidden": "true" })
|
|
4306
|
-
]
|
|
4307
|
-
},
|
|
4308
|
-
option.value
|
|
4309
|
-
)) })
|
|
4310
|
-
] })
|
|
4311
|
-
}
|
|
4312
|
-
)
|
|
4313
|
-
] });
|
|
4314
|
-
});
|
|
4315
|
-
Select.displayName = "Select";
|
|
4316
4378
|
function MultiSelect({
|
|
4317
4379
|
id,
|
|
4318
4380
|
options,
|
|
@@ -5299,6 +5361,14 @@ function Field(rawProps) {
|
|
|
5299
5361
|
function isGroup(entry) {
|
|
5300
5362
|
return "group" in entry;
|
|
5301
5363
|
}
|
|
5364
|
+
function formFieldNames(fields) {
|
|
5365
|
+
const noms = [];
|
|
5366
|
+
for (const entree of fields) {
|
|
5367
|
+
if (isGroup(entree)) noms.push(...entree.fields.map((f) => f.name));
|
|
5368
|
+
else noms.push(entree.name);
|
|
5369
|
+
}
|
|
5370
|
+
return noms;
|
|
5371
|
+
}
|
|
5302
5372
|
var VIDE = {};
|
|
5303
5373
|
function Form({
|
|
5304
5374
|
fields,
|
|
@@ -5323,6 +5393,26 @@ function Form({
|
|
|
5323
5393
|
...onSubmit ? { onSubmit } : {}
|
|
5324
5394
|
});
|
|
5325
5395
|
const form = adapter ?? interne;
|
|
5396
|
+
const locale = headless.useSiaLocale();
|
|
5397
|
+
const [echec, setEchec] = React.useState(null);
|
|
5398
|
+
const envoyer = () => {
|
|
5399
|
+
setEchec(null);
|
|
5400
|
+
form.submit().catch((error) => {
|
|
5401
|
+
const { fields: erreurs, message } = headless.readSubmitError(error);
|
|
5402
|
+
const connus = new Set(formFieldNames(fields));
|
|
5403
|
+
const sousLesChamps = {};
|
|
5404
|
+
const ailleurs = [];
|
|
5405
|
+
for (const [nom, texte] of Object.entries(erreurs)) {
|
|
5406
|
+
if (connus.has(nom)) sousLesChamps[nom] = texte;
|
|
5407
|
+
else ailleurs.push(texte);
|
|
5408
|
+
}
|
|
5409
|
+
form.setErrors(sousLesChamps);
|
|
5410
|
+
if (ailleurs.length > 0) setEchec(ailleurs.join(" "));
|
|
5411
|
+
else if (Object.keys(sousLesChamps).length === 0) {
|
|
5412
|
+
setEchec(message ?? locale.submitError);
|
|
5413
|
+
}
|
|
5414
|
+
});
|
|
5415
|
+
};
|
|
5326
5416
|
const busy = loading || form.state.isSubmitting;
|
|
5327
5417
|
const submitDisabled = busy || requireDirty && !form.state.isDirty || requireValid && !form.state.isValid;
|
|
5328
5418
|
const grille = (nombre) => ({
|
|
@@ -5358,7 +5448,7 @@ function Form({
|
|
|
5358
5448
|
noValidate: true,
|
|
5359
5449
|
onSubmit: (event) => {
|
|
5360
5450
|
event.preventDefault();
|
|
5361
|
-
|
|
5451
|
+
envoyer();
|
|
5362
5452
|
},
|
|
5363
5453
|
children: [
|
|
5364
5454
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sia-form-grid", style: grille(columns), children: fields.map(
|
|
@@ -5377,6 +5467,15 @@ function Form({
|
|
|
5377
5467
|
)
|
|
5378
5468
|
] }, entry.group) : rendre(entry)
|
|
5379
5469
|
) }),
|
|
5470
|
+
echec && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5471
|
+
Alert,
|
|
5472
|
+
{
|
|
5473
|
+
tone: "danger",
|
|
5474
|
+
className: "sia-form-error",
|
|
5475
|
+
onDismiss: () => setEchec(null),
|
|
5476
|
+
children: echec
|
|
5477
|
+
}
|
|
5478
|
+
),
|
|
5380
5479
|
actions ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sia-form-actions", children: [
|
|
5381
5480
|
showClear && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5382
5481
|
Button,
|
|
@@ -5412,23 +5511,15 @@ function Descriptions({ items, title, columns = 2, bordered = false, className }
|
|
|
5412
5511
|
] }, item.key)) })
|
|
5413
5512
|
] });
|
|
5414
5513
|
}
|
|
5415
|
-
function nomsDeChamps(fields) {
|
|
5416
|
-
const noms = [];
|
|
5417
|
-
for (const entree of fields) {
|
|
5418
|
-
if ("group" in entree) noms.push(...entree.fields.map((f) => f.name));
|
|
5419
|
-
else noms.push(entree.name);
|
|
5420
|
-
}
|
|
5421
|
-
return noms;
|
|
5422
|
-
}
|
|
5423
5514
|
function valeursVides(fields) {
|
|
5424
5515
|
const valeurs = {};
|
|
5425
|
-
for (const nom of
|
|
5516
|
+
for (const nom of formFieldNames(fields)) valeurs[nom] = "";
|
|
5426
5517
|
return valeurs;
|
|
5427
5518
|
}
|
|
5428
5519
|
function valeursDeLigne(row, fields) {
|
|
5429
5520
|
const source = row;
|
|
5430
5521
|
const valeurs = {};
|
|
5431
|
-
for (const nom of
|
|
5522
|
+
for (const nom of formFieldNames(fields)) {
|
|
5432
5523
|
const valeur = source[nom];
|
|
5433
5524
|
valeurs[nom] = typeof valeur === "string" || typeof valeur === "number" || typeof valeur === "boolean" || Array.isArray(valeur) ? valeur : "";
|
|
5434
5525
|
}
|
|
@@ -5473,11 +5564,12 @@ function CrudDialogs({
|
|
|
5473
5564
|
submitText: dialog?.submitText ?? (creation ? "Cr\xE9er" : "Enregistrer"),
|
|
5474
5565
|
requireDirty: modification,
|
|
5475
5566
|
onSubmit: async (values) => {
|
|
5476
|
-
await onSubmit?.(values, {
|
|
5567
|
+
const resultat = await onSubmit?.(values, {
|
|
5477
5568
|
mode: creation ? "create" : "edit",
|
|
5478
5569
|
...state?.row !== void 0 ? { row: state.row } : {},
|
|
5479
5570
|
...state?.index !== void 0 ? { index: state.index } : {}
|
|
5480
5571
|
});
|
|
5572
|
+
if (headless.hasFormErrors(resultat)) return resultat;
|
|
5481
5573
|
onClose();
|
|
5482
5574
|
}
|
|
5483
5575
|
},
|
|
@@ -5561,6 +5653,7 @@ function CrudPage({
|
|
|
5561
5653
|
searchKeys: clesDeRecherche,
|
|
5562
5654
|
searchPlaceholder,
|
|
5563
5655
|
onSearch,
|
|
5656
|
+
searchDelay,
|
|
5564
5657
|
loading = false,
|
|
5565
5658
|
error,
|
|
5566
5659
|
onRetry,
|
|
@@ -5568,6 +5661,9 @@ function CrudPage({
|
|
|
5568
5661
|
page,
|
|
5569
5662
|
totalPages,
|
|
5570
5663
|
onPageChange,
|
|
5664
|
+
pageSize,
|
|
5665
|
+
onPageSizeChange,
|
|
5666
|
+
pageSizeOptions,
|
|
5571
5667
|
table,
|
|
5572
5668
|
children,
|
|
5573
5669
|
className
|
|
@@ -5647,9 +5743,12 @@ function CrudPage({
|
|
|
5647
5743
|
if (!extraRowActions) {
|
|
5648
5744
|
return actionsDeLigne.length > 0 ? actionsDeLigne : void 0;
|
|
5649
5745
|
}
|
|
5746
|
+
const suppression = actionsDeLigne.filter((a) => a.key === "delete");
|
|
5747
|
+
const autres = actionsDeLigne.filter((a) => a.key !== "delete");
|
|
5650
5748
|
return (row, index) => [
|
|
5651
|
-
...
|
|
5652
|
-
...typeof extraRowActions === "function" ? extraRowActions(row, index) : extraRowActions
|
|
5749
|
+
...autres,
|
|
5750
|
+
...typeof extraRowActions === "function" ? extraRowActions(row, index) : extraRowActions,
|
|
5751
|
+
...suppression
|
|
5653
5752
|
];
|
|
5654
5753
|
}, [actionsDeLigne, extraRowActions]);
|
|
5655
5754
|
const creation = operations?.create === false ? null : operations?.create ?? {};
|
|
@@ -5683,6 +5782,7 @@ function CrudPage({
|
|
|
5683
5782
|
...searchKeys ? { searchKeys } : {},
|
|
5684
5783
|
...searchPlaceholder ? { searchPlaceholder } : {},
|
|
5685
5784
|
...onSearch ? { onSearch } : {},
|
|
5785
|
+
...searchDelay !== void 0 ? { searchDelay } : {},
|
|
5686
5786
|
...toutesLesActions ? { rowActions: toutesLesActions } : {},
|
|
5687
5787
|
...can ? { can } : {},
|
|
5688
5788
|
loading,
|
|
@@ -5745,7 +5845,10 @@ function CrudPage({
|
|
|
5745
5845
|
page,
|
|
5746
5846
|
totalPages,
|
|
5747
5847
|
onPageChange,
|
|
5748
|
-
showTotal: true
|
|
5848
|
+
showTotal: true,
|
|
5849
|
+
...pageSize !== void 0 ? { pageSize } : {},
|
|
5850
|
+
...onPageSizeChange ? { onPageSizeChange } : {},
|
|
5851
|
+
...pageSizeOptions ? { pageSizeOptions } : {}
|
|
5749
5852
|
}
|
|
5750
5853
|
)
|
|
5751
5854
|
] });
|
|
@@ -6208,6 +6311,14 @@ var PhoneInput = React.forwardRef(
|
|
|
6208
6311
|
[countries, initial, picked, value]
|
|
6209
6312
|
);
|
|
6210
6313
|
const national = value.startsWith(country.dial) ? value.slice(country.dial.length) : digitsOnly(value);
|
|
6314
|
+
const options = React.useMemo(
|
|
6315
|
+
() => countries.map((entry) => ({
|
|
6316
|
+
value: entry.code,
|
|
6317
|
+
label: `${entry.flag} ${entry.label} (${entry.dial})`,
|
|
6318
|
+
keywords: [entry.code]
|
|
6319
|
+
})),
|
|
6320
|
+
[countries]
|
|
6321
|
+
);
|
|
6211
6322
|
const commit = (next) => {
|
|
6212
6323
|
if (!controlled) setInternal(next);
|
|
6213
6324
|
onValueChange?.(next);
|
|
@@ -6229,35 +6340,31 @@ var PhoneInput = React.forwardRef(
|
|
|
6229
6340
|
if (country.digits) next = next.slice(0, country.digits);
|
|
6230
6341
|
commit(next ? `${country.dial}${next}` : "");
|
|
6231
6342
|
},
|
|
6232
|
-
left: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-phone__country", children: [
|
|
6343
|
+
left: lockCountry ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-phone__country", children: [
|
|
6233
6344
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-phone__flag", "aria-hidden": "true", children: country.flag }),
|
|
6234
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-phone__dial", children: country.dial })
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
" (",
|
|
6255
|
-
entry.dial,
|
|
6256
|
-
")"
|
|
6257
|
-
] }, entry.code))
|
|
6345
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-phone__dial", children: country.dial })
|
|
6346
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6347
|
+
Select,
|
|
6348
|
+
{
|
|
6349
|
+
variant: "embedded",
|
|
6350
|
+
searchable: true,
|
|
6351
|
+
className: "sia-phone__country",
|
|
6352
|
+
"aria-label": locale.countryCode,
|
|
6353
|
+
options,
|
|
6354
|
+
value: country.code,
|
|
6355
|
+
disabled: disabled ?? false,
|
|
6356
|
+
renderValue: () => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sia-phone__value", children: [
|
|
6357
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-phone__flag", "aria-hidden": "true", children: country.flag }),
|
|
6358
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sia-phone__dial", children: country.dial })
|
|
6359
|
+
] }),
|
|
6360
|
+
onValueChange: (code) => {
|
|
6361
|
+
const next = countries.find((entry) => entry.code === code);
|
|
6362
|
+
if (!next) return;
|
|
6363
|
+
setPicked(next.code);
|
|
6364
|
+
commit(national ? `${next.dial}${national}` : "");
|
|
6258
6365
|
}
|
|
6259
|
-
|
|
6260
|
-
|
|
6366
|
+
}
|
|
6367
|
+
)
|
|
6261
6368
|
}
|
|
6262
6369
|
);
|
|
6263
6370
|
}
|
|
@@ -7263,6 +7370,7 @@ exports.CrudDialogs = CrudDialogs;
|
|
|
7263
7370
|
exports.CrudPage = CrudPage;
|
|
7264
7371
|
exports.CurrencyInput = CurrencyInput;
|
|
7265
7372
|
exports.DEFAULT_COUNTRIES = DEFAULT_COUNTRIES;
|
|
7373
|
+
exports.DEFAULT_PAGE_SIZE_OPTIONS = DEFAULT_PAGE_SIZE_OPTIONS;
|
|
7266
7374
|
exports.DataTable = DataTable;
|
|
7267
7375
|
exports.DatePicker = DatePicker;
|
|
7268
7376
|
exports.DateRangeFilter = DateRangeFilter;
|
|
@@ -7373,6 +7481,7 @@ exports.YearPicker = YearPicker;
|
|
|
7373
7481
|
exports.confirmUnsavedNavigation = confirmUnsavedNavigation;
|
|
7374
7482
|
exports.createUrlTableStorage = createUrlTableStorage;
|
|
7375
7483
|
exports.defineResource = defineResource;
|
|
7484
|
+
exports.formFieldNames = formFieldNames;
|
|
7376
7485
|
exports.formatDuration = formatDuration;
|
|
7377
7486
|
exports.formatTimeValue = formatTimeValue;
|
|
7378
7487
|
exports.initialsOf = initialsOf;
|