@btst/plugin-cms 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 (204) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/api/getters.cjs +328 -0
  3. package/dist/api/getters.mjs +314 -0
  4. package/dist/api/index.cjs +29 -0
  5. package/dist/api/index.d.cts +209 -0
  6. package/dist/api/index.d.mts +209 -0
  7. package/dist/api/index.d.ts +209 -0
  8. package/dist/api/index.mjs +7 -0
  9. package/dist/api/lifecycle-migrations.cjs +13 -0
  10. package/dist/api/lifecycle-migrations.mjs +11 -0
  11. package/dist/api/mutations.cjs +59 -0
  12. package/dist/api/mutations.mjs +57 -0
  13. package/dist/api/operations.cjs +1769 -0
  14. package/dist/api/operations.mjs +1762 -0
  15. package/dist/api/plugin.cjs +337 -0
  16. package/dist/api/plugin.mjs +331 -0
  17. package/dist/api/query-key-defs.cjs +44 -0
  18. package/dist/api/query-key-defs.mjs +39 -0
  19. package/dist/api/relations.cjs +76 -0
  20. package/dist/api/relations.mjs +70 -0
  21. package/dist/client/components/forms/content-form.cjs +286 -0
  22. package/dist/client/components/forms/content-form.mjs +284 -0
  23. package/dist/client/components/forms/file-upload.cjs +160 -0
  24. package/dist/client/components/forms/file-upload.mjs +158 -0
  25. package/dist/client/components/forms/relation-field.cjs +237 -0
  26. package/dist/client/components/forms/relation-field.mjs +235 -0
  27. package/dist/client/components/index.cjs +14 -0
  28. package/dist/client/components/index.d.cts +20 -0
  29. package/dist/client/components/index.d.mts +20 -0
  30. package/dist/client/components/index.d.ts +20 -0
  31. package/dist/client/components/index.mjs +10 -0
  32. package/dist/client/components/inverse-relations-panel.cjs +272 -0
  33. package/dist/client/components/inverse-relations-panel.mjs +270 -0
  34. package/dist/client/components/loading/dashboard-skeleton.cjs +18 -0
  35. package/dist/client/components/loading/dashboard-skeleton.mjs +16 -0
  36. package/dist/client/components/loading/editor-skeleton.cjs +32 -0
  37. package/dist/client/components/loading/editor-skeleton.mjs +30 -0
  38. package/dist/client/components/loading/list-skeleton.cjs +32 -0
  39. package/dist/client/components/loading/list-skeleton.mjs +30 -0
  40. package/dist/client/components/pages/404-page.cjs +26 -0
  41. package/dist/client/components/pages/404-page.mjs +24 -0
  42. package/dist/client/components/pages/content-editor-page.cjs +84 -0
  43. package/dist/client/components/pages/content-editor-page.internal.cjs +170 -0
  44. package/dist/client/components/pages/content-editor-page.internal.mjs +168 -0
  45. package/dist/client/components/pages/content-editor-page.mjs +82 -0
  46. package/dist/client/components/pages/content-list-page.cjs +49 -0
  47. package/dist/client/components/pages/content-list-page.internal.cjs +334 -0
  48. package/dist/client/components/pages/content-list-page.internal.mjs +332 -0
  49. package/dist/client/components/pages/content-list-page.mjs +47 -0
  50. package/dist/client/components/pages/dashboard-page.cjs +42 -0
  51. package/dist/client/components/pages/dashboard-page.internal.cjs +102 -0
  52. package/dist/client/components/pages/dashboard-page.internal.mjs +100 -0
  53. package/dist/client/components/pages/dashboard-page.mjs +40 -0
  54. package/dist/client/components/shared/default-error.cjs +17 -0
  55. package/dist/client/components/shared/default-error.mjs +15 -0
  56. package/dist/client/components/shared/empty-state.cjs +16 -0
  57. package/dist/client/components/shared/empty-state.mjs +14 -0
  58. package/dist/client/components/shared/page-wrapper.cjs +29 -0
  59. package/dist/client/components/shared/page-wrapper.mjs +27 -0
  60. package/dist/client/constants.cjs +5 -0
  61. package/dist/client/constants.mjs +3 -0
  62. package/dist/client/hooks/cms-hooks.cjs +300 -0
  63. package/dist/client/hooks/cms-hooks.mjs +280 -0
  64. package/dist/client/hooks/cms-resource.cjs +13 -0
  65. package/dist/client/hooks/cms-resource.mjs +11 -0
  66. package/dist/client/hooks/index.cjs +25 -0
  67. package/dist/client/hooks/index.d.cts +693 -0
  68. package/dist/client/hooks/index.d.mts +693 -0
  69. package/dist/client/hooks/index.d.ts +693 -0
  70. package/dist/client/hooks/index.mjs +1 -0
  71. package/dist/client/index.cjs +15 -0
  72. package/dist/client/index.d.cts +654 -0
  73. package/dist/client/index.d.mts +654 -0
  74. package/dist/client/index.d.ts +654 -0
  75. package/dist/client/index.mjs +3 -0
  76. package/dist/client/overrides.cjs +26 -0
  77. package/dist/client/overrides.mjs +24 -0
  78. package/dist/client/plugin.cjs +316 -0
  79. package/dist/client/plugin.mjs +314 -0
  80. package/dist/client.css +3 -0
  81. package/dist/db.cjs +118 -0
  82. package/dist/db.mjs +116 -0
  83. package/dist/permissions.cjs +46 -0
  84. package/dist/permissions.d.cts +42 -0
  85. package/dist/permissions.d.mts +42 -0
  86. package/dist/permissions.d.ts +42 -0
  87. package/dist/permissions.mjs +44 -0
  88. package/dist/query-keys.cjs +229 -0
  89. package/dist/query-keys.d.cts +8 -0
  90. package/dist/query-keys.d.mts +8 -0
  91. package/dist/query-keys.d.ts +8 -0
  92. package/dist/query-keys.mjs +225 -0
  93. package/dist/schemas.cjs +81 -0
  94. package/dist/schemas.mjs +72 -0
  95. package/dist/shared/plugin-cms.BBshPRkb.d.cts +6 -0
  96. package/dist/shared/plugin-cms.BBshPRkb.d.mts +6 -0
  97. package/dist/shared/plugin-cms.BBshPRkb.d.ts +6 -0
  98. package/dist/shared/plugin-cms.DQLAoogy.d.ts +1749 -0
  99. package/dist/shared/plugin-cms.W4Le8D91.d.mts +1749 -0
  100. package/dist/shared/plugin-cms.c-GeWvTf.d.cts +1749 -0
  101. package/dist/style.css +6 -0
  102. package/dist/types.cjs +2 -0
  103. package/dist/types.d.cts +406 -0
  104. package/dist/types.d.mts +406 -0
  105. package/dist/types.d.ts +406 -0
  106. package/dist/types.mjs +1 -0
  107. package/dist/ui/src/components/accordion.cjs +81 -0
  108. package/dist/ui/src/components/accordion.mjs +62 -0
  109. package/dist/ui/src/components/alert-dialog.cjs +157 -0
  110. package/dist/ui/src/components/alert-dialog.mjs +132 -0
  111. package/dist/ui/src/components/auto-form/common/label.cjs +18 -0
  112. package/dist/ui/src/components/auto-form/common/label.mjs +16 -0
  113. package/dist/ui/src/components/auto-form/common/tooltip.cjs +9 -0
  114. package/dist/ui/src/components/auto-form/common/tooltip.mjs +7 -0
  115. package/dist/ui/src/components/auto-form/config.cjs +40 -0
  116. package/dist/ui/src/components/auto-form/config.mjs +37 -0
  117. package/dist/ui/src/components/auto-form/dependencies.cjs +48 -0
  118. package/dist/ui/src/components/auto-form/dependencies.mjs +46 -0
  119. package/dist/ui/src/components/auto-form/fields/array.cjs +266 -0
  120. package/dist/ui/src/components/auto-form/fields/array.mjs +264 -0
  121. package/dist/ui/src/components/auto-form/fields/checkbox.cjs +38 -0
  122. package/dist/ui/src/components/auto-form/fields/checkbox.mjs +36 -0
  123. package/dist/ui/src/components/auto-form/fields/date.cjs +67 -0
  124. package/dist/ui/src/components/auto-form/fields/date.mjs +65 -0
  125. package/dist/ui/src/components/auto-form/fields/enum.cjs +73 -0
  126. package/dist/ui/src/components/auto-form/fields/enum.mjs +71 -0
  127. package/dist/ui/src/components/auto-form/fields/input.cjs +32 -0
  128. package/dist/ui/src/components/auto-form/fields/input.mjs +30 -0
  129. package/dist/ui/src/components/auto-form/fields/number.cjs +31 -0
  130. package/dist/ui/src/components/auto-form/fields/number.mjs +29 -0
  131. package/dist/ui/src/components/auto-form/fields/object.cjs +233 -0
  132. package/dist/ui/src/components/auto-form/fields/object.mjs +217 -0
  133. package/dist/ui/src/components/auto-form/fields/radio-group.cjs +67 -0
  134. package/dist/ui/src/components/auto-form/fields/radio-group.mjs +65 -0
  135. package/dist/ui/src/components/auto-form/fields/switch.cjs +38 -0
  136. package/dist/ui/src/components/auto-form/fields/switch.mjs +36 -0
  137. package/dist/ui/src/components/auto-form/fields/textarea.cjs +31 -0
  138. package/dist/ui/src/components/auto-form/fields/textarea.mjs +29 -0
  139. package/dist/ui/src/components/auto-form/helpers.cjs +270 -0
  140. package/dist/ui/src/components/auto-form/helpers.mjs +259 -0
  141. package/dist/ui/src/components/auto-form/index.cjs +92 -0
  142. package/dist/ui/src/components/auto-form/index.mjs +86 -0
  143. package/dist/ui/src/components/auto-form/stepped-auto-form.cjs +374 -0
  144. package/dist/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
  145. package/dist/ui/src/components/auto-form/types.cjs +11 -0
  146. package/dist/ui/src/components/auto-form/types.mjs +9 -0
  147. package/dist/ui/src/components/badge.cjs +42 -0
  148. package/dist/ui/src/components/badge.mjs +39 -0
  149. package/dist/ui/src/components/button.cjs +56 -0
  150. package/dist/ui/src/components/button.mjs +53 -0
  151. package/dist/ui/src/components/calendar.cjs +207 -0
  152. package/dist/ui/src/components/calendar.mjs +190 -0
  153. package/dist/ui/src/components/card.cjs +56 -0
  154. package/dist/ui/src/components/card.mjs +51 -0
  155. package/dist/ui/src/components/checkbox.cjs +48 -0
  156. package/dist/ui/src/components/checkbox.mjs +32 -0
  157. package/dist/ui/src/components/command.cjs +78 -0
  158. package/dist/ui/src/components/command.mjs +73 -0
  159. package/dist/ui/src/components/date-picker.cjs +41 -0
  160. package/dist/ui/src/components/date-picker.mjs +39 -0
  161. package/dist/ui/src/components/dialog.cjs +119 -0
  162. package/dist/ui/src/components/dialog.mjs +97 -0
  163. package/dist/ui/src/components/form.cjs +120 -0
  164. package/dist/ui/src/components/form.mjs +98 -0
  165. package/dist/ui/src/components/input.cjs +23 -0
  166. package/dist/ui/src/components/input.mjs +21 -0
  167. package/dist/ui/src/components/label.cjs +39 -0
  168. package/dist/ui/src/components/label.mjs +23 -0
  169. package/dist/ui/src/components/multi-select.cjs +555 -0
  170. package/dist/ui/src/components/multi-select.mjs +540 -0
  171. package/dist/ui/src/components/page-layout.cjs +25 -0
  172. package/dist/ui/src/components/page-layout.mjs +23 -0
  173. package/dist/ui/src/components/page-wrapper.cjs +20 -0
  174. package/dist/ui/src/components/page-wrapper.mjs +18 -0
  175. package/dist/ui/src/components/popover.cjs +60 -0
  176. package/dist/ui/src/components/popover.mjs +42 -0
  177. package/dist/ui/src/components/radio-group.cjs +62 -0
  178. package/dist/ui/src/components/radio-group.mjs +45 -0
  179. package/dist/ui/src/components/select.cjs +161 -0
  180. package/dist/ui/src/components/select.mjs +139 -0
  181. package/dist/ui/src/components/separator.cjs +43 -0
  182. package/dist/ui/src/components/separator.mjs +27 -0
  183. package/dist/ui/src/components/skeleton.cjs +17 -0
  184. package/dist/ui/src/components/skeleton.mjs +15 -0
  185. package/dist/ui/src/components/stack-attribution.cjs +24 -0
  186. package/dist/ui/src/components/stack-attribution.mjs +22 -0
  187. package/dist/ui/src/components/switch.cjs +48 -0
  188. package/dist/ui/src/components/switch.mjs +32 -0
  189. package/dist/ui/src/components/table.cjs +89 -0
  190. package/dist/ui/src/components/table.mjs +82 -0
  191. package/dist/ui/src/components/textarea.cjs +20 -0
  192. package/dist/ui/src/components/textarea.mjs +18 -0
  193. package/dist/ui/src/hooks/use-debounce.cjs +16 -0
  194. package/dist/ui/src/hooks/use-debounce.mjs +14 -0
  195. package/dist/ui/src/hooks/use-route-lifecycle.cjs +31 -0
  196. package/dist/ui/src/hooks/use-route-lifecycle.mjs +29 -0
  197. package/dist/ui/src/lib/schema-converter.cjs +133 -0
  198. package/dist/ui/src/lib/schema-converter.mjs +127 -0
  199. package/dist/ui/src/lib/utils.cjs +10 -0
  200. package/dist/ui/src/lib/utils.mjs +8 -0
  201. package/dist/utils.cjs +19 -0
  202. package/dist/utils.mjs +12 -0
  203. package/package.json +170 -3
  204. package/README.md +0 -3
@@ -0,0 +1,540 @@
1
+ 'use client';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { Command as Command$1, useCommandState } from 'cmdk';
4
+ import { X } from 'lucide-react';
5
+ import * as React from 'react';
6
+ import { useMemo, useEffect, useCallback, forwardRef } 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,25 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const utils = require('../lib/utils.cjs');
6
+
7
+ function PageLayout({
8
+ children,
9
+ className,
10
+ "data-testid": dataTestId
11
+ }) {
12
+ return /* @__PURE__ */ jsxRuntime.jsx(
13
+ "div",
14
+ {
15
+ className: utils.cn(
16
+ "container mx-auto flex min-h-dvh flex-col items-center gap-12 px-4 py-18 lg:px-16",
17
+ className
18
+ ),
19
+ "data-testid": dataTestId,
20
+ children
21
+ }
22
+ );
23
+ }
24
+
25
+ exports.PageLayout = PageLayout;
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { cn } from '../lib/utils.mjs';
4
+
5
+ function PageLayout({
6
+ children,
7
+ className,
8
+ "data-testid": dataTestId
9
+ }) {
10
+ return /* @__PURE__ */ jsx(
11
+ "div",
12
+ {
13
+ className: cn(
14
+ "container mx-auto flex min-h-dvh flex-col items-center gap-12 px-4 py-18 lg:px-16",
15
+ className
16
+ ),
17
+ "data-testid": dataTestId,
18
+ children
19
+ }
20
+ );
21
+ }
22
+
23
+ export { PageLayout };
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const pageLayout = require('./page-layout.cjs');
6
+ const stackAttribution = require('./stack-attribution.cjs');
7
+
8
+ function PageWrapper({
9
+ children,
10
+ className,
11
+ testId,
12
+ showAttribution = true
13
+ }) {
14
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15
+ /* @__PURE__ */ jsxRuntime.jsx(pageLayout.PageLayout, { className, "data-testid": testId, children }),
16
+ showAttribution && /* @__PURE__ */ jsxRuntime.jsx(stackAttribution.StackAttribution, {})
17
+ ] });
18
+ }
19
+
20
+ exports.PageWrapper = PageWrapper;
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { PageLayout } from './page-layout.mjs';
4
+ import { StackAttribution } from './stack-attribution.mjs';
5
+
6
+ function PageWrapper({
7
+ children,
8
+ className,
9
+ testId,
10
+ showAttribution = true
11
+ }) {
12
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
13
+ /* @__PURE__ */ jsx(PageLayout, { className, "data-testid": testId, children }),
14
+ showAttribution && /* @__PURE__ */ jsx(StackAttribution, {})
15
+ ] });
16
+ }
17
+
18
+ export { PageWrapper };
@@ -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;