@eightshift/ui-components 6.1.1 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/{Button-CFnNdpNZ.js → Button-DtRmB6b8.js} +7 -6
  2. package/dist/{Dialog-D0jMcN-a.js → Dialog-DTIxSDhz.js} +115 -52
  3. package/dist/{FocusScope-BJhC1-1e.js → FocusScope-CjFQ7cbd.js} +16 -16
  4. package/dist/{Hidden-Rfj-STx7.js → Hidden-DOH36apC.js} +23 -6
  5. package/dist/{Input-B4X6-x6r.js → Input-BG9DaxYN.js} +6 -6
  6. package/dist/{Label-BDlf9vIY.js → Label-_aSf9-8u.js} +1 -1
  7. package/dist/{ListBox-BaN0n5h3.js → ListBox-DXFyyj_r.js} +15 -12
  8. package/dist/{OverlayArrow-Dy0qw7WL.js → OverlayArrow-Fuxj-1QM.js} +27 -9
  9. package/dist/{RadioGroup-CjCAbUr4.js → RadioGroup-DCeiLxLK.js} +9 -9
  10. package/dist/{SearchField-CafsA525.js → SearchField-B_yKFXRk.js} +11 -11
  11. package/dist/{SelectionManager-oojq6MOy.js → SelectionManager-B02LcxLr.js} +143 -96
  12. package/dist/{Slider-BIbaMdUE.js → Slider-bR3fAmim.js} +7 -7
  13. package/dist/{VisuallyHidden-CqnizvzQ.js → VisuallyHidden-DZnWrkn8.js} +1 -1
  14. package/dist/assets/style-admin.css +637 -327
  15. package/dist/assets/style-editor.css +637 -327
  16. package/dist/assets/style.css +637 -327
  17. package/dist/assets/wp-overrides/allow-full-width-blocks.css +1 -1
  18. package/dist/assets/wp-overrides/fix-label-text-case.css +1 -1
  19. package/dist/assets/wp-overrides/increase-sidebar-width.css +1 -1
  20. package/dist/assets/wp-overrides/make-block-messages-nicer.css +7 -7
  21. package/dist/assets/wp-overrides/replace-fonts.css +5 -5
  22. package/dist/assets/wp-overrides/restyle-tooltips.css +3 -3
  23. package/dist/assets/wp-overrides/round-corners.css +1 -1
  24. package/dist/assets/wp-overrides/unify-button-sizes.css +1 -1
  25. package/dist/components/base-control/base-control.js +1 -1
  26. package/dist/components/base-control/container.js +1 -1
  27. package/dist/components/button/button.js +12 -9
  28. package/dist/components/checkbox/checkbox.js +10 -10
  29. package/dist/components/color-pickers/solid-color-picker.js +10 -10
  30. package/dist/components/expandable/expandable.js +5 -5
  31. package/dist/components/input-field/input-field.js +6 -9
  32. package/dist/components/link-input/link-input.js +191 -68
  33. package/dist/components/matrix-align/matrix-align.js +1 -1
  34. package/dist/components/menu/menu.js +5 -5
  35. package/dist/components/modal/modal.js +11 -8
  36. package/dist/components/notice/notice.js +3 -3
  37. package/dist/components/number-picker/number-picker.js +7 -7
  38. package/dist/components/options-panel/options-panel.js +6 -6
  39. package/dist/components/popover/popover.js +8 -7
  40. package/dist/components/radio/radio.js +2 -2
  41. package/dist/components/responsive/mini-responsive.js +81 -70
  42. package/dist/components/responsive/responsive.js +24 -40
  43. package/dist/components/responsive-preview/responsive-preview.js +1 -1
  44. package/dist/components/rich-label/rich-label.js +11 -5
  45. package/dist/components/select/async-multi-select.js +89 -47
  46. package/dist/components/select/async-select.js +90 -47
  47. package/dist/components/select/multi-select.js +161 -117
  48. package/dist/components/select/shared.js +5 -4
  49. package/dist/components/select/single-select.js +159 -115
  50. package/dist/components/slider/column-config-slider.js +3 -3
  51. package/dist/components/slider/slider.js +3 -3
  52. package/dist/components/tabs/tabs.js +39 -8
  53. package/dist/components/toggle/switch.js +5 -5
  54. package/dist/components/toggle/toggle.js +1 -1
  55. package/dist/components/toggle-button/toggle-button.js +6 -6
  56. package/dist/components/tooltip/tooltip.js +11 -9
  57. package/dist/{proxy-DFlYXk07.js → proxy-CNEXmkdK.js} +205 -137
  58. package/dist/{shared-CMLCUova.js → shared-CNH8QfV9.js} +50 -15
  59. package/dist/{textSelection-CeoEP4rL.js → textSelection-DA3VcKpG.js} +1 -1
  60. package/dist/{useButton-5YL_nmpZ.js → useButton-DyMX0EVr.js} +2 -2
  61. package/dist/{useEvent-Zze2g7CX.js → useEvent-Bfy68GHZ.js} +1 -1
  62. package/dist/{useFilter-8S94U4xM.js → useFilter-Bg5C34XC.js} +1 -1
  63. package/dist/{useFocusRing-rUOwLdTK.js → useFocusRing-B2glEZ25.js} +9 -7
  64. package/dist/{useFormReset-BxtOoO5Q.js → useFormReset-BoxsKyJ9.js} +1 -1
  65. package/dist/{useFormValidation-DTmPrTD8.js → useFormValidation-BrbMhS2N.js} +4 -3
  66. package/dist/{useHover-CmyvqeWX.js → useHover-DkmPQdGE.js} +76 -58
  67. package/dist/{useListState-B22CApJO.js → useListState-BjnzKozj.js} +3 -3
  68. package/dist/{useNumberField-CTkI-U9a.js → useNumberField-CsygZKz9.js} +45 -15
  69. package/dist/{usePress-CNefMs8d.js → usePress-Ck5xMtDr.js} +21 -21
  70. package/dist/{useToggle-CFFOmZWi.js → useToggle-Ddc7N8pR.js} +4 -4
  71. package/dist/{useToggleState-BWrKKisg.js → useToggleState-H_lORSWO.js} +1 -1
  72. package/package.json +22 -21
  73. package/dist/useSingleSelectListState-CDZGQDLC.js +0 -38
@@ -2,20 +2,20 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { s as sprintf } from "../../sprintf-DmNrJSYG.js";
3
3
  import { _ as __, a as _n } from "../../default-i18n-CnQeC5Pl.js";
4
4
  import { BaseControl } from "../base-control/base-control.js";
5
- import { $ as $d2f53cda644affe3$export$2f2b9559550c7bbc, a as $440f4836bcb56932$export$b94867ecbd698f21 } from "../../SearchField-CafsA525.js";
6
- import { $ as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../../Button-CFnNdpNZ.js";
7
- import { $ as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../../Input-B4X6-x6r.js";
8
- import { $ as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../../Label-BDlf9vIY.js";
9
- import { $ as $eed445e0843c11d0$export$41f133550aa26f48 } from "../../ListBox-BaN0n5h3.js";
10
- import { f as $07b14b47974efb58$export$5b6b19405a83ff9d } from "../../Dialog-D0jMcN-a.js";
11
- import { $ as $82d7e5349645de74$export$ef9b1a59e592288f, a as $82d7e5349645de74$export$e288731fd71264f0, S as SelectClearButton, O as OptionItemBase } from "../../shared-CMLCUova.js";
12
- import { useRef, cloneElement } from "react";
5
+ import { $ as $d2f53cda644affe3$export$2f2b9559550c7bbc, a as $440f4836bcb56932$export$b94867ecbd698f21 } from "../../SearchField-B_yKFXRk.js";
6
+ import { $ as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../../Button-DtRmB6b8.js";
7
+ import { f as $07b14b47974efb58$export$5b6b19405a83ff9d, i as $72a5793c14baf454$export$8b251419efc915eb } from "../../Dialog-DTIxSDhz.js";
8
+ import { $ as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../../Input-BG9DaxYN.js";
9
+ import { $ as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../../Label-_aSf9-8u.js";
10
+ import { $ as $eed445e0843c11d0$export$41f133550aa26f48, a as $eed445e0843c11d0$export$dca12b0bb56e4fc } from "../../ListBox-DXFyyj_r.js";
11
+ import { g as getGroupedOptions, $ as $82d7e5349645de74$export$ef9b1a59e592288f, a as $82d7e5349645de74$export$e288731fd71264f0, S as SelectClearButton, O as OptionItemBase } from "../../shared-CNH8QfV9.js";
12
+ import { $ as $e1995378a142960e$export$fb8073518f34e6ec } from "../../SelectionManager-B02LcxLr.js";
13
+ import { useMemo, useRef, cloneElement } from "react";
13
14
  import { icons } from "../../icons/icons.js";
14
15
  import "../../react-jsx-parser.min-DAh4myol.js";
15
16
  import { Spinner } from "../../icons/spinner.js";
16
17
  import { RichLabel } from "../rich-label/rich-label.js";
17
18
  import { unescapeHTML } from "../../utilities/text-helpers.js";
18
- import { randomId } from "../../utilities/hash.js";
19
19
  import { c as clsx } from "../../clsx-DgYk2OaC.js";
20
20
  import { c as cva } from "../../index-BHpUy2Ix.js";
21
21
  import { TriggeredPopover } from "../popover/popover.js";
@@ -43,6 +43,7 @@ import { $ as $f86e6c1ec7da6ebb$export$bc3384a35de93d66 } from "../../useAsyncLi
43
43
  * @param {Function} [props.getMeta] - Function to get the metadata for the item from the fetched data. `(item: Object<string, any>) => Object<string, any>` (optional)
44
44
  * @param {Function} [props.getIcon] - Function to get the icon for the item from the fetched data. `(item: Object<string, any>) => JSX.Element | string`
45
45
  * @param {Function} [props.getSubtitle] - Function to get the subtitle for the item from the fetched data. `(item: Object<string, any>) => string`
46
+ * @param {Function} [props.getGroup] - Function to get the group name for the item from the fetched data. `(item: Object<string, any>) => string`
46
47
  * @param {Function} [props.getData] - Function to pre-process the fetched data before it is used in the select. `(data: Object<string, any>[]) => Object<string, any>[]`
47
48
  * @param {Function} [props.fetchUrl] - Function to get the URL for fetching data. Provides typed search text if entered. `(searchText: string) => string`
48
49
  * @param {Object} [props.fetchConfig] - Configuration object for the fetch request, passed to the `fetch` function.
@@ -52,6 +53,8 @@ import { $ as $f86e6c1ec7da6ebb$export$bc3384a35de93d66 } from "../../useAsyncLi
52
53
  * @param {JSX.Element} [props.customValueDisplay] - If provided, replaces the default current value display of each selected item. `({ value: string, label: string, subtitle: string, metadata: any }) => JSX.Element`
53
54
  * @param {JSX.Element} [props.customDropdownArrow] - If provided, replaces the default dropdown arrow indicator.
54
55
  * @param {string} props.className - Classes to pass to the select menu.
56
+ * @param {string} [props.groupKey] - If provided, the options will be grouped by this key.
57
+ * @param {Object} [props.groupValueMapping] - If provided, the group headers will be mapped to these labels/icons.
55
58
  * @param {boolean} [props.noMinWidth=false] - If `true`, the select menu will not have a minimum width.
56
59
  * @param {boolean} [props.flat] - If `true`, component will look more flat. Useful for nested layer of controls.
57
60
  * @param {boolean} [props.noReorder] - If `true`, the option for reordering selected items is disabled.
@@ -98,11 +101,14 @@ const AsyncMultiSelect = (props) => {
98
101
  getMeta,
99
102
  getIcon,
100
103
  getSubtitle,
104
+ getGroup,
101
105
  getData = (data) => data,
102
106
  customMenuOption,
103
107
  customValueDisplay,
104
108
  customDropdownArrow,
105
109
  className,
110
+ groupKey,
111
+ groupValueMapping,
106
112
  flat,
107
113
  size = "default",
108
114
  noMinWidth = false,
@@ -121,7 +127,8 @@ const AsyncMultiSelect = (props) => {
121
127
  json = processLoadedOptions ? processLoadedOptions(getData(res)) : getData(res);
122
128
  } else {
123
129
  const res = await fetch(fetchUrl(filterText), { ...fetchConfig, signal });
124
- json = processLoadedOptions ? processLoadedOptions(getData(await res.json())) : getData(res);
130
+ const data = await res.json();
131
+ json = processLoadedOptions ? processLoadedOptions(getData(data)) : getData(data);
125
132
  }
126
133
  const output = json?.map((item, index) => {
127
134
  const id = getValue?.(item) ?? index;
@@ -132,6 +139,9 @@ const AsyncMultiSelect = (props) => {
132
139
  if (getSubtitle) {
133
140
  entry.subtitle = unescapeHTML(getSubtitle(item));
134
141
  }
142
+ if (getGroup) {
143
+ entry[groupKey ?? "_group"] = getGroup(item);
144
+ }
135
145
  return entry;
136
146
  });
137
147
  if (filterText.length > 0) {
@@ -150,6 +160,40 @@ const AsyncMultiSelect = (props) => {
150
160
  };
151
161
  }
152
162
  });
163
+ const groupedItems = useMemo(
164
+ () => getGroupedOptions(list?.items, groupKey ?? (getGroup ? "_group" : null), groupValueMapping),
165
+ [list?.items, groupKey, groupValueMapping, getGroup]
166
+ );
167
+ const renderItem = (item) => {
168
+ let icon2 = item?.icon ?? null;
169
+ if (typeof item?.icon === "string") {
170
+ icon2 = icons?.[item.icon] ?? null;
171
+ }
172
+ if (getIcon && !icon2) {
173
+ icon2 = getIcon(item);
174
+ }
175
+ return /* @__PURE__ */ jsxs(
176
+ OptionItemBase,
177
+ {
178
+ id: item.value,
179
+ textValue: item.label,
180
+ selectIndicator: true,
181
+ children: [
182
+ customMenuOption && customMenuOption(item),
183
+ !customMenuOption && /* @__PURE__ */ jsx(
184
+ RichLabel,
185
+ {
186
+ icon: icon2,
187
+ label: item.label,
188
+ subtitle: item.subtitle,
189
+ noColor: true
190
+ }
191
+ )
192
+ ]
193
+ },
194
+ item.value
195
+ );
196
+ };
153
197
  const handleSelectionChange = (rawSelected) => {
154
198
  let selected;
155
199
  if (list.filterText.length > 0) {
@@ -168,7 +212,6 @@ const AsyncMultiSelect = (props) => {
168
212
  selected = rawSelected;
169
213
  }
170
214
  list.setSelectedKeys(selected);
171
- list.filterText = "";
172
215
  if (selected === null || selected === void 0) {
173
216
  onChange(null);
174
217
  return;
@@ -186,16 +229,9 @@ const AsyncMultiSelect = (props) => {
186
229
  ...option
187
230
  };
188
231
  }).filter(Boolean);
189
- onChange(
190
- selectedValues.map((item) => ({
191
- label: item?.label,
192
- value: item?.value,
193
- subtitle: item?.subtitle,
194
- meta: item?.meta
195
- }))
196
- );
232
+ onChange(selectedValues);
197
233
  };
198
- const ref = useRef();
234
+ const ref = useRef(null);
199
235
  const currentValueKeys = value?.map((item) => item?.value ?? item);
200
236
  const buttonClass = cva("es:any-focus:outline-hidden es:text-start es:size-full es:inline-block es:group es:overflow-x-clip", {
201
237
  variants: {
@@ -276,6 +312,13 @@ const AsyncMultiSelect = (props) => {
276
312
  selectionMode: "multiple",
277
313
  isDisabled: disabled,
278
314
  value: currentValueKeys ?? [],
315
+ onOpenChange: (isOpen) => {
316
+ if (!isOpen) {
317
+ setTimeout(() => {
318
+ list.setFilterText("");
319
+ }, 100);
320
+ }
321
+ },
279
322
  onChange: (selected) => handleSelectionChange(selected),
280
323
  placeholder,
281
324
  ...rest,
@@ -370,10 +413,12 @@ const AsyncMultiSelect = (props) => {
370
413
  slot: null
371
414
  },
372
415
  className: "es:grid es:grid-cols-1 es:grid-rows-[auto_minmax(0,1fr)] es:p-0!",
373
- wrapperClassName: "es:w-72 es:px-1.5 es:h-fit es:from-surface-300/35 es:to-surface-300/35 es:overflow-clip es:rounded-20!",
416
+ wrapperClassName: "es:w-(--select-width) es:min-w-72 es:px-1.5 es:h-fit es:from-surface-300/35 es:to-surface-300/35 es:overflow-clip es:rounded-20!",
374
417
  hidden: noReorder || disabled || (value ?? [])?.length < 2,
418
+ style: { "--select-width": ref.current ? `${ref.current.offsetWidth}px` : "var(--trigger-width)" },
419
+ triggerRef: ref,
375
420
  children: [
376
- /* @__PURE__ */ jsx("span", { className: 'es:text-base es:mx-auto es:my-1 es:font-variation-["wdth"_140,"wght"_320] es:text-surface-600', children: __("Item order", "eightshift-ui-components") }),
421
+ /* @__PURE__ */ jsx("span", { className: 'es:text-sm es:ml-3 es:mt-2 es:mb-1 es:font-variation-["wdth"_100,"wght"_325,"ROND"_100] es:text-surface-600', children: __("Item order", "eightshift-ui-components") }),
377
422
  /* @__PURE__ */ jsx(
378
423
  DraggableList,
379
424
  {
@@ -421,7 +466,8 @@ const AsyncMultiSelect = (props) => {
421
466
  $07b14b47974efb58$export$5b6b19405a83ff9d,
422
467
  {
423
468
  className: ({ isEntering, isExiting }) => clsx(
424
- "es:w-(--trigger-width) es:min-w-72",
469
+ "es:font-sans",
470
+ "es:w-(--select-width) es:min-w-72",
425
471
  "es:outline-hidden",
426
472
  "es:rounded-b-xl es:rounded-t-3xl",
427
473
  "es:overflow-clip es:grid es:grid-cols-1",
@@ -445,6 +491,7 @@ const AsyncMultiSelect = (props) => {
445
491
  placement: "bottom left",
446
492
  maxHeight: 260,
447
493
  triggerRef: ref,
494
+ style: { "--select-width": ref.current ? `${ref.current.offsetWidth}px` : "var(--trigger-width)" },
448
495
  children: /* @__PURE__ */ jsxs(
449
496
  $d2f53cda644affe3$export$2f2b9559550c7bbc,
450
497
  {
@@ -463,7 +510,7 @@ const AsyncMultiSelect = (props) => {
463
510
  placeholder: __("Search...", "eightshift-ui-components"),
464
511
  className: clsx(
465
512
  "es:peer es:size-full es:h-9.5 es:outline-hidden! es:pl-3.5 es:pr-9 es:shadow-none! es:text-13! es:placeholder:text-surface-500 es:[&::-webkit-search-cancel-button]:hidden",
466
- "es:bg-accent-900/8 es:m-1.5 es:rounded-3xl es:border-none!",
513
+ "es:bg-accent-900/8 es:m-1.5 es:rounded-3xl! es:border-none!",
467
514
  "es:inset-ring! es:inset-ring-accent-950/7 es:focus:inset-ring-accent-950/20",
468
515
  "es:text-accent-950 es:placeholder:text-accent-700/50",
469
516
  "es:transition"
@@ -473,6 +520,7 @@ const AsyncMultiSelect = (props) => {
473
520
  /* @__PURE__ */ jsx(
474
521
  $d2b4bc8c273e7be6$export$353f5b6fc5456de1,
475
522
  {
523
+ slot: "clear",
476
524
  "aria-label": __("Clear", "eightshift-ui-components"),
477
525
  className: clsx(
478
526
  "es:absolute es:right-3 es:top-0 es:bottom-0 es:my-auto es:border-none es:bg-transparent",
@@ -486,11 +534,10 @@ const AsyncMultiSelect = (props) => {
486
534
  }
487
535
  ),
488
536
  list.isLoading && /* @__PURE__ */ jsx("div", { className: "es:p-3 es:min-h-16 es:flex es:items-center es:justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }),
489
- /* @__PURE__ */ jsx(
537
+ /* @__PURE__ */ jsxs(
490
538
  $eed445e0843c11d0$export$41f133550aa26f48,
491
539
  {
492
540
  className: clsx("es:space-y-0.75 es:p-1.5 es:pt-0 es:any-focus:outline-hidden es:h-full es:overflow-y-auto es:rounded-t-xl", list?.isLoading && "es:hidden"),
493
- items: list?.items ?? [],
494
541
  selectedKeys: list.selectedKeys,
495
542
  selectionMode: "multiple",
496
543
  selectionBehavior: "toggle",
@@ -508,34 +555,29 @@ const AsyncMultiSelect = (props) => {
508
555
  noColor: true
509
556
  }
510
557
  ),
511
- children: (item) => {
512
- let icon2 = getIcon ? getIcon(item) : item?.icon ?? null;
513
- if (typeof item?.icon === "string") {
514
- icon2 = icons?.[item.icon] ?? null;
515
- }
516
- return /* @__PURE__ */ jsxs(
517
- OptionItemBase,
558
+ children: [
559
+ groupedItems && /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: groupedItems, children: (section) => /* @__PURE__ */ jsxs(
560
+ $eed445e0843c11d0$export$dca12b0bb56e4fc,
518
561
  {
519
- id: item?.value ?? randomId(8),
520
- className: item?.className,
521
- selectIndicator: true,
562
+ id: section.key,
563
+ className: "es:flex es:flex-col es:gap-0.75",
522
564
  children: [
523
- customMenuOption && customMenuOption(item),
524
- !customMenuOption && /* @__PURE__ */ jsx(
565
+ /* @__PURE__ */ jsx($72a5793c14baf454$export$8b251419efc915eb, { className: "es:px-2.5 es:pb-1 es:pt-3 es:select-none", children: /* @__PURE__ */ jsx(
525
566
  RichLabel,
526
567
  {
527
- icon: icon2,
528
- label: item?.label,
529
- subtitle: item?.subtitle,
530
- labelClassName: "es:line-clamp-1",
531
- subtitleClassName: "es:line-clamp-1",
532
- noColor: true
568
+ icon: section?.icon,
569
+ label: section?.label,
570
+ subtitle: section?.subtitle,
571
+ endIcon: section?.endIcon,
572
+ fullWidth: true
533
573
  }
534
- )
574
+ ) }),
575
+ /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: section.options, children: (item) => renderItem(item) })
535
576
  ]
536
577
  }
537
- );
538
- }
578
+ ) }),
579
+ !groupedItems && /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: list.items ?? [], children: (item) => renderItem(item) })
580
+ ]
539
581
  }
540
582
  )
541
583
  ]
@@ -1,20 +1,20 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { _ as __ } from "../../default-i18n-CnQeC5Pl.js";
3
3
  import { BaseControl } from "../base-control/base-control.js";
4
- import { $ as $d2f53cda644affe3$export$2f2b9559550c7bbc, a as $440f4836bcb56932$export$b94867ecbd698f21 } from "../../SearchField-CafsA525.js";
5
- import { $ as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../../Button-CFnNdpNZ.js";
6
- import { $ as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../../Input-B4X6-x6r.js";
7
- import { $ as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../../Label-BDlf9vIY.js";
8
- import { $ as $eed445e0843c11d0$export$41f133550aa26f48 } from "../../ListBox-BaN0n5h3.js";
9
- import { f as $07b14b47974efb58$export$5b6b19405a83ff9d } from "../../Dialog-D0jMcN-a.js";
10
- import { $ as $82d7e5349645de74$export$ef9b1a59e592288f, a as $82d7e5349645de74$export$e288731fd71264f0, S as SelectClearButton, O as OptionItemBase } from "../../shared-CMLCUova.js";
11
- import { useRef, cloneElement } from "react";
4
+ import { $ as $d2f53cda644affe3$export$2f2b9559550c7bbc, a as $440f4836bcb56932$export$b94867ecbd698f21 } from "../../SearchField-B_yKFXRk.js";
5
+ import { $ as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../../Button-DtRmB6b8.js";
6
+ import { f as $07b14b47974efb58$export$5b6b19405a83ff9d, i as $72a5793c14baf454$export$8b251419efc915eb } from "../../Dialog-DTIxSDhz.js";
7
+ import { $ as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../../Input-BG9DaxYN.js";
8
+ import { $ as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../../Label-_aSf9-8u.js";
9
+ import { $ as $eed445e0843c11d0$export$41f133550aa26f48, a as $eed445e0843c11d0$export$dca12b0bb56e4fc } from "../../ListBox-DXFyyj_r.js";
10
+ import { g as getGroupedOptions, $ as $82d7e5349645de74$export$ef9b1a59e592288f, a as $82d7e5349645de74$export$e288731fd71264f0, S as SelectClearButton, O as OptionItemBase } from "../../shared-CNH8QfV9.js";
11
+ import { $ as $e1995378a142960e$export$fb8073518f34e6ec } from "../../SelectionManager-B02LcxLr.js";
12
+ import { useRef, useMemo, cloneElement } from "react";
12
13
  import { icons } from "../../icons/icons.js";
13
14
  import "../../react-jsx-parser.min-DAh4myol.js";
14
15
  import { Spinner } from "../../icons/spinner.js";
15
16
  import { RichLabel } from "../rich-label/rich-label.js";
16
17
  import { unescapeHTML } from "../../utilities/text-helpers.js";
17
- import { randomId } from "../../utilities/hash.js";
18
18
  import { c as clsx } from "../../clsx-DgYk2OaC.js";
19
19
  import { c as cva } from "../../index-BHpUy2Ix.js";
20
20
  import { $ as $f86e6c1ec7da6ebb$export$bc3384a35de93d66 } from "../../useAsyncList-DsZvQXls.js";
@@ -39,6 +39,7 @@ import { $ as $f86e6c1ec7da6ebb$export$bc3384a35de93d66 } from "../../useAsyncLi
39
39
  * @param {Function} [props.getMeta] - Function to get the metadata for the item from the fetched data. `(item: Object<string, any>) => Object<string, any>` (optional)
40
40
  * @param {Function} [props.getIcon] - Function to get the icon for the item from the fetched data. `(item: Object<string, any>) => JSX.Element | string`
41
41
  * @param {Function} [props.getSubtitle] - Function to get the subtitle for the item from the fetched data. `(item: Object<string, any>) => string`
42
+ * @param {Function} [props.getGroup] - Function to get the group name for the item from the fetched data. `(item: Object<string, any>) => string`
42
43
  * @param {Function} [props.getData] - Function to pre-process the fetched data before it is used in the select. `(data: Object<string, any>[]) => Object<string, any>[]`
43
44
  * @param {Function} [props.fetchUrl] - Function to get the URL for fetching data. Provides typed search text if entered. `(searchText: string) => string`
44
45
  * @param {Object} [props.fetchConfig] - Configuration object for the fetch request, passed to the `fetch` function.
@@ -47,7 +48,9 @@ import { $ as $f86e6c1ec7da6ebb$export$bc3384a35de93d66 } from "../../useAsyncLi
47
48
  * @param {JSX.Element} [props.customMenuOption] - If provided, replaces the default item in the dropdown menu. `({ value: string, label: string, subtitle: string, metadata: any }) => JSX.Element`
48
49
  * @param {JSX.Element} [props.customValueDisplay] - If provided, replaces the default current value display of each selected item. `({ value: string, label: string, subtitle: string, metadata: any }) => JSX.Element`
49
50
  * @param {JSX.Element} [props.customDropdownArrow] - If provided, replaces the default dropdown arrow indicator.
50
- * @param {string} props.className - Classes to pass to the select menu.
51
+ * @param {string} [props.className] - Classes to pass to the select menu.
52
+ * @param {string} [props.groupKey] - If provided, the options will be grouped by this key.
53
+ * @param {Object} [props.groupValueMapping] - If provided, the group headers will be mapped to these labels/icons.
51
54
  * @param {boolean} [props.flat] - If `true`, component will look more flat. Useful for nested layer of controls.
52
55
  * @param {SelectSize} [props.size='default'] - Sets the size of the input field.
53
56
  * @param {boolean} [props.noMinWidth=false] - If `true`, the select menu will not have a minimum width.
@@ -80,7 +83,7 @@ const AsyncSelect = (props) => {
80
83
  subtitle,
81
84
  actions,
82
85
  inline,
83
- value,
86
+ value: rawValue,
84
87
  onChange,
85
88
  disabled = false,
86
89
  clearable = false,
@@ -98,16 +101,20 @@ const AsyncSelect = (props) => {
98
101
  getMeta,
99
102
  getIcon,
100
103
  getSubtitle,
104
+ getGroup,
101
105
  getData = (data) => data,
102
106
  extraItemProps,
103
107
  hidden,
108
+ groupKey,
109
+ groupValueMapping,
104
110
  flat,
105
111
  size = "default",
106
112
  noMinWidth = false,
107
113
  ...rest
108
114
  } = props;
115
+ const value = rawValue && !Array.isArray(rawValue) && typeof rawValue === "object" ? rawValue : null;
109
116
  const list = $f86e6c1ec7da6ebb$export$bc3384a35de93d66({
110
- initialSelectedKeys: value?.value ? [value?.value] : [],
117
+ initialSelectedKeys: value?.value ? [value.value] : [],
111
118
  getKey: (item) => item?.value,
112
119
  async load({ signal, filterText }) {
113
120
  let json = [];
@@ -116,7 +123,8 @@ const AsyncSelect = (props) => {
116
123
  json = processLoadedOptions ? processLoadedOptions(getData(res)) : getData(res);
117
124
  } else {
118
125
  const res = await fetch(fetchUrl(filterText), { ...fetchConfig, signal });
119
- json = processLoadedOptions ? processLoadedOptions(getData(await res.json())) : getData(res);
126
+ const data = await res.json();
127
+ json = processLoadedOptions ? processLoadedOptions(getData(data)) : getData(data);
120
128
  }
121
129
  const output = json?.map((item, index) => {
122
130
  const id = getValue?.(item) ?? index;
@@ -127,6 +135,9 @@ const AsyncSelect = (props) => {
127
135
  if (getSubtitle) {
128
136
  entry.subtitle = unescapeHTML(getSubtitle(item));
129
137
  }
138
+ if (getGroup) {
139
+ entry[groupKey ?? "_group"] = getGroup(item);
140
+ }
130
141
  return entry;
131
142
  });
132
143
  if (filterText.length > 0) {
@@ -144,7 +155,41 @@ const AsyncSelect = (props) => {
144
155
  };
145
156
  }
146
157
  });
147
- const ref = useRef();
158
+ const ref = useRef(null);
159
+ const groupedItems = useMemo(
160
+ () => getGroupedOptions(list?.items, groupKey ?? (getGroup ? "_group" : null), groupValueMapping),
161
+ [list?.items, groupKey, groupValueMapping, getGroup]
162
+ );
163
+ const renderItem = (item) => {
164
+ let icon2 = item?.icon ?? null;
165
+ if (typeof item?.icon === "string") {
166
+ icon2 = icons?.[item.icon] ?? null;
167
+ }
168
+ if (getIcon && !icon2) {
169
+ icon2 = getIcon(item);
170
+ }
171
+ return /* @__PURE__ */ jsxs(
172
+ OptionItemBase,
173
+ {
174
+ id: item.value,
175
+ textValue: item.label,
176
+ selectIndicator: true,
177
+ children: [
178
+ customMenuOption && customMenuOption(item),
179
+ !customMenuOption && /* @__PURE__ */ jsx(
180
+ RichLabel,
181
+ {
182
+ icon: icon2,
183
+ label: item.label,
184
+ subtitle: item.subtitle,
185
+ noColor: true
186
+ }
187
+ )
188
+ ]
189
+ },
190
+ item.value
191
+ );
192
+ };
148
193
  if (hidden) {
149
194
  return null;
150
195
  }
@@ -219,7 +264,6 @@ const AsyncSelect = (props) => {
219
264
  }
220
265
  );
221
266
  const handleSelectionChange = (selected) => {
222
- list.filterText = "";
223
267
  if (selected === null || selected === void 0) {
224
268
  onChange(null);
225
269
  return;
@@ -232,18 +276,20 @@ const AsyncSelect = (props) => {
232
276
  if (item && "id" in item) {
233
277
  delete item.id;
234
278
  }
235
- onChange({
236
- label: item?.label,
237
- value: item?.value,
238
- subtitle: item?.subtitle,
239
- meta: item?.meta
240
- });
279
+ onChange(item);
241
280
  };
242
281
  return /* @__PURE__ */ jsx(
243
282
  $82d7e5349645de74$export$ef9b1a59e592288f,
244
283
  {
245
284
  isDisabled: disabled,
246
285
  value: value?.value ?? null,
286
+ onOpenChange: (isOpen) => {
287
+ if (!isOpen) {
288
+ setTimeout(() => {
289
+ list.setFilterText("");
290
+ }, 100);
291
+ }
292
+ },
247
293
  onChange: (selected) => handleSelectionChange(selected),
248
294
  placeholder,
249
295
  ...rest,
@@ -320,7 +366,8 @@ const AsyncSelect = (props) => {
320
366
  $07b14b47974efb58$export$5b6b19405a83ff9d,
321
367
  {
322
368
  className: ({ isEntering, isExiting }) => clsx(
323
- "es:w-(--trigger-width) es:min-w-72",
369
+ "es:font-sans",
370
+ "es:w-(--select-width) es:min-w-72",
324
371
  "es:outline-hidden",
325
372
  "es:rounded-t-3xl",
326
373
  "es:overflow-clip es:grid es:grid-cols-1",
@@ -343,8 +390,9 @@ const AsyncSelect = (props) => {
343
390
  isExiting && "es:placement-top:motion-translate-y-out-[0.5rem] es:placement-bottom:motion-translate-y-out-[-0.5rem]"
344
391
  ),
345
392
  placement: "bottom left",
346
- maxHeight: 300,
393
+ maxHeight: 260,
347
394
  triggerRef: ref,
395
+ style: { "--select-width": ref.current ? `${ref.current.offsetWidth}px` : "var(--trigger-width)" },
348
396
  children: /* @__PURE__ */ jsxs(
349
397
  $d2f53cda644affe3$export$2f2b9559550c7bbc,
350
398
  {
@@ -363,7 +411,7 @@ const AsyncSelect = (props) => {
363
411
  placeholder: __("Search...", "eightshift-ui-components"),
364
412
  className: clsx(
365
413
  "es:peer es:size-full es:h-9.5 es:outline-hidden! es:pl-3.5 es:pr-9 es:shadow-none! es:text-13! es:placeholder:text-surface-500 es:[&::-webkit-search-cancel-button]:hidden",
366
- "es:bg-accent-900/8 es:m-1.5 es:rounded-3xl es:border-none!",
414
+ "es:bg-accent-900/8 es:m-1.5 es:rounded-3xl! es:border-none!",
367
415
  "es:inset-ring! es:inset-ring-accent-950/7 es:focus:inset-ring-accent-950/20",
368
416
  "es:text-accent-950 es:placeholder:text-accent-700/50",
369
417
  "es:transition"
@@ -373,6 +421,7 @@ const AsyncSelect = (props) => {
373
421
  /* @__PURE__ */ jsx(
374
422
  $d2b4bc8c273e7be6$export$353f5b6fc5456de1,
375
423
  {
424
+ slot: "clear",
376
425
  "aria-label": __("Clear", "eightshift-ui-components"),
377
426
  className: clsx(
378
427
  "es:absolute es:right-3 es:top-0 es:bottom-0 es:my-auto es:border-none es:bg-transparent",
@@ -386,11 +435,10 @@ const AsyncSelect = (props) => {
386
435
  }
387
436
  ),
388
437
  list.isLoading && /* @__PURE__ */ jsx("div", { className: "es:p-3 es:min-h-16 es:flex es:items-center es:justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }),
389
- /* @__PURE__ */ jsx(
438
+ /* @__PURE__ */ jsxs(
390
439
  $eed445e0843c11d0$export$41f133550aa26f48,
391
440
  {
392
441
  className: clsx("es:space-y-0.75 es:p-1.5 es:pt-0 es:any-focus:outline-hidden es:h-full es:overflow-y-auto es:rounded-t-xl", list?.isLoading && "es:hidden"),
393
- items: list.items,
394
442
  selectedKeys: list.selectedKeys,
395
443
  onSelectionChange: (selected) => {
396
444
  list.setSelectedKeys(selected);
@@ -407,34 +455,29 @@ const AsyncSelect = (props) => {
407
455
  noColor: true
408
456
  }
409
457
  ),
410
- children: (item) => {
411
- let icon2 = getIcon ? getIcon(item) : item?.icon ?? null;
412
- if (typeof item?.icon === "string") {
413
- icon2 = icons?.[item.icon] ?? null;
414
- }
415
- return /* @__PURE__ */ jsxs(
416
- OptionItemBase,
458
+ children: [
459
+ groupedItems && /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: groupedItems, children: (section) => /* @__PURE__ */ jsxs(
460
+ $eed445e0843c11d0$export$dca12b0bb56e4fc,
417
461
  {
418
- id: item?.value ?? randomId(8),
419
- className: item?.className,
420
- selectIndicator: true,
462
+ id: section.key,
463
+ className: "es:flex es:flex-col es:gap-0.75",
421
464
  children: [
422
- customMenuOption && customMenuOption(item),
423
- !customMenuOption && /* @__PURE__ */ jsx(
465
+ /* @__PURE__ */ jsx($72a5793c14baf454$export$8b251419efc915eb, { className: "es:px-2.5 es:pb-1 es:pt-3 es:select-none", children: /* @__PURE__ */ jsx(
424
466
  RichLabel,
425
467
  {
426
- icon: icon2,
427
- label: item?.label,
428
- subtitle: item?.subtitle,
429
- labelClassName: "es:line-clamp-1",
430
- subtitleClassName: "es:line-clamp-1",
431
- noColor: true
468
+ icon: section?.icon,
469
+ label: section?.label,
470
+ subtitle: section?.subtitle,
471
+ endIcon: section?.endIcon,
472
+ fullWidth: true
432
473
  }
433
- )
474
+ ) }),
475
+ /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: section.options, children: (item) => renderItem(item) })
434
476
  ]
435
477
  }
436
- );
437
- }
478
+ ) }),
479
+ !groupedItems && /* @__PURE__ */ jsx($e1995378a142960e$export$fb8073518f34e6ec, { items: list.items, children: (item) => renderItem(item) })
480
+ ]
438
481
  }
439
482
  )
440
483
  ]