@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.
- package/chunk-2NUE7GJ3.js +44 -0
- package/chunk-2NUE7GJ3.js.map +1 -0
- package/chunk-3PZY5HRH.mjs +82 -0
- package/chunk-3PZY5HRH.mjs.map +1 -0
- package/{components/ui/extension/multi-select.js → chunk-3TG6ZVFG.js} +63 -62
- package/chunk-3TG6ZVFG.js.map +1 -0
- package/{components/ui/extension/multi-select.mjs → chunk-7JYFZETL.mjs} +64 -63
- package/chunk-7JYFZETL.mjs.map +1 -0
- package/chunk-FSU3BKPK.js +130 -0
- package/chunk-FSU3BKPK.js.map +1 -0
- package/{chunk-3ZN766EW.js → chunk-G6WKPZTL.js} +3 -3
- package/{chunk-3ZN766EW.js.map → chunk-G6WKPZTL.js.map} +1 -1
- package/chunk-IQIHYWXX.js +83 -0
- package/chunk-IQIHYWXX.js.map +1 -0
- package/{chunk-AJLAS62X.js → chunk-LAIO3QZX.js} +4 -4
- package/{chunk-AJLAS62X.js.map → chunk-LAIO3QZX.js.map} +1 -1
- package/{chunk-MJT6B7OJ.js → chunk-LPDYWZN6.js} +3 -3
- package/{chunk-MJT6B7OJ.js.map → chunk-LPDYWZN6.js.map} +1 -1
- package/{chunk-432PQWGO.mjs → chunk-RJVQU443.mjs} +2 -2
- package/chunk-USW6AILM.mjs +43 -0
- package/chunk-USW6AILM.mjs.map +1 -0
- package/{chunk-HKZRXGJ7.mjs → chunk-YDRPNCWF.mjs} +4 -4
- package/{chunk-ZMMYQNQV.mjs → chunk-ZFBUIBJH.mjs} +2 -2
- package/chunk-ZQK6REIM.mjs +129 -0
- package/chunk-ZQK6REIM.mjs.map +1 -0
- package/components/form/hook-multi-select.d.mts +14 -0
- package/components/form/hook-multi-select.d.ts +14 -0
- package/components/form/hook-multi-select.js +76 -0
- package/components/form/hook-multi-select.js.map +1 -0
- package/components/form/hook-multi-select.mjs +75 -0
- package/components/form/hook-multi-select.mjs.map +1 -0
- package/components/form/hook-searchable-select.js +5 -5
- package/components/form/hook-searchable-select.mjs +4 -4
- package/components/form/hook-tag-picker.d.mts +12 -0
- package/components/form/hook-tag-picker.d.ts +12 -0
- package/components/form/hook-tag-picker.js +66 -0
- package/components/form/hook-tag-picker.js.map +1 -0
- package/components/form/hook-tag-picker.mjs +65 -0
- package/components/form/hook-tag-picker.mjs.map +1 -0
- package/components/form/multi-select.d.mts +25 -1
- package/components/form/multi-select.d.ts +25 -1
- package/components/form/multi-select.js +20 -1
- package/components/form/multi-select.js.map +1 -1
- package/components/form/multi-select.mjs +19 -0
- package/components/form/searchable-select.js +5 -5
- package/components/form/searchable-select.mjs +4 -4
- package/components/form/tag-picker.d.mts +21 -0
- package/components/form/tag-picker.d.ts +21 -0
- package/components/form/tag-picker.js +14 -0
- package/components/form/tag-picker.js.map +1 -0
- package/components/form/tag-picker.mjs +13 -0
- package/components/form/tag-picker.mjs.map +1 -0
- package/components/ui/combobox.js +5 -5
- package/components/ui/combobox.mjs +2 -2
- package/components/ui/command.js +4 -4
- package/components/ui/command.mjs +3 -3
- package/components/ui/input-group.js +3 -3
- package/components/ui/input-group.mjs +2 -2
- package/components/ui/{extension/multi-select.d.mts → multi-select.d.mts} +4 -3
- package/components/ui/{extension/multi-select.d.ts → multi-select.d.ts} +4 -3
- package/components/ui/multi-select.js +29 -0
- package/components/ui/multi-select.js.map +1 -0
- package/components/ui/multi-select.mjs +28 -0
- package/components/ui/multi-select.mjs.map +1 -0
- package/components/ui/tag-picker.d.mts +14 -0
- package/components/ui/tag-picker.d.ts +14 -0
- package/components/ui/tag-picker.js +12 -0
- package/components/ui/tag-picker.js.map +1 -0
- package/components/ui/tag-picker.mjs +11 -0
- package/components/ui/tag-picker.mjs.map +1 -0
- package/components/widgets/dialog-manager/index.js +1 -1
- package/components/widgets/dialog-manager/index.js.map +1 -1
- package/components/widgets/dialog-manager/index.mjs +1 -1
- package/layouts/sidebar1/app-sidebar.js +2 -2
- package/layouts/sidebar1/app-sidebar.mjs +2 -2
- package/layouts/sidebar1/context-switcher.js +1 -1
- package/layouts/sidebar1/context-switcher.mjs +1 -1
- package/layouts/sidebar1/index.js +3 -3
- package/layouts/sidebar1/index.js.map +1 -1
- package/layouts/sidebar1/index.mjs +3 -3
- package/layouts/sidebar1/nav-menus.js +1 -1
- package/layouts/sidebar1/nav-menus.mjs +1 -1
- package/layouts/sidebar1/nav-user.js +2 -2
- package/layouts/sidebar1/nav-user.mjs +2 -2
- package/layouts/simple/index.js +2 -2
- package/layouts/simple/index.mjs +3 -3
- package/package.json +1 -1
- package/components/ui/extension/multi-select.js.map +0 -1
- package/components/ui/extension/multi-select.mjs.map +0 -1
- /package/{chunk-432PQWGO.mjs.map → chunk-RJVQU443.mjs.map} +0 -0
- /package/{chunk-HKZRXGJ7.mjs.map → chunk-YDRPNCWF.mjs.map} +0 -0
- /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 "
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
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 "
|
|
12
|
+
} from "./chunk-KGUUDFJE.mjs";
|
|
20
13
|
import {
|
|
21
14
|
__objRest,
|
|
22
15
|
__spreadProps,
|
|
23
16
|
__spreadValues
|
|
24
|
-
} from "
|
|
17
|
+
} from "./chunk-YOSPWY5K.mjs";
|
|
25
18
|
|
|
26
|
-
// components/ui/
|
|
27
|
-
import {
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
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("
|
|
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
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
"
|
|
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: () =>
|
|
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-
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
-
"
|
|
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:
|
|
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(
|
|
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
|
-
"
|
|
296
|
+
"flex cursor-pointer justify-between rounded-md px-2 py-1 transition-colors",
|
|
297
297
|
className,
|
|
298
|
-
isIncluded && "opacity-50
|
|
299
|
-
|
|
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
|
-
|
|
311
|
+
MultiSelectorTrigger,
|
|
311
312
|
MultiSelectorInput,
|
|
312
|
-
|
|
313
|
+
MultiSelectorContent,
|
|
313
314
|
MultiSelectorList,
|
|
314
|
-
|
|
315
|
+
MultiSelectorItem
|
|
315
316
|
};
|
|
316
|
-
//# sourceMappingURL=
|
|
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 "{normalizedInput}"</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
|
|
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(
|
|
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-
|
|
88
|
+
//# sourceMappingURL=chunk-G6WKPZTL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/jahn/projects/shadcn-theme/packages/react/dist/chunk-
|
|
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"]}
|