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