@btst/components 0.0.0-stage → 1.0.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 (161) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/_private/ui/styles/markdown-editor.css +31 -0
  3. package/dist/auto-form/index.cjs +8 -0
  4. package/dist/auto-form/index.d.cts +26 -0
  5. package/dist/auto-form/index.d.mts +26 -0
  6. package/dist/auto-form/index.d.ts +26 -0
  7. package/dist/auto-form/index.mjs +1 -0
  8. package/dist/empty/index.cjs +12 -0
  9. package/dist/empty/index.d.cts +15 -0
  10. package/dist/empty/index.d.mts +15 -0
  11. package/dist/empty/index.d.ts +15 -0
  12. package/dist/empty/index.mjs +1 -0
  13. package/dist/form-builder/index.cjs +16 -0
  14. package/dist/form-builder/index.d.cts +395 -0
  15. package/dist/form-builder/index.d.mts +395 -0
  16. package/dist/form-builder/index.d.ts +395 -0
  17. package/dist/form-builder/index.mjs +4 -0
  18. package/dist/markdown/index.cjs +9 -0
  19. package/dist/markdown/index.d.cts +46 -0
  20. package/dist/markdown/index.d.mts +46 -0
  21. package/dist/markdown/index.d.ts +46 -0
  22. package/dist/markdown/index.mjs +2 -0
  23. package/dist/multi-select/index.cjs +7 -0
  24. package/dist/multi-select/index.d.cts +78 -0
  25. package/dist/multi-select/index.d.mts +78 -0
  26. package/dist/multi-select/index.d.ts +78 -0
  27. package/dist/multi-select/index.mjs +1 -0
  28. package/dist/search-select/index.cjs +7 -0
  29. package/dist/search-select/index.d.cts +16 -0
  30. package/dist/search-select/index.d.mts +16 -0
  31. package/dist/search-select/index.d.ts +16 -0
  32. package/dist/search-select/index.mjs +1 -0
  33. package/dist/shared/components.BdvBiegH.d.cts +291 -0
  34. package/dist/shared/components.BdvBiegH.d.mts +291 -0
  35. package/dist/shared/components.BdvBiegH.d.ts +291 -0
  36. package/dist/shared/components.CZMWR72v.d.cts +10 -0
  37. package/dist/shared/components.CZMWR72v.d.mts +10 -0
  38. package/dist/shared/components.CZMWR72v.d.ts +10 -0
  39. package/dist/stepped-auto-form/index.cjs +7 -0
  40. package/dist/stepped-auto-form/index.d.cts +37 -0
  41. package/dist/stepped-auto-form/index.d.mts +37 -0
  42. package/dist/stepped-auto-form/index.d.ts +37 -0
  43. package/dist/stepped-auto-form/index.mjs +1 -0
  44. package/dist/style.css +440 -0
  45. package/dist/ui/src/components/accordion.cjs +81 -0
  46. package/dist/ui/src/components/accordion.mjs +62 -0
  47. package/dist/ui/src/components/auto-form/common/label.cjs +18 -0
  48. package/dist/ui/src/components/auto-form/common/label.mjs +16 -0
  49. package/dist/ui/src/components/auto-form/common/tooltip.cjs +9 -0
  50. package/dist/ui/src/components/auto-form/common/tooltip.mjs +7 -0
  51. package/dist/ui/src/components/auto-form/config.cjs +40 -0
  52. package/dist/ui/src/components/auto-form/config.mjs +37 -0
  53. package/dist/ui/src/components/auto-form/dependencies.cjs +48 -0
  54. package/dist/ui/src/components/auto-form/dependencies.mjs +46 -0
  55. package/dist/ui/src/components/auto-form/fields/array.cjs +266 -0
  56. package/dist/ui/src/components/auto-form/fields/array.mjs +264 -0
  57. package/dist/ui/src/components/auto-form/fields/checkbox.cjs +38 -0
  58. package/dist/ui/src/components/auto-form/fields/checkbox.mjs +36 -0
  59. package/dist/ui/src/components/auto-form/fields/date.cjs +67 -0
  60. package/dist/ui/src/components/auto-form/fields/date.mjs +65 -0
  61. package/dist/ui/src/components/auto-form/fields/enum.cjs +73 -0
  62. package/dist/ui/src/components/auto-form/fields/enum.mjs +71 -0
  63. package/dist/ui/src/components/auto-form/fields/input.cjs +32 -0
  64. package/dist/ui/src/components/auto-form/fields/input.mjs +30 -0
  65. package/dist/ui/src/components/auto-form/fields/number.cjs +31 -0
  66. package/dist/ui/src/components/auto-form/fields/number.mjs +29 -0
  67. package/dist/ui/src/components/auto-form/fields/object.cjs +233 -0
  68. package/dist/ui/src/components/auto-form/fields/object.mjs +217 -0
  69. package/dist/ui/src/components/auto-form/fields/radio-group.cjs +67 -0
  70. package/dist/ui/src/components/auto-form/fields/radio-group.mjs +65 -0
  71. package/dist/ui/src/components/auto-form/fields/switch.cjs +38 -0
  72. package/dist/ui/src/components/auto-form/fields/switch.mjs +36 -0
  73. package/dist/ui/src/components/auto-form/fields/textarea.cjs +31 -0
  74. package/dist/ui/src/components/auto-form/fields/textarea.mjs +29 -0
  75. package/dist/ui/src/components/auto-form/helpers.cjs +270 -0
  76. package/dist/ui/src/components/auto-form/helpers.mjs +259 -0
  77. package/dist/ui/src/components/auto-form/index.cjs +102 -0
  78. package/dist/ui/src/components/auto-form/index.mjs +93 -0
  79. package/dist/ui/src/components/auto-form/stepped-auto-form.cjs +374 -0
  80. package/dist/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
  81. package/dist/ui/src/components/auto-form/types.cjs +11 -0
  82. package/dist/ui/src/components/auto-form/types.mjs +9 -0
  83. package/dist/ui/src/components/badge.cjs +42 -0
  84. package/dist/ui/src/components/badge.mjs +39 -0
  85. package/dist/ui/src/components/button.cjs +56 -0
  86. package/dist/ui/src/components/button.mjs +53 -0
  87. package/dist/ui/src/components/calendar.cjs +207 -0
  88. package/dist/ui/src/components/calendar.mjs +190 -0
  89. package/dist/ui/src/components/checkbox.cjs +48 -0
  90. package/dist/ui/src/components/checkbox.mjs +32 -0
  91. package/dist/ui/src/components/command.cjs +118 -0
  92. package/dist/ui/src/components/command.mjs +111 -0
  93. package/dist/ui/src/components/date-picker.cjs +41 -0
  94. package/dist/ui/src/components/date-picker.mjs +39 -0
  95. package/dist/ui/src/components/dialog.cjs +141 -0
  96. package/dist/ui/src/components/dialog.mjs +118 -0
  97. package/dist/ui/src/components/empty.cjs +104 -0
  98. package/dist/ui/src/components/empty.mjs +97 -0
  99. package/dist/ui/src/components/form-builder/canvas.cjs +111 -0
  100. package/dist/ui/src/components/form-builder/canvas.mjs +109 -0
  101. package/dist/ui/src/components/form-builder/components/index.cjs +571 -0
  102. package/dist/ui/src/components/form-builder/components/index.mjs +554 -0
  103. package/dist/ui/src/components/form-builder/edit-field-dialog.cjs +131 -0
  104. package/dist/ui/src/components/form-builder/edit-field-dialog.mjs +129 -0
  105. package/dist/ui/src/components/form-builder/form-preview.cjs +73 -0
  106. package/dist/ui/src/components/form-builder/form-preview.mjs +71 -0
  107. package/dist/ui/src/components/form-builder/index.cjs +350 -0
  108. package/dist/ui/src/components/form-builder/index.mjs +344 -0
  109. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.cjs +263 -0
  110. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.mjs +261 -0
  111. package/dist/ui/src/components/form-builder/palette.cjs +52 -0
  112. package/dist/ui/src/components/form-builder/palette.mjs +49 -0
  113. package/dist/ui/src/components/form-builder/schema-utils.cjs +128 -0
  114. package/dist/ui/src/components/form-builder/schema-utils.mjs +122 -0
  115. package/dist/ui/src/components/form-builder/sortable-field.cjs +151 -0
  116. package/dist/ui/src/components/form-builder/sortable-field.mjs +148 -0
  117. package/dist/ui/src/components/form-builder/step-tabs.cjs +180 -0
  118. package/dist/ui/src/components/form-builder/step-tabs.mjs +178 -0
  119. package/dist/ui/src/components/form-builder/types.cjs +7 -0
  120. package/dist/ui/src/components/form-builder/types.mjs +5 -0
  121. package/dist/ui/src/components/form-builder/validation-schemas.cjs +67 -0
  122. package/dist/ui/src/components/form-builder/validation-schemas.mjs +56 -0
  123. package/dist/ui/src/components/form.cjs +120 -0
  124. package/dist/ui/src/components/form.mjs +98 -0
  125. package/dist/ui/src/components/input.cjs +23 -0
  126. package/dist/ui/src/components/input.mjs +21 -0
  127. package/dist/ui/src/components/label.cjs +39 -0
  128. package/dist/ui/src/components/label.mjs +23 -0
  129. package/dist/ui/src/components/markdown-content.cjs +334 -0
  130. package/dist/ui/src/components/markdown-content.mjs +325 -0
  131. package/dist/ui/src/components/markdown-editor.cjs +180 -0
  132. package/dist/ui/src/components/markdown-editor.mjs +178 -0
  133. package/dist/ui/src/components/multi-select.cjs +555 -0
  134. package/dist/ui/src/components/multi-select.mjs +540 -0
  135. package/dist/ui/src/components/popover.cjs +60 -0
  136. package/dist/ui/src/components/popover.mjs +42 -0
  137. package/dist/ui/src/components/radio-group.cjs +62 -0
  138. package/dist/ui/src/components/radio-group.mjs +45 -0
  139. package/dist/ui/src/components/search-select.cjs +99 -0
  140. package/dist/ui/src/components/search-select.mjs +83 -0
  141. package/dist/ui/src/components/select.cjs +161 -0
  142. package/dist/ui/src/components/select.mjs +139 -0
  143. package/dist/ui/src/components/separator.cjs +43 -0
  144. package/dist/ui/src/components/separator.mjs +27 -0
  145. package/dist/ui/src/components/switch.cjs +48 -0
  146. package/dist/ui/src/components/switch.mjs +32 -0
  147. package/dist/ui/src/components/tabs.cjs +84 -0
  148. package/dist/ui/src/components/tabs.mjs +65 -0
  149. package/dist/ui/src/components/textarea.cjs +20 -0
  150. package/dist/ui/src/components/textarea.mjs +18 -0
  151. package/dist/ui/src/hooks/use-debounce.cjs +16 -0
  152. package/dist/ui/src/hooks/use-debounce.mjs +14 -0
  153. package/dist/ui/src/lib/schema-converter.cjs +94 -0
  154. package/dist/ui/src/lib/schema-converter.mjs +92 -0
  155. package/dist/ui/src/lib/throttle.cjs +56 -0
  156. package/dist/ui/src/lib/throttle.mjs +54 -0
  157. package/dist/ui/src/lib/utils.cjs +10 -0
  158. package/dist/ui/src/lib/utils.mjs +8 -0
  159. package/dist/ui.css +131 -0
  160. package/package.json +176 -3
  161. package/README.md +0 -3
@@ -0,0 +1,555 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const cmdk = require('cmdk');
6
+ const lucideReact = require('lucide-react');
7
+ const React = require('react');
8
+ const badge = require('./badge.cjs');
9
+ const command = require('./command.cjs');
10
+ const utils = require('../lib/utils.cjs');
11
+ const useDebounce = require('../hooks/use-debounce.cjs');
12
+
13
+ function _interopNamespaceCompat(e) {
14
+ if (e && typeof e === 'object' && 'default' in e) return e;
15
+ const n = Object.create(null);
16
+ if (e) {
17
+ for (const k in e) {
18
+ n[k] = e[k];
19
+ }
20
+ }
21
+ n.default = e;
22
+ return n;
23
+ }
24
+
25
+ const React__namespace = /*#__PURE__*/_interopNamespaceCompat(React);
26
+
27
+ const EMPTY_ARRAY = [];
28
+ function transToGroupOption(options, groupBy) {
29
+ if (options.length === 0) {
30
+ return {};
31
+ }
32
+ if (!groupBy) {
33
+ return {
34
+ "": options
35
+ };
36
+ }
37
+ const groupOption = {};
38
+ options.forEach((option) => {
39
+ const key = option[groupBy] || "";
40
+ if (!groupOption[key]) {
41
+ groupOption[key] = [];
42
+ }
43
+ groupOption[key].push(option);
44
+ });
45
+ return groupOption;
46
+ }
47
+ function removePickedOption(groupOption, picked) {
48
+ const cloneOption = JSON.parse(JSON.stringify(groupOption));
49
+ for (const [key, value] of Object.entries(cloneOption)) {
50
+ cloneOption[key] = value.filter(
51
+ (val) => !picked.find((p) => p.value === val.value)
52
+ );
53
+ }
54
+ return cloneOption;
55
+ }
56
+ function isOptionsExist(groupOption, targetOption) {
57
+ for (const [, value] of Object.entries(groupOption)) {
58
+ if (value.some((option) => targetOption.find((p) => p.value === option.value))) {
59
+ return true;
60
+ }
61
+ }
62
+ return false;
63
+ }
64
+ const CommandEmpty = React.forwardRef(({ className, ...props }, forwardedRef) => {
65
+ const render = cmdk.useCommandState((state) => state.filtered.count === 0);
66
+ if (!render) return null;
67
+ return /* @__PURE__ */ jsxRuntime.jsx(
68
+ "div",
69
+ {
70
+ ref: forwardedRef,
71
+ className: utils.cn("py-6 text-center text-sm", className),
72
+ "cmdk-empty": "",
73
+ role: "presentation",
74
+ ...props
75
+ }
76
+ );
77
+ });
78
+ CommandEmpty.displayName = "CommandEmpty";
79
+ const MultipleSelector = React__namespace.forwardRef(
80
+ ({
81
+ value,
82
+ onChange,
83
+ placeholder,
84
+ defaultOptions: arrayDefaultOptions = EMPTY_ARRAY,
85
+ options: arrayOptions,
86
+ delay,
87
+ onSearch,
88
+ onSearchSync,
89
+ loadingIndicator,
90
+ emptyIndicator,
91
+ maxSelected = Number.MAX_SAFE_INTEGER,
92
+ onMaxSelected,
93
+ hidePlaceholderWhenSelected,
94
+ disabled,
95
+ groupBy,
96
+ className,
97
+ badgeClassName,
98
+ selectFirstItem = true,
99
+ creatable = false,
100
+ triggerSearchOnFocus = false,
101
+ commandProps,
102
+ inputProps,
103
+ hideClearAllButton = false
104
+ }, ref) => {
105
+ const inputRef = React__namespace.useRef(null);
106
+ const [open, setOpen] = React__namespace.useState(false);
107
+ const [onScrollbar, setOnScrollbar] = React__namespace.useState(false);
108
+ const [isLoading, setIsLoading] = React__namespace.useState(false);
109
+ const dropdownRef = React__namespace.useRef(null);
110
+ const [selected, setSelected] = React__namespace.useState(
111
+ value || EMPTY_ARRAY
112
+ );
113
+ const [options, setOptions] = React__namespace.useState(
114
+ transToGroupOption(arrayDefaultOptions, groupBy)
115
+ );
116
+ const [inputValue, setInputValue] = React__namespace.useState("");
117
+ const debouncedSearchTerm = useDebounce.useDebounce(inputValue, delay || 500);
118
+ const selectedValue = React.useMemo(() => {
119
+ return {
120
+ selectedValue: [...selected],
121
+ input: inputRef.current,
122
+ focus: () => inputRef?.current?.focus(),
123
+ reset: () => setSelected([])
124
+ };
125
+ }, [selected]);
126
+ React__namespace.useImperativeHandle(ref, () => selectedValue, [selectedValue]);
127
+ const handleClickOutside = (event) => {
128
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
129
+ setOpen(false);
130
+ inputRef.current.blur();
131
+ }
132
+ };
133
+ const handleUnselect = React__namespace.useCallback(
134
+ (option) => {
135
+ const newOptions = selected.filter((s) => s.value !== option.value);
136
+ setSelected(newOptions);
137
+ onChange?.(newOptions);
138
+ },
139
+ [onChange, selected]
140
+ );
141
+ const handleKeyDown = React__namespace.useCallback(
142
+ (e) => {
143
+ const input = inputRef.current;
144
+ if (input) {
145
+ if (e.key === "Delete" || e.key === "Backspace") {
146
+ if (input.value === "" && selected.length > 0) {
147
+ const lastSelectOption = selected[selected.length - 1];
148
+ if (lastSelectOption && !lastSelectOption.fixed) {
149
+ handleUnselect(lastSelectOption);
150
+ }
151
+ }
152
+ }
153
+ if (e.key === "Escape") {
154
+ input.blur();
155
+ }
156
+ }
157
+ },
158
+ [handleUnselect, selected]
159
+ );
160
+ React.useEffect(() => {
161
+ if (open) {
162
+ document.addEventListener("mousedown", handleClickOutside);
163
+ document.addEventListener("touchend", handleClickOutside);
164
+ } else {
165
+ document.removeEventListener("mousedown", handleClickOutside);
166
+ document.removeEventListener("touchend", handleClickOutside);
167
+ }
168
+ return () => {
169
+ document.removeEventListener("mousedown", handleClickOutside);
170
+ document.removeEventListener("touchend", handleClickOutside);
171
+ };
172
+ }, [open]);
173
+ React.useEffect(() => {
174
+ if (value) {
175
+ setSelected(value);
176
+ }
177
+ }, [value]);
178
+ React.useEffect(() => {
179
+ if (!arrayOptions || onSearch) {
180
+ return;
181
+ }
182
+ const newOption = transToGroupOption(
183
+ arrayOptions || EMPTY_ARRAY,
184
+ groupBy
185
+ );
186
+ if (JSON.stringify(newOption) !== JSON.stringify(options)) {
187
+ setOptions(newOption);
188
+ }
189
+ }, [arrayDefaultOptions, arrayOptions, groupBy, onSearch, options]);
190
+ React.useEffect(() => {
191
+ const doSearchSync = () => {
192
+ const res = onSearchSync?.(debouncedSearchTerm);
193
+ setOptions(transToGroupOption(res || [], groupBy));
194
+ };
195
+ const exec = async () => {
196
+ if (!onSearchSync || !open) return;
197
+ if (triggerSearchOnFocus) {
198
+ doSearchSync();
199
+ }
200
+ if (debouncedSearchTerm) {
201
+ doSearchSync();
202
+ }
203
+ };
204
+ void exec();
205
+ }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);
206
+ React.useEffect(() => {
207
+ const doSearch = async () => {
208
+ setIsLoading(true);
209
+ const res = await onSearch?.(debouncedSearchTerm);
210
+ setOptions(transToGroupOption(res || [], groupBy));
211
+ setIsLoading(false);
212
+ };
213
+ const exec = async () => {
214
+ if (!onSearch || !open) return;
215
+ if (triggerSearchOnFocus) {
216
+ await doSearch();
217
+ }
218
+ if (debouncedSearchTerm) {
219
+ await doSearch();
220
+ }
221
+ };
222
+ void exec();
223
+ }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);
224
+ const handleCommandKeyDown = React.useCallback(
225
+ (e) => {
226
+ handleKeyDown(e);
227
+ commandProps?.onKeyDown?.(e);
228
+ },
229
+ [handleKeyDown, commandProps]
230
+ );
231
+ const handleBadgeGroupClick = React.useCallback(() => {
232
+ if (disabled) return;
233
+ inputRef?.current?.focus();
234
+ }, [disabled]);
235
+ const targetOption = React.useMemo(() => {
236
+ return [{ value: inputValue, label: inputValue }];
237
+ }, [inputValue]);
238
+ const handleCommandItemMouseDown = React.useCallback(
239
+ (e) => {
240
+ e.preventDefault();
241
+ e.stopPropagation();
242
+ },
243
+ []
244
+ );
245
+ const handleCommandItemSelect = React.useCallback(
246
+ (value2) => {
247
+ if (selected.length >= maxSelected) {
248
+ onMaxSelected?.(selected.length);
249
+ return;
250
+ }
251
+ setInputValue("");
252
+ const newOptions = [...selected, { value: value2, label: value2 }];
253
+ setSelected(newOptions);
254
+ onChange?.(newOptions);
255
+ },
256
+ [maxSelected, onMaxSelected, selected, onChange]
257
+ );
258
+ const CreatableItem = () => {
259
+ if (!creatable) return void 0;
260
+ if (isOptionsExist(options, targetOption) || selected.find((s) => s.value === inputValue)) {
261
+ return void 0;
262
+ }
263
+ const Item = /* @__PURE__ */ jsxRuntime.jsx(
264
+ command.CommandItem,
265
+ {
266
+ value: inputValue,
267
+ className: "cursor-pointer",
268
+ onMouseDown: handleCommandItemMouseDown,
269
+ onSelect: handleCommandItemSelect,
270
+ children: `Create "${inputValue}"`
271
+ }
272
+ );
273
+ if (!onSearch && inputValue.length > 0) {
274
+ return Item;
275
+ }
276
+ if (onSearch && debouncedSearchTerm.length > 0 && !isLoading) {
277
+ return Item;
278
+ }
279
+ return void 0;
280
+ };
281
+ const EmptyItem = React__namespace.useCallback(() => {
282
+ if (!emptyIndicator) return void 0;
283
+ if (onSearch && !creatable && Object.keys(options).length === 0) {
284
+ return /* @__PURE__ */ jsxRuntime.jsx(command.CommandItem, { value: "-", disabled: true, children: emptyIndicator });
285
+ }
286
+ return /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: emptyIndicator });
287
+ }, [creatable, emptyIndicator, onSearch, options]);
288
+ const selectables = React__namespace.useMemo(
289
+ () => removePickedOption(options, selected),
290
+ [options, selected]
291
+ );
292
+ const commandFilter = React__namespace.useCallback(() => {
293
+ if (commandProps?.filter) {
294
+ return commandProps.filter;
295
+ }
296
+ if (creatable) {
297
+ return (value2, search) => {
298
+ return value2.toLowerCase().includes(search.toLowerCase()) ? 1 : -1;
299
+ };
300
+ }
301
+ return void 0;
302
+ }, [creatable, commandProps?.filter]);
303
+ const handlePrimitiveInputValueChange = React.useCallback(
304
+ (value2) => {
305
+ setInputValue(value2);
306
+ inputProps?.onValueChange?.(value2);
307
+ },
308
+ [inputProps]
309
+ );
310
+ const handlePrimitiveInputBlur = React.useCallback(
311
+ (event) => {
312
+ if (!onScrollbar) {
313
+ setOpen(false);
314
+ }
315
+ inputProps?.onBlur?.(event);
316
+ },
317
+ [onScrollbar, inputProps]
318
+ );
319
+ const handlePrimitiveInputFocus = React.useCallback(
320
+ (event) => {
321
+ setOpen(true);
322
+ if (triggerSearchOnFocus) {
323
+ onSearch?.(debouncedSearchTerm);
324
+ }
325
+ inputProps?.onFocus?.(event);
326
+ },
327
+ [triggerSearchOnFocus, debouncedSearchTerm, inputProps, onSearch]
328
+ );
329
+ const handleClearAllButtonClick = React.useCallback(() => {
330
+ setSelected(selected.filter((s) => s.fixed));
331
+ onChange?.(selected.filter((s) => s.fixed));
332
+ }, [selected, onChange]);
333
+ const handleCommandListMouseLeave = React.useCallback(() => {
334
+ setOnScrollbar(false);
335
+ }, []);
336
+ const handleCommandListMouseEnter = React.useCallback(() => {
337
+ setOnScrollbar(true);
338
+ }, []);
339
+ const handleCommandListMouseUp = React.useCallback(() => {
340
+ inputRef?.current?.focus();
341
+ }, []);
342
+ const handleCommandGroupItemMouseDown = React.useCallback(
343
+ (e) => {
344
+ e.preventDefault();
345
+ e.stopPropagation();
346
+ },
347
+ []
348
+ );
349
+ const handleCommandGroupItemSelect = React.useCallback(
350
+ (option) => {
351
+ if (selected.length >= maxSelected) {
352
+ onMaxSelected?.(selected.length);
353
+ return;
354
+ }
355
+ setInputValue("");
356
+ const newOptions = [...selected, option];
357
+ setSelected(newOptions);
358
+ onChange?.(newOptions);
359
+ },
360
+ [maxSelected, onMaxSelected, selected, onChange]
361
+ );
362
+ return /* @__PURE__ */ jsxRuntime.jsxs(
363
+ command.Command,
364
+ {
365
+ ref: dropdownRef,
366
+ ...commandProps,
367
+ onKeyDown: handleCommandKeyDown,
368
+ className: utils.cn(
369
+ "h-auto overflow-visible bg-transparent",
370
+ commandProps?.className
371
+ ),
372
+ shouldFilter: commandProps?.shouldFilter !== void 0 ? commandProps.shouldFilter : !onSearch,
373
+ filter: commandFilter(),
374
+ children: [
375
+ /* @__PURE__ */ jsxRuntime.jsx(
376
+ "div",
377
+ {
378
+ className: utils.cn(
379
+ "min-h-10 rounded-md border border-input text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
380
+ {
381
+ "px-3 py-2": selected.length !== 0,
382
+ "cursor-text": !disabled && selected.length !== 0
383
+ },
384
+ className
385
+ ),
386
+ onClick: handleBadgeGroupClick,
387
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-wrap gap-1", children: [
388
+ selected.map((option) => {
389
+ return /* @__PURE__ */ jsxRuntime.jsx(
390
+ OptionBadge,
391
+ {
392
+ option,
393
+ onUnselect: handleUnselect,
394
+ badgeClassName,
395
+ disabled
396
+ },
397
+ option.value
398
+ );
399
+ }),
400
+ /* @__PURE__ */ jsxRuntime.jsx(
401
+ cmdk.Command.Input,
402
+ {
403
+ ...inputProps,
404
+ ref: inputRef,
405
+ value: inputValue,
406
+ disabled,
407
+ onValueChange: handlePrimitiveInputValueChange,
408
+ onBlur: handlePrimitiveInputBlur,
409
+ onFocus: handlePrimitiveInputFocus,
410
+ placeholder: hidePlaceholderWhenSelected && selected.length !== 0 ? "" : placeholder,
411
+ className: utils.cn(
412
+ "flex-1 bg-transparent outline-none placeholder:text-muted-foreground",
413
+ {
414
+ "w-full": hidePlaceholderWhenSelected,
415
+ "px-3 py-2": selected.length === 0,
416
+ "ml-1": selected.length !== 0
417
+ },
418
+ inputProps?.className
419
+ )
420
+ }
421
+ ),
422
+ /* @__PURE__ */ jsxRuntime.jsx(
423
+ "button",
424
+ {
425
+ type: "button",
426
+ onClick: handleClearAllButtonClick,
427
+ className: utils.cn(
428
+ "absolute right-0 h-6 w-6 p-0",
429
+ (hideClearAllButton || disabled || selected.length < 1 || selected.filter((s) => s.fixed).length === selected.length) && "hidden"
430
+ ),
431
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {})
432
+ }
433
+ )
434
+ ] })
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: open && /* @__PURE__ */ jsxRuntime.jsx(
438
+ command.CommandList,
439
+ {
440
+ className: "absolute top-1 z-10 w-full rounded-md border bg-popover text-popover-foreground shadow-md outline-none animate-in",
441
+ onMouseLeave: handleCommandListMouseLeave,
442
+ onMouseEnter: handleCommandListMouseEnter,
443
+ onMouseUp: handleCommandListMouseUp,
444
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loadingIndicator }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
445
+ EmptyItem(),
446
+ CreatableItem(),
447
+ !selectFirstItem && /* @__PURE__ */ jsxRuntime.jsx(command.CommandItem, { value: "-", className: "hidden" }),
448
+ Object.entries(selectables).map(([key, dropdowns]) => /* @__PURE__ */ jsxRuntime.jsx(
449
+ command.CommandGroup,
450
+ {
451
+ heading: key,
452
+ className: "h-full overflow-auto",
453
+ children: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dropdowns.map((option) => {
454
+ return /* @__PURE__ */ jsxRuntime.jsx(
455
+ CommandGroupItem,
456
+ {
457
+ option,
458
+ onSelect: handleCommandGroupItemSelect,
459
+ onMouseDown: handleCommandGroupItemMouseDown
460
+ },
461
+ option.value
462
+ );
463
+ }) })
464
+ },
465
+ key
466
+ ))
467
+ ] })
468
+ }
469
+ ) })
470
+ ]
471
+ }
472
+ );
473
+ }
474
+ );
475
+ MultipleSelector.displayName = "MultipleSelector";
476
+ const OptionBadge = ({
477
+ option,
478
+ onUnselect,
479
+ badgeClassName,
480
+ disabled
481
+ }) => {
482
+ const handleUnselect = React.useCallback(() => {
483
+ onUnselect(option);
484
+ }, [onUnselect, option]);
485
+ const handleKeyDown = React.useCallback(
486
+ (e) => {
487
+ if (e.key === "Enter") {
488
+ onUnselect(option);
489
+ }
490
+ },
491
+ [onUnselect, option]
492
+ );
493
+ const handleMouseDown = React.useCallback(
494
+ (e) => {
495
+ e.preventDefault();
496
+ e.stopPropagation();
497
+ },
498
+ []
499
+ );
500
+ return /* @__PURE__ */ jsxRuntime.jsxs(
501
+ badge.Badge,
502
+ {
503
+ className: utils.cn(
504
+ "data-disabled:bg-muted-foreground data-disabled:text-muted data-disabled:hover:bg-muted-foreground",
505
+ "data-fixed:bg-muted-foreground data-fixed:text-muted data-fixed:hover:bg-muted-foreground",
506
+ badgeClassName
507
+ ),
508
+ "data-fixed": option.fixed,
509
+ "data-disabled": disabled || void 0,
510
+ children: [
511
+ option.label,
512
+ /* @__PURE__ */ jsxRuntime.jsx(
513
+ "button",
514
+ {
515
+ className: utils.cn(
516
+ "ml-1 rounded-full outline-none ring-offset-background focus:ring-2 focus:ring-ring focus:ring-offset-2",
517
+ (disabled || option.fixed) && "hidden"
518
+ ),
519
+ onKeyDown: handleKeyDown,
520
+ onMouseDown: handleMouseDown,
521
+ onClick: handleUnselect,
522
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
523
+ }
524
+ )
525
+ ]
526
+ },
527
+ option.value
528
+ );
529
+ };
530
+ const CommandGroupItem = ({
531
+ option,
532
+ onSelect,
533
+ onMouseDown
534
+ }) => {
535
+ const handleSelect = React.useCallback(() => {
536
+ onSelect(option);
537
+ }, [onSelect, option]);
538
+ return /* @__PURE__ */ jsxRuntime.jsx(
539
+ command.CommandItem,
540
+ {
541
+ value: option.value,
542
+ disabled: option.disable,
543
+ onMouseDown,
544
+ onSelect: handleSelect,
545
+ className: utils.cn(
546
+ "cursor-pointer",
547
+ option.disable && "cursor-default text-muted-foreground"
548
+ ),
549
+ children: option.label
550
+ },
551
+ option.value
552
+ );
553
+ };
554
+
555
+ module.exports = MultipleSelector;