@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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, forwardRef, useRef, useImperativeHandle, useEffect, memo, useContext, useState, useId, useMemo, useCallback, useLayoutEffect, Children, isValidElement, cloneElement, Fragment as Fragment$1 } from 'react';
3
- import { cn, toneClass, formatCurrency, parseCurrency, formatTimeAgo, formatDate, normalizeIdentifier, truncate, formatDateTime, formatNumber } from '@sia-ui/utils';
4
- import { useDisclosureState, overlayStack, navContains, useHoverIntent, navLeaves, navSome, useComponentDefaults, useSiaLocale, computeFloatingPosition, useAccordionState, navPath, filterNavTree, navKeyForPath, paginationItems, useTableQuery, useSliderState, useLocalForm, useSession, useToasts, toastStore, toast, useRovingIndex } from '@sia-ui/headless';
3
+ import { cn, toneClass, looseIncludes, formatCurrency, parseCurrency, formatTimeAgo, formatDate, normalizeIdentifier, truncate, formatDateTime, formatNumber } from '@sia-ui/utils';
4
+ import { useDisclosureState, overlayStack, navContains, useHoverIntent, navLeaves, navSome, useComponentDefaults, useSiaLocale, computeFloatingPosition, useAccordionState, navPath, filterNavTree, navKeyForPath, paginationItems, useTableQuery, useSliderState, useLocalForm, hasFormErrors, useSession, useToasts, toastStore, toast, readSubmitError, useRovingIndex } from '@sia-ui/headless';
5
5
  export { toast, toastStore } from '@sia-ui/headless';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { useOutsideClick, Portal, useMediaQuery, usePortal, useControllableState } from '@sia-ui/react';
@@ -276,7 +276,8 @@ var Drawer = forwardRef(
276
276
  isOpen,
277
277
  phase: state,
278
278
  open: doOpen,
279
- close: doClose
279
+ close: doClose,
280
+ toggle
280
281
  } = useDisclosureState({
281
282
  ...open !== void 0 ? { open } : {},
282
283
  defaultOpen,
@@ -285,15 +286,17 @@ var Drawer = forwardRef(
285
286
  });
286
287
  const drawerRef = useRef(null);
287
288
  const zIndexRef = useRef(null);
289
+ const fermer = useRef(doClose);
290
+ fermer.current = doClose;
288
291
  useImperativeHandle(
289
292
  ref,
290
293
  () => ({
291
294
  open: doOpen,
292
295
  close: doClose,
293
- toggle: () => isOpen ? doClose() : doOpen(),
296
+ toggle,
294
297
  isOpen: () => isOpen
295
298
  }),
296
- [isOpen, open]
299
+ [isOpen, doOpen, doClose, toggle]
297
300
  );
298
301
  useEffect(() => {
299
302
  if (!isOpen) return;
@@ -310,7 +313,7 @@ var Drawer = forwardRef(
310
313
  const onKeyDown = (e) => {
311
314
  if (!closeOnEsc || e.key !== "Escape") return;
312
315
  if (overlayStack.isTop(zIndexRef.current)) {
313
- doClose();
316
+ fermer.current();
314
317
  }
315
318
  };
316
319
  window.addEventListener("keydown", onKeyDown);
@@ -2020,9 +2023,9 @@ function Calendar({
2020
2023
  if (mode === void 0) setPanelMode(next);
2021
2024
  onPanelChange?.(monthIso(controlledMonth), next);
2022
2025
  };
2023
- const isDisabled = (date) => Boolean(
2026
+ const isDisabled = useCallback((date) => Boolean(
2024
2027
  disabledDate?.(date) || validRange && (date < validRange[0] || date > validRange[1])
2025
- );
2028
+ ), [disabledDate, validRange]);
2026
2029
  const selectDate = (date) => {
2027
2030
  if (isDisabled(date)) return;
2028
2031
  if (selectionMode === "range") {
@@ -2056,7 +2059,7 @@ function Calendar({
2056
2059
  ...rangeEdge ? { rangeEdge } : {}
2057
2060
  };
2058
2061
  });
2059
- }, [year, monthIndex, firstDayOfWeek, disabledDate, validRange, currentValue, currentRange.start, currentRange.end]);
2062
+ }, [year, monthIndex, firstDayOfWeek, isDisabled, currentValue, currentRange.start, currentRange.end]);
2060
2063
  const weekdays = Array.from({ length: 7 }, (_, index) => new Intl.DateTimeFormat(locale, { weekday: "short" }).format(new Date(2024, 0, 7 + firstDayOfWeek + index)));
2061
2064
  const monthName = new Intl.DateTimeFormat(locale, { month: "long" }).format(controlledMonth);
2062
2065
  const updateFromString = (next) => setMonth(parseMonth(next));
@@ -2703,6 +2706,8 @@ function Timer({ duration = 6e4, initialValue = 0, direction = "down", running =
2703
2706
  const initial = direction === "down" ? duration : initialValue;
2704
2707
  const [value, setValue] = useState(initial);
2705
2708
  const finishCalled = useRef(false);
2709
+ const latest = useRef({ value, onChange, onFinish });
2710
+ latest.current = { value, onChange, onFinish };
2706
2711
  useEffect(() => {
2707
2712
  setValue(direction === "down" ? duration : initialValue);
2708
2713
  finishCalled.current = false;
@@ -2710,15 +2715,15 @@ function Timer({ duration = 6e4, initialValue = 0, direction = "down", running =
2710
2715
  useEffect(() => {
2711
2716
  if (!running) return;
2712
2717
  const startedAt = Date.now();
2713
- const base = value;
2718
+ const base = latest.current.value;
2714
2719
  const update = () => {
2715
2720
  const elapsed = Date.now() - startedAt;
2716
2721
  const next = direction === "down" ? Math.max(0, base - elapsed) : base + elapsed;
2717
2722
  setValue(next);
2718
- onChange?.(next);
2723
+ latest.current.onChange?.(next);
2719
2724
  if (direction === "down" && next === 0 && !finishCalled.current) {
2720
2725
  finishCalled.current = true;
2721
- onFinish?.();
2726
+ latest.current.onFinish?.();
2722
2727
  }
2723
2728
  };
2724
2729
  update();
@@ -2740,6 +2745,270 @@ function PageHeader({ title, description, eyebrow, actions, className }) {
2740
2745
  actions && /* @__PURE__ */ jsx("div", { className: "sia-page-header__actions", children: actions })
2741
2746
  ] });
2742
2747
  }
2748
+ function optionsFromChildren(children) {
2749
+ return Children.toArray(children).flatMap((child) => {
2750
+ if (!isValidElement(child))
2751
+ return [];
2752
+ const value = child.props.value;
2753
+ if (value === void 0) return [];
2754
+ return [{
2755
+ value: String(value),
2756
+ label: child.props.children,
2757
+ ...child.props.disabled !== void 0 ? { disabled: child.props.disabled } : {}
2758
+ }];
2759
+ });
2760
+ }
2761
+ function optionText(option) {
2762
+ return [option.label, option.description, ...option.keywords ?? []].map((value) => typeof value === "string" || typeof value === "number" ? String(value) : "").join(" ");
2763
+ }
2764
+ var Select = forwardRef(function Select2({
2765
+ id,
2766
+ name,
2767
+ options,
2768
+ children,
2769
+ value,
2770
+ defaultValue = "",
2771
+ onValueChange,
2772
+ placeholder = "S\xE9lectionner",
2773
+ searchable = false,
2774
+ searchPlaceholder = "Rechercher...",
2775
+ fetcher,
2776
+ debounce = 250,
2777
+ loadingText = "Chargement des options...",
2778
+ emptyText = "Aucun r\xE9sultat",
2779
+ errorText = "Impossible de charger les options",
2780
+ clearable = false,
2781
+ disabled = false,
2782
+ invalid = false,
2783
+ required = false,
2784
+ placement = "bottom-start",
2785
+ renderValue,
2786
+ variant = "default",
2787
+ className,
2788
+ "aria-invalid": ariaInvalid,
2789
+ "aria-required": ariaRequired,
2790
+ ...ariaProps
2791
+ }, forwardedRef) {
2792
+ const generatedId = useId();
2793
+ const controlId = id ?? `sia-select-${generatedId.replace(/:/g, "")}`;
2794
+ const listboxId = `${controlId}-listbox`;
2795
+ const triggerRef = useRef(null);
2796
+ const searchRef = useRef(null);
2797
+ const staticOptions = useMemo(
2798
+ () => options ?? optionsFromChildren(children),
2799
+ [children, options]
2800
+ );
2801
+ const [internalValue, setInternalValue] = useState(defaultValue);
2802
+ const [open, setOpen] = useState(false);
2803
+ const [query, setQuery] = useState("");
2804
+ const [remoteOptions, setRemoteOptions] = useState([]);
2805
+ const [selectedRemoteOption, setSelectedRemoteOption] = useState();
2806
+ const [loading, setLoading] = useState(false);
2807
+ const [loadError, setLoadError] = useState(false);
2808
+ const [activeIndex, setActiveIndex] = useState(-1);
2809
+ const currentValue = value ?? internalValue;
2810
+ const sourceOptions = fetcher ? remoteOptions : staticOptions;
2811
+ const visibleOptions = useMemo(() => {
2812
+ if (fetcher) return sourceOptions;
2813
+ const needle = query.trim();
2814
+ return needle ? sourceOptions.filter((option) => looseIncludes(optionText(option), needle)) : sourceOptions;
2815
+ }, [fetcher, query, sourceOptions]);
2816
+ const selectedOption = [...staticOptions, ...remoteOptions].find(
2817
+ (option) => option.value === currentValue
2818
+ ) ?? (selectedRemoteOption?.value === currentValue ? selectedRemoteOption : void 0);
2819
+ useEffect(() => {
2820
+ if (!open || !fetcher) return;
2821
+ const controller = new AbortController();
2822
+ const timeout = window.setTimeout(async () => {
2823
+ setLoading(true);
2824
+ setLoadError(false);
2825
+ try {
2826
+ const nextOptions = await fetcher(query, controller.signal);
2827
+ if (!controller.signal.aborted) setRemoteOptions(nextOptions);
2828
+ } catch {
2829
+ if (!controller.signal.aborted) setLoadError(true);
2830
+ } finally {
2831
+ if (!controller.signal.aborted) setLoading(false);
2832
+ }
2833
+ }, debounce);
2834
+ return () => {
2835
+ window.clearTimeout(timeout);
2836
+ controller.abort();
2837
+ };
2838
+ }, [debounce, fetcher, open, query]);
2839
+ useEffect(() => {
2840
+ if (!open) return;
2841
+ const selected = visibleOptions.findIndex((option) => option.value === currentValue);
2842
+ setActiveIndex(selected >= 0 ? selected : visibleOptions.findIndex((option) => !option.disabled));
2843
+ if (searchable || fetcher) window.setTimeout(() => searchRef.current?.focus(), 0);
2844
+ }, [currentValue, fetcher, open, searchable, visibleOptions]);
2845
+ const setTriggerRef = (node) => {
2846
+ triggerRef.current = node;
2847
+ if (typeof forwardedRef === "function") forwardedRef(node);
2848
+ else if (forwardedRef) forwardedRef.current = node;
2849
+ };
2850
+ const changeValue = (nextValue, option) => {
2851
+ if (value === void 0) setInternalValue(nextValue);
2852
+ onValueChange?.(nextValue, option);
2853
+ };
2854
+ const choose = (option) => {
2855
+ if (option.disabled) return;
2856
+ if (fetcher) setSelectedRemoteOption(option);
2857
+ changeValue(option.value, option);
2858
+ setOpen(false);
2859
+ setQuery("");
2860
+ window.setTimeout(() => triggerRef.current?.focus(), 0);
2861
+ };
2862
+ const moveActive = (direction) => {
2863
+ if (!visibleOptions.length) return;
2864
+ let next = activeIndex;
2865
+ for (let count = 0; count < visibleOptions.length; count += 1) {
2866
+ next = (next + direction + visibleOptions.length) % visibleOptions.length;
2867
+ if (!visibleOptions[next]?.disabled) break;
2868
+ }
2869
+ setActiveIndex(next);
2870
+ };
2871
+ const handleKeyDown = (event) => {
2872
+ if (["ArrowDown", "ArrowUp"].includes(event.key)) {
2873
+ event.preventDefault();
2874
+ if (!open) setOpen(true);
2875
+ else moveActive(event.key === "ArrowDown" ? 1 : -1);
2876
+ return;
2877
+ }
2878
+ if (event.key === "Home" && open) {
2879
+ event.preventDefault();
2880
+ setActiveIndex(visibleOptions.findIndex((option) => !option.disabled));
2881
+ } else if (event.key === "End" && open) {
2882
+ event.preventDefault();
2883
+ for (let index = visibleOptions.length - 1; index >= 0; index -= 1) {
2884
+ if (!visibleOptions[index]?.disabled) {
2885
+ setActiveIndex(index);
2886
+ break;
2887
+ }
2888
+ }
2889
+ } else if (event.key === "Enter" && open && activeIndex >= 0) {
2890
+ event.preventDefault();
2891
+ const active = visibleOptions[activeIndex];
2892
+ if (active) choose(active);
2893
+ } else if (event.key === "Escape" && open) {
2894
+ event.preventDefault();
2895
+ setOpen(false);
2896
+ triggerRef.current?.focus();
2897
+ } else if (!open && clearable && currentValue && ["Backspace", "Delete"].includes(event.key)) {
2898
+ event.preventDefault();
2899
+ changeValue("");
2900
+ }
2901
+ };
2902
+ const showSearch = searchable || Boolean(fetcher);
2903
+ const activeOption = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
2904
+ return /* @__PURE__ */ jsxs(
2905
+ "div",
2906
+ {
2907
+ className: cn(
2908
+ "sia-select",
2909
+ variant === "embedded" && "sia-select--embedded",
2910
+ disabled && "sia-select--disabled",
2911
+ className
2912
+ ),
2913
+ children: [
2914
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: currentValue }),
2915
+ /* @__PURE__ */ jsxs(
2916
+ "button",
2917
+ {
2918
+ ref: setTriggerRef,
2919
+ id: controlId,
2920
+ type: "button",
2921
+ className: cn("sia-select__trigger", invalid && "sia-select__trigger--invalid"),
2922
+ role: "combobox",
2923
+ "aria-haspopup": "listbox",
2924
+ "aria-expanded": open,
2925
+ "aria-controls": listboxId,
2926
+ "aria-activedescendant": open && activeOption ? `${listboxId}-${activeIndex}` : void 0,
2927
+ "aria-invalid": ariaInvalid ?? (invalid || void 0),
2928
+ "aria-required": ariaRequired ?? (required || void 0),
2929
+ disabled,
2930
+ onClick: () => setOpen((current) => !current),
2931
+ onKeyDown: handleKeyDown,
2932
+ ...ariaProps,
2933
+ children: [
2934
+ /* @__PURE__ */ jsx("span", { className: cn("sia-select__value", !selectedOption && "sia-select__placeholder"), children: renderValue ? renderValue(selectedOption) : selectedOption?.label ?? placeholder }),
2935
+ /* @__PURE__ */ jsxs("span", { className: "sia-select__actions", children: [
2936
+ clearable && currentValue && !disabled && /* @__PURE__ */ jsx(
2937
+ "span",
2938
+ {
2939
+ className: "sia-select__clear",
2940
+ "aria-hidden": "true",
2941
+ title: "Effacer la s\xE9lection",
2942
+ onClick: (event) => {
2943
+ event.stopPropagation();
2944
+ changeValue("");
2945
+ },
2946
+ children: /* @__PURE__ */ jsx(XIcon, {})
2947
+ }
2948
+ ),
2949
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "sia-select__chevron", "aria-hidden": "true" })
2950
+ ] })
2951
+ ]
2952
+ }
2953
+ ),
2954
+ /* @__PURE__ */ jsx(
2955
+ Overlay,
2956
+ {
2957
+ open,
2958
+ anchorRef: triggerRef,
2959
+ onOpenChange: setOpen,
2960
+ placement,
2961
+ matchAnchorWidth: true,
2962
+ className: "sia-select__overlay",
2963
+ children: /* @__PURE__ */ jsxs("div", { className: "sia-select__panel", onKeyDown: handleKeyDown, children: [
2964
+ showSearch && /* @__PURE__ */ jsxs("div", { className: "sia-select__search-wrap", children: [
2965
+ /* @__PURE__ */ jsx(SearchIcon, { "aria-hidden": "true" }),
2966
+ /* @__PURE__ */ jsx(
2967
+ "input",
2968
+ {
2969
+ ref: searchRef,
2970
+ className: "sia-select__search",
2971
+ value: query,
2972
+ placeholder: searchPlaceholder,
2973
+ "aria-label": searchPlaceholder,
2974
+ onChange: (event) => setQuery(event.target.value)
2975
+ }
2976
+ ),
2977
+ loading && /* @__PURE__ */ jsx(Spinner, { size: "xs", label: "Chargement" })
2978
+ ] }),
2979
+ /* @__PURE__ */ jsx("div", { id: listboxId, role: "listbox", "aria-busy": loading || void 0, className: "sia-select__options", children: loading && !visibleOptions.length ? /* @__PURE__ */ jsx("div", { className: "sia-select__status", children: loadingText }) : loadError ? /* @__PURE__ */ jsx("div", { className: "sia-select__status sia-select__status--error", children: errorText }) : !visibleOptions.length ? /* @__PURE__ */ jsx("div", { className: "sia-select__status", children: emptyText }) : visibleOptions.map((option, index) => /* @__PURE__ */ jsxs(
2980
+ "button",
2981
+ {
2982
+ id: `${listboxId}-${index}`,
2983
+ type: "button",
2984
+ role: "option",
2985
+ "aria-selected": currentValue === option.value,
2986
+ disabled: option.disabled,
2987
+ className: cn(
2988
+ "sia-select__option",
2989
+ index === activeIndex && "sia-select__option--active"
2990
+ ),
2991
+ onMouseEnter: () => setActiveIndex(index),
2992
+ onClick: () => choose(option),
2993
+ children: [
2994
+ /* @__PURE__ */ jsxs("span", { className: "sia-select__option-content", children: [
2995
+ /* @__PURE__ */ jsx("span", { children: option.label }),
2996
+ option.description && /* @__PURE__ */ jsx("small", { children: option.description })
2997
+ ] }),
2998
+ currentValue === option.value && /* @__PURE__ */ jsx(CheckIcon, { "aria-hidden": "true" })
2999
+ ]
3000
+ },
3001
+ option.value
3002
+ )) })
3003
+ ] })
3004
+ }
3005
+ )
3006
+ ]
3007
+ }
3008
+ );
3009
+ });
3010
+ Select.displayName = "Select";
3011
+ var DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];
2743
3012
  function Pagination({
2744
3013
  page,
2745
3014
  totalPages,
@@ -2750,6 +3019,11 @@ function Pagination({
2750
3019
  jumpTo = false,
2751
3020
  showTotal = false,
2752
3021
  compact = false,
3022
+ pageSize,
3023
+ onPageSizeChange,
3024
+ pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
3025
+ pageSizeLabel,
3026
+ renderPageSize,
2753
3027
  ariaLabel,
2754
3028
  className
2755
3029
  }) {
@@ -2760,8 +3034,17 @@ function Pagination({
2760
3034
  const current = Math.min(Math.max(page, 1), Math.max(totalPages, 1));
2761
3035
  const [draft, setDraft] = useState(String(current));
2762
3036
  useEffect(() => setDraft(String(current)), [current]);
2763
- if (totalPages <= 1) return null;
2764
- const items = paginationItems(current, totalPages, siblingCount);
3037
+ const tailles = useMemo(() => {
3038
+ if (pageSize === void 0 || pageSizeOptions.includes(pageSize)) {
3039
+ return pageSizeOptions;
3040
+ }
3041
+ return [...pageSizeOptions, pageSize].sort((a, b) => a - b);
3042
+ }, [pageSize, pageSizeOptions]);
3043
+ const choixTaille = pageSize !== void 0 && onPageSizeChange && tailles.length > 0;
3044
+ const plusieursPages = totalPages > 1;
3045
+ const tailleLibelle = pageSizeLabel ?? locale.perPage;
3046
+ if (!plusieursPages && !choixTaille) return null;
3047
+ const items = plusieursPages ? paginationItems(current, totalPages, siblingCount) : [];
2765
3048
  const jump = (event) => {
2766
3049
  event.preventDefault();
2767
3050
  const asked = Number(draft);
@@ -2781,71 +3064,97 @@ function Pagination({
2781
3064
  ),
2782
3065
  "aria-label": ariaLabel ?? "Pagination",
2783
3066
  children: [
2784
- /* @__PURE__ */ jsxs(
2785
- "button",
2786
- {
2787
- type: "button",
2788
- className: "sia-pagination__step",
2789
- disabled: current === 1,
2790
- "aria-label": previousLabel,
2791
- onClick: () => onPageChange(current - 1),
2792
- children: [
2793
- /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
2794
- !compact && /* @__PURE__ */ jsx("span", { children: previousLabel })
2795
- ]
2796
- }
2797
- ),
2798
- items.map(
2799
- (item) => typeof item === "number" ? /* @__PURE__ */ jsx(
3067
+ plusieursPages && /* @__PURE__ */ jsxs("div", { className: "sia-pagination__pages", children: [
3068
+ /* @__PURE__ */ jsxs(
2800
3069
  "button",
2801
3070
  {
2802
3071
  type: "button",
2803
- className: "sia-pagination__page",
2804
- "aria-current": item === current ? "page" : void 0,
2805
- onClick: () => onPageChange(item),
2806
- children: item
2807
- },
2808
- item
2809
- ) : /* @__PURE__ */ jsx("span", { className: "sia-pagination__gap", "aria-hidden": "true", children: "\u2026" }, item)
2810
- ),
2811
- /* @__PURE__ */ jsxs(
2812
- "button",
2813
- {
2814
- type: "button",
2815
- className: "sia-pagination__step",
2816
- disabled: current === totalPages,
2817
- "aria-label": nextLabel,
2818
- onClick: () => onPageChange(current + 1),
2819
- children: [
2820
- !compact && /* @__PURE__ */ jsx("span", { children: nextLabel }),
2821
- /* @__PURE__ */ jsx(ChevronRightIcon, {})
2822
- ]
2823
- }
2824
- ),
2825
- showTotal && /* @__PURE__ */ jsxs("span", { className: "sia-pagination__total", children: [
2826
- locale.page,
2827
- " ",
2828
- current,
2829
- " / ",
2830
- totalPages
2831
- ] }),
2832
- jumpTo && /* @__PURE__ */ jsxs("form", { className: "sia-pagination__jump", onSubmit: jump, children: [
2833
- /* @__PURE__ */ jsx("label", { htmlFor: jumpId, children: locale.goToPage }),
2834
- /* @__PURE__ */ jsx(
2835
- "input",
2836
- {
2837
- id: jumpId,
2838
- type: "text",
2839
- inputMode: "numeric",
2840
- value: draft,
2841
- "aria-label": locale.goToPage,
2842
- onChange: (event) => setDraft(event.target.value.replace(/\D/g, "")),
2843
- onBlur: jump
3072
+ className: "sia-pagination__step",
3073
+ disabled: current === 1,
3074
+ "aria-label": previousLabel,
3075
+ onClick: () => onPageChange(current - 1),
3076
+ children: [
3077
+ /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
3078
+ !compact && /* @__PURE__ */ jsx("span", { children: previousLabel })
3079
+ ]
2844
3080
  }
2845
3081
  ),
2846
- /* @__PURE__ */ jsxs("span", { className: "sia-pagination__jump-total", "aria-hidden": "true", children: [
2847
- "/ ",
3082
+ items.map(
3083
+ (item) => typeof item === "number" ? /* @__PURE__ */ jsx(
3084
+ "button",
3085
+ {
3086
+ type: "button",
3087
+ className: "sia-pagination__page",
3088
+ "aria-current": item === current ? "page" : void 0,
3089
+ onClick: () => onPageChange(item),
3090
+ children: item
3091
+ },
3092
+ item
3093
+ ) : /* @__PURE__ */ jsx("span", { className: "sia-pagination__gap", "aria-hidden": "true", children: "\u2026" }, item)
3094
+ ),
3095
+ /* @__PURE__ */ jsxs(
3096
+ "button",
3097
+ {
3098
+ type: "button",
3099
+ className: "sia-pagination__step",
3100
+ disabled: current === totalPages,
3101
+ "aria-label": nextLabel,
3102
+ onClick: () => onPageChange(current + 1),
3103
+ children: [
3104
+ !compact && /* @__PURE__ */ jsx("span", { children: nextLabel }),
3105
+ /* @__PURE__ */ jsx(ChevronRightIcon, {})
3106
+ ]
3107
+ }
3108
+ )
3109
+ ] }),
3110
+ (choixTaille || plusieursPages && (showTotal || jumpTo)) && /* @__PURE__ */ jsxs("div", { className: "sia-pagination__settings", children: [
3111
+ plusieursPages && showTotal && /* @__PURE__ */ jsxs("span", { className: "sia-pagination__total", children: [
3112
+ locale.page,
3113
+ " ",
3114
+ current,
3115
+ " / ",
2848
3116
  totalPages
3117
+ ] }),
3118
+ choixTaille && /* @__PURE__ */ jsx("div", { className: "sia-pagination__size", children: renderPageSize ? renderPageSize({
3119
+ pageSize,
3120
+ options: tailles,
3121
+ onChange: onPageSizeChange,
3122
+ label: tailleLibelle
3123
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3124
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: tailleLibelle }),
3125
+ /* @__PURE__ */ jsx(
3126
+ Select,
3127
+ {
3128
+ variant: "embedded",
3129
+ "aria-label": tailleLibelle,
3130
+ placement: "top-end",
3131
+ value: String(pageSize),
3132
+ options: tailles.map((taille) => ({
3133
+ value: String(taille),
3134
+ label: String(taille)
3135
+ })),
3136
+ onValueChange: (valeur) => onPageSizeChange(Number(valeur))
3137
+ }
3138
+ )
3139
+ ] }) }),
3140
+ plusieursPages && jumpTo && /* @__PURE__ */ jsxs("form", { className: "sia-pagination__jump", onSubmit: jump, children: [
3141
+ /* @__PURE__ */ jsx("label", { htmlFor: jumpId, children: locale.goToPage }),
3142
+ /* @__PURE__ */ jsx(
3143
+ "input",
3144
+ {
3145
+ id: jumpId,
3146
+ type: "text",
3147
+ inputMode: "numeric",
3148
+ value: draft,
3149
+ "aria-label": locale.goToPage,
3150
+ onChange: (event) => setDraft(event.target.value.replace(/\D/g, "")),
3151
+ onBlur: jump
3152
+ }
3153
+ ),
3154
+ /* @__PURE__ */ jsxs("span", { className: "sia-pagination__jump-total", "aria-hidden": "true", children: [
3155
+ "/ ",
3156
+ totalPages
3157
+ ] })
2849
3158
  ] })
2850
3159
  ] })
2851
3160
  ]
@@ -3131,6 +3440,7 @@ function DataTable({
3131
3440
  searchKeys,
3132
3441
  searchPlaceholder,
3133
3442
  onSearch,
3443
+ searchDelay = 0,
3134
3444
  layout = "auto",
3135
3445
  maxHeight,
3136
3446
  stickyHeader = false,
@@ -3249,9 +3559,10 @@ function DataTable({
3249
3559
  {
3250
3560
  value: recherche,
3251
3561
  placeholder: searchPlaceholder ?? locale.search,
3562
+ ...onSearch && searchDelay > 0 ? { onSearch, searchDelay } : {},
3252
3563
  onValueChange: (v) => {
3253
3564
  setRecherche(v);
3254
- onSearch?.(v);
3565
+ if (searchDelay <= 0) onSearch?.(v);
3255
3566
  }
3256
3567
  }
3257
3568
  ),
@@ -4044,255 +4355,6 @@ function DateTimePicker({ value, defaultValue = { date: "", time: "" }, onValueC
4044
4355
  /* @__PURE__ */ jsx(TimePicker, { ...timeProps, value: current.time, minuteStep, secondStep, showSeconds, hourFormat, needConfirm, tone, ...stateProps, "aria-label": "Heure", onValueChange: (time) => update({ ...current, time }) })
4045
4356
  ] });
4046
4357
  }
4047
- function optionsFromChildren(children) {
4048
- return Children.toArray(children).flatMap((child) => {
4049
- if (!isValidElement(child))
4050
- return [];
4051
- const value = child.props.value;
4052
- if (value === void 0) return [];
4053
- return [{
4054
- value: String(value),
4055
- label: child.props.children,
4056
- ...child.props.disabled !== void 0 ? { disabled: child.props.disabled } : {}
4057
- }];
4058
- });
4059
- }
4060
- function optionText(option) {
4061
- return [option.label, option.description, ...option.keywords ?? []].map((value) => typeof value === "string" || typeof value === "number" ? String(value) : "").join(" ").toLocaleLowerCase();
4062
- }
4063
- var Select = forwardRef(function Select2({
4064
- id,
4065
- name,
4066
- options,
4067
- children,
4068
- value,
4069
- defaultValue = "",
4070
- onValueChange,
4071
- placeholder = "S\xE9lectionner",
4072
- searchable = false,
4073
- searchPlaceholder = "Rechercher...",
4074
- fetcher,
4075
- debounce = 250,
4076
- loadingText = "Chargement des options...",
4077
- emptyText = "Aucun r\xE9sultat",
4078
- errorText = "Impossible de charger les options",
4079
- clearable = false,
4080
- disabled = false,
4081
- invalid = false,
4082
- required = false,
4083
- placement = "bottom-start",
4084
- className,
4085
- "aria-invalid": ariaInvalid,
4086
- "aria-required": ariaRequired,
4087
- ...ariaProps
4088
- }, forwardedRef) {
4089
- const generatedId = useId();
4090
- const controlId = id ?? `sia-select-${generatedId.replace(/:/g, "")}`;
4091
- const listboxId = `${controlId}-listbox`;
4092
- const triggerRef = useRef(null);
4093
- const searchRef = useRef(null);
4094
- const staticOptions = useMemo(
4095
- () => options ?? optionsFromChildren(children),
4096
- [children, options]
4097
- );
4098
- const [internalValue, setInternalValue] = useState(defaultValue);
4099
- const [open, setOpen] = useState(false);
4100
- const [query, setQuery] = useState("");
4101
- const [remoteOptions, setRemoteOptions] = useState([]);
4102
- const [selectedRemoteOption, setSelectedRemoteOption] = useState();
4103
- const [loading, setLoading] = useState(false);
4104
- const [loadError, setLoadError] = useState(false);
4105
- const [activeIndex, setActiveIndex] = useState(-1);
4106
- const currentValue = value ?? internalValue;
4107
- const sourceOptions = fetcher ? remoteOptions : staticOptions;
4108
- const visibleOptions = useMemo(() => {
4109
- if (fetcher) return sourceOptions;
4110
- const needle = query.trim().toLocaleLowerCase();
4111
- return needle ? sourceOptions.filter((option) => optionText(option).includes(needle)) : sourceOptions;
4112
- }, [fetcher, query, sourceOptions]);
4113
- const selectedOption = [...staticOptions, ...remoteOptions].find(
4114
- (option) => option.value === currentValue
4115
- ) ?? (selectedRemoteOption?.value === currentValue ? selectedRemoteOption : void 0);
4116
- useEffect(() => {
4117
- if (!open || !fetcher) return;
4118
- const controller = new AbortController();
4119
- const timeout = window.setTimeout(async () => {
4120
- setLoading(true);
4121
- setLoadError(false);
4122
- try {
4123
- const nextOptions = await fetcher(query, controller.signal);
4124
- if (!controller.signal.aborted) setRemoteOptions(nextOptions);
4125
- } catch {
4126
- if (!controller.signal.aborted) setLoadError(true);
4127
- } finally {
4128
- if (!controller.signal.aborted) setLoading(false);
4129
- }
4130
- }, debounce);
4131
- return () => {
4132
- window.clearTimeout(timeout);
4133
- controller.abort();
4134
- };
4135
- }, [debounce, fetcher, open, query]);
4136
- useEffect(() => {
4137
- if (!open) return;
4138
- setActiveIndex(visibleOptions.findIndex((option) => option.value === currentValue));
4139
- if (searchable || fetcher) window.setTimeout(() => searchRef.current?.focus(), 0);
4140
- }, [currentValue, fetcher, open, searchable, visibleOptions]);
4141
- const setTriggerRef = (node) => {
4142
- triggerRef.current = node;
4143
- if (typeof forwardedRef === "function") forwardedRef(node);
4144
- else if (forwardedRef) forwardedRef.current = node;
4145
- };
4146
- const changeValue = (nextValue, option) => {
4147
- if (value === void 0) setInternalValue(nextValue);
4148
- onValueChange?.(nextValue, option);
4149
- };
4150
- const choose = (option) => {
4151
- if (option.disabled) return;
4152
- if (fetcher) setSelectedRemoteOption(option);
4153
- changeValue(option.value, option);
4154
- setOpen(false);
4155
- setQuery("");
4156
- window.setTimeout(() => triggerRef.current?.focus(), 0);
4157
- };
4158
- const moveActive = (direction) => {
4159
- if (!visibleOptions.length) return;
4160
- let next = activeIndex;
4161
- for (let count = 0; count < visibleOptions.length; count += 1) {
4162
- next = (next + direction + visibleOptions.length) % visibleOptions.length;
4163
- if (!visibleOptions[next]?.disabled) break;
4164
- }
4165
- setActiveIndex(next);
4166
- };
4167
- const handleKeyDown = (event) => {
4168
- if (["ArrowDown", "ArrowUp"].includes(event.key)) {
4169
- event.preventDefault();
4170
- if (!open) setOpen(true);
4171
- else moveActive(event.key === "ArrowDown" ? 1 : -1);
4172
- return;
4173
- }
4174
- if (event.key === "Home" && open) {
4175
- event.preventDefault();
4176
- setActiveIndex(visibleOptions.findIndex((option) => !option.disabled));
4177
- } else if (event.key === "End" && open) {
4178
- event.preventDefault();
4179
- for (let index = visibleOptions.length - 1; index >= 0; index -= 1) {
4180
- if (!visibleOptions[index]?.disabled) {
4181
- setActiveIndex(index);
4182
- break;
4183
- }
4184
- }
4185
- } else if (event.key === "Enter" && open && activeIndex >= 0) {
4186
- event.preventDefault();
4187
- const active = visibleOptions[activeIndex];
4188
- if (active) choose(active);
4189
- } else if (event.key === "Escape" && open) {
4190
- event.preventDefault();
4191
- setOpen(false);
4192
- triggerRef.current?.focus();
4193
- } else if (!open && clearable && currentValue && ["Backspace", "Delete"].includes(event.key)) {
4194
- event.preventDefault();
4195
- changeValue("");
4196
- }
4197
- };
4198
- const showSearch = searchable || Boolean(fetcher);
4199
- const activeOption = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
4200
- return /* @__PURE__ */ jsxs("div", { className: cn("sia-select", disabled && "sia-select--disabled", className), children: [
4201
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: currentValue }),
4202
- /* @__PURE__ */ jsxs(
4203
- "button",
4204
- {
4205
- ref: setTriggerRef,
4206
- id: controlId,
4207
- type: "button",
4208
- className: cn("sia-select__trigger", invalid && "sia-select__trigger--invalid"),
4209
- role: "combobox",
4210
- "aria-haspopup": "listbox",
4211
- "aria-expanded": open,
4212
- "aria-controls": listboxId,
4213
- "aria-activedescendant": open && activeOption ? `${listboxId}-${activeIndex}` : void 0,
4214
- "aria-invalid": ariaInvalid ?? (invalid || void 0),
4215
- "aria-required": ariaRequired ?? (required || void 0),
4216
- disabled,
4217
- onClick: () => setOpen((current) => !current),
4218
- onKeyDown: handleKeyDown,
4219
- ...ariaProps,
4220
- children: [
4221
- /* @__PURE__ */ jsx("span", { className: cn("sia-select__value", !selectedOption && "sia-select__placeholder"), children: selectedOption?.label ?? placeholder }),
4222
- /* @__PURE__ */ jsxs("span", { className: "sia-select__actions", children: [
4223
- clearable && currentValue && !disabled && /* @__PURE__ */ jsx(
4224
- "span",
4225
- {
4226
- className: "sia-select__clear",
4227
- "aria-hidden": "true",
4228
- title: "Effacer la s\xE9lection",
4229
- onClick: (event) => {
4230
- event.stopPropagation();
4231
- changeValue("");
4232
- },
4233
- children: /* @__PURE__ */ jsx(XIcon, {})
4234
- }
4235
- ),
4236
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "sia-select__chevron", "aria-hidden": "true" })
4237
- ] })
4238
- ]
4239
- }
4240
- ),
4241
- /* @__PURE__ */ jsx(
4242
- Overlay,
4243
- {
4244
- open,
4245
- anchorRef: triggerRef,
4246
- onOpenChange: setOpen,
4247
- placement,
4248
- matchAnchorWidth: true,
4249
- className: "sia-select__overlay",
4250
- children: /* @__PURE__ */ jsxs("div", { className: "sia-select__panel", onKeyDown: handleKeyDown, children: [
4251
- showSearch && /* @__PURE__ */ jsxs("div", { className: "sia-select__search-wrap", children: [
4252
- /* @__PURE__ */ jsx(SearchIcon, { "aria-hidden": "true" }),
4253
- /* @__PURE__ */ jsx(
4254
- "input",
4255
- {
4256
- ref: searchRef,
4257
- className: "sia-select__search",
4258
- value: query,
4259
- placeholder: searchPlaceholder,
4260
- "aria-label": searchPlaceholder,
4261
- onChange: (event) => setQuery(event.target.value)
4262
- }
4263
- ),
4264
- loading && /* @__PURE__ */ jsx(Spinner, { size: "xs", label: "Chargement" })
4265
- ] }),
4266
- /* @__PURE__ */ jsx("div", { id: listboxId, role: "listbox", "aria-busy": loading || void 0, className: "sia-select__options", children: loading && !visibleOptions.length ? /* @__PURE__ */ jsx("div", { className: "sia-select__status", children: loadingText }) : loadError ? /* @__PURE__ */ jsx("div", { className: "sia-select__status sia-select__status--error", children: errorText }) : !visibleOptions.length ? /* @__PURE__ */ jsx("div", { className: "sia-select__status", children: emptyText }) : visibleOptions.map((option, index) => /* @__PURE__ */ jsxs(
4267
- "button",
4268
- {
4269
- id: `${listboxId}-${index}`,
4270
- type: "button",
4271
- role: "option",
4272
- "aria-selected": currentValue === option.value,
4273
- disabled: option.disabled,
4274
- className: cn(
4275
- "sia-select__option",
4276
- index === activeIndex && "sia-select__option--active"
4277
- ),
4278
- onMouseEnter: () => setActiveIndex(index),
4279
- onClick: () => choose(option),
4280
- children: [
4281
- /* @__PURE__ */ jsxs("span", { className: "sia-select__option-content", children: [
4282
- /* @__PURE__ */ jsx("span", { children: option.label }),
4283
- option.description && /* @__PURE__ */ jsx("small", { children: option.description })
4284
- ] }),
4285
- currentValue === option.value && /* @__PURE__ */ jsx(CheckIcon, { "aria-hidden": "true" })
4286
- ]
4287
- },
4288
- option.value
4289
- )) })
4290
- ] })
4291
- }
4292
- )
4293
- ] });
4294
- });
4295
- Select.displayName = "Select";
4296
4358
  function MultiSelect({
4297
4359
  id,
4298
4360
  options,
@@ -5279,6 +5341,14 @@ function Field(rawProps) {
5279
5341
  function isGroup(entry) {
5280
5342
  return "group" in entry;
5281
5343
  }
5344
+ function formFieldNames(fields) {
5345
+ const noms = [];
5346
+ for (const entree of fields) {
5347
+ if (isGroup(entree)) noms.push(...entree.fields.map((f) => f.name));
5348
+ else noms.push(entree.name);
5349
+ }
5350
+ return noms;
5351
+ }
5282
5352
  var VIDE = {};
5283
5353
  function Form({
5284
5354
  fields,
@@ -5303,6 +5373,26 @@ function Form({
5303
5373
  ...onSubmit ? { onSubmit } : {}
5304
5374
  });
5305
5375
  const form = adapter ?? interne;
5376
+ const locale = useSiaLocale();
5377
+ const [echec, setEchec] = useState(null);
5378
+ const envoyer = () => {
5379
+ setEchec(null);
5380
+ form.submit().catch((error) => {
5381
+ const { fields: erreurs, message } = readSubmitError(error);
5382
+ const connus = new Set(formFieldNames(fields));
5383
+ const sousLesChamps = {};
5384
+ const ailleurs = [];
5385
+ for (const [nom, texte] of Object.entries(erreurs)) {
5386
+ if (connus.has(nom)) sousLesChamps[nom] = texte;
5387
+ else ailleurs.push(texte);
5388
+ }
5389
+ form.setErrors(sousLesChamps);
5390
+ if (ailleurs.length > 0) setEchec(ailleurs.join(" "));
5391
+ else if (Object.keys(sousLesChamps).length === 0) {
5392
+ setEchec(message ?? locale.submitError);
5393
+ }
5394
+ });
5395
+ };
5306
5396
  const busy = loading || form.state.isSubmitting;
5307
5397
  const submitDisabled = busy || requireDirty && !form.state.isDirty || requireValid && !form.state.isValid;
5308
5398
  const grille = (nombre) => ({
@@ -5338,7 +5428,7 @@ function Form({
5338
5428
  noValidate: true,
5339
5429
  onSubmit: (event) => {
5340
5430
  event.preventDefault();
5341
- void form.submit();
5431
+ envoyer();
5342
5432
  },
5343
5433
  children: [
5344
5434
  /* @__PURE__ */ jsx("div", { className: "sia-form-grid", style: grille(columns), children: fields.map(
@@ -5357,6 +5447,15 @@ function Form({
5357
5447
  )
5358
5448
  ] }, entry.group) : rendre(entry)
5359
5449
  ) }),
5450
+ echec && /* @__PURE__ */ jsx(
5451
+ Alert,
5452
+ {
5453
+ tone: "danger",
5454
+ className: "sia-form-error",
5455
+ onDismiss: () => setEchec(null),
5456
+ children: echec
5457
+ }
5458
+ ),
5360
5459
  actions ?? /* @__PURE__ */ jsxs("div", { className: "sia-form-actions", children: [
5361
5460
  showClear && /* @__PURE__ */ jsx(
5362
5461
  Button,
@@ -5392,23 +5491,15 @@ function Descriptions({ items, title, columns = 2, bordered = false, className }
5392
5491
  ] }, item.key)) })
5393
5492
  ] });
5394
5493
  }
5395
- function nomsDeChamps(fields) {
5396
- const noms = [];
5397
- for (const entree of fields) {
5398
- if ("group" in entree) noms.push(...entree.fields.map((f) => f.name));
5399
- else noms.push(entree.name);
5400
- }
5401
- return noms;
5402
- }
5403
5494
  function valeursVides(fields) {
5404
5495
  const valeurs = {};
5405
- for (const nom of nomsDeChamps(fields)) valeurs[nom] = "";
5496
+ for (const nom of formFieldNames(fields)) valeurs[nom] = "";
5406
5497
  return valeurs;
5407
5498
  }
5408
5499
  function valeursDeLigne(row, fields) {
5409
5500
  const source = row;
5410
5501
  const valeurs = {};
5411
- for (const nom of nomsDeChamps(fields)) {
5502
+ for (const nom of formFieldNames(fields)) {
5412
5503
  const valeur = source[nom];
5413
5504
  valeurs[nom] = typeof valeur === "string" || typeof valeur === "number" || typeof valeur === "boolean" || Array.isArray(valeur) ? valeur : "";
5414
5505
  }
@@ -5453,11 +5544,12 @@ function CrudDialogs({
5453
5544
  submitText: dialog?.submitText ?? (creation ? "Cr\xE9er" : "Enregistrer"),
5454
5545
  requireDirty: modification,
5455
5546
  onSubmit: async (values) => {
5456
- await onSubmit?.(values, {
5547
+ const resultat = await onSubmit?.(values, {
5457
5548
  mode: creation ? "create" : "edit",
5458
5549
  ...state?.row !== void 0 ? { row: state.row } : {},
5459
5550
  ...state?.index !== void 0 ? { index: state.index } : {}
5460
5551
  });
5552
+ if (hasFormErrors(resultat)) return resultat;
5461
5553
  onClose();
5462
5554
  }
5463
5555
  },
@@ -5541,6 +5633,7 @@ function CrudPage({
5541
5633
  searchKeys: clesDeRecherche,
5542
5634
  searchPlaceholder,
5543
5635
  onSearch,
5636
+ searchDelay,
5544
5637
  loading = false,
5545
5638
  error,
5546
5639
  onRetry,
@@ -5548,6 +5641,9 @@ function CrudPage({
5548
5641
  page,
5549
5642
  totalPages,
5550
5643
  onPageChange,
5644
+ pageSize,
5645
+ onPageSizeChange,
5646
+ pageSizeOptions,
5551
5647
  table,
5552
5648
  children,
5553
5649
  className
@@ -5627,9 +5723,12 @@ function CrudPage({
5627
5723
  if (!extraRowActions) {
5628
5724
  return actionsDeLigne.length > 0 ? actionsDeLigne : void 0;
5629
5725
  }
5726
+ const suppression = actionsDeLigne.filter((a) => a.key === "delete");
5727
+ const autres = actionsDeLigne.filter((a) => a.key !== "delete");
5630
5728
  return (row, index) => [
5631
- ...actionsDeLigne,
5632
- ...typeof extraRowActions === "function" ? extraRowActions(row, index) : extraRowActions
5729
+ ...autres,
5730
+ ...typeof extraRowActions === "function" ? extraRowActions(row, index) : extraRowActions,
5731
+ ...suppression
5633
5732
  ];
5634
5733
  }, [actionsDeLigne, extraRowActions]);
5635
5734
  const creation = operations?.create === false ? null : operations?.create ?? {};
@@ -5663,6 +5762,7 @@ function CrudPage({
5663
5762
  ...searchKeys ? { searchKeys } : {},
5664
5763
  ...searchPlaceholder ? { searchPlaceholder } : {},
5665
5764
  ...onSearch ? { onSearch } : {},
5765
+ ...searchDelay !== void 0 ? { searchDelay } : {},
5666
5766
  ...toutesLesActions ? { rowActions: toutesLesActions } : {},
5667
5767
  ...can ? { can } : {},
5668
5768
  loading,
@@ -5725,7 +5825,10 @@ function CrudPage({
5725
5825
  page,
5726
5826
  totalPages,
5727
5827
  onPageChange,
5728
- showTotal: true
5828
+ showTotal: true,
5829
+ ...pageSize !== void 0 ? { pageSize } : {},
5830
+ ...onPageSizeChange ? { onPageSizeChange } : {},
5831
+ ...pageSizeOptions ? { pageSizeOptions } : {}
5729
5832
  }
5730
5833
  )
5731
5834
  ] });
@@ -6188,6 +6291,14 @@ var PhoneInput = forwardRef(
6188
6291
  [countries, initial, picked, value]
6189
6292
  );
6190
6293
  const national = value.startsWith(country.dial) ? value.slice(country.dial.length) : digitsOnly(value);
6294
+ const options = useMemo(
6295
+ () => countries.map((entry) => ({
6296
+ value: entry.code,
6297
+ label: `${entry.flag} ${entry.label} (${entry.dial})`,
6298
+ keywords: [entry.code]
6299
+ })),
6300
+ [countries]
6301
+ );
6191
6302
  const commit = (next) => {
6192
6303
  if (!controlled) setInternal(next);
6193
6304
  onValueChange?.(next);
@@ -6209,35 +6320,31 @@ var PhoneInput = forwardRef(
6209
6320
  if (country.digits) next = next.slice(0, country.digits);
6210
6321
  commit(next ? `${country.dial}${next}` : "");
6211
6322
  },
6212
- left: /* @__PURE__ */ jsxs("span", { className: "sia-phone__country", children: [
6323
+ left: lockCountry ? /* @__PURE__ */ jsxs("span", { className: "sia-phone__country", children: [
6213
6324
  /* @__PURE__ */ jsx("span", { className: "sia-phone__flag", "aria-hidden": "true", children: country.flag }),
6214
- /* @__PURE__ */ jsx("span", { className: "sia-phone__dial", children: country.dial }),
6215
- !lockCountry && /* @__PURE__ */ jsx(
6216
- "select",
6217
- {
6218
- className: "sia-phone__select",
6219
- "aria-label": locale.countryCode,
6220
- value: country.code,
6221
- disabled,
6222
- onChange: (event) => {
6223
- const next = countries.find(
6224
- (entry) => entry.code === event.target.value
6225
- );
6226
- if (!next) return;
6227
- setPicked(next.code);
6228
- commit(national ? `${next.dial}${national}` : "");
6229
- },
6230
- children: countries.map((entry) => /* @__PURE__ */ jsxs("option", { value: entry.code, children: [
6231
- entry.flag,
6232
- " ",
6233
- entry.label,
6234
- " (",
6235
- entry.dial,
6236
- ")"
6237
- ] }, entry.code))
6325
+ /* @__PURE__ */ jsx("span", { className: "sia-phone__dial", children: country.dial })
6326
+ ] }) : /* @__PURE__ */ jsx(
6327
+ Select,
6328
+ {
6329
+ variant: "embedded",
6330
+ searchable: true,
6331
+ className: "sia-phone__country",
6332
+ "aria-label": locale.countryCode,
6333
+ options,
6334
+ value: country.code,
6335
+ disabled: disabled ?? false,
6336
+ renderValue: () => /* @__PURE__ */ jsxs("span", { className: "sia-phone__value", children: [
6337
+ /* @__PURE__ */ jsx("span", { className: "sia-phone__flag", "aria-hidden": "true", children: country.flag }),
6338
+ /* @__PURE__ */ jsx("span", { className: "sia-phone__dial", children: country.dial })
6339
+ ] }),
6340
+ onValueChange: (code) => {
6341
+ const next = countries.find((entry) => entry.code === code);
6342
+ if (!next) return;
6343
+ setPicked(next.code);
6344
+ commit(national ? `${next.dial}${national}` : "");
6238
6345
  }
6239
- )
6240
- ] })
6346
+ }
6347
+ )
6241
6348
  }
6242
6349
  );
6243
6350
  }
@@ -7189,4 +7296,4 @@ function YearPicker({ value, defaultValue = (/* @__PURE__ */ new Date()).getFull
7189
7296
  return /* @__PURE__ */ jsx("select", { className: cn("sia-year-picker", className), value, defaultValue: value === void 0 ? defaultValue : void 0, onChange: (event) => onValueChange?.(Number(event.target.value)), children: years.map((year) => /* @__PURE__ */ jsx("option", { value: year, children: year }, year)) });
7190
7297
  }
7191
7298
 
7192
- export { Accordion, Alert, AlertCircleIcon, AmountDisplay, AppShell, AppShellBrand, AppShellRailItem, ArrowRightIcon, AspectRatio, AsyncState, AuditMeta, AuthLayout, Autocomplete, Avatar, AvatarGroup, Badge, BottomTabs, Breadcrumb, Button, Calendar, CalendarIcon, Can, Card, CardBody, CardFooter, CardHeader, Chart, CheckIcon, Checkbox, CheckboxGroup, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClockIcon, Collapse, ColorPicker, CommandPalette, ConfirmDialog, Container, ContextMenu, Countdown, CrudDialogs, CrudPage, CurrencyInput, DEFAULT_COUNTRIES, DataTable, DatePicker, DateRangeFilter, DateRangePicker, DateTimePicker, Descriptions, Divider, Drawer, DrawerBody, DrawerClose, DrawerFooter, DrawerHeader, DrawerTitle, DropdownMenu, DurationDisplay, EmptyState, EntityMeta, ErrorState, EventCalendar, EyeIcon, EyeOffIcon, Field, FileUpload, FiltersBar, Form, Field as FormField, Heading, HoverCard, IconButton, ImageUpload, InfoIcon, InlineCode, Input, InputNumber, JsonEditor, KpiGrid, Label, MarkdownEditor, MenuList, MiniCalendar, MinusIcon, Modal, MonthPicker, MoreHorizontalIcon, MultiSelect, OtpInput, Overlay, PageHeader, Pagination, PasswordInput, PermissionGate, PhoneInput, PlusIcon, Popover, Progress, QRCode, Radio, RadioButton, RadioGroup, Rating, ReferenceSelect, RelativeTime, RequireSession, ResizablePanel, RichTextEditor, ScrollArea, SearchIcon, SearchInput, Select, SettingsIcon, Sidebar, Skeleton, Slider, Sparkline, Spinner, Stack, StarIcon, StatCard, Statistic, Steps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, TagsInput, Text, Textarea, TimePicker, TimeRangePicker, Timeline, Timer, ToastProvider, Toaster, Toggle, ToggleGroup, Tooltip, Tour, Transfer, TrashIcon, Tree, TreeSelect, UnsavedChangesGuard, UploadIcon, WeekPicker, XIcon, YearPicker, confirmUnsavedNavigation, createUrlTableStorage, defineResource, formatDuration, formatTimeValue, initialsOf, parseTimeValue, resourceColumns, resourceDefaults, resourceDetailColumns, resourceFormFields, resourcePermissions, resourceRowKey, resourceSearchKeys, resourceValidator, tintForName, useDataTableQuery, useToast };
7299
+ export { Accordion, Alert, AlertCircleIcon, AmountDisplay, AppShell, AppShellBrand, AppShellRailItem, ArrowRightIcon, AspectRatio, AsyncState, AuditMeta, AuthLayout, Autocomplete, Avatar, AvatarGroup, Badge, BottomTabs, Breadcrumb, Button, Calendar, CalendarIcon, Can, Card, CardBody, CardFooter, CardHeader, Chart, CheckIcon, Checkbox, CheckboxGroup, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClockIcon, Collapse, ColorPicker, CommandPalette, ConfirmDialog, Container, ContextMenu, Countdown, CrudDialogs, CrudPage, CurrencyInput, DEFAULT_COUNTRIES, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, DatePicker, DateRangeFilter, DateRangePicker, DateTimePicker, Descriptions, Divider, Drawer, DrawerBody, DrawerClose, DrawerFooter, DrawerHeader, DrawerTitle, DropdownMenu, DurationDisplay, EmptyState, EntityMeta, ErrorState, EventCalendar, EyeIcon, EyeOffIcon, Field, FileUpload, FiltersBar, Form, Field as FormField, Heading, HoverCard, IconButton, ImageUpload, InfoIcon, InlineCode, Input, InputNumber, JsonEditor, KpiGrid, Label, MarkdownEditor, MenuList, MiniCalendar, MinusIcon, Modal, MonthPicker, MoreHorizontalIcon, MultiSelect, OtpInput, Overlay, PageHeader, Pagination, PasswordInput, PermissionGate, PhoneInput, PlusIcon, Popover, Progress, QRCode, Radio, RadioButton, RadioGroup, Rating, ReferenceSelect, RelativeTime, RequireSession, ResizablePanel, RichTextEditor, ScrollArea, SearchIcon, SearchInput, Select, SettingsIcon, Sidebar, Skeleton, Slider, Sparkline, Spinner, Stack, StarIcon, StatCard, Statistic, Steps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, TagsInput, Text, Textarea, TimePicker, TimeRangePicker, Timeline, Timer, ToastProvider, Toaster, Toggle, ToggleGroup, Tooltip, Tour, Transfer, TrashIcon, Tree, TreeSelect, UnsavedChangesGuard, UploadIcon, WeekPicker, XIcon, YearPicker, confirmUnsavedNavigation, createUrlTableStorage, defineResource, formFieldNames, formatDuration, formatTimeValue, initialsOf, parseTimeValue, resourceColumns, resourceDefaults, resourceDetailColumns, resourceFormFields, resourcePermissions, resourceRowKey, resourceSearchKeys, resourceValidator, tintForName, useDataTableQuery, useToast };