@keboola/design 11.4.0 → 11.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.
Files changed (173) hide show
  1. package/AGENTS.md +191 -1
  2. package/CHANGELOG.md +358 -0
  3. package/COMPONENT-API.md +68 -47
  4. package/dist/{AIKit-DDg5DBCG.js → AIKit-CNX6aiKm.js} +208 -62
  5. package/dist/AIKit-CNX6aiKm.js.map +1 -0
  6. package/dist/{Alert-DHJFrWnS.js → Alert-Ba5b2YPq.js} +2 -2
  7. package/dist/{Alert-DHJFrWnS.js.map → Alert-Ba5b2YPq.js.map} +1 -1
  8. package/dist/{Badge-Ch26CXoP.js → Badge-D0pXdekt.js} +2 -2
  9. package/dist/Badge-D0pXdekt.js.map +1 -0
  10. package/dist/{BrandEditor-Go7w8Zj2.js → BrandEditor-CSANsxUz.js} +6 -6
  11. package/dist/{BrandEditor-Go7w8Zj2.js.map → BrandEditor-CSANsxUz.js.map} +1 -1
  12. package/dist/{BrandLogo-Dmi7jo21.js → BrandLogo-CoKBk4MI.js} +4 -4
  13. package/dist/BrandLogo-CoKBk4MI.js.map +1 -0
  14. package/dist/{Breadcrumb-uEkM6adI.js → Breadcrumb-g_xn_-Nf.js} +2 -2
  15. package/dist/{Breadcrumb-uEkM6adI.js.map → Breadcrumb-g_xn_-Nf.js.map} +1 -1
  16. package/dist/{Checkbox-fC0BuO2B.js → Checkbox-CUIn2jap.js} +2 -2
  17. package/dist/{Checkbox-fC0BuO2B.js.map → Checkbox-CUIn2jap.js.map} +1 -1
  18. package/dist/{Clipboard-ChPdiUy3.js → Clipboard-BTW6C-b_.js} +2 -2
  19. package/dist/{Clipboard-ChPdiUy3.js.map → Clipboard-BTW6C-b_.js.map} +1 -1
  20. package/dist/{ClipboardButton-D9pDjgkB.js → ClipboardButton-CwZJdRaz.js} +2 -2
  21. package/dist/{ClipboardButton-D9pDjgkB.js.map → ClipboardButton-CwZJdRaz.js.map} +1 -1
  22. package/dist/{CodeEditor-Cxy3HnKH.js → CodeEditor-C9zy7PxK.js} +6 -6
  23. package/dist/{CodeEditor-Cxy3HnKH.js.map → CodeEditor-C9zy7PxK.js.map} +1 -1
  24. package/dist/{ColorInput-Bxj-1eLT.js → ColorInput-BZV-u_94.js} +3 -3
  25. package/dist/{ColorInput-Bxj-1eLT.js.map → ColorInput-BZV-u_94.js.map} +1 -1
  26. package/dist/{Combobox-Cs_1pj2q.js → Combobox-BfIfaVMA.js} +273 -104
  27. package/dist/Combobox-BfIfaVMA.js.map +1 -0
  28. package/dist/{Command-B7ML9YMv.js → Command-Bfa1kpbt.js} +2 -2
  29. package/dist/{Command-B7ML9YMv.js.map → Command-Bfa1kpbt.js.map} +1 -1
  30. package/dist/{CopyField-BO_sh-HO.js → CopyField-DpT0Ngz1.js} +2 -2
  31. package/dist/{CopyField-BO_sh-HO.js.map → CopyField-DpT0Ngz1.js.map} +1 -1
  32. package/dist/{DateInput-ZdaMQo5i.js → DateInput-DiEd5uCL.js} +3 -3
  33. package/dist/{DateInput-ZdaMQo5i.js.map → DateInput-DiEd5uCL.js.map} +1 -1
  34. package/dist/{DateRangeInput-DkvNh_sT.js → DateRangeInput-DPfVYchl.js} +3 -3
  35. package/dist/{DateRangeInput-DkvNh_sT.js.map → DateRangeInput-DPfVYchl.js.map} +1 -1
  36. package/dist/{FieldItem-CCd9-xnp.js → FieldItem-B7XMmZSz.js} +3 -3
  37. package/dist/{FieldItem-CCd9-xnp.js.map → FieldItem-B7XMmZSz.js.map} +1 -1
  38. package/dist/{Form-k6PH-em3.js → Form-CsttTHn4.js} +7 -7
  39. package/dist/Form-CsttTHn4.js.map +1 -0
  40. package/dist/{FormGroup-DbcDtrgU.js → FormGroup-DHvTFdno.js} +3 -3
  41. package/dist/{FormGroup-DbcDtrgU.js.map → FormGroup-DHvTFdno.js.map} +1 -1
  42. package/dist/{InputGroup-BnLHY0eq.js → InputGroup-DcZRlVnN.js} +22 -14
  43. package/dist/InputGroup-DcZRlVnN.js.map +1 -0
  44. package/dist/{Kbd-CvSM3D3-.js → Kbd-Cvvt91Q8.js} +14 -4
  45. package/dist/Kbd-Cvvt91Q8.js.map +1 -0
  46. package/dist/{MermaidDiagram-WkonYErO.js → MermaidDiagram-CXG5tC6J.js} +19 -18
  47. package/dist/MermaidDiagram-CXG5tC6J.js.map +1 -0
  48. package/dist/{MultiActionButtonGroup-CxWH7yWK.js → MultiActionButtonGroup-DokHbPgM.js} +2 -2
  49. package/dist/{MultiActionButtonGroup-CxWH7yWK.js.map → MultiActionButtonGroup-DokHbPgM.js.map} +1 -1
  50. package/dist/{Navbar-B2UsolVU.js → Navbar-Liy1TPI7.js} +6 -6
  51. package/dist/{Navbar-B2UsolVU.js.map → Navbar-Liy1TPI7.js.map} +1 -1
  52. package/dist/PageHeader-Q3IpCnQd.js.map +1 -1
  53. package/dist/{PageToolbar-DnbFt14Q.js → PageToolbar-DExqEYGl.js} +2 -2
  54. package/dist/{PageToolbar-DnbFt14Q.js.map → PageToolbar-DExqEYGl.js.map} +1 -1
  55. package/dist/{Popconfirm-CILjmzKI.js → Popconfirm-5pBzT_HQ.js} +10 -11
  56. package/dist/{Popconfirm-CILjmzKI.js.map → Popconfirm-5pBzT_HQ.js.map} +1 -1
  57. package/dist/{RadioGroup-XFzFd1ti.js → RadioGroup-DXPbSj8P.js} +2 -2
  58. package/dist/{RadioGroup-XFzFd1ti.js.map → RadioGroup-DXPbSj8P.js.map} +1 -1
  59. package/dist/{Search-4Bxtt8hS.js → Search-5uQAiNIP.js} +2 -2
  60. package/dist/{Search-4Bxtt8hS.js.map → Search-5uQAiNIP.js.map} +1 -1
  61. package/dist/{SearchInput-f_oY9T4Z.js → SearchInput-D4UgAXJK.js} +3 -3
  62. package/dist/{SearchInput-f_oY9T4Z.js.map → SearchInput-D4UgAXJK.js.map} +1 -1
  63. package/dist/{SectionNav-BpJlisbT.js → SectionNav-OkKCjSA-.js} +3 -3
  64. package/dist/{SectionNav-BpJlisbT.js.map → SectionNav-OkKCjSA-.js.map} +1 -1
  65. package/dist/{Select-DpcgKqKB.js → Select-DV3Hak_l.js} +3 -4
  66. package/dist/Select-DV3Hak_l.js.map +1 -0
  67. package/dist/{Sidebar-Cm6I4dE1.js → Sidebar-D3cY1kha.js} +44 -20
  68. package/dist/Sidebar-D3cY1kha.js.map +1 -0
  69. package/dist/{Slider-pPC_3gz9.js → Slider-CRf-bB4y.js} +2 -2
  70. package/dist/{Slider-pPC_3gz9.js.map → Slider-CRf-bB4y.js.map} +1 -1
  71. package/dist/{Switch-ChfPKcTE.js → Switch-B0WdGSjz.js} +7 -7
  72. package/dist/{Switch-ChfPKcTE.js.map → Switch-B0WdGSjz.js.map} +1 -1
  73. package/dist/{TextInput-DHM6dHmn.js → TextInput-DH5SkbsE.js} +3 -3
  74. package/dist/{TextInput-DHM6dHmn.js.map → TextInput-DH5SkbsE.js.map} +1 -1
  75. package/dist/{ThemeProvider-DrQJtzpd.js → ThemeProvider-2RMdVGxO.js} +17 -12
  76. package/dist/{ThemeProvider-DrQJtzpd.js.map → ThemeProvider-2RMdVGxO.js.map} +1 -1
  77. package/dist/{Timeline-6btyJl4D.js → Timeline-BG5Xogxh.js} +11 -11
  78. package/dist/{Timeline-6btyJl4D.js.map → Timeline-BG5Xogxh.js.map} +1 -1
  79. package/dist/{Workbench-BzE-Vvd9.js → Workbench-UR2FBC7I.js} +3 -1
  80. package/dist/Workbench-UR2FBC7I.js.map +1 -0
  81. package/dist/{ZoomableSvg-BWnDkR61.js → ZoomableSvg-pooPb1Cu.js} +3 -3
  82. package/dist/{ZoomableSvg-BWnDkR61.js.map → ZoomableSvg-pooPb1Cu.js.map} +1 -1
  83. package/dist/editors.js +4 -4
  84. package/dist/flint.js +134 -8
  85. package/dist/flint.js.map +1 -1
  86. package/dist/index.d.ts +537 -135
  87. package/dist/index.js +40 -39
  88. package/dist/internal/blocks/AIKit.js +2 -2
  89. package/dist/internal/blocks/AuthLayout.js +118 -0
  90. package/dist/internal/blocks/AuthLayout.js.map +1 -0
  91. package/dist/internal/blocks/BrandEditor.js +1 -1
  92. package/dist/internal/blocks/ClipboardButton.js +1 -1
  93. package/dist/internal/blocks/ColorInput.js +1 -1
  94. package/dist/internal/blocks/Command.js +1 -1
  95. package/dist/internal/blocks/CopyField.js +1 -1
  96. package/dist/internal/blocks/DateInput.js +1 -1
  97. package/dist/internal/blocks/DateRangeInput.js +1 -1
  98. package/dist/internal/blocks/ExportMenu.js +1 -1
  99. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  100. package/dist/internal/blocks/Form.js +1 -1
  101. package/dist/internal/blocks/FormGroup.js +1 -1
  102. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  103. package/dist/internal/blocks/MultiCombobox.js +107 -48
  104. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  105. package/dist/internal/blocks/NumberInput.js +1 -1
  106. package/dist/internal/blocks/PageToolbar.js +1 -1
  107. package/dist/internal/blocks/PasswordInput.js +2 -2
  108. package/dist/internal/blocks/SearchInput.js +1 -1
  109. package/dist/internal/blocks/SearchInputWithNavigation.js +2 -2
  110. package/dist/internal/blocks/SectionNav.js +1 -1
  111. package/dist/internal/blocks/TextInput.js +1 -1
  112. package/dist/internal/blocks/Textarea.js +1 -1
  113. package/dist/internal/blocks/TimeInput.js +2 -2
  114. package/dist/internal/components/Alert.js +1 -1
  115. package/dist/internal/components/Avatar.js +1 -1
  116. package/dist/internal/components/Badge.js +1 -1
  117. package/dist/internal/components/BrandLogo.js +1 -1
  118. package/dist/internal/components/Breadcrumb.js +1 -1
  119. package/dist/internal/components/Checkbox.js +1 -1
  120. package/dist/internal/components/Clipboard.js +1 -1
  121. package/dist/internal/components/CollapsiblePanel.js +1 -1
  122. package/dist/internal/components/Combobox.js +2 -2
  123. package/dist/internal/components/InputGroup.js +1 -1
  124. package/dist/internal/components/Kbd.js +1 -1
  125. package/dist/internal/components/Navbar.js +1 -1
  126. package/dist/internal/components/Popconfirm.js +1 -1
  127. package/dist/internal/components/RadioGroup.js +1 -1
  128. package/dist/internal/components/Search.js +1 -1
  129. package/dist/internal/components/Select.js +1 -1
  130. package/dist/internal/components/Sidebar.js +1 -1
  131. package/dist/internal/components/Slider.js +1 -1
  132. package/dist/internal/components/Switch.js +1 -1
  133. package/dist/internal/components/ThemeProvider.js +1 -1
  134. package/dist/internal/components/Timeline.js +1 -1
  135. package/dist/internal/components/Tooltip.js +1 -1
  136. package/dist/internal/components/Truncated.js +1 -1
  137. package/dist/internal/components/Workbench.js +1 -1
  138. package/dist/internal/components/ZoomableSvg.js +1 -1
  139. package/dist/internal/utils.js +2 -2
  140. package/dist/markdown-editor.js +29 -23
  141. package/dist/markdown-editor.js.map +1 -1
  142. package/dist/mermaid.js +1 -1
  143. package/dist/rjsf.js +22 -23
  144. package/dist/rjsf.js.map +1 -1
  145. package/dist/styles.css +1 -1
  146. package/dist/testing.js +1 -1
  147. package/dist/{useColorSchemeState-klihG9-i.js → themeScopeContext-D7fSyb06.js} +16 -3
  148. package/dist/themeScopeContext-D7fSyb06.js.map +1 -0
  149. package/dist/{themeTokens-D70HeNVF.js → themeTokens-qP1-55O7.js} +37 -10
  150. package/dist/themeTokens-qP1-55O7.js.map +1 -0
  151. package/dist/{utils-B5Z52hYs.js → utils-DSvrhU8E.js} +6 -2
  152. package/dist/{utils-B5Z52hYs.js.map → utils-DSvrhU8E.js.map} +1 -1
  153. package/dist/vega.d.ts +1 -1
  154. package/dist/vega.js +3 -3
  155. package/dist/vega.js.map +1 -1
  156. package/dist/{vegaTheme-DfoEQhOy.js → vegaTheme-CSvFEMBl.js} +6 -6
  157. package/dist/vegaTheme-CSvFEMBl.js.map +1 -0
  158. package/package.json +12 -10
  159. package/src/styles.css +3 -0
  160. package/dist/AIKit-DDg5DBCG.js.map +0 -1
  161. package/dist/Badge-Ch26CXoP.js.map +0 -1
  162. package/dist/BrandLogo-Dmi7jo21.js.map +0 -1
  163. package/dist/Combobox-Cs_1pj2q.js.map +0 -1
  164. package/dist/Form-k6PH-em3.js.map +0 -1
  165. package/dist/InputGroup-BnLHY0eq.js.map +0 -1
  166. package/dist/Kbd-CvSM3D3-.js.map +0 -1
  167. package/dist/MermaidDiagram-WkonYErO.js.map +0 -1
  168. package/dist/Select-DpcgKqKB.js.map +0 -1
  169. package/dist/Sidebar-Cm6I4dE1.js.map +0 -1
  170. package/dist/Workbench-BzE-Vvd9.js.map +0 -1
  171. package/dist/themeTokens-D70HeNVF.js.map +0 -1
  172. package/dist/useColorSchemeState-klihG9-i.js.map +0 -1
  173. package/dist/vegaTheme-DfoEQhOy.js.map +0 -1
@@ -1,16 +1,36 @@
1
1
  import { useArgoDesign } from "../../context-D7X470dy.js";
2
2
  import { ChevronDown, Plus, X } from "../../icons-Cek151jC.js";
3
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
4
- import { Combobox as Combobox$1, createCreatableItem, defaultGroupToLabel, defaultItemToDisabled, defaultItemToIcon, defaultItemToLabel, defaultQueryToCreateLabel, defaultToCreateValue, isCreatableItem, isGroupItem, isGroupItems, isLabeledItem, toLabel } from "../../Combobox-Cs_1pj2q.js";
5
- import { Fragment, useState } from "react";
3
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
4
+ import { Combobox as Combobox$1, createCreatableItem, defaultGroupToLabel, defaultItemToDisabled, defaultItemToIcon, defaultItemToLabel, defaultQueryToCreateLabel, defaultToCreateValue, isCreatableItem, isGroupItem, isGroupItems, isSelectAllItem, namedLabel, sanitizeTypedInput, selectAllItem, toItemEquality, toLabel, useQueryReporter } from "../../Combobox-BfIfaVMA.js";
5
+ import { Fragment, useMemo, useState } from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Combobox } from "@base-ui/react/combobox";
8
8
  //#region src/blocks/MultiCombobox/MultiCombobox.tsx
9
- const selectAllItem = {
10
- value: "__select_all__",
11
- label: "Select All"
9
+ /**
10
+ * The strings one creatable entry stands for.
11
+ *
12
+ * - `id1, id2,` is two values: the blanks a stray separator leaves are dropped.
13
+ * - A repeat collapses to its first occurrence, case-insensitively, as everything the control
14
+ * matches by display string does — one entry cannot add the same value twice.
15
+ * - A `null` separator yields the entry itself.
16
+ */
17
+ const DEFAULT_CREATE_SEPARATOR = ",";
18
+ /**
19
+ * How the create row lists the values it adds: each separated by the entry's own separator, then
20
+ * a space. A `RegExp` stands for many strings, so the default separator stands in for it.
21
+ */
22
+ const joinCreateParts = (parts, separator) => parts.join(`${typeof separator === "string" ? separator : DEFAULT_CREATE_SEPARATOR} `);
23
+ const splitCreateEntry = (entry, separator) => {
24
+ if (separator === null) return [entry];
25
+ const seen = /* @__PURE__ */ new Set();
26
+ return entry.split(separator).map((part) => part.trim()).filter((part) => {
27
+ if (part === "") return false;
28
+ const key = part.toLowerCase();
29
+ if (seen.has(key)) return false;
30
+ seen.add(key);
31
+ return true;
32
+ });
12
33
  };
13
- const isSelectAllItem = (item) => isLabeledItem(item) && item.value === "__select_all__";
14
34
  /**
15
35
  * Multi-selection combobox with chip display and search. Built on Base UI Combobox.
16
36
  *
@@ -18,20 +38,23 @@ const isSelectAllItem = (item) => isLabeledItem(item) && item.value === "__selec
18
38
  * Items render as chips above the input; `maxVisible` collapses excess into a `+N more` chip.
19
39
  * **When NOT to use:** for single selection use `Combobox`; for short enums without search use `Select`.
20
40
  * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` for form integration.
21
- * Pass `allowSelectAll` for a sticky "Select All" item when the full enum is small. Pass `allowCreate`
22
- * to let the user add free-form values that are not in `items` (e.g. entering column names by hand).
41
+ * Pass `allowSelectAll` for a "Select All" item when the full enum is small — it covers the whole set
42
+ * and hides itself while a query is active. Pass `allowCreate` to let the user add free-form values
43
+ * that are not in `items` (e.g. entering column names by hand).
23
44
  *
24
45
  * @see RECIPES.md#creatable-multi-combobox — for free-form-plus-enumerated patterns
25
46
  * @see RECIPES.md#filter-toolbar — for combining multi-select with other filter chips
26
47
  */
27
- const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onValueChange, itemToStringLabel, itemToStringValue, disabled, filter: filterProp, inputRef, variant, sizing, focusVariant, state, placeholder, allowClear, id, name, onBlur, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, className, allowSelectAll = false, empty = "No items", indicator, allowCreate, queryToCreateValue, queryToCreateLabel = defaultQueryToCreateLabel, itemToDisabled = defaultItemToDisabled, itemToLabel = defaultItemToLabel, itemToIcon = defaultItemToIcon, groupToLabel = defaultGroupToLabel, itemToChipLabel, itemToChipColor, pinnedChipLabels, maxVisible = 3 }) => {
48
+ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onValueChange, itemToStringLabel, itemToStringValue, disabled, filter: filterProp, isItemEqualToValue: isItemEqualToValueProp, inputRef, variant, sizing, focusVariant, state, placeholder, allowClear = true, id, name, onBlur, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, className, allowSelectAll = false, empty = "No items", indicator, inputValueSanitizer, onQueryChange, allowCreate, canCreate, queryToCreateValue, queryToCreateLabel = defaultQueryToCreateLabel, createSeparator = DEFAULT_CREATE_SEPARATOR, itemToDisabled = defaultItemToDisabled, itemToLabel: itemToLabelProp, itemToIcon = defaultItemToIcon, groupToLabel = defaultGroupToLabel, itemToChipLabel, itemToChipColor, pinnedChipLabels, renderChips, maxVisible = 3 }) => {
28
49
  const itemsProp = _itemsProp ?? [];
29
50
  const valueProp = _valueProp ?? [];
51
+ const itemToLabel = itemToLabelProp ?? (itemToStringLabel ? (item) => namedLabel(itemToStringLabel(item)) : defaultItemToLabel);
30
52
  const chipVariant = useArgoDesign() ? "pill" : "default";
31
53
  const [inputValue, setInputValue] = useState("");
32
54
  const [createdItems, setCreatedItems] = useState([]);
33
55
  const query = inputValue.trim();
34
- const queryLower = query.toLowerCase();
56
+ useQueryReporter(query, onQueryChange);
57
+ const ownsInput = Boolean(allowCreate || inputValueSanitizer || onQueryChange);
35
58
  const baseItems = (() => {
36
59
  if (createdItems.length === 0) return itemsProp;
37
60
  if (isGroupItems(itemsProp)) return [...itemsProp, { items: createdItems }];
@@ -39,59 +62,101 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
39
62
  })();
40
63
  const allFlatItems = baseItems.flatMap((item) => isGroupItem(item) ? item.items : item);
41
64
  const sampleItem = allFlatItems[0];
42
- const isAllSelected = allFlatItems.length === (valueProp?.length ?? 0);
65
+ const hasSelectAllRow = allowSelectAll && allFlatItems.length > 0;
66
+ const isAllSelected = hasSelectAllRow && allFlatItems.length === (valueProp?.length ?? 0);
43
67
  const defaultFilter = Combobox.useFilter({
44
68
  multiple: true,
45
69
  value: valueProp
46
70
  });
47
- const itemsWithSelectAllItem = (() => {
48
- if (!allowSelectAll) return baseItems;
49
- return [selectAllItem, ...baseItems];
50
- })();
71
+ const itemsWithSelectAllItem = hasSelectAllRow ? [selectAllItem, ...baseItems] : baseItems;
51
72
  const itemToString = (item) => itemToStringLabel?.(item) ?? toLabel(item);
73
+ const labelKey = (item) => itemToString(item).toLowerCase();
74
+ const createParts = !allowCreate || disabled || !query ? [] : splitCreateEntry(query, createSeparator);
75
+ const selectedKeys = /* @__PURE__ */ new Set();
76
+ if (createParts.length > 0) for (const item of valueProp) selectedKeys.add(labelKey(item));
77
+ const itemKeys = /* @__PURE__ */ new Set();
78
+ if (createParts.length > 0 && canCreate) for (const item of allFlatItems) itemKeys.add(labelKey(item));
79
+ const namesAnItem = (key) => canCreate ? itemKeys.has(key) : allFlatItems.some((item) => labelKey(item) === key);
80
+ /**
81
+ * What the entry adds to the selection: its values the selection does not already hold.
82
+ *
83
+ * - The create row is named from this and committing it adds exactly this, so the row cannot
84
+ * promise something else. A value naming an existing item counts — committing selects it.
85
+ * - `canCreate` drops a value the control would mint and the gate rejects. One naming an item
86
+ * is selected rather than minted, so its format is not that gate's business.
87
+ * - `value` is the whole selection (it is never `undefined`, so the control is always the
88
+ * controlled one), which is why the commit path re-derives nothing.
89
+ */
90
+ const addedCreateParts = createParts.filter((part) => {
91
+ const key = part.toLowerCase();
92
+ if (selectedKeys.has(key)) return false;
93
+ return !canCreate || namesAnItem(key) || canCreate(part);
94
+ });
95
+ const soleValueKey = createParts.length === 1 ? createParts[0].toLowerCase() : void 0;
96
+ const showCreateRow = addedCreateParts.length > 0 && (soleValueKey === void 0 || !namesAnItem(soleValueKey));
52
97
  const items = (() => {
53
98
  const base = itemsWithSelectAllItem;
54
- if (!allowCreate || disabled || !query) return base;
55
- const exactMatch = allFlatItems.some((item) => itemToString(item).toLowerCase() === queryLower);
56
- const alreadySelected = valueProp.some((item) => itemToString(item).toLowerCase() === queryLower);
57
- if (exactMatch || alreadySelected) return base;
99
+ if (!showCreateRow) return base;
58
100
  const creatable = createCreatableItem(query);
59
101
  return isGroupItems(base) ? [...base, { items: [creatable] }] : [...base, creatable];
60
102
  })();
61
103
  const filter = (item, query, itemToString) => {
62
- if (isSelectAllItem(item)) return true;
104
+ if (isSelectAllItem(item)) return query.trim() === "";
63
105
  if (isCreatableItem(item)) return true;
64
106
  if (filterProp) return filterProp(item, query, itemToString);
65
107
  return defaultFilter.contains(item, query, itemToString);
66
108
  };
109
+ const isItemEqualToValue = useMemo(() => toItemEquality(isItemEqualToValueProp), [isItemEqualToValueProp]);
67
110
  const wrappedItemToStringLabel = !allowCreate ? itemToStringLabel : (item) => isCreatableItem(item) ? item.value : itemToString(item);
68
111
  const wrappedItemToStringValue = !allowCreate || !itemToStringValue ? itemToStringValue : (item) => isCreatableItem(item) ? item.value : itemToStringValue(item);
69
- const value = (() => {
70
- if (!allowSelectAll) return valueProp;
71
- return isAllSelected ? [...valueProp, selectAllItem] : valueProp;
72
- })();
112
+ const value = isAllSelected ? [...valueProp, selectAllItem] : valueProp;
113
+ const handleInputValueChange = (next, { reason }) => {
114
+ setInputValue(sanitizeTypedInput(next, reason, inputValueSanitizer));
115
+ };
73
116
  const handleValueChange = (next, event) => {
117
+ if (ownsInput) setInputValue((prev) => prev === "" ? prev : "");
74
118
  if (!onValueChange) return;
75
119
  const created = [];
76
- const converted = allowCreate ? next.map((item) => {
77
- if (!isCreatableItem(item)) return item;
78
- const value = defaultToCreateValue(item.value, sampleItem, queryToCreateValue);
79
- created.push(value);
80
- return value;
81
- }) : next;
120
+ const converted = (() => {
121
+ if (!allowCreate || !next.some(isCreatableItem)) return next;
122
+ const itemsByLabel = /* @__PURE__ */ new Map();
123
+ for (const item of allFlatItems) itemsByLabel.set(labelKey(item), item);
124
+ return next.flatMap((item) => {
125
+ if (!isCreatableItem(item)) return [item];
126
+ return addedCreateParts.map((part) => {
127
+ const existing = itemsByLabel.get(part.toLowerCase());
128
+ if (existing !== void 0) return existing;
129
+ const value = defaultToCreateValue(part, sampleItem, queryToCreateValue);
130
+ created.push(value);
131
+ return value;
132
+ });
133
+ });
134
+ })();
82
135
  const hasSelectAll = converted.some((item) => isSelectAllItem(item));
83
136
  const newValue = (() => {
84
- if (!allowSelectAll) return converted;
137
+ if (!hasSelectAllRow) return converted;
85
138
  if (!hasSelectAll) return isAllSelected ? [] : converted;
86
139
  return isAllSelected ? converted.filter((item) => !isSelectAllItem(item)) : allFlatItems;
87
140
  })();
88
141
  if (allowCreate) {
89
142
  const selected = new Set(newValue.map(itemToString));
90
143
  setCreatedItems((prev) => [...prev, ...created].filter((item) => selected.has(itemToString(item))));
91
- setInputValue("");
92
144
  }
93
145
  onValueChange(newValue, event);
94
146
  };
147
+ /**
148
+ * The create row.
149
+ *
150
+ * - `queryToCreateLabel` receives the values committing the row adds, rather than the entry as
151
+ * typed — so the row cannot name a value it drops as a stray separator, a repeat, or one the
152
+ * selection already holds, nor stay silent about one it selects from `items`.
153
+ * - For an entry standing for a single value that string is the entry itself.
154
+ */
155
+ const renderCreatableItem = (item) => /* @__PURE__ */ jsx(Combobox$1.Item, {
156
+ value: item,
157
+ icon: /* @__PURE__ */ jsx(Plus, {}),
158
+ children: queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator))
159
+ });
95
160
  const renderItem = (item) => {
96
161
  return /* @__PURE__ */ jsx(Combobox$1.Item, {
97
162
  value: item,
@@ -108,14 +173,15 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
108
173
  value,
109
174
  defaultValue,
110
175
  filter,
176
+ isItemEqualToValue,
111
177
  onValueChange: handleValueChange,
112
178
  itemToStringLabel: wrappedItemToStringLabel,
113
179
  itemToStringValue: wrappedItemToStringValue,
114
180
  disabled,
115
181
  inputRef,
116
- ...allowCreate ? {
182
+ ...ownsInput ? {
117
183
  inputValue,
118
- onInputValueChange: (nextValue) => setInputValue(nextValue)
184
+ onInputValueChange: handleInputValueChange
119
185
  } : {},
120
186
  children: [/* @__PURE__ */ jsx(Combobox.Chips, {
121
187
  render: /* @__PURE__ */ jsx(Fragment, {}),
@@ -132,7 +198,8 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
132
198
  variant: chipVariant,
133
199
  itemToChipLabel: itemToChipLabel ?? itemToLabel,
134
200
  itemToChipColor,
135
- pinnedChipLabels
201
+ pinnedChipLabels,
202
+ children: renderChips
136
203
  }), /* @__PURE__ */ jsxs("div", {
137
204
  className: "tw:flex tw:flex-1 tw:items-center tw:gap-1",
138
205
  children: [
@@ -145,7 +212,7 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
145
212
  "aria-required": ariaRequired,
146
213
  placeholder,
147
214
  disabled,
148
- className: "tw:w-auto tw:min-w-[120px] tw:flex-1"
215
+ className: "tw:w-auto tw:min-w-[120px] tw:flex-1 tw:!px-0 tw:!py-0"
149
216
  }),
150
217
  allowClear && /* @__PURE__ */ jsx(InputGroup.Button, {
151
218
  asChild: true,
@@ -167,20 +234,12 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
167
234
  if (isSelectAllItem(itemOrGroup)) return /* @__PURE__ */ jsx(Combobox$1.Item, {
168
235
  value: itemOrGroup,
169
236
  indicator: "checkbox",
170
- children: "Select All"
171
- });
172
- if (isCreatableItem(itemOrGroup)) return /* @__PURE__ */ jsx(Combobox$1.Item, {
173
- value: itemOrGroup,
174
- icon: /* @__PURE__ */ jsx(Plus, {}),
175
- children: queryToCreateLabel(itemOrGroup.value)
237
+ children: itemOrGroup.label
176
238
  });
239
+ if (isCreatableItem(itemOrGroup)) return renderCreatableItem(itemOrGroup);
177
240
  if (isGroupItem(itemOrGroup)) {
178
241
  const maybeCreatable = itemOrGroup.items[0];
179
- if (isCreatableItem(maybeCreatable)) return /* @__PURE__ */ jsx(Combobox$1.Item, {
180
- value: maybeCreatable,
181
- icon: /* @__PURE__ */ jsx(Plus, {}),
182
- children: queryToCreateLabel(maybeCreatable.value)
183
- });
242
+ if (isCreatableItem(maybeCreatable)) return renderCreatableItem(maybeCreatable);
184
243
  const groupLabel = groupToLabel(itemOrGroup);
185
244
  return /* @__PURE__ */ jsxs(Combobox$1.Group, {
186
245
  items: itemOrGroup.items,
@@ -1 +1 @@
1
- {"version":3,"file":"MultiCombobox.js","names":["BaseCombobox","Combobox"],"sources":["../../../src/blocks/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["import { type ComponentProps, Fragment, type ReactNode, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Combobox } from '../../components/Combobox';\nimport type { Group, LabeledItem } from '../../components/Combobox/types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultItemToLabel,\n defaultQueryToCreateLabel,\n defaultToCreateValue,\n isCreatableItem,\n isGroupItem,\n isGroupItems,\n isLabeledItem,\n toLabel,\n} from '../../components/Combobox/utils';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useArgoDesign } from '../../components/ThemeProvider/context';\nimport { ChevronDown, Plus, X } from '../../icons';\n\ntype ComboboxProps<Value> = BaseCombobox.Root.Props<Value, true>;\ntype ComboboxInputProps = ComponentProps<typeof Combobox.Input>;\ntype ComboboxInputGroupProps = ComponentProps<typeof Combobox.InputGroup>;\ntype ComboboxItemProps = ComponentProps<typeof Combobox.Item>;\ntype ComboboxChipsProps<Value> = ComponentProps<typeof Combobox.Chips<Value>>;\n\ntype Indicator = NonNullable<ComboboxItemProps['indicator']>;\n\ntype CreatableProps<Value> = {\n allowCreate?: boolean;\n queryToCreateLabel?: (query: string) => ReactNode;\n queryToCreateValue?: (query: string) => Value;\n};\n\n/**\n * Props for `MultiCombobox`. Generic over `Value` (the item shape) and `GroupShape` (optional group wrapper).\n * Use `itemToLabel` / `itemToIcon` / `itemToDisabled` to project custom item shapes; use `filter` to override\n * the default substring matcher. Pass `allowCreate` to let the user add free-form values not in `items`.\n */\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = Pick<\n ComboboxInputProps,\n // `name`, `onBlur` and the `aria-*` set are forwarded to the input so a form connector can hand\n // over the wiring it derives from the field — without the `aria-*` set the control cannot be linked\n // to its own help and error text, and without `onBlur` the field never registers as blurred, which\n // is the gate `FieldItem` reveals errors on.\n 'placeholder' | 'id' | 'name' | 'onBlur' | 'aria-describedby' | 'aria-invalid' | 'aria-required'\n> &\n Pick<ComboboxInputGroupProps, 'variant' | 'focusVariant' | 'sizing' | 'state' | 'className'> &\n Pick<\n ComboboxProps<Value>,\n | 'disabled'\n | 'inputRef'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'itemToStringLabel'\n | 'itemToStringValue'\n | 'filter'\n > &\n Pick<\n ComboboxChipsProps<Value>,\n 'itemToChipLabel' | 'itemToChipColor' | 'pinnedChipLabels' | 'maxVisible'\n > &\n CreatableProps<Value> & {\n items?: readonly (Value | GroupShape)[];\n\n // root specific\n allowClear?: boolean;\n allowSelectAll?: boolean;\n empty?: ReactNode;\n indicator?: Indicator;\n\n // item specific\n itemToLabel?: (item: Value) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n\n // group specific\n groupToLabel?: (group: GroupShape) => ReactNode;\n };\n\nconst selectAllItem: LabeledItem = {\n value: '__select_all__',\n label: 'Select All',\n};\n\nconst isSelectAllItem = <Value,>(item: Value) =>\n isLabeledItem(item) && item.value === '__select_all__';\n\n/**\n * Multi-selection combobox with chip display and search. Built on Base UI Combobox.\n *\n * **When to use:** picking several items from a searchable enumerated list (filter by tags, assign labels).\n * Items render as chips above the input; `maxVisible` collapses excess into a `+N more` chip.\n * **When NOT to use:** for single selection use `Combobox`; for short enums without search use `Select`.\n * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` for form integration.\n * Pass `allowSelectAll` for a sticky \"Select All\" item when the full enum is small. Pass `allowCreate`\n * to let the user add free-form values that are not in `items` (e.g. entering column names by hand).\n *\n * @see RECIPES.md#creatable-multi-combobox — for free-form-plus-enumerated patterns\n * @see RECIPES.md#filter-toolbar — for combining multi-select with other filter chips\n */\nexport const MultiCombobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\n // root props\n items: _itemsProp,\n value: _valueProp,\n defaultValue,\n onValueChange,\n itemToStringLabel,\n itemToStringValue,\n disabled,\n filter: filterProp,\n inputRef,\n\n // input props\n variant,\n sizing,\n focusVariant,\n state,\n placeholder,\n allowClear,\n id,\n name,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n // own props\n allowSelectAll = false,\n empty = 'No items',\n indicator,\n\n // creatable\n allowCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n\n // own item props\n itemToDisabled = defaultItemToDisabled,\n itemToLabel = defaultItemToLabel,\n itemToIcon = defaultItemToIcon,\n groupToLabel = defaultGroupToLabel,\n itemToChipLabel,\n itemToChipColor,\n pinnedChipLabels,\n // Nothing chose 3: value editors override it to `Infinity` (a chip inside `+N` can be neither\n // read nor removed) and single-row filters to `1`. Changing it moves eleven call sites at once,\n // so it waits for a PR that can look at them.\n maxVisible = 3,\n}: Props<Value, GroupShape>) => {\n const itemsProp = _itemsProp ?? [];\n const valueProp = _valueProp ?? [];\n const renderArgo = useArgoDesign();\n const chipVariant = renderArgo ? 'pill' : 'default';\n\n const [inputValue, setInputValue] = useState('');\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const query = inputValue.trim();\n const queryLower = query.toLowerCase();\n\n // Created values are appended to `items` so Base UI can keep resolving them (as chips and as\n // list options) once the query clears — otherwise a value that isn't in `items` gets dropped.\n // `handleValueChange` drops the ones the selection no longer holds, so this list tracks the\n // selection rather than every value ever typed.\n const baseItems = (() => {\n if (createdItems.length === 0) return itemsProp;\n if (isGroupItems(itemsProp))\n return [...itemsProp, { items: createdItems } as unknown as GroupShape];\n return [...itemsProp, ...createdItems];\n })();\n\n const allFlatItems = baseItems.flatMap((item) => (isGroupItem(item) ? item.items : item));\n const sampleItem = allFlatItems[0] as Value | undefined;\n const isAllSelected = allFlatItems.length === (valueProp?.length ?? 0);\n\n const defaultFilter = BaseCombobox.useFilter({\n multiple: true,\n value: valueProp,\n });\n\n const itemsWithSelectAllItem = (() => {\n if (!allowSelectAll) return baseItems;\n return [selectAllItem, ...baseItems];\n })();\n\n const itemToString = (item: Value) => itemToStringLabel?.(item) ?? toLabel(item);\n\n const items = (() => {\n const base = itemsWithSelectAllItem;\n if (!allowCreate || disabled || !query) return base;\n\n const exactMatch = allFlatItems.some((item) => itemToString(item).toLowerCase() === queryLower);\n const alreadySelected = valueProp.some(\n (item) => itemToString(item).toLowerCase() === queryLower,\n );\n if (exactMatch || alreadySelected) return base;\n\n const creatable = createCreatableItem(query);\n return isGroupItems(base)\n ? [...base, { items: [creatable] } as unknown as GroupShape]\n : [...base, creatable as unknown as Value];\n })();\n\n const filter = (item: Value, query: string, itemToString?: (value: Value) => string) => {\n // keep select always visible\n if (isSelectAllItem(item)) return true;\n // always offer the transient \"create\" option\n if (isCreatableItem(item)) return true;\n\n if (filterProp) return filterProp(item, query, itemToString);\n return defaultFilter.contains(item, query, itemToString);\n };\n\n const wrappedItemToStringLabel: ComboboxProps<Value>['itemToStringLabel'] = !allowCreate\n ? itemToStringLabel\n : (item) => (isCreatableItem(item) ? item.value : itemToString(item));\n\n const wrappedItemToStringValue: ComboboxProps<Value>['itemToStringValue'] =\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n const value = (() => {\n if (!allowSelectAll) return valueProp;\n return isAllSelected ? [...valueProp, selectAllItem as Value] : valueProp;\n })();\n\n const handleValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n if (!onValueChange) return;\n\n const created: Value[] = [];\n const converted = allowCreate\n ? next.map((item) => {\n if (!isCreatableItem(item)) return item;\n const value = defaultToCreateValue(item.value, sampleItem, queryToCreateValue) as Value;\n created.push(value);\n return value;\n })\n : next;\n\n const hasSelectAll = converted.some((item) => isSelectAllItem(item));\n const newValue = (() => {\n if (!allowSelectAll) return converted;\n if (!hasSelectAll) return isAllSelected ? [] : converted;\n return isAllSelected ? converted.filter((item) => !isSelectAllItem(item)) : allFlatItems;\n })();\n\n if (allowCreate) {\n // Keep only the created values the selection being emitted still holds — `valueProp` is the\n // selection before this change, so a value created right now is not in it yet.\n const selected = new Set(newValue.map(itemToString));\n setCreatedItems((prev) =>\n [...prev, ...created].filter((item) => selected.has(itemToString(item))),\n );\n setInputValue('');\n }\n\n onValueChange(newValue, event);\n };\n\n const renderItem = (item: Value) => {\n return (\n <Combobox.Item\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n >\n {itemToLabel(item)}\n </Combobox.Item>\n );\n };\n\n return (\n <Combobox.Root<Value, true>\n multiple\n // Base UI highlights nothing until ArrowDown, so Enter after typing would drop the query\n // silently — no selection, and the popup closes. Highlighting the first match makes Enter\n // commit it, including the creatable row when `allowCreate` is on.\n autoHighlight\n items={items}\n value={value}\n defaultValue={defaultValue}\n filter={filter}\n onValueChange={handleValueChange}\n itemToStringLabel={wrappedItemToStringLabel}\n itemToStringValue={wrappedItemToStringValue}\n disabled={disabled}\n inputRef={inputRef}\n {...(allowCreate\n ? { inputValue, onInputValueChange: (nextValue: string) => setInputValue(nextValue) }\n : {})}\n >\n <BaseCombobox.Chips render={<Fragment />}>\n <Combobox.InputGroup\n variant={variant}\n sizing={sizing}\n state={state}\n focusVariant={focusVariant}\n className={className}\n >\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5\">\n <Combobox.Chips<Value>\n maxVisible={maxVisible}\n variant={chipVariant}\n itemToChipLabel={itemToChipLabel ?? itemToLabel}\n itemToChipColor={itemToChipColor}\n pinnedChipLabels={pinnedChipLabels}\n />\n <div className=\"tw:flex tw:flex-1 tw:items-center tw:gap-1\">\n <Combobox.Input\n id={id}\n name={name}\n onBlur={onBlur}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n aria-required={ariaRequired}\n placeholder={placeholder}\n disabled={disabled}\n className=\"tw:w-auto tw:min-w-[120px] tw:flex-1\"\n />\n {allowClear && (\n <InputGroup.Button asChild aria-label=\"Clear\" disabled={disabled}>\n <BaseCombobox.Clear>\n <X className=\"tw:size-4\" />\n </BaseCombobox.Clear>\n </InputGroup.Button>\n )}\n <InputGroup.Button disabled={disabled} asChild aria-label=\"Open combobox\">\n <BaseCombobox.Trigger>\n <ChevronDown className=\"tw:size-4\" />\n </BaseCombobox.Trigger>\n </InputGroup.Button>\n </div>\n </div>\n </Combobox.InputGroup>\n </BaseCombobox.Chips>\n <Combobox.Content>\n <Combobox.Empty>{empty}</Combobox.Empty>\n <Combobox.List>\n {(itemOrGroup: Value | GroupShape) => {\n if (isSelectAllItem(itemOrGroup)) {\n return (\n <Combobox.Item value={itemOrGroup} indicator=\"checkbox\">\n Select All\n </Combobox.Item>\n );\n }\n\n if (isCreatableItem(itemOrGroup)) {\n return (\n <Combobox.Item value={itemOrGroup} icon={<Plus />}>\n {queryToCreateLabel(itemOrGroup.value)}\n </Combobox.Item>\n );\n }\n\n if (isGroupItem(itemOrGroup)) {\n const maybeCreatable = itemOrGroup.items[0];\n\n if (isCreatableItem(maybeCreatable)) {\n return (\n <Combobox.Item value={maybeCreatable} icon={<Plus />}>\n {queryToCreateLabel(maybeCreatable.value)}\n </Combobox.Item>\n );\n }\n\n const groupLabel = groupToLabel(itemOrGroup);\n return (\n <Combobox.Group items={itemOrGroup.items}>\n {groupLabel && <Combobox.GroupLabel>{groupLabel}</Combobox.GroupLabel>}\n <Combobox.GroupList>{renderItem}</Combobox.GroupList>\n </Combobox.Group>\n );\n }\n\n return renderItem(itemOrGroup);\n }}\n </Combobox.List>\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"MultiCombobox.js","names":["BaseCombobox","Combobox"],"sources":["../../../src/blocks/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["import { type ComponentProps, Fragment, type ReactNode, useMemo, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Combobox } from '../../components/Combobox';\nimport { namedLabel } from '../../components/Combobox/blankValues';\nimport { sanitizeTypedInput, useQueryReporter } from '../../components/Combobox/query';\nimport type { CreatableItem, Group } from '../../components/Combobox/types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultItemToLabel,\n defaultQueryToCreateLabel,\n defaultToCreateValue,\n isCreatableItem,\n isGroupItem,\n isGroupItems,\n isSelectAllItem,\n selectAllItem,\n toItemEquality,\n toLabel,\n} from '../../components/Combobox/utils';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useArgoDesign } from '../../components/ThemeProvider/context';\nimport { ChevronDown, Plus, X } from '../../icons';\n\ntype ComboboxProps<Value> = BaseCombobox.Root.Props<Value, true>;\ntype ComboboxInputProps = ComponentProps<typeof Combobox.Input>;\ntype ComboboxInputGroupProps = ComponentProps<typeof Combobox.InputGroup>;\ntype ComboboxItemProps = ComponentProps<typeof Combobox.Item>;\ntype ComboboxChipsProps<Value> = ComponentProps<typeof Combobox.Chips<Value>>;\n\ntype Indicator = NonNullable<ComboboxItemProps['indicator']>;\n\n/**\n * The strings one creatable entry stands for.\n *\n * - `id1, id2,` is two values: the blanks a stray separator leaves are dropped.\n * - A repeat collapses to its first occurrence, case-insensitively, as everything the control\n * matches by display string does — one entry cannot add the same value twice.\n * - A `null` separator yields the entry itself.\n */\nconst DEFAULT_CREATE_SEPARATOR = ',';\n\n/**\n * How the create row lists the values it adds: each separated by the entry's own separator, then\n * a space. A `RegExp` stands for many strings, so the default separator stands in for it.\n */\nconst joinCreateParts = (parts: string[], separator: string | RegExp | null) =>\n parts.join(`${typeof separator === 'string' ? separator : DEFAULT_CREATE_SEPARATOR} `);\n\nconst splitCreateEntry = (entry: string, separator: string | RegExp | null): string[] => {\n if (separator === null) return [entry];\n\n const seen = new Set<string>();\n return entry\n .split(separator)\n .map((part) => part.trim())\n .filter((part) => {\n if (part === '') return false;\n const key = part.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\ntype CreatableProps<Value> = {\n allowCreate?: boolean;\n /**\n * Words the create row. Receives the values committing the row will add — an entry standing for\n * several values arrives trimmed and re-joined with its own separator, not as typed.\n */\n queryToCreateLabel?: (query: string) => ReactNode;\n /**\n * Projects one entered string into an item. Called once per value, so a split entry calls it\n * several times, each with an already-trimmed part.\n */\n queryToCreateValue?: (query: string) => Value;\n /**\n * Gate on each value the entry stands for, for `allowCreate`.\n *\n * - Returning `false` drops that value, so an entry left with none hides the create row and the\n * empty state shows instead.\n * - Only called for a value that matches no item and nothing already selected — one naming an\n * item is selected rather than minted, so its format is not this gate's business.\n * - Reach for it when a free-form value has a format (a column name, an email address).\n */\n canCreate?: (query: string) => boolean;\n /**\n * Separator that makes one creatable entry stand for several values. Defaults to **`','`**, so\n * pasting `id1, id2, id3` adds three chips.\n *\n * - Pass a string or a non-capturing `RegExp` for another convention: `';'` for an Outlook\n * address list, `/[\\s,]+/` where a value can never contain a space. A capture group would be\n * handed back as a value of its own — that is `String.prototype.split`'s own behaviour.\n * - Pass `null` where a value legitimately contains the separator — a free-text label, a\n * sentence — and one entry must stay one chip.\n * - Whitespace is deliberately not part of the default: tags and column names contain spaces,\n * and each part is trimmed anyway, so `id1, id2` needs nothing more than the comma.\n */\n createSeparator?: string | RegExp | null;\n};\n\n/**\n * Props for `MultiCombobox`. Generic over `Value` (the item shape) and `GroupShape` (optional group wrapper).\n * Use `itemToLabel` / `itemToIcon` / `itemToDisabled` to project custom item shapes; use `filter` to override\n * the default substring matcher. Pass `isItemEqualToValue` when the items are objects a store recreates —\n * without it Base UI matches `value` against `items` by reference. Pass `allowCreate` to let the user add\n * free-form values not in `items`.\n */\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = Pick<\n ComboboxInputProps,\n // `name`, `onBlur` and the `aria-*` set are forwarded to the input so a form connector can hand\n // over the wiring it derives from the field — without the `aria-*` set the control cannot be linked\n // to its own help and error text, and without `onBlur` the field never registers as blurred, which\n // is the gate `FieldItem` reveals errors on.\n 'placeholder' | 'id' | 'name' | 'onBlur' | 'aria-describedby' | 'aria-invalid' | 'aria-required'\n> &\n Pick<ComboboxInputGroupProps, 'variant' | 'focusVariant' | 'sizing' | 'state' | 'className'> &\n Pick<\n ComboboxProps<Value>,\n | 'disabled'\n | 'inputRef'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'itemToStringLabel'\n | 'itemToStringValue'\n | 'filter'\n | 'isItemEqualToValue'\n > &\n Pick<\n ComboboxChipsProps<Value>,\n 'itemToChipLabel' | 'itemToChipColor' | 'pinnedChipLabels' | 'maxVisible'\n > &\n CreatableProps<Value> & {\n items?: readonly (Value | GroupShape)[];\n\n // root specific\n /**\n * Offer a clear-all button once something is selected. Defaults to **`true`**.\n *\n * - `BaseCombobox.Clear` only mounts while chips exist, so an empty control renders identically\n * either way. Individual chips stay removable regardless.\n * - Pass `false` where emptying the whole selection must not be one click away.\n */\n allowClear?: boolean;\n /**\n * Adds a \"Select All\" row that selects the whole item set.\n *\n * - The row is hidden while a query narrows the list — it never means \"everything matching\".\n * - Selecting it while everything is already selected clears the selection.\n */\n allowSelectAll?: boolean;\n empty?: ReactNode;\n indicator?: Indicator;\n\n // query specific\n /**\n * Rewrites what the user types before the control adopts it.\n *\n * - The query the list filters by is the rewritten text, and so is every value a created entry\n * is split into — a character the user cannot type is one they cannot create.\n * - Reach for it where a created value has a character set: a column name, a scope, an\n * identifier. `canCreate` is the gate for a format the user must get right themselves.\n * - It has to rewrite rather than drop: it sees the whole text on every keystroke, so one\n * calling `trim()` swallows the space before the next word.\n */\n inputValueSanitizer?: (input: string) => string;\n /**\n * Reports the query the list filters by, `inputValueSanitizer` already applied.\n *\n * - For an owner that needs the query for itself: a server-side search, an option order, the\n * text a synthetic row is offered for. The mount render reports too, so a search driven by\n * this needs no first fetch of its own.\n * - Notification only, and deliberately not Base UI's own `onInputValueChange`: the control\n * keeps ownership of the text — a pick clears it — so there is no controlled `inputValue`\n * to hold in sync.\n */\n onQueryChange?: (query: string) => void;\n\n // item specific\n /**\n * The item's row in the list, and its chip unless `itemToChipLabel` overrides it.\n *\n * - Defaults to `itemToStringLabel`, so a control that projects its items — ids carrying the\n * selection, the label looked up beside them — states the projection once.\n * - Pass it separately only where the row is richer than the input's own text.\n */\n itemToLabel?: (item: Value) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n\n // chip specific\n /**\n * Renders the chip area from the selected values, in place of the default chips.\n *\n * - For the case no per-value accessor can express: one node standing for the whole selection\n * (\"3 tables selected\"), or a chip count that is not the value count.\n * - A chip that merely holds richer content — a link, an action of its own — needs no slot:\n * `itemToChipLabel` returns a `ReactNode` and the chip lets it take the keyboard.\n * - The chip props above go unused while this is set, `maxVisible` and its `+N` chip included.\n * - `Combobox.Chip` builds a removable chip.\n */\n renderChips?: (values: Value[]) => ReactNode;\n\n // group specific\n groupToLabel?: (group: GroupShape) => ReactNode;\n };\n\n/**\n * Multi-selection combobox with chip display and search. Built on Base UI Combobox.\n *\n * **When to use:** picking several items from a searchable enumerated list (filter by tags, assign labels).\n * Items render as chips above the input; `maxVisible` collapses excess into a `+N more` chip.\n * **When NOT to use:** for single selection use `Combobox`; for short enums without search use `Select`.\n * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` for form integration.\n * Pass `allowSelectAll` for a \"Select All\" item when the full enum is small — it covers the whole set\n * and hides itself while a query is active. Pass `allowCreate` to let the user add free-form values\n * that are not in `items` (e.g. entering column names by hand).\n *\n * @see RECIPES.md#creatable-multi-combobox — for free-form-plus-enumerated patterns\n * @see RECIPES.md#filter-toolbar — for combining multi-select with other filter chips\n */\nexport const MultiCombobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\n // root props\n items: _itemsProp,\n value: _valueProp,\n defaultValue,\n onValueChange,\n itemToStringLabel,\n itemToStringValue,\n disabled,\n filter: filterProp,\n isItemEqualToValue: isItemEqualToValueProp,\n inputRef,\n\n // input props\n variant,\n sizing,\n focusVariant,\n state,\n placeholder,\n allowClear = true,\n id,\n name,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n // own props\n allowSelectAll = false,\n empty = 'No items',\n indicator,\n\n // query\n inputValueSanitizer,\n onQueryChange,\n\n // creatable\n allowCreate,\n canCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n createSeparator = DEFAULT_CREATE_SEPARATOR,\n\n // own item props\n itemToDisabled = defaultItemToDisabled,\n itemToLabel: itemToLabelProp,\n itemToIcon = defaultItemToIcon,\n groupToLabel = defaultGroupToLabel,\n itemToChipLabel,\n itemToChipColor,\n pinnedChipLabels,\n renderChips,\n // Nothing chose 3: value editors override it to `Infinity` (a chip inside `+N` can be neither\n // read nor removed) and single-row filters to `1`. Changing it moves eleven call sites at once,\n // so it waits for a PR that can look at them.\n maxVisible = 3,\n}: Props<Value, GroupShape>) => {\n const itemsProp = _itemsProp ?? [];\n const valueProp = _valueProp ?? [];\n // `itemToStringLabel` is a projection, not a display accessor, so a blank it returns still needs\n // naming — rows and chips are where a blank value would otherwise render as nothing.\n const itemToLabel =\n itemToLabelProp ??\n (itemToStringLabel ? (item: Value) => namedLabel(itemToStringLabel(item)) : defaultItemToLabel);\n const renderArgo = useArgoDesign();\n const chipVariant = renderArgo ? 'pill' : 'default';\n\n const [inputValue, setInputValue] = useState('');\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const query = inputValue.trim();\n\n useQueryReporter(query, onQueryChange);\n\n // Who holds the input's text. Base UI keeps it unless something here needs to read or rewrite\n // it, because taking it means re-rendering this component on every keystroke — a cost the many\n // controls that only pick from a list should not pay.\n const ownsInput = Boolean(allowCreate || inputValueSanitizer || onQueryChange);\n\n // Created values are appended to `items` so Base UI can keep resolving them (as chips and as\n // list options) once the query clears — otherwise a value that isn't in `items` gets dropped.\n // `handleValueChange` drops the ones the selection no longer holds, so this list tracks the\n // selection rather than every value ever typed.\n const baseItems = (() => {\n if (createdItems.length === 0) return itemsProp;\n if (isGroupItems(itemsProp))\n return [...itemsProp, { items: createdItems } as unknown as GroupShape];\n return [...itemsProp, ...createdItems];\n })();\n\n const allFlatItems = baseItems.flatMap((item) => (isGroupItem(item) ? item.items : item));\n const sampleItem = allFlatItems[0] as Value | undefined;\n // An empty item set has no Select All row: there is nothing to select all of, and reading\n // `0 === 0` as \"everything is selected\" would put the row's own entry into `value`.\n const hasSelectAllRow = allowSelectAll && allFlatItems.length > 0;\n const isAllSelected = hasSelectAllRow && allFlatItems.length === (valueProp?.length ?? 0);\n\n const defaultFilter = BaseCombobox.useFilter({\n multiple: true,\n value: valueProp,\n });\n\n const itemsWithSelectAllItem = hasSelectAllRow ? [selectAllItem, ...baseItems] : baseItems;\n\n const itemToString = (item: Value) => itemToStringLabel?.(item) ?? toLabel(item);\n // An item's display string, case-folded — the key an entered value is matched against.\n const labelKey = (item: Value) => itemToString(item).toLowerCase();\n\n // The values the current entry stands for. Everything the create row is decided from hangs off\n // this, so an empty entry costs a creatable control nothing.\n const createParts =\n !allowCreate || disabled || !query ? [] : splitCreateEntry(query, createSeparator);\n\n const selectedKeys = new Set<string>();\n if (createParts.length > 0) for (const item of valueProp) selectedKeys.add(labelKey(item));\n\n // Does an item carry this display string? `canCreate` asks it per value, so there it earns a\n // set; without the gate only a single-value entry asks, and an early-exiting scan is cheaper.\n const itemKeys = new Set<string>();\n if (createParts.length > 0 && canCreate) {\n for (const item of allFlatItems) itemKeys.add(labelKey(item));\n }\n const namesAnItem = (key: string) =>\n canCreate ? itemKeys.has(key) : allFlatItems.some((item) => labelKey(item) === key);\n\n /**\n * What the entry adds to the selection: its values the selection does not already hold.\n *\n * - The create row is named from this and committing it adds exactly this, so the row cannot\n * promise something else. A value naming an existing item counts — committing selects it.\n * - `canCreate` drops a value the control would mint and the gate rejects. One naming an item\n * is selected rather than minted, so its format is not that gate's business.\n * - `value` is the whole selection (it is never `undefined`, so the control is always the\n * controlled one), which is why the commit path re-derives nothing.\n */\n const addedCreateParts = createParts.filter((part) => {\n const key = part.toLowerCase();\n if (selectedKeys.has(key)) return false;\n return !canCreate || namesAnItem(key) || canCreate(part);\n });\n\n // The one value a single-value entry stands for, keyed — `undefined` for a split entry.\n const soleValueKey = createParts.length === 1 ? createParts[0]!.toLowerCase() : undefined;\n\n // A single value naming an item needs no create row: the list already offers that item's own\n // row, which the default substring filter matches for a single-value entry but not for a split\n // one. The item scan runs only for an entry that would otherwise show the row.\n const showCreateRow =\n addedCreateParts.length > 0 && (soleValueKey === undefined || !namesAnItem(soleValueKey));\n\n const items = (() => {\n const base = itemsWithSelectAllItem;\n if (!showCreateRow) return base;\n\n const creatable = createCreatableItem(query);\n return isGroupItems(base)\n ? [...base, { items: [creatable] } as unknown as GroupShape]\n : [...base, creatable as unknown as Value];\n })();\n\n const filter = (item: Value, query: string, itemToString?: (value: Value) => string) => {\n // Select All covers the whole item set, so it exists only while no query narrows the list.\n if (isSelectAllItem(item)) return query.trim() === '';\n // always offer the transient \"create\" option\n if (isCreatableItem(item)) return true;\n\n if (filterProp) return filterProp(item, query, itemToString);\n return defaultFilter.contains(item, query, itemToString);\n };\n\n // Base UI stores the comparer and lists it in an effect's deps, so a fresh identity per render\n // re-renders every option row and rescans the item list.\n const isItemEqualToValue = useMemo(\n () => toItemEquality(isItemEqualToValueProp),\n [isItemEqualToValueProp],\n );\n\n const wrappedItemToStringLabel: ComboboxProps<Value>['itemToStringLabel'] = !allowCreate\n ? itemToStringLabel\n : (item) => (isCreatableItem(item) ? item.value : itemToString(item));\n\n const wrappedItemToStringValue: ComboboxProps<Value>['itemToStringValue'] =\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n const value = isAllSelected ? [...valueProp, selectAllItem as Value] : valueProp;\n\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n next,\n { reason },\n ) => {\n setInputValue(sanitizeTypedInput(next, reason, inputValueSanitizer));\n };\n\n const handleValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n // Emptying the input once the selection changes is this component's job while it holds the\n // text; Base UI does it itself otherwise. React bails out when the text is already empty.\n if (ownsInput) setInputValue((prev) => (prev === '' ? prev : ''));\n if (!onValueChange) return;\n\n const created: Value[] = [];\n const converted = (() => {\n if (!allowCreate || !next.some(isCreatableItem)) return next;\n\n // Items by display string, so a value naming one selects it rather than minting a twin that\n // would be a second chip for one value. Built per commit — the render path only needs to\n // know whether a single value names an item.\n const itemsByLabel = new Map<string, Value>();\n for (const item of allFlatItems) itemsByLabel.set(labelKey(item), item);\n\n return next.flatMap((item) => {\n if (!isCreatableItem(item)) return [item];\n\n return addedCreateParts.map((part) => {\n const existing = itemsByLabel.get(part.toLowerCase());\n if (existing !== undefined) return existing;\n\n const value = defaultToCreateValue(part, sampleItem, queryToCreateValue) as Value;\n created.push(value);\n return value;\n });\n });\n })();\n\n const hasSelectAll = converted.some((item) => isSelectAllItem(item));\n const newValue = (() => {\n if (!hasSelectAllRow) return converted;\n if (!hasSelectAll) return isAllSelected ? [] : converted;\n return isAllSelected ? converted.filter((item) => !isSelectAllItem(item)) : allFlatItems;\n })();\n\n if (allowCreate) {\n // Keep only the created values the selection being emitted still holds — `valueProp` is the\n // selection before this change, so a value created right now is not in it yet.\n const selected = new Set(newValue.map(itemToString));\n setCreatedItems((prev) =>\n [...prev, ...created].filter((item) => selected.has(itemToString(item))),\n );\n }\n\n onValueChange(newValue, event);\n };\n\n /**\n * The create row.\n *\n * - `queryToCreateLabel` receives the values committing the row adds, rather than the entry as\n * typed — so the row cannot name a value it drops as a stray separator, a repeat, or one the\n * selection already holds, nor stay silent about one it selects from `items`.\n * - For an entry standing for a single value that string is the entry itself.\n */\n const renderCreatableItem = (item: CreatableItem) => (\n <Combobox.Item value={item} icon={<Plus />}>\n {queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator))}\n </Combobox.Item>\n );\n\n const renderItem = (item: Value) => {\n return (\n <Combobox.Item\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n >\n {itemToLabel(item)}\n </Combobox.Item>\n );\n };\n\n return (\n <Combobox.Root<Value, true>\n multiple\n // Base UI highlights nothing until ArrowDown, so Enter after typing would drop the query\n // silently — no selection, and the popup closes. Highlighting the first match makes Enter\n // commit it, including the creatable row when `allowCreate` is on.\n autoHighlight\n items={items}\n value={value}\n defaultValue={defaultValue}\n filter={filter}\n isItemEqualToValue={isItemEqualToValue}\n onValueChange={handleValueChange}\n itemToStringLabel={wrappedItemToStringLabel}\n itemToStringValue={wrappedItemToStringValue}\n disabled={disabled}\n inputRef={inputRef}\n {...(ownsInput ? { inputValue, onInputValueChange: handleInputValueChange } : {})}\n >\n <BaseCombobox.Chips render={<Fragment />}>\n <Combobox.InputGroup\n variant={variant}\n sizing={sizing}\n state={state}\n focusVariant={focusVariant}\n className={className}\n >\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5\">\n <Combobox.Chips<Value>\n maxVisible={maxVisible}\n variant={chipVariant}\n itemToChipLabel={itemToChipLabel ?? itemToLabel}\n itemToChipColor={itemToChipColor}\n pinnedChipLabels={pinnedChipLabels}\n >\n {renderChips}\n </Combobox.Chips>\n <div className=\"tw:flex tw:flex-1 tw:items-center tw:gap-1\">\n <Combobox.Input\n id={id}\n name={name}\n onBlur={onBlur}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n aria-required={ariaRequired}\n placeholder={placeholder}\n disabled={disabled}\n // This row already owns its own edge padding above, and chips share the row with\n // the input rather than sitting outside it — cancel the group's own `&_input`\n // padding so it doesn't double up on top of this row's.\n className=\"tw:w-auto tw:min-w-[120px] tw:flex-1 tw:!px-0 tw:!py-0\"\n />\n {allowClear && (\n <InputGroup.Button asChild aria-label=\"Clear\" disabled={disabled}>\n <BaseCombobox.Clear>\n <X className=\"tw:size-4\" />\n </BaseCombobox.Clear>\n </InputGroup.Button>\n )}\n <InputGroup.Button disabled={disabled} asChild aria-label=\"Open combobox\">\n <BaseCombobox.Trigger>\n <ChevronDown className=\"tw:size-4\" />\n </BaseCombobox.Trigger>\n </InputGroup.Button>\n </div>\n </div>\n </Combobox.InputGroup>\n </BaseCombobox.Chips>\n <Combobox.Content>\n <Combobox.Empty>{empty}</Combobox.Empty>\n <Combobox.List>\n {(itemOrGroup: Value | GroupShape) => {\n if (isSelectAllItem(itemOrGroup)) {\n return (\n <Combobox.Item value={itemOrGroup} indicator=\"checkbox\">\n {itemOrGroup.label}\n </Combobox.Item>\n );\n }\n\n if (isCreatableItem(itemOrGroup)) {\n return renderCreatableItem(itemOrGroup);\n }\n\n if (isGroupItem(itemOrGroup)) {\n const maybeCreatable = itemOrGroup.items[0];\n\n if (isCreatableItem(maybeCreatable)) {\n return renderCreatableItem(maybeCreatable);\n }\n\n const groupLabel = groupToLabel(itemOrGroup);\n return (\n <Combobox.Group items={itemOrGroup.items}>\n {groupLabel && <Combobox.GroupLabel>{groupLabel}</Combobox.GroupLabel>}\n <Combobox.GroupList>{renderItem}</Combobox.GroupList>\n </Combobox.Group>\n );\n }\n\n return renderItem(itemOrGroup);\n }}\n </Combobox.List>\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
1
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/blocks/NumberInput/NumberInput.tsx
4
4
  const toNumberOrNull = (event) => Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber;
@@ -1,2 +1,2 @@
1
- import { PageToolbar } from "../../PageToolbar-DnbFt14Q.js";
1
+ import { PageToolbar } from "../../PageToolbar-DExqEYGl.js";
2
2
  export { PageToolbar };
@@ -1,7 +1,7 @@
1
- import { createChangeInputEvent } from "../../utils-B5Z52hYs.js";
1
+ import { createChangeInputEvent } from "../../utils-DSvrhU8E.js";
2
2
  import { mergeRefs } from "../utils/mergeRefs.js";
3
3
  import { ArrowBigUpDash, Eye, EyeOff, X } from "../../icons-Cek151jC.js";
4
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
4
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
5
5
  import { useControllableState } from "../../useControllableState-M6494mCT.js";
6
6
  import { useRef, useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,2 +1,2 @@
1
- import { SearchInput } from "../../SearchInput-f_oY9T4Z.js";
1
+ import { SearchInput } from "../../SearchInput-D4UgAXJK.js";
2
2
  export { SearchInput };
@@ -1,10 +1,10 @@
1
1
  import { cn } from "../../classNames-BzrkDnOD.js";
2
- import { keyCodes } from "../../utils-B5Z52hYs.js";
2
+ import { keyCodes } from "../../utils-DSvrhU8E.js";
3
3
  import { ChevronDown, ChevronUp, Search } from "../../icons-Cek151jC.js";
4
4
  import { Button } from "../../Button-DsRrU5F1.js";
5
5
  import { ButtonGroup } from "../components/ButtonGroup.js";
6
6
  import { Separator } from "../components/Separator.js";
7
- import { TextInput } from "../../TextInput-DHM6dHmn.js";
7
+ import { TextInput } from "../../TextInput-DH5SkbsE.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/blocks/SearchInputWithNavigation/SearchInputWithNavigation.tsx
10
10
  const SearchInputWithNavigation = ({ ref, value, onValueChange, placeholder = "Search...", variant = "secondary", onClear, focusVariant, currentIndex, totalResults, onNavigateNext, onNavigatePrevious, className }) => {
@@ -1,2 +1,2 @@
1
- import { SectionNav } from "../../SectionNav-BpJlisbT.js";
1
+ import { SectionNav } from "../../SectionNav-OkKCjSA-.js";
2
2
  export { SectionNav };
@@ -1,2 +1,2 @@
1
- import { TextInput } from "../../TextInput-DHM6dHmn.js";
1
+ import { TextInput } from "../../TextInput-DH5SkbsE.js";
2
2
  export { TextInput };
@@ -1,4 +1,4 @@
1
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
1
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
2
2
  import { useControllableState } from "../../useControllableState-M6494mCT.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  //#region src/blocks/Textarea/Textarea.tsx
@@ -1,7 +1,7 @@
1
- import { createChangeInputEvent } from "../../utils-B5Z52hYs.js";
1
+ import { createChangeInputEvent } from "../../utils-DSvrhU8E.js";
2
2
  import { mergeRefs } from "../utils/mergeRefs.js";
3
3
  import { Clock, X } from "../../icons-Cek151jC.js";
4
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
4
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
5
5
  import { useControllableState } from "../../useControllableState-M6494mCT.js";
6
6
  import { TimePicker } from "../../TimePicker-BGeqc-Ed.js";
7
7
  import { useRef, useState } from "react";
@@ -1,2 +1,2 @@
1
- import { Alert } from "../../Alert-DHJFrWnS.js";
1
+ import { Alert } from "../../Alert-Ba5b2YPq.js";
2
2
  export { Alert };
@@ -1,5 +1,5 @@
1
1
  import { cn } from "../../classNames-BzrkDnOD.js";
2
- import { useSHA256 } from "../../utils-B5Z52hYs.js";
2
+ import { useSHA256 } from "../../utils-DSvrhU8E.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import BoringAvatar from "boring-avatars";
5
5
  //#region src/components/Avatar.tsx
@@ -1,2 +1,2 @@
1
- import { Badge } from "../../Badge-Ch26CXoP.js";
1
+ import { Badge } from "../../Badge-D0pXdekt.js";
2
2
  export { Badge };
@@ -1,2 +1,2 @@
1
- import { BrandLogo } from "../../BrandLogo-Dmi7jo21.js";
1
+ import { BrandLogo } from "../../BrandLogo-CoKBk4MI.js";
2
2
  export { BrandLogo };
@@ -1,2 +1,2 @@
1
- import { Breadcrumb } from "../../Breadcrumb-uEkM6adI.js";
1
+ import { Breadcrumb } from "../../Breadcrumb-g_xn_-Nf.js";
2
2
  export { Breadcrumb };
@@ -1,2 +1,2 @@
1
- import { Checkbox } from "../../Checkbox-fC0BuO2B.js";
1
+ import { Checkbox } from "../../Checkbox-CUIn2jap.js";
2
2
  export { Checkbox };
@@ -1,2 +1,2 @@
1
- import { Clipboard } from "../../Clipboard-ChPdiUy3.js";
1
+ import { Clipboard } from "../../Clipboard-BTW6C-b_.js";
2
2
  export { Clipboard };
@@ -1,5 +1,5 @@
1
1
  import { cn } from "../../classNames-BzrkDnOD.js";
2
- import { keyCodes } from "../../utils-B5Z52hYs.js";
2
+ import { keyCodes } from "../../utils-DSvrhU8E.js";
3
3
  import { ChevronDown } from "../../icons-Cek151jC.js";
4
4
  import { Collapsible } from "../../Collapsible-BQXWEOBC.js";
5
5
  import { useState } from "react";
@@ -1,2 +1,2 @@
1
- import { Combobox } from "../../Combobox-Cs_1pj2q.js";
2
- export { Combobox };
1
+ import { Combobox, filterByWords, matchByWords, namedLabel, withBlankValues } from "../../Combobox-BfIfaVMA.js";
2
+ export { Combobox, filterByWords, matchByWords, namedLabel, withBlankValues };
@@ -1,2 +1,2 @@
1
- import { InputGroup } from "../../InputGroup-BnLHY0eq.js";
1
+ import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
2
2
  export { InputGroup };
@@ -1,2 +1,2 @@
1
- import { Kbd, kbdVariants, keys } from "../../Kbd-CvSM3D3-.js";
1
+ import { Kbd, kbdVariants, keys } from "../../Kbd-Cvvt91Q8.js";
2
2
  export { Kbd, kbdVariants, keys };
@@ -1,2 +1,2 @@
1
- import { Navbar } from "../../Navbar-B2UsolVU.js";
1
+ import { Navbar } from "../../Navbar-Liy1TPI7.js";
2
2
  export { Navbar };
@@ -1,2 +1,2 @@
1
- import { Popconfirm } from "../../Popconfirm-CILjmzKI.js";
1
+ import { Popconfirm } from "../../Popconfirm-5pBzT_HQ.js";
2
2
  export { Popconfirm };
@@ -1,2 +1,2 @@
1
- import { RadioGroup } from "../../RadioGroup-XFzFd1ti.js";
1
+ import { RadioGroup } from "../../RadioGroup-DXPbSj8P.js";
2
2
  export { RadioGroup };
@@ -1,2 +1,2 @@
1
- import { Search, SearchForm } from "../../Search-4Bxtt8hS.js";
1
+ import { Search, SearchForm } from "../../Search-5uQAiNIP.js";
2
2
  export { Search, SearchForm };
@@ -1,2 +1,2 @@
1
- import { Select } from "../../Select-DpcgKqKB.js";
1
+ import { Select } from "../../Select-DV3Hak_l.js";
2
2
  export { Select };
@@ -1,2 +1,2 @@
1
- import { Sidebar, SidebarProvider, useOptionalSidebar, useSidebar } from "../../Sidebar-Cm6I4dE1.js";
1
+ import { Sidebar, SidebarProvider, useOptionalSidebar, useSidebar } from "../../Sidebar-D3cY1kha.js";
2
2
  export { Sidebar, SidebarProvider, useOptionalSidebar, useSidebar };
@@ -1,2 +1,2 @@
1
- import { Slider } from "../../Slider-pPC_3gz9.js";
1
+ import { Slider } from "../../Slider-CRf-bB4y.js";
2
2
  export { Slider };
@@ -1,2 +1,2 @@
1
- import { Switch } from "../../Switch-ChfPKcTE.js";
1
+ import { Switch } from "../../Switch-B0WdGSjz.js";
2
2
  export { Switch };
@@ -1,4 +1,4 @@
1
1
  import { DEFAULT_BRAND_ID, DEFAULT_COLOR_SCHEME } from "../../defaults-i_xG2F_1.js";
2
2
  import { ArgoDesignContext, useArgoDesign, useTheme } from "../../context-D7X470dy.js";
3
- import { ThemeProvider, ThemeScope, brandSchema, exampleCustomer, keboola, keboolaLegacySidebar, keboolaLegacyTopnav, useThemeScopeContainer } from "../../ThemeProvider-DrQJtzpd.js";
3
+ import { ThemeProvider, ThemeScope, brandSchema, exampleCustomer, keboola, keboolaLegacySidebar, keboolaLegacyTopnav, useThemeScopeContainer } from "../../ThemeProvider-2RMdVGxO.js";
4
4
  export { ArgoDesignContext, DEFAULT_COLOR_SCHEME, DEFAULT_BRAND_ID as DEFAULT_KEBOOLA_BRAND_ID, ThemeProvider, ThemeScope, brandSchema, exampleCustomer, keboola, keboolaLegacySidebar, keboolaLegacyTopnav, useArgoDesign, useTheme, useThemeScopeContainer };
@@ -1,2 +1,2 @@
1
- import { Timeline } from "../../Timeline-6btyJl4D.js";
1
+ import { Timeline } from "../../Timeline-BG5Xogxh.js";
2
2
  export { Timeline };
@@ -1,2 +1,2 @@
1
- import { Tooltip, TooltipProvider } from "../../utils-B5Z52hYs.js";
1
+ import { Tooltip, TooltipProvider } from "../../utils-DSvrhU8E.js";
2
2
  export { Tooltip, TooltipProvider };
@@ -1,5 +1,5 @@
1
1
  import { cn } from "../../classNames-BzrkDnOD.js";
2
- import { Tooltip } from "../../utils-B5Z52hYs.js";
2
+ import { Tooltip } from "../../utils-DSvrhU8E.js";
3
3
  import { useState } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/Truncated.tsx
@@ -1,2 +1,2 @@
1
- import { DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Workbench, useWorkbench } from "../../Workbench-BzE-Vvd9.js";
1
+ import { DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Workbench, useWorkbench } from "../../Workbench-UR2FBC7I.js";
2
2
  export { DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Workbench, useWorkbench };
@@ -1,2 +1,2 @@
1
- import { ZoomableSvg, svgToPngBlob, toSvgFileContent } from "../../ZoomableSvg-BWnDkR61.js";
1
+ import { ZoomableSvg, svgToPngBlob, toSvgFileContent } from "../../ZoomableSvg-pooPb1Cu.js";
2
2
  export { ZoomableSvg, svgToPngBlob, toSvgFileContent };