@egose/shadcn-theme 0.1.6 → 0.1.7

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 (92) hide show
  1. package/chunk-2NUE7GJ3.js +44 -0
  2. package/chunk-2NUE7GJ3.js.map +1 -0
  3. package/chunk-3PZY5HRH.mjs +82 -0
  4. package/chunk-3PZY5HRH.mjs.map +1 -0
  5. package/{components/ui/extension/multi-select.js → chunk-3TG6ZVFG.js} +63 -62
  6. package/chunk-3TG6ZVFG.js.map +1 -0
  7. package/{components/ui/extension/multi-select.mjs → chunk-7JYFZETL.mjs} +64 -63
  8. package/chunk-7JYFZETL.mjs.map +1 -0
  9. package/chunk-FSU3BKPK.js +130 -0
  10. package/chunk-FSU3BKPK.js.map +1 -0
  11. package/{chunk-3ZN766EW.js → chunk-G6WKPZTL.js} +3 -3
  12. package/{chunk-3ZN766EW.js.map → chunk-G6WKPZTL.js.map} +1 -1
  13. package/chunk-IQIHYWXX.js +83 -0
  14. package/chunk-IQIHYWXX.js.map +1 -0
  15. package/{chunk-AJLAS62X.js → chunk-LAIO3QZX.js} +4 -4
  16. package/{chunk-AJLAS62X.js.map → chunk-LAIO3QZX.js.map} +1 -1
  17. package/{chunk-MJT6B7OJ.js → chunk-LPDYWZN6.js} +3 -3
  18. package/{chunk-MJT6B7OJ.js.map → chunk-LPDYWZN6.js.map} +1 -1
  19. package/{chunk-432PQWGO.mjs → chunk-RJVQU443.mjs} +2 -2
  20. package/chunk-USW6AILM.mjs +43 -0
  21. package/chunk-USW6AILM.mjs.map +1 -0
  22. package/{chunk-HKZRXGJ7.mjs → chunk-YDRPNCWF.mjs} +4 -4
  23. package/{chunk-ZMMYQNQV.mjs → chunk-ZFBUIBJH.mjs} +2 -2
  24. package/chunk-ZQK6REIM.mjs +129 -0
  25. package/chunk-ZQK6REIM.mjs.map +1 -0
  26. package/components/form/hook-multi-select.d.mts +14 -0
  27. package/components/form/hook-multi-select.d.ts +14 -0
  28. package/components/form/hook-multi-select.js +76 -0
  29. package/components/form/hook-multi-select.js.map +1 -0
  30. package/components/form/hook-multi-select.mjs +75 -0
  31. package/components/form/hook-multi-select.mjs.map +1 -0
  32. package/components/form/hook-searchable-select.js +5 -5
  33. package/components/form/hook-searchable-select.mjs +4 -4
  34. package/components/form/hook-tag-picker.d.mts +12 -0
  35. package/components/form/hook-tag-picker.d.ts +12 -0
  36. package/components/form/hook-tag-picker.js +66 -0
  37. package/components/form/hook-tag-picker.js.map +1 -0
  38. package/components/form/hook-tag-picker.mjs +65 -0
  39. package/components/form/hook-tag-picker.mjs.map +1 -0
  40. package/components/form/multi-select.d.mts +25 -1
  41. package/components/form/multi-select.d.ts +25 -1
  42. package/components/form/multi-select.js +20 -1
  43. package/components/form/multi-select.js.map +1 -1
  44. package/components/form/multi-select.mjs +19 -0
  45. package/components/form/searchable-select.js +5 -5
  46. package/components/form/searchable-select.mjs +4 -4
  47. package/components/form/tag-picker.d.mts +21 -0
  48. package/components/form/tag-picker.d.ts +21 -0
  49. package/components/form/tag-picker.js +14 -0
  50. package/components/form/tag-picker.js.map +1 -0
  51. package/components/form/tag-picker.mjs +13 -0
  52. package/components/form/tag-picker.mjs.map +1 -0
  53. package/components/ui/combobox.js +5 -5
  54. package/components/ui/combobox.mjs +2 -2
  55. package/components/ui/command.js +4 -4
  56. package/components/ui/command.mjs +3 -3
  57. package/components/ui/input-group.js +3 -3
  58. package/components/ui/input-group.mjs +2 -2
  59. package/components/ui/{extension/multi-select.d.mts → multi-select.d.mts} +4 -3
  60. package/components/ui/{extension/multi-select.d.ts → multi-select.d.ts} +4 -3
  61. package/components/ui/multi-select.js +29 -0
  62. package/components/ui/multi-select.js.map +1 -0
  63. package/components/ui/multi-select.mjs +28 -0
  64. package/components/ui/multi-select.mjs.map +1 -0
  65. package/components/ui/tag-picker.d.mts +14 -0
  66. package/components/ui/tag-picker.d.ts +14 -0
  67. package/components/ui/tag-picker.js +12 -0
  68. package/components/ui/tag-picker.js.map +1 -0
  69. package/components/ui/tag-picker.mjs +11 -0
  70. package/components/ui/tag-picker.mjs.map +1 -0
  71. package/components/widgets/dialog-manager/index.js +1 -1
  72. package/components/widgets/dialog-manager/index.js.map +1 -1
  73. package/components/widgets/dialog-manager/index.mjs +1 -1
  74. package/layouts/sidebar1/app-sidebar.js +2 -2
  75. package/layouts/sidebar1/app-sidebar.mjs +2 -2
  76. package/layouts/sidebar1/context-switcher.js +1 -1
  77. package/layouts/sidebar1/context-switcher.mjs +1 -1
  78. package/layouts/sidebar1/index.js +3 -3
  79. package/layouts/sidebar1/index.js.map +1 -1
  80. package/layouts/sidebar1/index.mjs +3 -3
  81. package/layouts/sidebar1/nav-menus.js +1 -1
  82. package/layouts/sidebar1/nav-menus.mjs +1 -1
  83. package/layouts/sidebar1/nav-user.js +2 -2
  84. package/layouts/sidebar1/nav-user.mjs +2 -2
  85. package/layouts/simple/index.js +2 -2
  86. package/layouts/simple/index.mjs +3 -3
  87. package/package.json +1 -1
  88. package/components/ui/extension/multi-select.js.map +0 -1
  89. package/components/ui/extension/multi-select.mjs.map +0 -1
  90. /package/{chunk-432PQWGO.mjs.map → chunk-RJVQU443.mjs.map} +0 -0
  91. /package/{chunk-HKZRXGJ7.mjs.map → chunk-YDRPNCWF.mjs.map} +0 -0
  92. /package/{chunk-ZMMYQNQV.mjs.map → chunk-ZFBUIBJH.mjs.map} +0 -0
@@ -1,30 +1,23 @@
1
- "use client";
2
- import {
3
- Badge
4
- } from "../../../chunk-WIISPZZE.mjs";
5
1
  import {
6
2
  Command,
7
3
  CommandEmpty,
8
4
  CommandItem,
9
5
  CommandList
10
- } from "../../../chunk-ZMMYQNQV.mjs";
11
- import "../../../chunk-HKZRXGJ7.mjs";
12
- import "../../../chunk-OPNHC6JN.mjs";
13
- import "../../../chunk-QF6PFV6M.mjs";
14
- import "../../../chunk-YQENFZOY.mjs";
15
- import "../../../chunk-7BYWDRRI.mjs";
16
- import "../../../chunk-3GHC4JQU.mjs";
6
+ } from "./chunk-ZFBUIBJH.mjs";
7
+ import {
8
+ Badge
9
+ } from "./chunk-WIISPZZE.mjs";
17
10
  import {
18
11
  cn
19
- } from "../../../chunk-KGUUDFJE.mjs";
12
+ } from "./chunk-KGUUDFJE.mjs";
20
13
  import {
21
14
  __objRest,
22
15
  __spreadProps,
23
16
  __spreadValues
24
- } from "../../../chunk-YOSPWY5K.mjs";
17
+ } from "./chunk-YOSPWY5K.mjs";
25
18
 
26
- // components/ui/extension/multi-select.tsx
27
- import { IconX, IconCheck } from "@tabler/icons-react";
19
+ // components/ui/multi-select.tsx
20
+ import { IconCheck, IconX } from "@tabler/icons-react";
28
21
  import { Command as CommandPrimitive } from "cmdk";
29
22
  import React, { createContext, forwardRef, useCallback, useContext, useState } from "react";
30
23
  var MultiSelectContext = createContext(null);
@@ -50,14 +43,16 @@ var MultiSelector = (_a) => {
50
43
  loop = false,
51
44
  className,
52
45
  children,
53
- dir
46
+ dir,
47
+ disabled = false
54
48
  } = _b, props = __objRest(_b, [
55
49
  "values",
56
50
  "onValuesChange",
57
51
  "loop",
58
52
  "className",
59
53
  "children",
60
- "dir"
54
+ "dir",
55
+ "disabled"
61
56
  ]);
62
57
  const [inputValue, setInputValue] = useState("");
63
58
  const [open, setOpen] = useState(false);
@@ -65,20 +60,21 @@ var MultiSelector = (_a) => {
65
60
  const inputRef = React.useRef(null);
66
61
  const onValueChangeHandler = useCallback(
67
62
  (val) => {
68
- const element = searchForValue(value, val);
69
- if (element !== -1) {
70
- onValueChange(value.filter((_, index) => index !== element));
63
+ if (disabled) return;
64
+ const exists = value.some((currentValue) => currentValue.value === val.value);
65
+ if (exists) {
66
+ onValueChange(value.filter((currentValue) => currentValue.value !== val.value));
71
67
  } else {
72
68
  onValueChange([...value, val]);
73
69
  }
74
70
  },
75
- // eslint-disable-next-line react-hooks/exhaustive-deps
76
- [value]
71
+ [disabled, onValueChange, value]
77
72
  );
78
73
  const handleKeyDown = useCallback(
79
74
  (e) => {
80
75
  var _a2, _b2;
81
76
  e.stopPropagation();
77
+ if (disabled) return;
82
78
  const target = inputRef.current;
83
79
  if (!target) return;
84
80
  const selectionStart = (_a2 = target.selectionStart) != null ? _a2 : 0;
@@ -104,10 +100,8 @@ var MultiSelector = (_a) => {
104
100
  if (value.length > 0 && (activeIndex !== -1 || loop)) {
105
101
  moveNext();
106
102
  }
107
- } else {
108
- if (value.length > 0 && target.selectionStart === 0) {
109
- movePrev();
110
- }
103
+ } else if (value.length > 0 && target.selectionStart === 0) {
104
+ movePrev();
111
105
  }
112
106
  break;
113
107
  case "ArrowRight":
@@ -115,10 +109,8 @@ var MultiSelector = (_a) => {
115
109
  if (value.length > 0 && target.selectionStart === 0) {
116
110
  movePrev();
117
111
  }
118
- } else {
119
- if (value.length > 0 && (activeIndex !== -1 || loop)) {
120
- moveNext();
121
- }
112
+ } else if (value.length > 0 && (activeIndex !== -1 || loop)) {
113
+ moveNext();
122
114
  }
123
115
  break;
124
116
  case "Backspace":
@@ -127,10 +119,8 @@ var MultiSelector = (_a) => {
127
119
  if (activeIndex !== -1 && activeIndex < value.length) {
128
120
  onValueChangeHandler(value[activeIndex]);
129
121
  moveCurrent();
130
- } else {
131
- if (target.selectionStart === 0) {
132
- onValueChangeHandler(value[value.length - 1]);
133
- }
122
+ } else if (target.selectionStart === 0) {
123
+ onValueChangeHandler(value[value.length - 1]);
134
124
  }
135
125
  }
136
126
  break;
@@ -147,7 +137,7 @@ var MultiSelector = (_a) => {
147
137
  break;
148
138
  }
149
139
  },
150
- [value, activeIndex, loop]
140
+ [activeIndex, dir, disabled, loop, onValueChangeHandler, open, value]
151
141
  );
152
142
  return /* @__PURE__ */ React.createElement(
153
143
  MultiSelectContext.Provider,
@@ -161,14 +151,15 @@ var MultiSelector = (_a) => {
161
151
  setInputValue,
162
152
  activeIndex,
163
153
  setActiveIndex,
164
- ref: inputRef
154
+ ref: inputRef,
155
+ disabled
165
156
  }
166
157
  },
167
158
  /* @__PURE__ */ React.createElement(
168
159
  Command,
169
160
  __spreadValues({
170
161
  onKeyDown: handleKeyDown,
171
- className: cn("overflow-visible bg-transparent flex flex-col space-y-2", className),
162
+ className: cn("flex flex-col overflow-visible bg-transparent", className),
172
163
  dir
173
164
  }, props),
174
165
  children
@@ -178,7 +169,7 @@ var MultiSelector = (_a) => {
178
169
  var MultiSelectorTrigger = forwardRef(
179
170
  (_a, ref) => {
180
171
  var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
181
- const { value, onValueChange, activeIndex } = useMultiSelect();
172
+ const { value, onValueChange, activeIndex, disabled } = useMultiSelect();
182
173
  const mousePreventDefault = useCallback((e) => {
183
174
  e.preventDefault();
184
175
  e.stopPropagation();
@@ -188,10 +179,9 @@ var MultiSelectorTrigger = forwardRef(
188
179
  __spreadValues({
189
180
  ref,
190
181
  className: cn(
191
- "flex flex-wrap gap-1 px-2 py-2 ring-1 ring-muted rounded-lg bg-background border rounded-sm",
192
- {
193
- "ring-1 focus-within:ring-ring": activeIndex === -1
194
- },
182
+ "flex flex-wrap gap-1 rounded-lg border bg-background px-2 py-1",
183
+ activeIndex === -1 && "focus-within:ring-1 focus-within:ring-ring",
184
+ disabled && "cursor-not-allowed opacity-60",
195
185
  className
196
186
  )
197
187
  }, props),
@@ -200,8 +190,8 @@ var MultiSelectorTrigger = forwardRef(
200
190
  {
201
191
  key: item.value,
202
192
  className: cn(
203
- "px-1.5 rounded-md flex items-center gap-1",
204
- activeIndex === index && "ring-2 ring-muted-foreground "
193
+ "flex items-center gap-1 rounded-md px-1.5",
194
+ activeIndex === index && "ring-2 ring-muted-foreground"
205
195
  ),
206
196
  variant: "secondary"
207
197
  },
@@ -209,14 +199,19 @@ var MultiSelectorTrigger = forwardRef(
209
199
  /* @__PURE__ */ React.createElement(
210
200
  "button",
211
201
  {
212
- "aria-label": `Remove ${item} option`,
213
- "aria-roledescription": "button to remove option",
202
+ "aria-label": `Remove ${item.label} option`,
214
203
  type: "button",
204
+ disabled,
215
205
  onMouseDown: mousePreventDefault,
216
- onClick: () => onValueChange(item)
206
+ onClick: (event) => {
207
+ event.preventDefault();
208
+ event.stopPropagation();
209
+ onValueChange(item);
210
+ },
211
+ className: "inline-flex cursor-pointer items-center justify-center rounded-md p-1 transition-colors hover:bg-red-50 hover:text-red-700 focus-visible:bg-red-100 focus-visible:outline-none disabled:cursor-not-allowed"
217
212
  },
218
213
  /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Remove ", item.label, " option"),
219
- /* @__PURE__ */ React.createElement(IconX, { className: "h-4 w-4 hover:stroke-destructive" })
214
+ /* @__PURE__ */ React.createElement(IconX, { className: "h-3.5 w-3.5" })
220
215
  )
221
216
  )),
222
217
  children
@@ -225,14 +220,15 @@ var MultiSelectorTrigger = forwardRef(
225
220
  );
226
221
  MultiSelectorTrigger.displayName = "MultiSelectorTrigger";
227
222
  var MultiSelectorInput = forwardRef((_a, ref) => {
228
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
229
- const { setOpen, inputValue, setInputValue, activeIndex, setActiveIndex, ref: inputRef } = useMultiSelect();
223
+ var _b = _a, { className, disabled: disabledProp } = _b, props = __objRest(_b, ["className", "disabled"]);
224
+ const { setOpen, inputValue, setInputValue, activeIndex, setActiveIndex, ref: inputRef, disabled } = useMultiSelect();
230
225
  return /* @__PURE__ */ React.createElement(
231
226
  CommandPrimitive.Input,
232
227
  __spreadProps(__spreadValues({}, props), {
233
228
  tabIndex: 0,
234
229
  ref: inputRef,
235
230
  value: inputValue,
231
+ disabled: disabled || disabledProp,
236
232
  onValueChange: activeIndex === -1 ? setInputValue : void 0,
237
233
  onBlur: () => {
238
234
  setInputValue("");
@@ -241,7 +237,7 @@ var MultiSelectorInput = forwardRef((_a, ref) => {
241
237
  onFocus: () => setOpen(true),
242
238
  onClick: () => setActiveIndex(-1),
243
239
  className: cn(
244
- "p-0 bg-transparent border-none outline-none focus:outline-none focus:ring-0 placeholder:text-muted-foreground flex-1 text-sm",
240
+ "flex-1 border-none bg-transparent p-0 text-sm outline-none placeholder:text-muted-foreground focus:outline-none focus:ring-0",
245
241
  className,
246
242
  activeIndex !== -1 && "caret-transparent"
247
243
  )
@@ -251,7 +247,8 @@ var MultiSelectorInput = forwardRef((_a, ref) => {
251
247
  MultiSelectorInput.displayName = "MultiSelectorInput";
252
248
  var MultiSelectorContent = forwardRef(({ children }, ref) => {
253
249
  const { open } = useMultiSelect();
254
- return /* @__PURE__ */ React.createElement("div", { ref, className: "relative" }, open ? children : null);
250
+ if (!open) return null;
251
+ return /* @__PURE__ */ React.createElement("div", { ref, className: "relative" }, children);
255
252
  });
256
253
  MultiSelectorContent.displayName = "MultiSelectorContent";
257
254
  var MultiSelectorList = forwardRef(({ className, children }, ref) => {
@@ -260,7 +257,7 @@ var MultiSelectorList = forwardRef(({ className, children }, ref) => {
260
257
  {
261
258
  ref,
262
259
  className: cn(
263
- "p-2 flex flex-col gap-2 rounded-md scrollbar-thin scrollbar-track-transparent transition-colors scrollbar-thumb-muted-foreground dark:scrollbar-thumb-muted scrollbar-thumb-rounded-lg w-full absolute bg-background shadow-md z-100 border border-muted top-0",
260
+ "absolute top-0 z-100 flex w-full flex-col gap-2 rounded-md border border-muted bg-background p-2 shadow-md scrollbar-thin scrollbar-track-transparent scrollbar-thumb-rounded-lg scrollbar-thumb-muted-foreground transition-colors dark:scrollbar-thumb-muted",
264
261
  className
265
262
  )
266
263
  },
@@ -270,22 +267,25 @@ var MultiSelectorList = forwardRef(({ className, children }, ref) => {
270
267
  });
271
268
  MultiSelectorList.displayName = "MultiSelectorList";
272
269
  var MultiSelectorItem = forwardRef((_a, ref) => {
273
- var _b = _a, { className, value, label, children } = _b, props = __objRest(_b, ["className", "value", "label", "children"]);
274
- const { value: Options, onValueChange, setInputValue } = useMultiSelect();
270
+ var _b = _a, { className, value, label, children, disabled: disabledProp } = _b, props = __objRest(_b, ["className", "value", "label", "children", "disabled"]);
271
+ const { value: options, onValueChange, setInputValue, disabled } = useMultiSelect();
275
272
  const mousePreventDefault = useCallback((e) => {
276
273
  e.preventDefault();
277
274
  e.stopPropagation();
278
275
  }, []);
279
- const isIncluded = searchForValue(Options, {
276
+ const isIncluded = searchForValue(options, {
280
277
  value,
281
278
  label
282
279
  }) !== -1;
280
+ const isDisabled = disabled || disabledProp;
283
281
  return /* @__PURE__ */ React.createElement(
284
282
  CommandItem,
285
283
  __spreadProps(__spreadValues({
286
284
  ref
287
285
  }, props), {
286
+ disabled: isDisabled,
288
287
  onSelect: () => {
288
+ if (isDisabled) return;
289
289
  onValueChange({
290
290
  value,
291
291
  label
@@ -293,10 +293,10 @@ var MultiSelectorItem = forwardRef((_a, ref) => {
293
293
  setInputValue("");
294
294
  },
295
295
  className: cn(
296
- "rounded-md cursor-pointer px-2 py-1 transition-colors flex justify-between",
296
+ "flex cursor-pointer justify-between rounded-md px-2 py-1 transition-colors",
297
297
  className,
298
- isIncluded && "opacity-50 cursor-default",
299
- props.disabled && "opacity-50 cursor-not-allowed"
298
+ isIncluded && "cursor-default opacity-50",
299
+ isDisabled && "cursor-not-allowed opacity-50"
300
300
  ),
301
301
  onMouseDown: mousePreventDefault
302
302
  }),
@@ -305,12 +305,13 @@ var MultiSelectorItem = forwardRef((_a, ref) => {
305
305
  );
306
306
  });
307
307
  MultiSelectorItem.displayName = "MultiSelectorItem";
308
+
308
309
  export {
309
310
  MultiSelector,
310
- MultiSelectorContent,
311
+ MultiSelectorTrigger,
311
312
  MultiSelectorInput,
312
- MultiSelectorItem,
313
+ MultiSelectorContent,
313
314
  MultiSelectorList,
314
- MultiSelectorTrigger
315
+ MultiSelectorItem
315
316
  };
316
- //# sourceMappingURL=multi-select.mjs.map
317
+ //# sourceMappingURL=chunk-7JYFZETL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/ui/multi-select.tsx"],"sourcesContent":["\"use client\";\nimport { IconCheck, IconX } from '@tabler/icons-react';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport React, { type KeyboardEvent, createContext, forwardRef, useCallback, useContext, useState } from 'react';\n\nimport { cn } from '../../utils/ui';\nimport { Badge } from './badge';\nimport { Command, CommandEmpty, CommandItem, CommandList } from './command';\n\nexport type MultiSelectValue = {\n value: string;\n label: string;\n};\n\ninterface MultiSelectorProps extends React.ComponentPropsWithoutRef<typeof CommandPrimitive> {\n values: MultiSelectValue[];\n onValuesChange: (value: MultiSelectValue[]) => void;\n loop?: boolean;\n className?: string;\n children?: React.ReactNode;\n dir?: 'ltr' | 'rtl';\n disabled?: boolean;\n}\n\ninterface MultiSelectContextProps {\n value: MultiSelectValue[];\n onValueChange: (value: MultiSelectValue) => void;\n open: boolean;\n setOpen: (value: boolean) => void;\n inputValue: string;\n setInputValue: React.Dispatch<React.SetStateAction<string>>;\n activeIndex: number;\n setActiveIndex: React.Dispatch<React.SetStateAction<number>>;\n ref: React.RefObject<HTMLInputElement | null>;\n disabled: boolean;\n}\n\nconst MultiSelectContext = createContext<MultiSelectContextProps | null>(null);\n\nconst useMultiSelect = () => {\n const context = useContext(MultiSelectContext);\n if (!context) {\n throw new Error('useMultiSelect must be used within MultiSelectProvider');\n }\n return context;\n};\n\nfunction searchForValue(source: MultiSelectValue[], value: MultiSelectValue) {\n for (let i = 0; i < source.length; i++) {\n if (source[i].value === value.value) {\n return i;\n }\n }\n return -1;\n}\n\nconst MultiSelector = ({\n values: value,\n onValuesChange: onValueChange,\n loop = false,\n className,\n children,\n dir,\n disabled = false,\n ...props\n}: MultiSelectorProps) => {\n const [inputValue, setInputValue] = useState('');\n const [open, setOpen] = useState<boolean>(false);\n const [activeIndex, setActiveIndex] = useState<number>(-1);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n const onValueChangeHandler = useCallback(\n (val: MultiSelectValue) => {\n if (disabled) return;\n\n const exists = value.some((currentValue) => currentValue.value === val.value);\n if (exists) {\n onValueChange(value.filter((currentValue) => currentValue.value !== val.value));\n } else {\n onValueChange([...value, val]);\n }\n },\n [disabled, onValueChange, value],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n e.stopPropagation();\n\n if (disabled) return;\n\n const target = inputRef.current;\n\n if (!target) return;\n\n const selectionStart = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n\n if (selectionStart !== selectionEnd) {\n return;\n }\n\n const moveNext = () => {\n const nextIndex = activeIndex + 1;\n setActiveIndex(nextIndex > value.length - 1 ? (loop ? 0 : -1) : nextIndex);\n };\n\n const movePrev = () => {\n const prevIndex = activeIndex - 1;\n setActiveIndex(prevIndex < 0 ? value.length - 1 : prevIndex);\n };\n\n const moveCurrent = () => {\n const newIndex = activeIndex - 1 <= 0 ? (value.length - 1 === 0 ? -1 : 0) : activeIndex - 1;\n setActiveIndex(newIndex);\n };\n\n switch (e.key) {\n case 'ArrowLeft':\n if (dir === 'rtl') {\n if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n } else if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n break;\n\n case 'ArrowRight':\n if (dir === 'rtl') {\n if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n } else if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n break;\n\n case 'Backspace':\n case 'Delete':\n if (value.length > 0) {\n if (activeIndex !== -1 && activeIndex < value.length) {\n onValueChangeHandler(value[activeIndex]);\n moveCurrent();\n } else if (target.selectionStart === 0) {\n onValueChangeHandler(value[value.length - 1]);\n }\n }\n break;\n\n case 'Enter':\n setOpen(true);\n break;\n\n case 'Escape':\n if (activeIndex !== -1) {\n setActiveIndex(-1);\n } else if (open) {\n setInputValue('');\n setOpen(false);\n }\n break;\n }\n },\n [activeIndex, dir, disabled, loop, onValueChangeHandler, open, value],\n );\n\n return (\n <MultiSelectContext.Provider\n value={{\n value,\n onValueChange: onValueChangeHandler,\n open,\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n ref: inputRef,\n disabled,\n }}\n >\n <Command\n onKeyDown={handleKeyDown}\n className={cn('flex flex-col overflow-visible bg-transparent', className)}\n dir={dir}\n {...props}\n >\n {children}\n </Command>\n </MultiSelectContext.Provider>\n );\n};\n\nconst MultiSelectorTrigger = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => {\n const { value, onValueChange, activeIndex, disabled } = useMultiSelect();\n\n const mousePreventDefault = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n return (\n <div\n ref={ref}\n className={cn(\n 'flex flex-wrap gap-1 rounded-lg border bg-background px-2 py-1',\n activeIndex === -1 && 'focus-within:ring-1 focus-within:ring-ring',\n disabled && 'cursor-not-allowed opacity-60',\n className,\n )}\n {...props}\n >\n {value.map((item, index) => (\n <Badge\n key={item.value}\n className={cn(\n 'flex items-center gap-1 rounded-md px-1.5',\n activeIndex === index && 'ring-2 ring-muted-foreground',\n )}\n variant=\"secondary\"\n >\n <span className=\"text-xs\">{item.label}</span>\n <button\n aria-label={`Remove ${item.label} option`}\n type=\"button\"\n disabled={disabled}\n onMouseDown={mousePreventDefault}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n\n onValueChange(item);\n }}\n className=\"inline-flex cursor-pointer items-center justify-center rounded-md p-1 transition-colors hover:bg-red-50 hover:text-red-700 focus-visible:bg-red-100 focus-visible:outline-none disabled:cursor-not-allowed\"\n >\n <span className=\"sr-only\">Remove {item.label} option</span>\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n </Badge>\n ))}\n {children}\n </div>\n );\n },\n);\n\nMultiSelectorTrigger.displayName = 'MultiSelectorTrigger';\n\nconst MultiSelectorInput = forwardRef<\n React.ElementRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, disabled: disabledProp, ...props }, ref) => {\n const { setOpen, inputValue, setInputValue, activeIndex, setActiveIndex, ref: inputRef, disabled } = useMultiSelect();\n\n return (\n <CommandPrimitive.Input\n {...props}\n tabIndex={0}\n ref={inputRef}\n value={inputValue}\n disabled={disabled || disabledProp}\n onValueChange={activeIndex === -1 ? setInputValue : undefined}\n onBlur={() => {\n setInputValue('');\n setOpen(false);\n }}\n onFocus={() => setOpen(true)}\n onClick={() => setActiveIndex(-1)}\n className={cn(\n 'flex-1 border-none bg-transparent p-0 text-sm outline-none placeholder:text-muted-foreground focus:outline-none focus:ring-0',\n className,\n activeIndex !== -1 && 'caret-transparent',\n )}\n />\n );\n});\n\nMultiSelectorInput.displayName = 'MultiSelectorInput';\n\nconst MultiSelectorContent = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ children }, ref) => {\n const { open } = useMultiSelect();\n\n if (!open) return null;\n\n return (\n <div ref={ref} className=\"relative\">\n {children}\n </div>\n );\n});\n\nMultiSelectorContent.displayName = 'MultiSelectorContent';\n\nconst MultiSelectorList = forwardRef<\n React.ElementRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, children }, ref) => {\n return (\n <CommandList\n ref={ref}\n className={cn(\n 'absolute top-0 z-100 flex w-full flex-col gap-2 rounded-md border border-muted bg-background p-2 shadow-md scrollbar-thin scrollbar-track-transparent scrollbar-thumb-rounded-lg scrollbar-thumb-muted-foreground transition-colors dark:scrollbar-thumb-muted',\n className,\n )}\n >\n {children}\n <CommandEmpty>\n <span className=\"text-muted-foreground\">No results found</span>\n </CommandEmpty>\n </CommandList>\n );\n});\n\nMultiSelectorList.displayName = 'MultiSelectorList';\n\nconst MultiSelectorItem = forwardRef<\n React.ElementRef<typeof CommandPrimitive.Item>,\n { value: string; label: string } & React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, value, label, children, disabled: disabledProp, ...props }, ref) => {\n const { value: options, onValueChange, setInputValue, disabled } = useMultiSelect();\n\n const mousePreventDefault = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const isIncluded =\n searchForValue(options, {\n value,\n label,\n }) !== -1;\n\n const isDisabled = disabled || disabledProp;\n\n return (\n <CommandItem\n ref={ref}\n {...props}\n disabled={isDisabled}\n onSelect={() => {\n if (isDisabled) return;\n\n onValueChange({\n value,\n label,\n });\n setInputValue('');\n }}\n className={cn(\n 'flex cursor-pointer justify-between rounded-md px-2 py-1 transition-colors',\n className,\n isIncluded && 'cursor-default opacity-50',\n isDisabled && 'cursor-not-allowed opacity-50',\n )}\n onMouseDown={mousePreventDefault}\n >\n {children}\n {isIncluded && <IconCheck className=\"h-4 w-4\" />}\n </CommandItem>\n );\n});\n\nMultiSelectorItem.displayName = 'MultiSelectorItem';\n\nexport {\n MultiSelector,\n MultiSelectorTrigger,\n MultiSelectorInput,\n MultiSelectorContent,\n MultiSelectorList,\n MultiSelectorItem,\n};\n"],"mappings":"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","names":["_a","_b"]}
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
3
+
4
+ var _chunk2YMMYND2js = require('./chunk-2YMMYND2.js');
5
+
6
+
7
+ var _chunkPSPAJNNBjs = require('./chunk-PSPAJNNB.js');
8
+
9
+ // components/ui/tag-picker.tsx
10
+ var _iconsreact = require('@tabler/icons-react');
11
+ var _react = require('react');
12
+ function normalizeTagName(name) {
13
+ return name.replace(/\s+/g, " ").trim();
14
+ }
15
+ function TagPicker({
16
+ id,
17
+ value,
18
+ onChange,
19
+ suggestions = [],
20
+ placeholder = "Add tags...",
21
+ disabled = false,
22
+ className
23
+ }) {
24
+ const [inputValue, setInputValue] = _react.useState.call(void 0, "");
25
+ const [isFocused, setIsFocused] = _react.useState.call(void 0, false);
26
+ const selectedKeys = _react.useMemo.call(void 0, () => new Set(value.map((item) => item.toLocaleLowerCase())), [value]);
27
+ const normalizedInput = normalizeTagName(inputValue);
28
+ const normalizedInputKey = normalizedInput.toLocaleLowerCase();
29
+ const filteredSuggestions = _react.useMemo.call(void 0, () => {
30
+ return suggestions.filter((suggestion) => !selectedKeys.has(suggestion.toLocaleLowerCase())).filter((suggestion) => {
31
+ if (!normalizedInput) {
32
+ return true;
33
+ }
34
+ return suggestion.toLocaleLowerCase().includes(normalizedInputKey);
35
+ }).slice(0, 8);
36
+ }, [normalizedInput, normalizedInputKey, selectedKeys, suggestions]);
37
+ const canCreate = !!normalizedInput && !selectedKeys.has(normalizedInputKey) && !suggestions.some((suggestion) => suggestion.toLocaleLowerCase() === normalizedInputKey);
38
+ const addTag = (rawName) => {
39
+ const nextName = normalizeTagName(rawName);
40
+ if (!nextName) {
41
+ setInputValue("");
42
+ return;
43
+ }
44
+ const nextKey = nextName.toLocaleLowerCase();
45
+ const matchingSuggestion = suggestions.find((suggestion) => suggestion.toLocaleLowerCase() === nextKey);
46
+ const finalName = matchingSuggestion != null ? matchingSuggestion : nextName;
47
+ if (selectedKeys.has(finalName.toLocaleLowerCase())) {
48
+ setInputValue("");
49
+ return;
50
+ }
51
+ onChange([...value, finalName]);
52
+ setInputValue("");
53
+ };
54
+ const removeTag = (tagName) => {
55
+ onChange(value.filter((item) => item.toLocaleLowerCase() !== tagName.toLocaleLowerCase()));
56
+ };
57
+ const showMenu = !disabled && isFocused && (filteredSuggestions.length > 0 || canCreate);
58
+ return /* @__PURE__ */ React.createElement("div", { className: _chunkPSPAJNNBjs.cn.call(void 0, "space-y-2", className) }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
59
+ "div",
60
+ {
61
+ className: _chunkPSPAJNNBjs.cn.call(void 0,
62
+ "flex min-h-8 flex-wrap items-center gap-1 rounded-lg border bg-background px-2 py-1 text-sm",
63
+ "focus-within:ring-1 focus-within:ring-ring",
64
+ disabled && "cursor-not-allowed opacity-60"
65
+ )
66
+ },
67
+ value.map((tagName) => /* @__PURE__ */ React.createElement(_chunk2YMMYND2js.Badge, { key: tagName, variant: "secondary", className: "flex items-center gap-1 rounded-md px-1.5" }, /* @__PURE__ */ React.createElement("span", { className: "text-xs" }, tagName), !disabled && /* @__PURE__ */ React.createElement(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ className: "inline-flex cursor-pointer items-center justify-center rounded-md p-1 transition-colors hover:bg-red-50 hover:text-red-700 focus-visible:bg-red-100 focus-visible:outline-none",
72
+ onMouseDown: (event) => event.preventDefault(),
73
+ onClick: () => removeTag(tagName),
74
+ "aria-label": `Remove ${tagName}`
75
+ },
76
+ /* @__PURE__ */ React.createElement(_iconsreact.IconX, { className: "h-3.5 w-3.5" })
77
+ ))),
78
+ /* @__PURE__ */ React.createElement(
79
+ "input",
80
+ {
81
+ id,
82
+ value: inputValue,
83
+ disabled,
84
+ placeholder: value.length === 0 ? placeholder : "",
85
+ className: "min-w-24 flex-1 border-0 bg-transparent p-0 pl-1 text-sm outline-none placeholder:text-muted-foreground",
86
+ onFocus: () => setIsFocused(true),
87
+ onBlur: () => {
88
+ window.setTimeout(() => setIsFocused(false), 100);
89
+ },
90
+ onChange: (event) => setInputValue(event.target.value),
91
+ onKeyDown: (event) => {
92
+ if ((event.key === "Enter" || event.key === ",") && normalizedInput) {
93
+ event.preventDefault();
94
+ addTag(normalizedInput);
95
+ }
96
+ if (event.key === "Backspace" && !inputValue && value.length > 0) {
97
+ event.preventDefault();
98
+ removeTag(value[value.length - 1]);
99
+ }
100
+ }
101
+ }
102
+ )
103
+ ), showMenu && /* @__PURE__ */ React.createElement("div", { className: "absolute z-50 mt-1 w-full rounded-md border bg-background p-1 shadow-md" }, filteredSuggestions.map((suggestion) => /* @__PURE__ */ React.createElement(
104
+ "button",
105
+ {
106
+ key: suggestion,
107
+ type: "button",
108
+ className: "flex w-full items-center justify-between rounded-sm px-2 py-1.5 text-left text-sm hover:bg-muted",
109
+ onMouseDown: (event) => event.preventDefault(),
110
+ onClick: () => addTag(suggestion)
111
+ },
112
+ /* @__PURE__ */ React.createElement("span", null, suggestion),
113
+ /* @__PURE__ */ React.createElement("span", { className: "text-xs text-muted-foreground" }, "Existing")
114
+ )), canCreate && /* @__PURE__ */ React.createElement(
115
+ "button",
116
+ {
117
+ type: "button",
118
+ className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-muted",
119
+ onMouseDown: (event) => event.preventDefault(),
120
+ onClick: () => addTag(normalizedInput)
121
+ },
122
+ /* @__PURE__ */ React.createElement(_iconsreact.IconPlus, { className: "h-3.5 w-3.5" }),
123
+ /* @__PURE__ */ React.createElement("span", null, 'Create "', normalizedInput, '"')
124
+ ))));
125
+ }
126
+
127
+
128
+
129
+ exports.TagPicker = TagPicker;
130
+ //# sourceMappingURL=chunk-FSU3BKPK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-FSU3BKPK.js","../components/ui/tag-picker.tsx"],"names":[],"mappings":"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","file":"/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-FSU3BKPK.js","sourcesContent":[null,"\"use client\";\nimport { IconPlus, IconX } from '@tabler/icons-react';\nimport { useMemo, useState } from 'react';\n\nimport { cn } from '../../utils/ui';\nimport { Badge } from './badge';\n\nfunction normalizeTagName(name: string) {\n return name.replace(/\\s+/g, ' ').trim();\n}\n\nexport interface TagPickerProps {\n id?: string;\n value: string[];\n onChange: (values: string[]) => void;\n suggestions?: string[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport function TagPicker({\n id,\n value,\n onChange,\n suggestions = [],\n placeholder = 'Add tags...',\n disabled = false,\n className,\n}: TagPickerProps) {\n const [inputValue, setInputValue] = useState('');\n const [isFocused, setIsFocused] = useState(false);\n\n const selectedKeys = useMemo(() => new Set(value.map((item) => item.toLocaleLowerCase())), [value]);\n const normalizedInput = normalizeTagName(inputValue);\n const normalizedInputKey = normalizedInput.toLocaleLowerCase();\n\n const filteredSuggestions = useMemo(() => {\n return suggestions\n .filter((suggestion) => !selectedKeys.has(suggestion.toLocaleLowerCase()))\n .filter((suggestion) => {\n if (!normalizedInput) {\n return true;\n }\n return suggestion.toLocaleLowerCase().includes(normalizedInputKey);\n })\n .slice(0, 8);\n }, [normalizedInput, normalizedInputKey, selectedKeys, suggestions]);\n\n const canCreate =\n !!normalizedInput &&\n !selectedKeys.has(normalizedInputKey) &&\n !suggestions.some((suggestion) => suggestion.toLocaleLowerCase() === normalizedInputKey);\n\n const addTag = (rawName: string) => {\n const nextName = normalizeTagName(rawName);\n if (!nextName) {\n setInputValue('');\n return;\n }\n\n const nextKey = nextName.toLocaleLowerCase();\n const matchingSuggestion = suggestions.find((suggestion) => suggestion.toLocaleLowerCase() === nextKey);\n const finalName = matchingSuggestion ?? nextName;\n\n if (selectedKeys.has(finalName.toLocaleLowerCase())) {\n setInputValue('');\n return;\n }\n\n onChange([...value, finalName]);\n setInputValue('');\n };\n\n const removeTag = (tagName: string) => {\n onChange(value.filter((item) => item.toLocaleLowerCase() !== tagName.toLocaleLowerCase()));\n };\n\n const showMenu = !disabled && isFocused && (filteredSuggestions.length > 0 || canCreate);\n\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"relative\">\n <div\n className={cn(\n 'flex min-h-8 flex-wrap items-center gap-1 rounded-lg border bg-background px-2 py-1 text-sm',\n 'focus-within:ring-1 focus-within:ring-ring',\n disabled && 'cursor-not-allowed opacity-60',\n )}\n >\n {value.map((tagName) => (\n <Badge key={tagName} variant=\"secondary\" className=\"flex items-center gap-1 rounded-md px-1.5\">\n <span className=\"text-xs\">{tagName}</span>\n {!disabled && (\n <button\n type=\"button\"\n className=\"inline-flex cursor-pointer items-center justify-center rounded-md p-1 transition-colors hover:bg-red-50 hover:text-red-700 focus-visible:bg-red-100 focus-visible:outline-none\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => removeTag(tagName)}\n aria-label={`Remove ${tagName}`}\n >\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </Badge>\n ))}\n\n <input\n id={id}\n value={inputValue}\n disabled={disabled}\n placeholder={value.length === 0 ? placeholder : ''}\n className=\"min-w-24 flex-1 border-0 bg-transparent p-0 pl-1 text-sm outline-none placeholder:text-muted-foreground\"\n onFocus={() => setIsFocused(true)}\n onBlur={() => {\n window.setTimeout(() => setIsFocused(false), 100);\n }}\n onChange={(event) => setInputValue(event.target.value)}\n onKeyDown={(event) => {\n if ((event.key === 'Enter' || event.key === ',') && normalizedInput) {\n event.preventDefault();\n addTag(normalizedInput);\n }\n\n if (event.key === 'Backspace' && !inputValue && value.length > 0) {\n event.preventDefault();\n removeTag(value[value.length - 1]);\n }\n }}\n />\n </div>\n\n {showMenu && (\n <div className=\"absolute z-50 mt-1 w-full rounded-md border bg-background p-1 shadow-md\">\n {filteredSuggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-sm px-2 py-1.5 text-left text-sm hover:bg-muted\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => addTag(suggestion)}\n >\n <span>{suggestion}</span>\n <span className=\"text-xs text-muted-foreground\">Existing</span>\n </button>\n ))}\n\n {canCreate && (\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-muted\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => addTag(normalizedInput)}\n >\n <IconPlus className=\"h-3.5 w-3.5\" />\n <span>Create &quot;{normalizedInput}&quot;</span>\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
 
9
- var _chunkAJLAS62Xjs = require('./chunk-AJLAS62X.js');
9
+ var _chunkLAIO3QZXjs = require('./chunk-LAIO3QZX.js');
10
10
 
11
11
 
12
12
 
@@ -79,10 +79,10 @@ function FormSearchableSelect({
79
79
  },
80
80
  selectedValue ? (_b = _options.find((opt) => opt.value === selectedValue)) == null ? void 0 : _b.label : placeholder || "Select...",
81
81
  /* @__PURE__ */ _react2.default.createElement(_lucidereact.ChevronsUpDown, { className: "opacity-50" })
82
- )), /* @__PURE__ */ _react2.default.createElement(_chunkQHCOMBHIjs.PopoverContent, { className: "w-full p-0" }, /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.Command, null, /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.CommandInput, { placeholder: `Search ${label != null ? label : "option"}...`, className: "h-9" }), /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.CommandList, null, /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.CommandEmpty, null, "No option found."), /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.CommandGroup, null, _options.map((option) => /* @__PURE__ */ _react2.default.createElement(_chunkAJLAS62Xjs.CommandItem, { key: option.value, value: option.value, onSelect: handleSelect }, option.label, /* @__PURE__ */ _react2.default.createElement(_lucidereact.Check, { className: _chunkPSPAJNNBjs.cn.call(void 0, "ml-auto", selectedValue === option.value ? "opacity-100" : "opacity-0") })))))))));
82
+ )), /* @__PURE__ */ _react2.default.createElement(_chunkQHCOMBHIjs.PopoverContent, { className: "w-full p-0" }, /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.Command, null, /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.CommandInput, { placeholder: `Search ${label != null ? label : "option"}...`, className: "h-9" }), /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.CommandList, null, /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.CommandEmpty, null, "No option found."), /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.CommandGroup, null, _options.map((option) => /* @__PURE__ */ _react2.default.createElement(_chunkLAIO3QZXjs.CommandItem, { key: option.value, value: option.value, onSelect: handleSelect }, option.label, /* @__PURE__ */ _react2.default.createElement(_lucidereact.Check, { className: _chunkPSPAJNNBjs.cn.call(void 0, "ml-auto", selectedValue === option.value ? "opacity-100" : "opacity-0") })))))))));
83
83
  }
84
84
 
85
85
 
86
86
 
87
87
  exports.FormSearchableSelect = FormSearchableSelect;
88
- //# sourceMappingURL=chunk-3ZN766EW.js.map
88
+ //# sourceMappingURL=chunk-G6WKPZTL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-3ZN766EW.js","../components/form/searchable-select.tsx"],"names":["_a"],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACtBA,4EAAkB;AAClB,wGAAuB;AACvB,oGAAsB;AAMtB,2CAAsC;AAOtC,SAAS,mBAAA,CAAoB,KAAA,EAAiB;AAC5C,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAA,GAAS;AACzB,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AAAA,EACpC,CAAC,CAAA;AACH;AAoBO,SAAS,oBAAA,CAAqB;AAAA,EACnC,EAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA,EAAc,EAAA;AAAA,EACd,IAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA8B;AApD9B,EAAA,IAAA,EAAA,EAAA,EAAA;AAqDE,EAAA,IAAI,SAAA,EAA2B,CAAC,CAAA;AAEhC,EAAA,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AACnB,IAAA,GAAA,CAAI,gCAAA,IAAU,CAAK,CAAC,CAAC,CAAA,EAAG;AACtB,MAAA,SAAA,EAAW,mBAAA,CAAoB,IAAgB,CAAA;AAAA,IACjD,EAAA,KAAO;AACL,MAAA,SAAA,EAAW,IAAA;AAAA,IACb;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,CAAC,EAAA,EAAI,GAAA,EAAK,iCAAA,IAAe,CAAA;AAE7B,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,EAAA,EAAI,eAAA,CAAM,QAAA,CAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,EAAA,EAAI,eAAA,CAAM,QAAA,CAAA,CAAS,GAAA,EAAA,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,YAAA,EAAA,GAAT,KAAA,EAAA,GAAA,EAAyB,EAAE,CAAA;AAEpF,EAAA,eAAA,CAAM,SAAA,CAAU,CAAA,EAAA,GAAM;AApExB,IAAA,IAAAA,GAAAA;AAqEI,IAAA,gBAAA,CAAA,CAAiBA,IAAAA,EAAA,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,YAAA,EAAA,GAAT,KAAA,EAAAA,IAAAA,EAAyB,EAAE,CAAA;AAAA,EAC9C,CAAA,EAAG,CAAC,KAAA,EAAO,YAAY,CAAC,CAAA;AAExB,EAAA,MAAM,aAAA,EAAe,CAAC,YAAA,EAAA,GAAyB;AAC7C,IAAA,MAAM,SAAA,EAAW,aAAA,IAAiB,cAAA,EAAgB,GAAA,EAAK,YAAA;AACvD,IAAA,gBAAA,CAAiB,QAAQ,CAAA;AACzB,IAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,IAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,uBACE,eAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,iCAAA,mCAAG,EAAqC,WAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,UAAA,CAAY,OAAO,EAAA,CAAA,EACxE,MAAA,mBACC,eAAA,CAAA,aAAA,CAAC,sBAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EAAI,SAAA,EAAW,WAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,UAAA,CAAY,KAAA,EAAO,SAAA,CAAA,EAC/C,KACH,CAAA,kBAGF,eAAA,CAAA,aAAA,CAAC,wBAAA,EAAA,EAAQ,IAAA,EAAY,YAAA,EAAc,QAAA,CAAA,kBACjC,eAAA,CAAA,aAAA,CAAC,+BAAA,EAAA,EAAe,OAAA,EAAO,KAAA,CAAA,kBACrB,eAAA,CAAA,aAAA;AAAA,IAAC,uBAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,WAAA;AAAA,MACR,UAAA,EAAW,SAAA;AAAA,MACX,IAAA,EAAK,UAAA;AAAA,MACL,eAAA,EAAe,IAAA;AAAA,MACf,QAAA;AAAA,MACA,SAAA,EAAW,iCAAA,sCAAG,EAAwC,WAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,UAAA,CAAY,KAAK;AAAA,IAAA,CAAA;AAAA,IAEtE,cAAA,EAAA,CAAgB,GAAA,EAAA,QAAA,CAAS,IAAA,CAAK,CAAC,GAAA,EAAA,GAAQ,GAAA,CAAI,MAAA,IAAU,aAAa,CAAA,EAAA,GAAlD,KAAA,EAAA,KAAA,EAAA,EAAA,EAAA,CAAqD,MAAA,EAAQ,YAAA,GAAe,WAAA;AAAA,oBAC7F,eAAA,CAAA,aAAA,CAAC,2BAAA,EAAA,EAAe,SAAA,EAAU,aAAA,CAAa;AAAA,EACzC,CACF,CAAA,kBAEA,eAAA,CAAA,aAAA,CAAC,+BAAA,EAAA,EAAe,SAAA,EAAU,aAAA,CAAA,kBACxB,eAAA,CAAA,aAAA,CAAC,wBAAA,EAAA,IAAA,kBACC,eAAA,CAAA,aAAA,CAAC,6BAAA,EAAA,EAAa,WAAA,EAAa,CAAA,OAAA,EAAU,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,QAAQ,CAAA,GAAA,CAAA,EAAO,SAAA,EAAU,MAAA,CAAM,CAAA,kBAC7E,eAAA,CAAA,aAAA,CAAC,4BAAA,EAAA,IAAA,kBACC,eAAA,CAAA,aAAA,CAAC,6BAAA,EAAA,IAAA,EAAa,kBAAgB,CAAA,kBAC9B,eAAA,CAAA,aAAA,CAAC,6BAAA,EAAA,IAAA,EACE,QAAA,CAAS,GAAA,CAAI,CAAC,MAAA,EAAA,mBACb,eAAA,CAAA,aAAA,CAAC,4BAAA,EAAA,EAAY,GAAA,EAAK,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,QAAA,EAAU,aAAA,CAAA,EAC5D,MAAA,CAAO,KAAA,kBACR,eAAA,CAAA,aAAA,CAAC,kBAAA,EAAA,EAAM,SAAA,EAAW,iCAAA,SAAG,EAAW,cAAA,IAAkB,MAAA,CAAO,MAAA,EAAQ,cAAA,EAAgB,WAAW,EAAA,CAAG,CACjG,CACD,CACH,CACF,CACF,CACF,CACF,CACF,CAAA;AAEJ;ADvCA;AACA;AACE;AACF,oDAAC","file":"/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-3ZN766EW.js","sourcesContent":[null,"\"use client\";\nimport React from 'react';\nimport _kebabCase from 'lodash-es/kebabCase';\nimport _isString from 'lodash-es/isString';\nimport { cn } from '../../utils/ui';\nimport { Label } from '../ui/label';\nimport { Button } from '../ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../ui/command';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Check, ChevronsUpDown } from 'lucide-react';\n\nexport interface SelectOption {\n label: string;\n value: string;\n}\n\nfunction listToSelectOptions(items: string[]) {\n return items.map((item) => {\n return { label: item, value: item };\n });\n}\n\nexport interface FormSearchableSelectProps {\n id?: string;\n name: string;\n label?: string;\n placeholder?: string;\n data: SelectOption[] | string[];\n defaultValue?: string;\n value?: string;\n onChange: (value?: string) => void;\n classNames?: {\n wrapper?: string;\n label?: string;\n input?: string;\n };\n required?: boolean;\n disabled?: boolean;\n}\n\nexport function FormSearchableSelect({\n id,\n name,\n label,\n placeholder = '',\n data,\n defaultValue,\n value,\n onChange,\n classNames,\n required,\n disabled,\n}: FormSearchableSelectProps) {\n let _options: SelectOption[] = [];\n\n if (data.length > 0) {\n if (_isString(data[0])) {\n _options = listToSelectOptions(data as string[]);\n } else {\n _options = data as SelectOption[];\n }\n }\n\n if (!id) id = _kebabCase(name);\n\n const [open, setOpen] = React.useState(false);\n const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? '');\n\n React.useEffect(() => {\n setSelectedValue(value ?? defaultValue ?? '');\n }, [value, defaultValue]);\n\n const handleSelect = (currentValue: string) => {\n const newValue = currentValue === selectedValue ? '' : currentValue;\n setSelectedValue(newValue);\n onChange(newValue);\n setOpen(false);\n };\n\n return (\n <div className={cn('$form-searchable-select space-y-1', classNames?.wrapper)}>\n {label && (\n <Label htmlFor={id} className={classNames?.label} required={required}>\n {label}\n </Label>\n )}\n\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"secondary\"\n appearance=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className={cn('w-full justify-between border-input!', classNames?.input)}\n >\n {selectedValue ? _options.find((opt) => opt.value === selectedValue)?.label : placeholder || 'Select...'}\n <ChevronsUpDown className=\"opacity-50\" />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent className=\"w-full p-0\">\n <Command>\n <CommandInput placeholder={`Search ${label ?? 'option'}...`} className=\"h-9\" />\n <CommandList>\n <CommandEmpty>No option found.</CommandEmpty>\n <CommandGroup>\n {_options.map((option) => (\n <CommandItem key={option.value} value={option.value} onSelect={handleSelect}>\n {option.label}\n <Check className={cn('ml-auto', selectedValue === option.value ? 'opacity-100' : 'opacity-0')} />\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-G6WKPZTL.js","../components/form/searchable-select.tsx"],"names":["_a"],"mappings":"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","file":"/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-G6WKPZTL.js","sourcesContent":[null,"\"use client\";\nimport React from 'react';\nimport _kebabCase from 'lodash-es/kebabCase';\nimport _isString from 'lodash-es/isString';\nimport { cn } from '../../utils/ui';\nimport { Label } from '../ui/label';\nimport { Button } from '../ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../ui/command';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Check, ChevronsUpDown } from 'lucide-react';\n\nexport interface SelectOption {\n label: string;\n value: string;\n}\n\nfunction listToSelectOptions(items: string[]) {\n return items.map((item) => {\n return { label: item, value: item };\n });\n}\n\nexport interface FormSearchableSelectProps {\n id?: string;\n name: string;\n label?: string;\n placeholder?: string;\n data: SelectOption[] | string[];\n defaultValue?: string;\n value?: string;\n onChange: (value?: string) => void;\n classNames?: {\n wrapper?: string;\n label?: string;\n input?: string;\n };\n required?: boolean;\n disabled?: boolean;\n}\n\nexport function FormSearchableSelect({\n id,\n name,\n label,\n placeholder = '',\n data,\n defaultValue,\n value,\n onChange,\n classNames,\n required,\n disabled,\n}: FormSearchableSelectProps) {\n let _options: SelectOption[] = [];\n\n if (data.length > 0) {\n if (_isString(data[0])) {\n _options = listToSelectOptions(data as string[]);\n } else {\n _options = data as SelectOption[];\n }\n }\n\n if (!id) id = _kebabCase(name);\n\n const [open, setOpen] = React.useState(false);\n const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? '');\n\n React.useEffect(() => {\n setSelectedValue(value ?? defaultValue ?? '');\n }, [value, defaultValue]);\n\n const handleSelect = (currentValue: string) => {\n const newValue = currentValue === selectedValue ? '' : currentValue;\n setSelectedValue(newValue);\n onChange(newValue);\n setOpen(false);\n };\n\n return (\n <div className={cn('$form-searchable-select space-y-1', classNames?.wrapper)}>\n {label && (\n <Label htmlFor={id} className={classNames?.label} required={required}>\n {label}\n </Label>\n )}\n\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"secondary\"\n appearance=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className={cn('w-full justify-between border-input!', classNames?.input)}\n >\n {selectedValue ? _options.find((opt) => opt.value === selectedValue)?.label : placeholder || 'Select...'}\n <ChevronsUpDown className=\"opacity-50\" />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent className=\"w-full p-0\">\n <Command>\n <CommandInput placeholder={`Search ${label ?? 'option'}...`} className=\"h-9\" />\n <CommandList>\n <CommandEmpty>No option found.</CommandEmpty>\n <CommandGroup>\n {_options.map((option) => (\n <CommandItem key={option.value} value={option.value} onSelect={handleSelect}>\n {option.label}\n <Check className={cn('ml-auto', selectedValue === option.value ? 'opacity-100' : 'opacity-0')} />\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n"]}