@enos5/enos-vue-default 1.5.4 → 1.5.6

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/dist/index.js CHANGED
@@ -1,4878 +1,61 @@
1
- import { ref, computed, watch, openBlock, createElementBlock, createElementVNode, Fragment, renderList, normalizeClass, normalizeStyle, toDisplayString, createBlock, createCommentVNode, renderSlot, createVNode, Transition, withCtx, mergeProps, useSlots, unref, withDirectives, vShow, useAttrs, vModelCheckbox, onMounted, nextTick, onBeforeUnmount, Teleport, withModifiers, onUnmounted, inject, provide, defineComponent, isVNode, cloneVNode, resolveDynamicComponent, createTextVNode, h, vModelText, createSlots } from "vue";
2
- import { LockClosedIcon, ChevronDownIcon, PhotoIcon, ExclamationCircleIcon, ExclamationTriangleIcon, ChevronUpIcon, MagnifyingGlassIcon, CheckIcon, PencilSquareIcon } from "@heroicons/vue/24/outline";
3
- import Editor from "@tinymce/tinymce-vue";
4
- import { Link } from "@inertiajs/vue3";
5
- const components = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6
- __proto__: null,
7
- get ActionCard() {
8
- return _sfc_main$O;
9
- },
10
- get ActionMessage() {
11
- return _sfc_main$N;
12
- },
13
- get ActionSection() {
14
- return _sfc_main$L;
15
- },
16
- get Badge() {
17
- return _sfc_main$K;
18
- },
19
- get Button() {
20
- return _sfc_main$J;
21
- },
22
- get Card() {
23
- return _sfc_main$Q;
24
- },
25
- get CardTabs() {
26
- return _sfc_main$R;
27
- },
28
- get Checkbox() {
29
- return _sfc_main$I;
30
- },
31
- get CheckboxInput() {
32
- return _sfc_main$H;
33
- },
34
- get CheckboxMultipleInput() {
35
- return _sfc_main$u;
36
- },
37
- get ConfirmationModal() {
38
- return _sfc_main$s;
39
- },
40
- get CustomSelect() {
41
- return _sfc_main$E;
42
- },
43
- get DateInput() {
44
- return DateInput;
45
- },
46
- get DialogModal() {
47
- return _sfc_main$r;
48
- },
49
- get Divider() {
50
- return _sfc_main$P;
51
- },
52
- get Dropdown() {
53
- return _sfc_main$q;
54
- },
55
- get DropdownLink() {
56
- return _sfc_main$p;
57
- },
58
- get EnosVueDefault() {
59
- return plugin;
60
- },
61
- get FormSection() {
62
- return _sfc_main$o;
63
- },
64
- get ImageInput() {
65
- return _sfc_main$B;
66
- },
67
- get InputError() {
68
- return _sfc_main$n;
69
- },
70
- get InputGroup() {
71
- return _sfc_main$v;
72
- },
73
- get InputLabel() {
74
- return _sfc_main$m;
75
- },
76
- get LinkButton() {
77
- return _sfc_main$l;
78
- },
79
- get Modal() {
80
- return _sfc_main$t;
81
- },
82
- get NotationInput() {
83
- return _sfc_main$A;
84
- },
85
- get RadioInput() {
86
- return _sfc_main$z;
87
- },
88
- get RadioMultipleInput() {
89
- return _sfc_main$x;
90
- },
91
- get SectionBorder() {
92
- return _sfc_main$k;
93
- },
94
- get SectionTitle() {
95
- return SectionTitle;
96
- },
97
- get SelectInput() {
98
- return _sfc_main$D;
99
- },
100
- get Sidebar() {
101
- return _sfc_main$j;
102
- },
103
- get SidebarContent() {
104
- return _sfc_main$i;
105
- },
106
- get SidebarFooter() {
107
- return _sfc_main$h;
108
- },
109
- get SidebarGroup() {
110
- return _sfc_main$g;
111
- },
112
- get SidebarGroupContent() {
113
- return _sfc_main$f;
114
- },
115
- get SidebarGroupLabel() {
116
- return _sfc_main$e;
117
- },
118
- get SidebarHeader() {
119
- return _sfc_main$d;
120
- },
121
- get SidebarInset() {
122
- return _sfc_main$c;
123
- },
124
- get SidebarMenu() {
125
- return _sfc_main$b;
126
- },
127
- get SidebarMenuButton() {
128
- return _sfc_main$a;
129
- },
130
- get SidebarMenuItem() {
131
- return _sfc_main$9;
132
- },
133
- get SidebarProvider() {
134
- return _sfc_main$8;
135
- },
136
- get SidebarTrigger() {
137
- return _sfc_main$7;
138
- },
139
- get SortControls() {
140
- return _sfc_main$6;
141
- },
142
- get TableList() {
143
- return _sfc_main$3;
144
- },
145
- get TableListForm() {
146
- return _sfc_main$2;
147
- },
148
- get TableSearch() {
149
- return _sfc_main$4;
150
- },
151
- get TextArea() {
152
- return _sfc_main$F;
153
- },
154
- get TextInput() {
155
- return _sfc_main$G;
156
- },
157
- get ThSortable() {
158
- return _sfc_main$5;
159
- },
160
- get TinyEditor() {
161
- return _sfc_main$w;
162
- },
163
- get Toast() {
164
- return _sfc_main$1;
165
- },
166
- get ToastContainer() {
167
- return _sfc_main;
168
- },
169
- get ToggleInput() {
170
- return _sfc_main$y;
171
- },
172
- get useSidebar() {
173
- return useSidebar;
174
- }
175
- }, Symbol.toStringTag, { value: "Module" }));
176
- const _hoisted_1$C = { class: "border-b border-neutral-200 bg-neutral-50/80 p-2 dark:border-neutral-800 dark:bg-neutral-900/80" };
177
- const _hoisted_2$l = {
178
- role: "tablist",
179
- class: "flex overflow-hidden rounded-lg bg-white shadow-sm ring-1 ring-neutral-200 dark:bg-neutral-950 dark:ring-neutral-800"
180
- };
181
- const _hoisted_3$e = ["aria-selected", "tabindex", "onClick", "onKeydown"];
182
- const _sfc_main$R = {
183
- __name: "CardTabs",
184
- props: {
185
- tabs: {
186
- type: Array,
187
- default: () => [],
188
- validator: (tabs) => tabs.every((tab) => typeof tab === "object" && tab !== null && typeof tab.value === "string" && tab.value.length > 0 && typeof tab.label === "string")
189
- },
190
- activeTab: {
191
- type: String,
192
- default: ""
193
- }
194
- },
195
- emits: [
196
- "update:activeTab",
197
- "tab-click"
198
- ],
199
- setup(__props, { emit: __emit }) {
200
- const props = __props;
201
- const emit = __emit;
202
- const tabButtons = ref([]);
203
- const availableTabValues = computed(() => props.tabs.map((tab) => tab.value));
204
- const currentActiveTab = computed(() => availableTabValues.value.includes(props.activeTab) ? props.activeTab : availableTabValues.value[0] ?? "");
205
- watch(currentActiveTab, (value) => {
206
- if (value !== props.activeTab) {
207
- emit("update:activeTab", value);
208
- }
209
- }, { immediate: true });
210
- const setTabButtonRef = (element, index) => {
211
- tabButtons.value[index] = element;
212
- };
213
- const activateTab = (value) => {
214
- if (!value || value === props.activeTab) {
215
- return;
216
- }
217
- emit("update:activeTab", value);
218
- emit("tab-click", value);
219
- };
220
- const focusTabAtIndex = (index) => {
221
- tabButtons.value[index]?.focus();
222
- };
223
- const onTabKeydown = (event, index) => {
224
- if (props.tabs.length === 0) {
225
- return;
226
- }
227
- let targetIndex = index;
228
- switch (event.key) {
229
- case "ArrowRight":
230
- case "ArrowDown":
231
- targetIndex = (index + 1) % props.tabs.length;
232
- break;
233
- case "ArrowLeft":
234
- case "ArrowUp":
235
- targetIndex = (index - 1 + props.tabs.length) % props.tabs.length;
236
- break;
237
- case "Home":
238
- targetIndex = 0;
239
- break;
240
- case "End":
241
- targetIndex = props.tabs.length - 1;
242
- break;
243
- default:
244
- return;
245
- }
246
- event.preventDefault();
247
- activateTab(props.tabs[targetIndex].value);
248
- focusTabAtIndex(targetIndex);
249
- };
250
- return (_ctx, _cache) => {
251
- return openBlock(), createElementBlock("div", _hoisted_1$C, [
252
- createElementVNode("div", _hoisted_2$l, [
253
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab, index) => {
254
- return openBlock(), createElementBlock("button", {
255
- key: tab.value,
256
- ref_for: true,
257
- ref: (element) => setTabButtonRef(element, index),
258
- type: "button",
259
- style: normalizeStyle({ width: `${100 / __props.tabs.length}%` }),
260
- role: "tab",
261
- "aria-selected": currentActiveTab.value === tab.value,
262
- tabindex: currentActiveTab.value === tab.value ? 0 : -1,
263
- class: normalizeClass([
264
- "px-4 py-3 text-center text-sm font-semibold tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900/20 focus-visible:ring-inset dark:focus-visible:ring-neutral-100/20",
265
- currentActiveTab.value === tab.value ? "bg-neutral-100 text-neutral-950 shadow-[inset_0_-2px_0_0_rgb(23_23_23)] dark:bg-neutral-800 dark:text-neutral-50 dark:shadow-[inset_0_-2px_0_0_rgb(245_245_245)]" : "text-neutral-700 hover:bg-neutral-50 dark:text-neutral-100 dark:hover:bg-neutral-900",
266
- {
267
- "border-r border-neutral-200 dark:border-neutral-800": index !== __props.tabs.length - 1
268
- }
269
- ]),
270
- onClick: ($event) => activateTab(tab.value),
271
- onKeydown: ($event) => onTabKeydown($event, index)
272
- }, toDisplayString(tab.label), 47, _hoisted_3$e);
273
- }), 128))
274
- ])
275
- ]);
276
- };
277
- }
278
- };
279
- const _hoisted_1$B = {
280
- key: 0,
281
- class: "mb-4"
282
- };
283
- const _hoisted_2$k = {
284
- key: 1,
285
- class: "mb-4 text-xl font-semibold tracking-tight text-neutral-950 dark:text-neutral-50"
286
- };
287
- const _sfc_main$Q = {
288
- __name: "Card",
289
- props: {
290
- title: {
291
- type: String,
292
- default: ""
293
- },
294
- sticky: {
295
- type: Boolean,
296
- default: false
297
- },
298
- paddingClass: {
299
- type: String,
300
- default: "p-6 lg:p-8"
301
- },
302
- cardClass: {
303
- type: String,
304
- default: ""
305
- },
306
- overflowClass: {
307
- type: String,
308
- default: "overflow-visible"
309
- },
310
- contentClass: {
311
- type: String,
312
- default: ""
313
- },
314
- tabs: {
315
- type: Array,
316
- default: () => [],
317
- validator: (tabs) => tabs.every((tab) => typeof tab === "object" && tab !== null && typeof tab.value === "string" && tab.value.length > 0 && typeof tab.label === "string")
318
- },
319
- activeTab: {
320
- type: String,
321
- default: ""
322
- }
323
- },
324
- emits: [
325
- "update:activeTab",
326
- "tab-click"
327
- ],
328
- setup(__props) {
329
- const props = __props;
330
- const previousActiveTab = ref("");
331
- const slideDirection = ref("right");
332
- const currentTabIndex = computed(() => {
333
- return props.tabs.findIndex((tab) => tab.value === props.activeTab);
334
- });
335
- computed(() => {
336
- return props.tabs.findIndex((tab) => tab.value === previousActiveTab.value);
337
- });
338
- watch(currentTabIndex, (newIndex, oldIndex) => {
339
- if (oldIndex !== void 0 && oldIndex !== -1 && newIndex !== -1 && newIndex !== oldIndex) {
340
- slideDirection.value = newIndex > oldIndex ? "right" : "left";
341
- previousActiveTab.value = props.activeTab;
342
- }
343
- });
344
- return (_ctx, _cache) => {
345
- return openBlock(), createElementBlock("div", {
346
- class: normalizeClass(["rounded-2xl border border-neutral-200 bg-white text-neutral-950 shadow-sm dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50", __props.overflowClass, { "sticky top-6 self-start": __props.sticky }, __props.cardClass])
347
- }, [
348
- __props.tabs.length > 0 ? (openBlock(), createBlock(_sfc_main$R, {
349
- key: 0,
350
- tabs: __props.tabs,
351
- "active-tab": __props.activeTab,
352
- "onUpdate:activeTab": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:activeTab", $event)),
353
- onTabClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("tab-click", $event))
354
- }, null, 8, ["tabs", "active-tab"])) : createCommentVNode("", true),
355
- createElementVNode("div", {
356
- class: normalizeClass(__props.paddingClass)
357
- }, [
358
- _ctx.$slots.customTitle ? (openBlock(), createElementBlock("div", _hoisted_1$B, [
359
- renderSlot(_ctx.$slots, "customTitle")
360
- ])) : __props.title ? (openBlock(), createElementBlock("h3", _hoisted_2$k, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
361
- createElementVNode("div", {
362
- class: normalizeClass(["relative", __props.tabs.length > 0 ? "overflow-hidden" : "overflow-visible"])
363
- }, [
364
- createVNode(Transition, {
365
- "enter-active-class": "transition-all duration-200 ease-in-out",
366
- "enter-from-class": slideDirection.value === "right" ? "translate-x-full opacity-0" : "-translate-x-full opacity-0",
367
- "enter-to-class": "translate-x-0 opacity-100",
368
- "leave-active-class": "transition-all duration-200 ease-in-out",
369
- "leave-from-class": "translate-x-0 opacity-100",
370
- "leave-to-class": slideDirection.value === "right" ? "-translate-x-full opacity-0" : "translate-x-full opacity-0",
371
- mode: "out-in"
372
- }, {
373
- default: withCtx(() => [
374
- (openBlock(), createElementBlock("div", {
375
- key: __props.activeTab,
376
- class: normalizeClass([
377
- __props.tabs.length > 0 ? "p-2" : "",
378
- "dark:text-neutral-50 dark:[&_h1]:text-neutral-50 dark:[&_h2]:text-neutral-50 dark:[&_h3]:text-neutral-50 dark:[&_h4]:text-neutral-50 dark:[&_h5]:text-neutral-50 dark:[&_h6]:text-neutral-50 dark:[&_p]:text-neutral-100 dark:[&_span]:text-neutral-100 dark:[&_label]:text-neutral-100 dark:[&_li]:text-neutral-100 dark:[&_a]:text-neutral-100",
379
- __props.contentClass
380
- ])
381
- }, [
382
- renderSlot(_ctx.$slots, "default")
383
- ], 2))
384
- ]),
385
- _: 3
386
- }, 8, ["enter-from-class", "leave-to-class"])
387
- ], 2)
388
- ], 2)
389
- ], 2);
390
- };
391
- }
392
- };
393
- const _sfc_main$P = /* @__PURE__ */ Object.assign({
394
- inheritAttrs: false
395
- }, {
396
- __name: "Divider",
397
- setup(__props) {
398
- return (_ctx, _cache) => {
399
- return openBlock(), createElementBlock("div", mergeProps({ class: "border-t border-neutral-200 dark:border-neutral-800" }, _ctx.$attrs), [
400
- renderSlot(_ctx.$slots, "default")
401
- ], 16);
402
- };
403
- }
404
- });
405
- const _sfc_main$O = {
406
- __name: "ActionCard",
407
- props: {
408
- title: {
409
- type: String,
410
- default: ""
411
- },
412
- actionsClass: {
413
- type: String,
414
- default: "space-y-3"
415
- }
416
- },
417
- setup(__props) {
418
- const slots = useSlots();
419
- return (_ctx, _cache) => {
420
- return openBlock(), createBlock(_sfc_main$Q, {
421
- title: __props.title,
422
- "content-class": __props.actionsClass
423
- }, {
424
- default: withCtx(() => [
425
- renderSlot(_ctx.$slots, "default"),
426
- unref(slots).danger ? (openBlock(), createBlock(_sfc_main$P, {
427
- key: 0,
428
- class: "mt-6 pt-4"
429
- }, {
430
- default: withCtx(() => [
431
- renderSlot(_ctx.$slots, "danger")
432
- ]),
433
- _: 3
434
- })) : createCommentVNode("", true)
435
- ]),
436
- _: 3
437
- }, 8, ["title", "content-class"]);
438
- };
439
- }
440
- };
441
- const _hoisted_1$A = { class: "text-sm text-gray-600" };
442
- const _sfc_main$N = {
443
- __name: "ActionMessage",
444
- props: {
445
- on: Boolean
446
- },
447
- setup(__props) {
448
- return (_ctx, _cache) => {
449
- return openBlock(), createElementBlock("div", null, [
450
- createVNode(Transition, {
451
- "leave-active-class": "transition ease-in duration-1000",
452
- "leave-from-class": "opacity-100",
453
- "leave-to-class": "opacity-0"
454
- }, {
455
- default: withCtx(() => [
456
- withDirectives(createElementVNode("div", _hoisted_1$A, [
457
- renderSlot(_ctx.$slots, "default")
458
- ], 512), [
459
- [vShow, __props.on]
460
- ])
461
- ]),
462
- _: 3
463
- })
464
- ]);
465
- };
466
- }
467
- };
468
- const _export_sfc = (sfc, props) => {
469
- const target = sfc.__vccOpts || sfc;
470
- for (const [key, val] of props) {
471
- target[key] = val;
472
- }
473
- return target;
474
- };
475
- const _sfc_main$M = {};
476
- const _hoisted_1$z = { class: "md:col-span-1 flex justify-between" };
477
- const _hoisted_2$j = { class: "px-4 sm:px-0" };
478
- const _hoisted_3$d = { class: "text-xl font-semibold tracking-tight text-neutral-950 dark:text-neutral-50" };
479
- const _hoisted_4$9 = { class: "mt-1 max-w-2xl text-sm text-neutral-600 dark:text-neutral-200" };
480
- const _hoisted_5$7 = { class: "px-4 sm:px-0" };
481
- function _sfc_render(_ctx, _cache) {
482
- return openBlock(), createElementBlock("div", _hoisted_1$z, [
483
- createElementVNode("div", _hoisted_2$j, [
484
- createElementVNode("h3", _hoisted_3$d, [
485
- renderSlot(_ctx.$slots, "title")
486
- ]),
487
- createElementVNode("p", _hoisted_4$9, [
488
- renderSlot(_ctx.$slots, "description")
489
- ])
490
- ]),
491
- createElementVNode("div", _hoisted_5$7, [
492
- renderSlot(_ctx.$slots, "aside")
493
- ])
494
- ]);
495
- }
496
- const SectionTitle = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["render", _sfc_render]]);
497
- const _hoisted_1$y = { class: "md:grid md:grid-cols-3 md:gap-6" };
498
- const _hoisted_2$i = { class: "mt-5 md:mt-0 md:col-span-2" };
499
- const _hoisted_3$c = { class: "rounded-lg border border-neutral-200 bg-white px-4 py-5 shadow-sm dark:border-neutral-800 dark:bg-neutral-950 sm:p-6" };
500
- const _sfc_main$L = {
501
- __name: "ActionSection",
502
- setup(__props) {
503
- return (_ctx, _cache) => {
504
- return openBlock(), createElementBlock("div", _hoisted_1$y, [
505
- createVNode(SectionTitle, null, {
506
- title: withCtx(() => [
507
- renderSlot(_ctx.$slots, "title")
508
- ]),
509
- description: withCtx(() => [
510
- renderSlot(_ctx.$slots, "description")
511
- ]),
512
- _: 3
513
- }),
514
- createElementVNode("div", _hoisted_2$i, [
515
- createElementVNode("div", _hoisted_3$c, [
516
- renderSlot(_ctx.$slots, "content")
517
- ])
518
- ])
519
- ]);
520
- };
521
- }
522
- };
523
- const _hoisted_1$x = { class: "sr-only" };
524
- const _sfc_main$K = {
525
- __name: "Badge",
526
- props: {
527
- type: {
528
- type: String,
529
- default: "default",
530
- validator: (value) => ["default", "dot"].includes(value)
531
- },
532
- color: {
533
- type: String,
534
- default: "default",
535
- validator: (value) => [
536
- "default",
537
- "primary",
538
- "secondary",
539
- "success",
540
- "warning",
541
- "danger",
542
- "info",
543
- "gray"
544
- ].includes(value)
545
- },
546
- size: {
547
- type: String,
548
- default: "md",
549
- validator: (value) => ["xs", "sm", "md", "lg"].includes(value)
550
- },
551
- rounded: {
552
- type: String,
553
- default: "full",
554
- validator: (value) => ["none", "sm", "md", "lg", "full"].includes(value)
555
- }
556
- },
557
- setup(__props) {
558
- const colorClasses = {
559
- default: { bg: "bg-slate-100", text: "text-slate-700", dot: "bg-slate-600" },
560
- primary: { bg: "bg-blue-100", text: "text-blue-700", dot: "bg-blue-600" },
561
- secondary: { bg: "bg-slate-100", text: "text-slate-700", dot: "bg-slate-600" },
562
- success: { bg: "bg-emerald-100", text: "text-emerald-700", dot: "bg-emerald-600" },
563
- warning: { bg: "bg-amber-100", text: "text-amber-700", dot: "bg-amber-600" },
564
- danger: { bg: "bg-rose-100", text: "text-rose-700", dot: "bg-rose-600" },
565
- info: { bg: "bg-cyan-100", text: "text-cyan-700", dot: "bg-cyan-600" },
566
- gray: { bg: "bg-slate-100", text: "text-slate-600", dot: "bg-slate-600" }
567
- };
568
- const sizeClasses = {
569
- xs: "px-1.5 py-0.5 text-xs",
570
- sm: "px-2 py-0.5 text-xs",
571
- md: "px-2.5 py-0.5 text-xs",
572
- lg: "px-3 py-1 text-sm"
573
- };
574
- const roundedClasses = {
575
- none: "rounded-none",
576
- sm: "rounded-sm",
577
- md: "rounded-md",
578
- lg: "rounded-lg",
579
- full: "rounded-full"
580
- };
581
- return (_ctx, _cache) => {
582
- return __props.type === "dot" ? (openBlock(), createElementBlock("span", {
583
- key: 0,
584
- class: normalizeClass(["inline-flex items-center justify-center w-6 h-6 rounded-full", colorClasses[__props.color].bg])
585
- }, [
586
- createElementVNode("span", {
587
- class: normalizeClass(["w-2 h-2 rounded-full", colorClasses[__props.color].dot])
588
- }, null, 2),
589
- createElementVNode("span", _hoisted_1$x, [
590
- renderSlot(_ctx.$slots, "default")
591
- ])
592
- ], 2)) : (openBlock(), createElementBlock("span", {
593
- key: 1,
594
- class: normalizeClass(["inline-flex items-center font-medium", [
595
- colorClasses[__props.color].bg,
596
- colorClasses[__props.color].text,
597
- sizeClasses[__props.size],
598
- roundedClasses[__props.rounded]
599
- ]])
600
- }, [
601
- renderSlot(_ctx.$slots, "default")
602
- ], 2));
603
- };
604
- }
605
- };
606
- const _hoisted_1$w = ["type", "disabled"];
607
- const _sfc_main$J = /* @__PURE__ */ Object.assign({
608
- inheritAttrs: false
609
- }, {
610
- __name: "Button",
611
- props: {
612
- type: {
613
- type: String,
614
- default: "submit"
615
- },
616
- disabled: {
617
- type: Boolean,
618
- default: false
619
- },
620
- variant: {
621
- type: String,
622
- default: "default"
623
- },
624
- size: {
625
- type: String,
626
- default: "default"
627
- }
628
- },
629
- setup(__props) {
630
- const attrs = useAttrs();
631
- const props = __props;
632
- const variantClasses = {
633
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
634
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
635
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
636
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
637
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
638
- link: "text-primary underline-offset-4 hover:underline",
639
- primary: "bg-primary text-primary-foreground hover:bg-primary/90",
640
- success: "bg-emerald-600 text-white hover:bg-emerald-600/90 dark:bg-emerald-600 dark:text-white dark:hover:bg-emerald-600/90",
641
- tertiary: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
642
- warning: "bg-amber-100 text-amber-700 hover:bg-amber-100/90 focus-visible:ring-amber-500/20 dark:bg-amber-600/20 dark:text-neutral-50 dark:hover:bg-amber-600/30 dark:focus-visible:ring-amber-500/40",
643
- danger: "bg-destructive/10 text-destructive hover:bg-destructive/15 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:text-destructive-foreground dark:hover:bg-destructive/25",
644
- "warning-solid": "bg-amber-500 text-white hover:bg-amber-500/90 dark:bg-amber-500 dark:text-white dark:hover:bg-amber-500/90",
645
- "danger-solid": "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
646
- };
647
- const sizeClasses = {
648
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
649
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
650
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
651
- icon: "size-9",
652
- "icon-sm": "size-8",
653
- "icon-lg": "size-10"
654
- };
655
- const resolvedVariant = computed(() => {
656
- return variantClasses[props.variant] ? props.variant : "default";
657
- });
658
- const resolvedSize = computed(() => {
659
- return sizeClasses[props.size] ? props.size : "default";
660
- });
661
- const buttonClasses = computed(() => [
662
- "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
663
- variantClasses[resolvedVariant.value],
664
- sizeClasses[resolvedSize.value],
665
- attrs.class
666
- ]);
667
- return (_ctx, _cache) => {
668
- return openBlock(), createElementBlock("button", mergeProps(unref(attrs), {
669
- type: __props.type,
670
- disabled: __props.disabled,
671
- class: buttonClasses.value
672
- }), [
673
- renderSlot(_ctx.$slots, "default")
674
- ], 16, _hoisted_1$w);
675
- };
676
- }
677
- });
678
- const _hoisted_1$v = ["value"];
679
- const _sfc_main$I = {
680
- __name: "Checkbox",
681
- props: {
682
- checked: {
683
- type: [Array, Boolean],
684
- default: false
685
- },
686
- value: {
687
- type: String,
688
- default: null
689
- }
690
- },
691
- emits: ["update:checked"],
692
- setup(__props, { emit: __emit }) {
693
- const emit = __emit;
694
- const props = __props;
695
- const proxyChecked = computed({
696
- get() {
697
- return props.checked;
698
- },
699
- set(val) {
700
- emit("update:checked", val);
701
- }
702
- });
703
- return (_ctx, _cache) => {
704
- return withDirectives((openBlock(), createElementBlock("input", {
705
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => proxyChecked.value = $event),
706
- type: "checkbox",
707
- value: __props.value,
708
- class: "rounded border-neutral-300 text-neutral-900 shadow-sm focus:ring-neutral-900 dark:border-neutral-700 dark:bg-neutral-950 dark:text-neutral-100 dark:focus:ring-neutral-100"
709
- }, null, 8, _hoisted_1$v)), [
710
- [vModelCheckbox, proxyChecked.value]
711
- ]);
712
- };
713
- }
714
- };
715
- const _hoisted_1$u = ["name", "checked", "disabled"];
716
- const _sfc_main$H = {
717
- __name: "CheckboxInput",
718
- props: {
719
- modelValue: {
720
- type: [Boolean, String, Number, null],
721
- default: false
722
- },
723
- value: {
724
- type: [Boolean, String, Number],
725
- default: true
726
- },
727
- uncheckedValue: {
728
- type: [Boolean, String, Number, null],
729
- default: false
730
- },
731
- label: {
732
- type: String,
733
- default: ""
734
- },
735
- name: {
736
- type: String,
737
- default: void 0
738
- },
739
- disabled: {
740
- type: Boolean,
741
- default: false
742
- }
743
- },
744
- emits: ["update:modelValue"],
745
- setup(__props, { emit: __emit }) {
746
- const emit = __emit;
747
- const props = __props;
748
- const isChecked = computed(() => props.modelValue === props.value);
749
- const hasFocus = ref(false);
750
- const handleFocus = () => {
751
- hasFocus.value = true;
752
- };
753
- const handleBlur = () => {
754
- hasFocus.value = false;
755
- };
756
- const onChange = (event) => {
757
- emit("update:modelValue", event.target.checked ? props.value : props.uncheckedValue);
758
- };
759
- return (_ctx, _cache) => {
760
- return openBlock(), createElementBlock("label", {
761
- class: normalizeClass(["inline-flex items-center gap-2 rounded-full border px-3 py-1 text-sm font-medium select-none transition-colors", [
762
- isChecked.value ? "border-neutral-900 bg-neutral-900 text-neutral-50 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50" : "border-neutral-200 text-neutral-600 dark:border-neutral-800 dark:text-neutral-100",
763
- __props.disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer",
764
- hasFocus.value && !__props.disabled ? "ring-2 ring-neutral-900/20 ring-offset-2 ring-offset-white dark:ring-neutral-100/20 dark:ring-offset-neutral-950" : ""
765
- ]])
766
- }, [
767
- createElementVNode("input", {
768
- type: "checkbox",
769
- class: "sr-only",
770
- name: __props.name,
771
- checked: isChecked.value,
772
- disabled: __props.disabled,
773
- onChange,
774
- onFocus: handleFocus,
775
- onBlur: handleBlur
776
- }, null, 40, _hoisted_1$u),
777
- createElementVNode("span", {
778
- class: normalizeClass(["inline-flex h-4 w-4 items-center justify-center border text-[10px] font-bold leading-none", [
779
- isChecked.value ? "border-current bg-white/15 text-current dark:bg-neutral-900/15" : "border-current/70 text-transparent",
780
- "rounded"
781
- ]])
782
- }, " ✓ ", 2),
783
- createElementVNode("span", null, toDisplayString(__props.label), 1)
784
- ], 2);
785
- };
786
- }
787
- };
788
- const _hoisted_1$t = { class: "relative flex items-center" };
789
- const _hoisted_2$h = {
790
- key: 0,
791
- class: "absolute inset-y-0 left-0 flex items-center pointer-events-none pl-3"
792
- };
793
- const _hoisted_3$b = ["type", "value", "disabled"];
794
- const _hoisted_4$8 = ["aria-label"];
795
- const _hoisted_5$6 = {
796
- key: 0,
797
- class: "h-5 w-5",
798
- fill: "none",
799
- stroke: "currentColor",
800
- viewBox: "0 0 24 24"
801
- };
802
- const _hoisted_6$6 = {
803
- key: 1,
804
- class: "h-5 w-5",
805
- fill: "none",
806
- stroke: "currentColor",
807
- viewBox: "0 0 24 24"
808
- };
809
- const DEFAULT_MAX_LENGTH$1 = 254;
810
- const _sfc_main$G = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
811
- __name: "TextInput",
812
- props: {
813
- modelValue: {
814
- type: [String, Number, null],
815
- default: ""
816
- },
817
- disabled: {
818
- type: Boolean,
819
- default: false
820
- },
821
- disabledClass: {
822
- type: String,
823
- default: "!border-neutral-200 !bg-neutral-100 !text-neutral-500 dark:!border-neutral-800 dark:!bg-neutral-900 dark:!text-neutral-500"
824
- }
825
- },
826
- emits: ["update:modelValue", "blur"],
827
- setup(__props, { expose: __expose, emit: __emit }) {
828
- const props = __props;
829
- const emit = __emit;
830
- const attrs = useAttrs();
831
- const input = ref(null);
832
- const revealed = ref(false);
833
- const baseType = computed(() => String(attrs.type ?? "text"));
834
- const isPasswordField = computed(() => baseType.value === "password");
835
- const inputType = computed(() => isPasswordField.value && revealed.value ? "text" : baseType.value);
836
- const normalizedValue = computed(() => props.modelValue ?? "");
837
- const inputAttrs = computed(() => {
838
- const { class: _class, type: _type, ...rest } = attrs;
839
- if (rest.maxlength === void 0) {
840
- rest.maxlength = DEFAULT_MAX_LENGTH$1;
841
- }
842
- return rest;
843
- });
844
- const inputClasses = computed(() => [
845
- "w-full min-w-0 max-w-full rounded-lg border border-neutral-200 bg-white text-neutral-950 shadow-sm outline-none transition-colors placeholder:text-neutral-400 focus:border-neutral-900 focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50 dark:placeholder:text-neutral-500 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10",
846
- attrs.class,
847
- isPasswordField.value ? "pr-10 pl-10" : ""
848
- ]);
849
- const toggleVisibility = () => {
850
- revealed.value = !revealed.value;
851
- };
852
- const handleWheel = (event) => {
853
- if (inputType.value !== "number") {
854
- return;
855
- }
856
- event.preventDefault();
857
- const scrollTarget = document.scrollingElement ?? document.documentElement ?? document.body;
858
- if (scrollTarget) {
859
- scrollTarget.scrollTop += event.deltaY;
860
- }
861
- };
862
- onMounted(() => {
863
- if (input.value?.hasAttribute("autofocus")) {
864
- input.value.focus();
865
- }
866
- });
867
- __expose({ focus: () => input.value?.focus() });
868
- return (_ctx, _cache) => {
869
- return openBlock(), createElementBlock("div", _hoisted_1$t, [
870
- isPasswordField.value ? (openBlock(), createElementBlock("div", _hoisted_2$h, [
871
- createVNode(unref(LockClosedIcon), { class: "h-5 w-5 text-neutral-400 dark:text-neutral-200" })
872
- ])) : createCommentVNode("", true),
873
- createElementVNode("input", mergeProps({
874
- ref_key: "input",
875
- ref: input
876
- }, inputAttrs.value, {
877
- type: inputType.value,
878
- class: [inputClasses.value, props.disabled ? props.disabledClass : null],
879
- value: normalizedValue.value,
880
- disabled: props.disabled,
881
- onInput: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event.target.value)),
882
- onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event)),
883
- onWheel: handleWheel
884
- }), null, 16, _hoisted_3$b),
885
- isPasswordField.value ? (openBlock(), createElementBlock("button", {
886
- key: 1,
887
- type: "button",
888
- class: "absolute inset-y-0 right-0 flex items-center pr-3 text-neutral-400 transition-colors hover:text-neutral-700 focus:outline-none dark:text-neutral-200 dark:hover:text-neutral-50",
889
- "aria-label": revealed.value ? "Hide password" : "Show password",
890
- onClick: toggleVisibility
891
- }, [
892
- revealed.value ? (openBlock(), createElementBlock("svg", _hoisted_5$6, [..._cache[2] || (_cache[2] = [
893
- createElementVNode("path", {
894
- "stroke-linecap": "round",
895
- "stroke-linejoin": "round",
896
- "stroke-width": "2",
897
- d: "M13.875 18.825A10.05 10.05 0 0112 19c-5 0-9.27-3.11-11-7 1.01-2.27 2.78-4.1 5-5.32m3.08-1.3A9.96 9.96 0 0112 5c5 0 9.27 3.11 11 7a11.03 11.03 0 01-4.16 4.91M15 12a3 3 0 00-3-3m0 0a3 3 0 00-2.94 3.59M3 3l18 18"
898
- }, null, -1)
899
- ])])) : (openBlock(), createElementBlock("svg", _hoisted_6$6, [..._cache[3] || (_cache[3] = [
900
- createElementVNode("path", {
901
- "stroke-linecap": "round",
902
- "stroke-linejoin": "round",
903
- "stroke-width": "2",
904
- d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
905
- }, null, -1),
906
- createElementVNode("path", {
907
- "stroke-linecap": "round",
908
- "stroke-linejoin": "round",
909
- "stroke-width": "2",
910
- d: "M2.458 12C3.732 7.943 7.523 5 12 5s8.268 2.943 9.542 7c-1.274 4.057-5.065 7-9.542 7S3.732 16.057 2.458 12z"
911
- }, null, -1)
912
- ])]))
913
- ], 8, _hoisted_4$8)) : createCommentVNode("", true)
914
- ]);
915
- };
916
- }
917
- });
918
- const _hoisted_1$s = ["value", "disabled"];
919
- const DEFAULT_MAX_LENGTH = 1e3;
920
- const _sfc_main$F = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
921
- __name: "TextArea",
922
- props: {
923
- modelValue: String,
924
- disabled: {
925
- type: Boolean,
926
- default: false
927
- },
928
- disabledClass: {
929
- type: String,
930
- default: "!border-neutral-200 !bg-neutral-100 !text-neutral-500 dark:!border-neutral-800 dark:!bg-neutral-900 dark:!text-neutral-500"
931
- },
932
- autoResize: {
933
- type: Boolean,
934
- default: true
935
- }
936
- },
937
- emits: ["update:modelValue"],
938
- setup(__props, { expose: __expose, emit: __emit }) {
939
- const props = __props;
940
- const emit = __emit;
941
- const attrs = useAttrs();
942
- const textarea = ref(null);
943
- const textareaAttrs = computed(() => {
944
- const { class: _class, ...rest } = attrs;
945
- if (rest.maxlength === void 0) {
946
- rest.maxlength = DEFAULT_MAX_LENGTH;
947
- }
948
- return rest;
949
- });
950
- const textareaClasses = computed(() => [
951
- "w-full min-w-0 max-w-full rounded-lg border border-neutral-200 bg-white px-4 py-3 text-sm text-neutral-950 shadow-sm outline-none transition-colors placeholder:text-neutral-400 focus:border-neutral-900 focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50 dark:placeholder:text-neutral-500 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10",
952
- props.autoResize ? "resize-none overflow-y-auto" : "resize-y",
953
- attrs.class
954
- ]);
955
- const resizeTextarea = () => {
956
- if (!props.autoResize || !textarea.value) {
957
- return;
958
- }
959
- textarea.value.style.height = "auto";
960
- textarea.value.style.height = `${textarea.value.scrollHeight}px`;
961
- };
962
- const updateValue = (event) => {
963
- emit("update:modelValue", event.target.value);
964
- resizeTextarea();
965
- };
966
- onMounted(() => {
967
- if (textarea.value?.hasAttribute("autofocus")) {
968
- textarea.value.focus();
969
- }
970
- nextTick(() => {
971
- resizeTextarea();
972
- });
973
- });
974
- watch(() => props.modelValue, () => {
975
- nextTick(() => {
976
- resizeTextarea();
977
- });
978
- });
979
- __expose({ focus: () => textarea.value?.focus() });
980
- return (_ctx, _cache) => {
981
- return openBlock(), createElementBlock("div", null, [
982
- createElementVNode("textarea", mergeProps({
983
- ref_key: "textarea",
984
- ref: textarea
985
- }, textareaAttrs.value, {
986
- class: [textareaClasses.value, props.disabled ? props.disabledClass : ""],
987
- value: props.modelValue,
988
- disabled: props.disabled,
989
- onInput: updateValue
990
- }), null, 16, _hoisted_1$s)
991
- ]);
992
- };
993
- }
994
- });
995
- const _hoisted_1$r = ["onClick"];
996
- const _sfc_main$E = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
997
- __name: "CustomSelect",
998
- props: {
999
- modelValue: {
1000
- type: [String, Number, Boolean, null],
1001
- default: ""
1002
- },
1003
- modelModifiers: {
1004
- type: Object,
1005
- default: () => ({})
1006
- },
1007
- options: {
1008
- type: Array,
1009
- default: () => []
1010
- },
1011
- placeholder: {
1012
- type: String,
1013
- default: ""
1014
- },
1015
- placeholderDisabled: {
1016
- type: Boolean,
1017
- default: false
1018
- },
1019
- disabled: {
1020
- type: Boolean,
1021
- default: false
1022
- },
1023
- softDeleteAware: {
1024
- type: Boolean,
1025
- default: false
1026
- },
1027
- labelKey: {
1028
- type: String,
1029
- default: "name"
1030
- },
1031
- valueKey: {
1032
- type: String,
1033
- default: "id"
1034
- },
1035
- deletedKey: {
1036
- type: String,
1037
- default: "deleted_at"
1038
- },
1039
- optionLabel: {
1040
- type: Function,
1041
- default: null
1042
- },
1043
- baseClass: {
1044
- type: [String, Array, Object],
1045
- default: "block w-full rounded-lg border border-neutral-200 bg-white px-4 py-3 text-sm shadow-sm outline-none transition-colors focus:border-neutral-900 focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10"
1046
- },
1047
- normalTextClass: {
1048
- type: [String, Array, Object],
1049
- default: "text-neutral-950 dark:text-neutral-50"
1050
- },
1051
- deletedSelectedClass: {
1052
- type: [String, Array, Object],
1053
- default: "text-red-600 dark:text-neutral-100"
1054
- },
1055
- optionClass: {
1056
- type: [String, Array, Object],
1057
- default: "text-neutral-950 dark:text-neutral-50"
1058
- },
1059
- deletedOptionClass: {
1060
- type: [String, Array, Object],
1061
- default: "text-red-600 dark:text-neutral-100"
1062
- },
1063
- placeholderClass: {
1064
- type: [String, Array, Object],
1065
- default: "text-neutral-500 dark:text-neutral-200"
1066
- },
1067
- dropdownClass: {
1068
- type: [String, Array, Object],
1069
- default: "z-50 max-h-60 overflow-auto rounded-lg border border-neutral-200 bg-white shadow-xl dark:border-neutral-800 dark:bg-neutral-950"
1070
- },
1071
- dropdownOptionClass: {
1072
- type: [String, Array, Object],
1073
- default: "cursor-pointer px-4 py-3 transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-900"
1074
- },
1075
- dropdownSelectedClass: {
1076
- type: [String, Array, Object],
1077
- default: "bg-neutral-100 font-medium text-neutral-950 dark:bg-neutral-900 dark:text-neutral-50"
1078
- }
1079
- },
1080
- emits: ["update:modelValue"],
1081
- setup(__props, { emit: __emit }) {
1082
- const props = __props;
1083
- const emit = __emit;
1084
- const attrs = useAttrs();
1085
- const isOpen = ref(false);
1086
- const rootRef = ref(null);
1087
- const triggerRef = ref(null);
1088
- const dropdownMenuRef = ref(null);
1089
- const dropdownStyle = ref({});
1090
- const isObjectOption = (option) => typeof option === "object" && option !== null;
1091
- const optionValue = (option) => {
1092
- if (isObjectOption(option)) {
1093
- return option[props.valueKey];
1094
- }
1095
- return option;
1096
- };
1097
- const optionText = (option) => {
1098
- if (props.optionLabel) {
1099
- return props.optionLabel(option);
1100
- }
1101
- if (isObjectOption(option)) {
1102
- return option[props.labelKey] ?? option[props.valueKey] ?? "";
1103
- }
1104
- return option;
1105
- };
1106
- const optionDeleted = (option) => {
1107
- if (!props.softDeleteAware || !isObjectOption(option)) {
1108
- return false;
1109
- }
1110
- return Boolean(option[props.deletedKey]);
1111
- };
1112
- const modelValueAsString = computed(() => String(props.modelValue ?? ""));
1113
- const selectedDeletedOption = computed(() => {
1114
- if (!props.softDeleteAware || modelValueAsString.value === "") {
1115
- return null;
1116
- }
1117
- return props.options.find((option) => optionDeleted(option) && String(optionValue(option) ?? "") === modelValueAsString.value) ?? null;
1118
- });
1119
- const availableOptions = computed(() => {
1120
- if (!props.softDeleteAware) {
1121
- return props.options;
1122
- }
1123
- return props.options.filter((option) => !optionDeleted(option));
1124
- });
1125
- const displayText = computed(() => {
1126
- if (props.modelValue === null || props.modelValue === void 0 || props.modelValue === "" && !props.options.some((option) => optionValue(option) === "")) {
1127
- return props.placeholder;
1128
- }
1129
- const selectedOption = props.options.find((option) => {
1130
- const optionVal = optionValue(option);
1131
- return optionVal === props.modelValue || String(optionVal) === String(props.modelValue);
1132
- });
1133
- return selectedOption ? optionText(selectedOption) : props.modelValue;
1134
- });
1135
- const normalizeEmittedValue = (value) => {
1136
- if (props.modelModifiers.number) {
1137
- if (value === "") {
1138
- return "";
1139
- }
1140
- return Number(value);
1141
- }
1142
- return value;
1143
- };
1144
- const toggleDropdown = () => {
1145
- if (!props.disabled) {
1146
- isOpen.value = !isOpen.value;
1147
- }
1148
- };
1149
- const selectOption = (option) => {
1150
- const value = optionValue(option);
1151
- emit("update:modelValue", normalizeEmittedValue(value));
1152
- isOpen.value = false;
1153
- };
1154
- const selectPlaceholder = () => {
1155
- if (!props.placeholderDisabled) {
1156
- emit("update:modelValue", normalizeEmittedValue(""));
1157
- isOpen.value = false;
1158
- }
1159
- };
1160
- const updateDropdownPosition = () => {
1161
- if (!triggerRef.value) {
1162
- return;
1163
- }
1164
- const rect = triggerRef.value.getBoundingClientRect();
1165
- const viewportWidth = window.innerWidth;
1166
- const viewportHeight = window.innerHeight;
1167
- const spaceBelow = viewportHeight - rect.bottom - 8;
1168
- const spaceAbove = rect.top - 8;
1169
- const shouldOpenUpward = spaceBelow < 240 && spaceAbove > spaceBelow;
1170
- const width = Math.min(rect.width, Math.max(viewportWidth - rect.left - 16, 160));
1171
- const maxHeight = Math.max(Math.min(240, shouldOpenUpward ? spaceAbove : spaceBelow), 120);
1172
- dropdownStyle.value = {
1173
- position: "fixed",
1174
- left: `${Math.max(rect.left, 8)}px`,
1175
- width: `${width}px`,
1176
- maxHeight: `${maxHeight}px`,
1177
- zIndex: "9999",
1178
- ...shouldOpenUpward ? { bottom: `${viewportHeight - rect.top + 1}px` } : { top: `${rect.bottom - 1}px` }
1179
- };
1180
- };
1181
- const closeDropdown = (event) => {
1182
- const clickedInsideTrigger = rootRef.value?.contains(event.target);
1183
- const clickedInsideMenu = dropdownMenuRef.value?.contains(event.target);
1184
- if (!clickedInsideTrigger && !clickedInsideMenu) {
1185
- isOpen.value = false;
1186
- }
1187
- };
1188
- onMounted(() => {
1189
- document.addEventListener("click", closeDropdown);
1190
- window.addEventListener("resize", updateDropdownPosition);
1191
- window.addEventListener("scroll", updateDropdownPosition, true);
1192
- });
1193
- onBeforeUnmount(() => {
1194
- document.removeEventListener("click", closeDropdown);
1195
- window.removeEventListener("resize", updateDropdownPosition);
1196
- window.removeEventListener("scroll", updateDropdownPosition, true);
1197
- });
1198
- watch(isOpen, async (open) => {
1199
- if (!open) {
1200
- return;
1201
- }
1202
- await nextTick();
1203
- updateDropdownPosition();
1204
- });
1205
- return (_ctx, _cache) => {
1206
- return openBlock(), createElementBlock("div", {
1207
- ref_key: "rootRef",
1208
- ref: rootRef,
1209
- class: "relative",
1210
- onClick: toggleDropdown
1211
- }, [
1212
- createElementVNode("div", mergeProps({
1213
- ref_key: "triggerRef",
1214
- ref: triggerRef,
1215
- class: [
1216
- __props.baseClass,
1217
- selectedDeletedOption.value ? __props.deletedSelectedClass : __props.normalTextClass,
1218
- "flex items-center justify-between cursor-pointer",
1219
- unref(attrs).class
1220
- ]
1221
- }, unref(attrs), { tabindex: "0" }), [
1222
- createElementVNode("span", {
1223
- class: normalizeClass(!__props.modelValue && __props.placeholder ? __props.placeholderClass : null)
1224
- }, toDisplayString(displayText.value), 3),
1225
- createVNode(unref(ChevronDownIcon), {
1226
- class: normalizeClass(["size-5 text-neutral-400 transition-transform dark:text-neutral-200", { "rotate-180": isOpen.value }])
1227
- }, null, 8, ["class"])
1228
- ], 16),
1229
- createVNode(Transition, {
1230
- "enter-active-class": "transition-all duration-200 ease-out",
1231
- "enter-from-class": "opacity-0 transform scale-95 -translate-y-2",
1232
- "enter-to-class": "opacity-100 transform scale-100 translate-y-0",
1233
- "leave-active-class": "transition-all duration-150 ease-in",
1234
- "leave-from-class": "opacity-100 transform scale-100 translate-y-0",
1235
- "leave-to-class": "opacity-0 transform scale-95 -translate-y-2"
1236
- }, {
1237
- default: withCtx(() => [
1238
- (openBlock(), createBlock(Teleport, { to: "body" }, [
1239
- isOpen.value ? (openBlock(), createElementBlock("div", {
1240
- key: 0,
1241
- ref_key: "dropdownMenuRef",
1242
- ref: dropdownMenuRef,
1243
- class: normalizeClass(__props.dropdownClass),
1244
- style: normalizeStyle(dropdownStyle.value)
1245
- }, [
1246
- __props.placeholder ? (openBlock(), createElementBlock("div", {
1247
- key: 0,
1248
- class: normalizeClass([
1249
- __props.dropdownOptionClass,
1250
- __props.placeholderClass,
1251
- { "text-gray-400": !__props.modelValue }
1252
- ]),
1253
- onClick: withModifiers(selectPlaceholder, ["stop"])
1254
- }, toDisplayString(__props.placeholder), 3)) : createCommentVNode("", true),
1255
- selectedDeletedOption.value ? (openBlock(), createElementBlock("div", {
1256
- key: 1,
1257
- class: normalizeClass([
1258
- __props.dropdownOptionClass,
1259
- __props.deletedOptionClass,
1260
- __props.dropdownSelectedClass
1261
- ])
1262
- }, toDisplayString(optionText(selectedDeletedOption.value)), 3)) : createCommentVNode("", true),
1263
- (openBlock(true), createElementBlock(Fragment, null, renderList(availableOptions.value, (option) => {
1264
- return openBlock(), createElementBlock("div", {
1265
- key: String(optionValue(option)),
1266
- class: normalizeClass([
1267
- __props.dropdownOptionClass,
1268
- __props.optionClass,
1269
- {
1270
- [__props.dropdownSelectedClass]: optionValue(option) === __props.modelValue || String(optionValue(option)) === String(__props.modelValue),
1271
- "rounded-b-lg": option === availableOptions.value[availableOptions.value.length - 1] && !__props.placeholder,
1272
- "rounded-lg": !__props.placeholder && availableOptions.value.length === 1
1273
- }
1274
- ]),
1275
- onClick: withModifiers(($event) => selectOption(option), ["stop"])
1276
- }, toDisplayString(optionText(option)), 11, _hoisted_1$r);
1277
- }), 128))
1278
- ], 6)) : createCommentVNode("", true)
1279
- ]))
1280
- ]),
1281
- _: 1
1282
- })
1283
- ], 512);
1284
- };
1285
- }
1286
- });
1287
- const _sfc_main$D = {
1288
- __name: "SelectInput",
1289
- props: {
1290
- modelValue: {
1291
- type: [String, Number, Boolean, null],
1292
- default: ""
1293
- },
1294
- modelModifiers: {
1295
- type: Object,
1296
- default: () => ({})
1297
- },
1298
- options: {
1299
- type: Array,
1300
- default: () => []
1301
- },
1302
- placeholder: {
1303
- type: String,
1304
- default: ""
1305
- },
1306
- placeholderDisabled: {
1307
- type: Boolean,
1308
- default: false
1309
- },
1310
- disabled: {
1311
- type: Boolean,
1312
- default: false
1313
- },
1314
- softDeleteAware: {
1315
- type: Boolean,
1316
- default: false
1317
- },
1318
- labelKey: {
1319
- type: String,
1320
- default: "name"
1321
- },
1322
- valueKey: {
1323
- type: String,
1324
- default: "id"
1325
- },
1326
- deletedKey: {
1327
- type: String,
1328
- default: "deleted_at"
1329
- },
1330
- optionLabel: {
1331
- type: Function,
1332
- default: null
1333
- },
1334
- baseClass: {
1335
- type: [String, Array, Object],
1336
- default: "block w-full rounded-lg border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
1337
- },
1338
- normalTextClass: {
1339
- type: [String, Array, Object],
1340
- default: "text-slate-900"
1341
- },
1342
- deletedSelectedClass: {
1343
- type: [String, Array, Object],
1344
- default: "text-red-600"
1345
- },
1346
- optionClass: {
1347
- type: [String, Array, Object],
1348
- default: "text-slate-900"
1349
- },
1350
- deletedOptionClass: {
1351
- type: [String, Array, Object],
1352
- default: "text-rose-700"
1353
- },
1354
- placeholderClass: {
1355
- type: [String, Array, Object],
1356
- default: "text-slate-500"
1357
- },
1358
- dropdownClass: {
1359
- type: [String, Array, Object],
1360
- default: "bg-white/95 border border-slate-200 rounded-xl shadow-xl max-h-60 overflow-auto z-50 backdrop-blur-sm"
1361
- },
1362
- dropdownOptionClass: {
1363
- type: [String, Array, Object],
1364
- default: "px-4 py-3 hover:bg-slate-100 cursor-pointer transition-colors"
1365
- },
1366
- dropdownSelectedClass: {
1367
- type: [String, Array, Object],
1368
- default: "bg-blue-50 text-blue-700 font-medium"
1369
- }
1370
- },
1371
- emits: ["update:modelValue"],
1372
- setup(__props, { emit: __emit }) {
1373
- const emit = __emit;
1374
- return (_ctx, _cache) => {
1375
- return openBlock(), createBlock(_sfc_main$E, mergeProps({
1376
- "model-value": __props.modelValue,
1377
- "model-modifiers": __props.modelModifiers,
1378
- options: __props.options,
1379
- placeholder: __props.placeholder,
1380
- "placeholder-disabled": __props.placeholderDisabled,
1381
- disabled: __props.disabled,
1382
- "soft-delete-aware": __props.softDeleteAware,
1383
- "label-key": __props.labelKey,
1384
- "value-key": __props.valueKey,
1385
- "deleted-key": __props.deletedKey,
1386
- "option-label": __props.optionLabel,
1387
- "base-class": __props.baseClass,
1388
- "normal-text-class": __props.normalTextClass,
1389
- "deleted-selected-class": __props.deletedSelectedClass,
1390
- "option-class": __props.optionClass,
1391
- "deleted-option-class": __props.deletedOptionClass,
1392
- "placeholder-class": __props.placeholderClass,
1393
- "dropdown-class": __props.dropdownClass,
1394
- "dropdown-option-class": __props.dropdownOptionClass,
1395
- "dropdown-selected-class": __props.dropdownSelectedClass,
1396
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event))
1397
- }, _ctx.$attrs), null, 16, ["model-value", "model-modifiers", "options", "placeholder", "placeholder-disabled", "disabled", "soft-delete-aware", "label-key", "value-key", "deleted-key", "option-label", "base-class", "normal-text-class", "deleted-selected-class", "option-class", "deleted-option-class", "placeholder-class", "dropdown-class", "dropdown-option-class", "dropdown-selected-class"]);
1398
- };
1399
- }
1400
- };
1401
- const _hoisted_1$q = ["type", "max", "value", "disabled"];
1402
- const _sfc_main$C = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
1403
- __name: "DateInput",
1404
- props: {
1405
- modelValue: {
1406
- type: [String, Number, null],
1407
- default: ""
1408
- },
1409
- withTimestamp: {
1410
- type: Boolean,
1411
- default: false
1412
- },
1413
- disabled: {
1414
- type: Boolean,
1415
- default: false
1416
- },
1417
- disabledClass: {
1418
- type: String,
1419
- default: "!border-neutral-200 !bg-neutral-100 !text-neutral-500 dark:!border-neutral-800 dark:!bg-neutral-900 dark:!text-neutral-500"
1420
- }
1421
- },
1422
- emits: ["update:modelValue"],
1423
- setup(__props, { expose: __expose, emit: __emit }) {
1424
- const props = __props;
1425
- const emit = __emit;
1426
- const attrs = useAttrs();
1427
- const input = ref(null);
1428
- const inputType = computed(() => props.withTimestamp ? "datetime-local" : "date");
1429
- const normalizedValue = computed(() => props.modelValue ?? "");
1430
- const cappedMax = computed(() => {
1431
- const limit = props.withTimestamp ? "9999-12-31T23:59" : "9999-12-31";
1432
- const incoming = attrs.max;
1433
- if (typeof incoming !== "string" || incoming === "") {
1434
- return limit;
1435
- }
1436
- return incoming > limit ? limit : incoming;
1437
- });
1438
- const inputAttrs = computed(() => {
1439
- const { class: _class, type: _type, ...rest } = attrs;
1440
- return rest;
1441
- });
1442
- const inputClasses = computed(() => [
1443
- "date-input w-full rounded-lg border border-neutral-200 bg-white px-4 py-3 text-sm text-neutral-950 shadow-sm outline-none transition-colors focus:border-neutral-900 focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10",
1444
- attrs.class
1445
- ]);
1446
- const normalizeDateValue = (rawValue) => {
1447
- if (typeof rawValue !== "string") {
1448
- return "";
1449
- }
1450
- return rawValue.replace(/^(\d{4})\d+/, "$1");
1451
- };
1452
- const handleDateInput = (event) => {
1453
- const target = event.target;
1454
- if (!target) {
1455
- return;
1456
- }
1457
- const rawValue = String(target.value ?? "");
1458
- const normalized = normalizeDateValue(rawValue);
1459
- if (normalized !== rawValue) {
1460
- target.value = normalized;
1461
- }
1462
- emit("update:modelValue", normalized);
1463
- };
1464
- onMounted(() => {
1465
- if (input.value?.hasAttribute("autofocus")) {
1466
- input.value.focus();
1467
- }
1468
- });
1469
- __expose({ focus: () => input.value?.focus() });
1470
- return (_ctx, _cache) => {
1471
- return openBlock(), createElementBlock("input", mergeProps({
1472
- ref_key: "input",
1473
- ref: input
1474
- }, inputAttrs.value, {
1475
- type: inputType.value,
1476
- max: cappedMax.value,
1477
- class: [inputClasses.value, props.disabled ? props.disabledClass : null],
1478
- value: normalizedValue.value,
1479
- disabled: props.disabled,
1480
- onInput: handleDateInput,
1481
- onChange: handleDateInput
1482
- }), null, 16, _hoisted_1$q);
1483
- };
1484
- }
1485
- });
1486
- const DateInput = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-35dd480a"]]);
1487
- const _hoisted_1$p = { class: "relative" };
1488
- const _hoisted_2$g = { class: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" };
1489
- const _hoisted_3$a = ["accept"];
1490
- const _hoisted_4$7 = {
1491
- key: 0,
1492
- class: "mt-4 rounded-lg border border-neutral-200 bg-neutral-50 p-4 dark:border-neutral-800 dark:bg-neutral-900/50"
1493
- };
1494
- const _hoisted_5$5 = { class: "flex items-center space-x-4" };
1495
- const _hoisted_6$5 = ["src"];
1496
- const _hoisted_7$5 = { class: "text-sm font-medium text-neutral-900 dark:text-neutral-50" };
1497
- const _hoisted_8$3 = { class: "text-xs text-neutral-500 dark:text-neutral-200" };
1498
- const _sfc_main$B = {
1499
- __name: "ImageInput",
1500
- props: {
1501
- currentImageUrl: {
1502
- type: String,
1503
- default: ""
1504
- },
1505
- accept: {
1506
- type: String,
1507
- default: "image/*"
1508
- },
1509
- currentLabel: {
1510
- type: String,
1511
- default: "Current logo"
1512
- },
1513
- currentSubtext: {
1514
- type: String,
1515
- default: "Upload a new logo to replace this one"
1516
- },
1517
- attrs: {
1518
- type: Object,
1519
- default: () => ({})
1520
- }
1521
- },
1522
- emits: ["update:modelValue"],
1523
- setup(__props, { emit: __emit }) {
1524
- const emit = __emit;
1525
- const props = __props;
1526
- const handleFileChange = (event) => {
1527
- const file = event.target.files?.[0] ?? null;
1528
- emit("update:modelValue", file);
1529
- };
1530
- return (_ctx, _cache) => {
1531
- return openBlock(), createElementBlock("div", null, [
1532
- createElementVNode("div", _hoisted_1$p, [
1533
- createElementVNode("div", _hoisted_2$g, [
1534
- createVNode(unref(PhotoIcon), { class: "size-5 text-neutral-400 dark:text-neutral-200" })
1535
- ]),
1536
- createElementVNode("input", mergeProps(__props.attrs, {
1537
- type: "file",
1538
- accept: __props.accept,
1539
- class: "block w-full cursor-pointer rounded-lg border border-neutral-200 bg-white py-3 pl-10 pr-4 text-sm text-neutral-700 shadow-sm transition-all duration-200 file:mr-4 file:rounded-md file:border-0 file:bg-neutral-900 file:px-4 file:py-2 file:text-sm file:font-medium file:text-neutral-50 hover:file:bg-neutral-800 focus:border-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-100 dark:file:bg-neutral-800 dark:file:text-neutral-50 dark:hover:file:bg-neutral-700 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10",
1540
- onChange: handleFileChange
1541
- }), null, 16, _hoisted_3$a)
1542
- ]),
1543
- props.currentImageUrl ? (openBlock(), createElementBlock("div", _hoisted_4$7, [
1544
- createElementVNode("div", _hoisted_5$5, [
1545
- createElementVNode("img", {
1546
- src: props.currentImageUrl,
1547
- alt: "Current logo",
1548
- class: "h-16 w-auto max-w-24 object-contain rounded-lg shadow-sm"
1549
- }, null, 8, _hoisted_6$5),
1550
- createElementVNode("div", null, [
1551
- createElementVNode("p", _hoisted_7$5, toDisplayString(props.currentLabel), 1),
1552
- createElementVNode("p", _hoisted_8$3, toDisplayString(props.currentSubtext), 1)
1553
- ])
1554
- ])
1555
- ])) : createCommentVNode("", true)
1556
- ]);
1557
- };
1558
- }
1559
- };
1560
- const _hoisted_1$o = { class: "flex h-12 overflow-hidden rounded-lg border border-neutral-200 bg-white text-sm dark:border-neutral-800 dark:bg-neutral-950" };
1561
- const _hoisted_2$f = ["disabled", "onClick"];
1562
- const _sfc_main$A = {
1563
- __name: "NotationInput",
1564
- props: {
1565
- modelValue: {
1566
- type: [String, Number, null],
1567
- default: ""
1568
- },
1569
- options: {
1570
- type: Array,
1571
- default: () => []
1572
- },
1573
- disabled: {
1574
- type: Boolean,
1575
- default: false
1576
- }
1577
- },
1578
- emits: ["update:modelValue"],
1579
- setup(__props, { emit: __emit }) {
1580
- const emit = __emit;
1581
- const props = __props;
1582
- const normalizedOptions = computed(() => {
1583
- return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
1584
- });
1585
- const isSelected = (option) => String(option) === String(props.modelValue ?? "");
1586
- const selectOption = (option) => emit("update:modelValue", option);
1587
- return (_ctx, _cache) => {
1588
- return openBlock(), createElementBlock("div", _hoisted_1$o, [
1589
- (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option, idx) => {
1590
- return openBlock(), createElementBlock("button", {
1591
- key: `notation-${idx}-${option}`,
1592
- type: "button",
1593
- class: normalizeClass(["flex-1 border-l border-neutral-200 px-2 text-center font-semibold transition-colors duration-150 first:border-l-0 dark:border-neutral-800", [
1594
- idx === 0 ? "rounded-l-lg" : "",
1595
- idx === normalizedOptions.value.length - 1 ? "rounded-r-lg" : "",
1596
- isSelected(option) ? "bg-neutral-900 text-neutral-50 dark:bg-neutral-800 dark:text-neutral-50" : "bg-white text-neutral-700 hover:bg-neutral-100 dark:bg-neutral-950 dark:text-neutral-100 dark:hover:bg-neutral-900",
1597
- "focus-visible:ring-2 focus-visible:ring-neutral-900/20 focus-visible:ring-offset-0 dark:focus-visible:ring-neutral-100/20"
1598
- ]]),
1599
- disabled: __props.disabled,
1600
- onClick: ($event) => selectOption(option)
1601
- }, toDisplayString(option), 11, _hoisted_2$f);
1602
- }), 128))
1603
- ]);
1604
- };
1605
- }
1606
- };
1607
- const _hoisted_1$n = ["name", "value", "checked", "disabled"];
1608
- const _sfc_main$z = {
1609
- __name: "RadioInput",
1610
- props: {
1611
- modelValue: {
1612
- type: [String, Number, Boolean, null],
1613
- default: null
1614
- },
1615
- value: {
1616
- type: [String, Number, Boolean],
1617
- default: true
1618
- },
1619
- label: {
1620
- type: String,
1621
- default: ""
1622
- },
1623
- name: {
1624
- type: String,
1625
- default: void 0
1626
- },
1627
- disabled: {
1628
- type: Boolean,
1629
- default: false
1630
- }
1631
- },
1632
- emits: ["update:modelValue"],
1633
- setup(__props, { emit: __emit }) {
1634
- const emit = __emit;
1635
- const props = __props;
1636
- const isChecked = computed(() => String(props.modelValue ?? "") === String(props.value));
1637
- const hasFocus = ref(false);
1638
- const handleFocus = () => {
1639
- hasFocus.value = true;
1640
- };
1641
- const handleBlur = () => {
1642
- hasFocus.value = false;
1643
- };
1644
- const onChange = () => emit("update:modelValue", props.value);
1645
- return (_ctx, _cache) => {
1646
- return openBlock(), createElementBlock("label", {
1647
- class: normalizeClass(["inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium select-none transition-colors", [
1648
- isChecked.value ? "border-neutral-900 bg-neutral-900 text-neutral-50 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-50" : "border-neutral-200 text-neutral-600 dark:border-neutral-800 dark:text-neutral-100",
1649
- __props.disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer",
1650
- hasFocus.value && !__props.disabled ? "ring-2 ring-neutral-900/20 ring-offset-2 ring-offset-white dark:ring-neutral-100/20 dark:ring-offset-neutral-950" : ""
1651
- ]])
1652
- }, [
1653
- createElementVNode("input", {
1654
- type: "radio",
1655
- class: "sr-only",
1656
- name: __props.name,
1657
- value: __props.value,
1658
- checked: isChecked.value,
1659
- disabled: __props.disabled,
1660
- onChange,
1661
- onFocus: handleFocus,
1662
- onBlur: handleBlur
1663
- }, null, 40, _hoisted_1$n),
1664
- createElementVNode("span", null, toDisplayString(isChecked.value ? "✓" : "○") + " " + toDisplayString(__props.label), 1)
1665
- ], 2);
1666
- };
1667
- }
1668
- };
1669
- const _hoisted_1$m = ["name", "checked", "disabled"];
1670
- const _hoisted_2$e = {
1671
- key: 0,
1672
- class: "text-sm text-neutral-700 dark:text-neutral-200"
1673
- };
1674
- const _sfc_main$y = {
1675
- __name: "ToggleInput",
1676
- props: {
1677
- modelValue: {
1678
- type: [Boolean, String, Number, null],
1679
- default: false
1680
- },
1681
- value: {
1682
- type: [Boolean, String, Number],
1683
- default: true
1684
- },
1685
- uncheckedValue: {
1686
- type: [Boolean, String, Number, null],
1687
- default: false
1688
- },
1689
- label: {
1690
- type: String,
1691
- default: ""
1692
- },
1693
- name: {
1694
- type: String,
1695
- default: void 0
1696
- },
1697
- disabled: {
1698
- type: Boolean,
1699
- default: false
1700
- }
1701
- },
1702
- emits: ["update:modelValue", "blur"],
1703
- setup(__props, { emit: __emit }) {
1704
- const emit = __emit;
1705
- const props = __props;
1706
- const isChecked = computed(() => props.modelValue === props.value);
1707
- const hasFocus = ref(false);
1708
- const handleFocus = () => {
1709
- hasFocus.value = true;
1710
- };
1711
- const handleBlur = (event) => {
1712
- hasFocus.value = false;
1713
- emit("blur", event);
1714
- };
1715
- const onChange = (event) => {
1716
- emit(
1717
- "update:modelValue",
1718
- event.target.checked ? props.value : props.uncheckedValue
1719
- );
1720
- };
1721
- return (_ctx, _cache) => {
1722
- return openBlock(), createElementBlock("label", {
1723
- class: normalizeClass(["inline-flex items-center gap-3 select-none", [
1724
- __props.disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer",
1725
- hasFocus.value && !__props.disabled ? "rounded-full ring-2 ring-neutral-900/20 ring-offset-2 ring-offset-white dark:ring-neutral-100/20 dark:ring-offset-neutral-950" : ""
1726
- ]])
1727
- }, [
1728
- createElementVNode("input", {
1729
- type: "checkbox",
1730
- class: "sr-only",
1731
- name: __props.name,
1732
- checked: isChecked.value,
1733
- disabled: __props.disabled,
1734
- onChange,
1735
- onFocus: handleFocus,
1736
- onBlur: handleBlur
1737
- }, null, 40, _hoisted_1$m),
1738
- createElementVNode("span", {
1739
- "aria-hidden": "true",
1740
- class: normalizeClass(["relative inline-flex h-6 w-11 items-center rounded-full border transition-colors duration-200", [
1741
- isChecked.value ? "border-neutral-900 bg-neutral-900 dark:border-neutral-100 dark:bg-neutral-100" : "border-neutral-300 bg-neutral-200 dark:border-neutral-700 dark:bg-neutral-800"
1742
- ]])
1743
- }, [
1744
- createElementVNode("span", {
1745
- class: normalizeClass(["inline-block size-4 rounded-full bg-white shadow-sm transition-transform duration-200 dark:bg-neutral-950", [isChecked.value ? "translate-x-6" : "translate-x-1"]])
1746
- }, null, 2)
1747
- ], 2),
1748
- __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$e, toDisplayString(__props.label), 1)) : createCommentVNode("", true)
1749
- ], 2);
1750
- };
1751
- }
1752
- };
1753
- const _hoisted_1$l = { class: "flex flex-wrap gap-3" };
1754
- const _sfc_main$x = {
1755
- __name: "RadioMultipleInput",
1756
- props: {
1757
- modelValue: {
1758
- type: [String, Number, null],
1759
- default: ""
1760
- },
1761
- options: {
1762
- type: Array,
1763
- default: () => []
1764
- },
1765
- name: {
1766
- type: String,
1767
- default: void 0
1768
- },
1769
- disabled: {
1770
- type: Boolean,
1771
- default: false
1772
- }
1773
- },
1774
- emits: ["update:modelValue"],
1775
- setup(__props, { emit: __emit }) {
1776
- const emit = __emit;
1777
- const props = __props;
1778
- const normalizedOptions = computed(() => {
1779
- return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
1780
- });
1781
- const selectOption = (option) => emit("update:modelValue", option);
1782
- return (_ctx, _cache) => {
1783
- return openBlock(), createElementBlock("div", _hoisted_1$l, [
1784
- (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1785
- return openBlock(), createBlock(_sfc_main$v, {
1786
- key: `radio-${__props.name ?? "group"}-${option}`,
1787
- type: "radio-input",
1788
- "model-value": props.modelValue,
1789
- name: __props.name,
1790
- value: option,
1791
- label: option,
1792
- disabled: __props.disabled,
1793
- "onUpdate:modelValue": selectOption
1794
- }, null, 8, ["model-value", "name", "value", "label", "disabled"]);
1795
- }), 128))
1796
- ]);
1797
- };
1798
- }
1799
- };
1800
- const _hoisted_1$k = {
1801
- key: 0,
1802
- class: "min-h-[12rem] w-full rounded-lg border border-slate-300 bg-slate-50"
1803
- };
1804
- const _sfc_main$w = {
1805
- __name: "TinyEditor",
1806
- props: {
1807
- modelValue: {
1808
- type: String,
1809
- default: ""
1810
- },
1811
- readonly: {
1812
- type: Boolean,
1813
- default: false
1814
- },
1815
- height: {
1816
- type: Number,
1817
- default: 300
1818
- },
1819
- menubar: {
1820
- type: [Boolean, String],
1821
- default: false
1822
- },
1823
- toolbar: {
1824
- type: [String, Array],
1825
- default: "undo redo | bold italic underline | bullist numlist | link image | alignleft aligncenter alignright | code"
1826
- },
1827
- plugins: {
1828
- type: [String, Array],
1829
- default: () => ["link", "table", "code", "lists", "image"]
1830
- },
1831
- init: {
1832
- type: Object,
1833
- default: () => ({})
1834
- },
1835
- licenseKey: {
1836
- type: String,
1837
- default: "gpl"
1838
- },
1839
- outputFormat: {
1840
- type: String,
1841
- default: "html"
1842
- }
1843
- },
1844
- emits: ["update:modelValue", "blur"],
1845
- setup(__props, { emit: __emit }) {
1846
- const props = __props;
1847
- const emit = __emit;
1848
- const content = ref(props.modelValue ?? "");
1849
- const isEditorReady = ref(false);
1850
- const editorRevision = ref(0);
1851
- const loadTinyMce = async () => {
1852
- const tinymceModule = await import("./tinymce-WPdeGquX.js").then((n) => n.t);
1853
- const tinymce = tinymceModule.default ?? tinymceModule;
1854
- if (typeof globalThis !== "undefined" && !globalThis.tinymce) {
1855
- globalThis.tinymce = tinymce;
1856
- }
1857
- await Promise.all([
1858
- import("./index-Ch9hFG6f.js").then((n) => n.i),
1859
- import("./index-6eLEqodC.js").then((n) => n.i),
1860
- import("./index-G1cAlO5C.js").then((n) => n.i),
1861
- import("./index-CiFpmPug.js").then((n) => n.i),
1862
- import("./index-BPcdR1qv.js").then((n) => n.i),
1863
- import("./index-Cjhk16SP.js").then((n) => n.i),
1864
- import("./index-D7sesyMc.js").then((n) => n.i),
1865
- import("./index-BHTvTOGk.js").then((n) => n.i)
1866
- ]);
1867
- isEditorReady.value = true;
1868
- };
1869
- watch(
1870
- () => props.modelValue,
1871
- (value) => {
1872
- const nextValue = value ?? "";
1873
- if (nextValue === content.value) {
1874
- return;
1875
- }
1876
- content.value = nextValue;
1877
- editorRevision.value += 1;
1878
- }
1879
- );
1880
- const normalizedToolbar = computed(() => Array.isArray(props.toolbar) ? props.toolbar.join(" | ") : props.toolbar);
1881
- const normalizedPlugins = computed(() => Array.isArray(props.plugins) ? [...props.plugins] : props.plugins);
1882
- const editorKey = computed(() => {
1883
- const mode = props.readonly ? "tiny-editor-readonly" : "tiny-editor-editable";
1884
- const menubarKey = props.menubar === void 0 ? "menubar-undefined" : `menubar-${String(props.menubar)}`;
1885
- return `${mode}-${menubarKey}-${editorRevision.value}`;
1886
- });
1887
- const editorInit = computed(() => ({
1888
- height: props.height,
1889
- menubar: props.menubar,
1890
- plugins: normalizedPlugins.value,
1891
- toolbar: normalizedToolbar.value,
1892
- skin: false,
1893
- content_css: false,
1894
- ...props.init
1895
- }));
1896
- onMounted(() => {
1897
- void loadTinyMce();
1898
- });
1899
- const handleEditorInput = (_event, editor) => {
1900
- const nextValue = editor.getContent({ format: props.outputFormat });
1901
- content.value = nextValue;
1902
- emit("update:modelValue", nextValue);
1903
- };
1904
- const handleEditorBlur = (_event, editor) => {
1905
- emit("blur", editor.getContent({ format: props.outputFormat }));
1906
- };
1907
- return (_ctx, _cache) => {
1908
- return openBlock(), createElementBlock("div", { key: editorKey.value }, [
1909
- !isEditorReady.value ? (openBlock(), createElementBlock("div", _hoisted_1$k)) : (openBlock(), createBlock(unref(Editor), {
1910
- key: 1,
1911
- "initial-value": content.value,
1912
- "license-key": __props.licenseKey,
1913
- readonly: __props.readonly,
1914
- "output-format": __props.outputFormat,
1915
- init: editorInit.value,
1916
- onInput: handleEditorInput,
1917
- onBlur: handleEditorBlur
1918
- }, null, 8, ["initial-value", "license-key", "readonly", "output-format", "init"]))
1919
- ]);
1920
- };
1921
- }
1922
- };
1923
- const _hoisted_1$j = ["for"];
1924
- const _hoisted_2$d = {
1925
- key: 1,
1926
- class: "text-xs text-gray-500 mb-1 block break-all"
1927
- };
1928
- const _hoisted_3$9 = {
1929
- key: 16,
1930
- class: "flex items-center mt-2 text-sm text-red-600"
1931
- };
1932
- const defaultFieldClass = "block w-full rounded-lg border border-neutral-200 bg-white px-4 py-3 text-sm text-neutral-950 placeholder:text-neutral-400 shadow-sm transition-all duration-200 focus:border-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50 dark:placeholder:text-neutral-500 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10";
1933
- const _sfc_main$v = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
1934
- __name: "InputGroup",
1935
- props: {
1936
- type: {
1937
- type: String,
1938
- required: true
1939
- },
1940
- label: {
1941
- type: String,
1942
- default: ""
1943
- },
1944
- helperText: {
1945
- type: String,
1946
- default: ""
1947
- },
1948
- name: {
1949
- type: String,
1950
- default: void 0
1951
- },
1952
- errorMessage: {
1953
- type: String,
1954
- default: ""
1955
- },
1956
- modelValue: {
1957
- type: [String, Number, Boolean, Array, null],
1958
- default: ""
1959
- },
1960
- disabled: {
1961
- type: Boolean,
1962
- default: false
1963
- },
1964
- disabledClass: {
1965
- type: String,
1966
- default: "!border-neutral-200 !bg-neutral-100 !text-neutral-500 dark:!border-neutral-800 dark:!bg-neutral-900 dark:!text-neutral-500"
1967
- },
1968
- modelModifiers: {
1969
- type: Object,
1970
- default: () => ({})
1971
- },
1972
- withTimestamp: {
1973
- type: Boolean,
1974
- default: false
1975
- },
1976
- options: {
1977
- type: Array,
1978
- default: () => []
1979
- },
1980
- placeholder: {
1981
- type: String,
1982
- default: ""
1983
- },
1984
- placeholderDisabled: {
1985
- type: Boolean,
1986
- default: false
1987
- },
1988
- softDeleteAware: {
1989
- type: Boolean,
1990
- default: false
1991
- },
1992
- labelKey: {
1993
- type: String,
1994
- default: "name"
1995
- },
1996
- valueKey: {
1997
- type: String,
1998
- default: "id"
1999
- },
2000
- deletedKey: {
2001
- type: String,
2002
- default: "deleted_at"
2003
- },
2004
- optionLabel: {
2005
- type: Function,
2006
- default: null
2007
- },
2008
- baseClass: {
2009
- type: [String, Array, Object],
2010
- default: void 0
2011
- },
2012
- normalTextClass: {
2013
- type: [String, Array, Object],
2014
- default: void 0
2015
- },
2016
- deletedSelectedClass: {
2017
- type: [String, Array, Object],
2018
- default: void 0
2019
- },
2020
- optionClass: {
2021
- type: [String, Array, Object],
2022
- default: void 0
2023
- },
2024
- deletedOptionClass: {
2025
- type: [String, Array, Object],
2026
- default: void 0
2027
- },
2028
- placeholderClass: {
2029
- type: [String, Array, Object],
2030
- default: void 0
2031
- },
2032
- accept: {
2033
- type: String,
2034
- default: void 0
2035
- },
2036
- currentImageUrl: {
2037
- type: String,
2038
- default: ""
2039
- },
2040
- currentLabel: {
2041
- type: String,
2042
- default: "Current logo"
2043
- },
2044
- currentSubtext: {
2045
- type: String,
2046
- default: "Upload a new logo to replace this one"
2047
- },
2048
- height: {
2049
- type: Number,
2050
- default: 300
2051
- },
2052
- menubar: {
2053
- type: [Boolean, String],
2054
- default: false
2055
- },
2056
- toolbar: {
2057
- type: [String, Array],
2058
- default: void 0
2059
- },
2060
- plugins: {
2061
- type: [String, Array],
2062
- default: void 0
2063
- },
2064
- init: {
2065
- type: Object,
2066
- default: void 0
2067
- },
2068
- licenseKey: {
2069
- type: String,
2070
- default: "gpl"
2071
- },
2072
- outputFormat: {
2073
- type: String,
2074
- default: "html"
2075
- }
2076
- },
2077
- emits: ["update:modelValue", "blur"],
2078
- setup(__props, { emit: __emit }) {
2079
- const props = __props;
2080
- const emit = __emit;
2081
- const attrs = useAttrs();
2082
- const updateValue = (value) => emit("update:modelValue", value);
2083
- const hasError = computed(() => Boolean(props.errorMessage));
2084
- const showsInlineChoiceControl = computed(
2085
- () => isCheckboxSingleType.value || isRadioSingleType.value || isToggleSingleType.value
2086
- );
2087
- const fieldId = computed(() => {
2088
- const id = attrs.id;
2089
- return typeof id === "string" && id !== "" ? id : void 0;
2090
- });
2091
- const textLikeTypes = [
2092
- "text",
2093
- "email",
2094
- "password",
2095
- "number",
2096
- "time",
2097
- "url",
2098
- "tel",
2099
- "search",
2100
- "month",
2101
- "week",
2102
- "color"
2103
- ];
2104
- const noComponentTypes = [];
2105
- const isImageType = computed(() => props.type === "image");
2106
- const isNotationType = computed(() => props.type === "notation");
2107
- const isCheckboxSingleType = computed(() => props.type === "checkbox-input");
2108
- const isRadioSingleType = computed(() => props.type === "radio-input");
2109
- const isToggleSingleType = computed(() => props.type === "toggle-input");
2110
- const isCheckboxType = computed(() => props.type === "checkbox");
2111
- const isRadioType = computed(() => props.type === "radio");
2112
- const isDateType = computed(
2113
- () => props.type === "date" || props.type === "datetime-local"
2114
- );
2115
- const isTextareaType = computed(() => props.type === "textarea");
2116
- const isTinyEditorType = computed(() => props.type === "tiny-editor");
2117
- const isSelectType = computed(() => props.type === "select");
2118
- const isTextLikeType = computed(() => textLikeTypes.includes(props.type));
2119
- const isNoComponentType = computed(() => noComponentTypes.includes(props.type));
2120
- const textInputBindings = computed(() => ({
2121
- ...attrs,
2122
- class: [defaultFieldClass, attrs.class],
2123
- type: props.type,
2124
- name: props.name,
2125
- modelValue: props.modelValue,
2126
- disabled: props.disabled,
2127
- disabledClass: props.disabledClass
2128
- }));
2129
- const textAreaBindings = computed(() => ({
2130
- ...attrs,
2131
- class: [defaultFieldClass, attrs.class],
2132
- name: props.name,
2133
- modelValue: props.modelValue,
2134
- disabled: props.disabled,
2135
- disabledClass: props.disabledClass
2136
- }));
2137
- const dateBindings = computed(() => ({
2138
- ...attrs,
2139
- class: [defaultFieldClass, attrs.class],
2140
- name: props.name,
2141
- modelValue: props.modelValue,
2142
- withTimestamp: props.type === "datetime-local" || props.withTimestamp,
2143
- disabled: props.disabled,
2144
- disabledClass: props.disabledClass
2145
- }));
2146
- const selectBindings = computed(() => {
2147
- const inputProps = {
2148
- ...attrs,
2149
- class: [defaultFieldClass, attrs.class],
2150
- name: props.name,
2151
- modelValue: props.modelValue,
2152
- modelModifiers: props.modelModifiers,
2153
- options: props.options,
2154
- placeholder: props.placeholder,
2155
- placeholderDisabled: props.placeholderDisabled,
2156
- disabled: props.disabled,
2157
- softDeleteAware: props.softDeleteAware,
2158
- labelKey: props.labelKey,
2159
- valueKey: props.valueKey,
2160
- deletedKey: props.deletedKey,
2161
- optionLabel: props.optionLabel
2162
- };
2163
- if (props.baseClass !== void 0) inputProps.baseClass = props.baseClass;
2164
- if (props.normalTextClass !== void 0)
2165
- inputProps.normalTextClass = props.normalTextClass;
2166
- if (props.deletedSelectedClass !== void 0)
2167
- inputProps.deletedSelectedClass = props.deletedSelectedClass;
2168
- if (props.optionClass !== void 0)
2169
- inputProps.optionClass = props.optionClass;
2170
- if (props.deletedOptionClass !== void 0)
2171
- inputProps.deletedOptionClass = props.deletedOptionClass;
2172
- if (props.placeholderClass !== void 0)
2173
- inputProps.placeholderClass = props.placeholderClass;
2174
- return inputProps;
2175
- });
2176
- const notationBindings = computed(() => ({
2177
- ...attrs,
2178
- name: props.name,
2179
- modelValue: props.modelValue,
2180
- options: props.options,
2181
- disabled: props.disabled
2182
- }));
2183
- const checkboxBindings = computed(() => ({
2184
- ...attrs,
2185
- name: props.name,
2186
- modelValue: props.modelValue,
2187
- options: props.options,
2188
- disabled: props.disabled
2189
- }));
2190
- const radioBindings = computed(() => ({
2191
- ...attrs,
2192
- modelValue: props.modelValue,
2193
- options: props.options,
2194
- name: props.name ?? attrs.name,
2195
- disabled: props.disabled
2196
- }));
2197
- const checkboxSingleBindings = computed(() => ({
2198
- ...attrs,
2199
- name: props.name,
2200
- modelValue: props.modelValue,
2201
- label: props.label || attrs.label || "",
2202
- disabled: props.disabled
2203
- }));
2204
- const radioSingleBindings = computed(() => ({
2205
- ...attrs,
2206
- modelValue: props.modelValue,
2207
- label: props.label || attrs.label || "",
2208
- name: props.name ?? attrs.name,
2209
- disabled: props.disabled
2210
- }));
2211
- const toggleSingleBindings = computed(() => ({
2212
- ...attrs,
2213
- name: props.name,
2214
- modelValue: props.modelValue,
2215
- label: props.label || attrs.label || "",
2216
- disabled: props.disabled
2217
- }));
2218
- const imageBindings = computed(() => {
2219
- return {
2220
- ...attrs,
2221
- accept: props.accept ?? attrs.accept ?? "image/*",
2222
- modelValue: props.modelValue,
2223
- currentImageUrl: props.currentImageUrl,
2224
- currentLabel: props.currentLabel,
2225
- currentSubtext: props.currentSubtext
2226
- };
2227
- });
2228
- const tinyEditorBindings = computed(() => {
2229
- const inputProps = {
2230
- ...attrs,
2231
- modelValue: typeof props.modelValue === "string" ? props.modelValue : "",
2232
- readonly: props.disabled,
2233
- height: props.height,
2234
- menubar: props.menubar,
2235
- licenseKey: props.licenseKey,
2236
- outputFormat: props.outputFormat
2237
- };
2238
- if (props.toolbar !== void 0) inputProps.toolbar = props.toolbar;
2239
- if (props.plugins !== void 0) inputProps.plugins = props.plugins;
2240
- if (props.init !== void 0) inputProps.init = props.init;
2241
- return inputProps;
2242
- });
2243
- return (_ctx, _cache) => {
2244
- return openBlock(), createElementBlock("div", null, [
2245
- __props.label && !showsInlineChoiceControl.value ? (openBlock(), createElementBlock("label", {
2246
- key: 0,
2247
- for: fieldId.value,
2248
- class: "text-base font-semibold text-gray-900 dark:text-gray-50 mb-1 block"
2249
- }, toDisplayString(__props.label), 9, _hoisted_1$j)) : createCommentVNode("", true),
2250
- __props.helperText && !showsInlineChoiceControl.value ? (openBlock(), createElementBlock("span", _hoisted_2$d, toDisplayString(__props.helperText), 1)) : createCommentVNode("", true),
2251
- isTextareaType.value ? (openBlock(), createBlock(_sfc_main$F, mergeProps({ key: 2 }, textAreaBindings.value, {
2252
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event)),
2253
- onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event))
2254
- }), null, 16)) : isTinyEditorType.value ? (openBlock(), createBlock(_sfc_main$w, mergeProps({ key: 3 }, tinyEditorBindings.value, {
2255
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => emit("update:modelValue", $event)),
2256
- onBlur: _cache[3] || (_cache[3] = ($event) => emit("blur", $event))
2257
- }), null, 16)) : isSelectType.value ? (openBlock(), createBlock(_sfc_main$D, mergeProps({ key: 4 }, selectBindings.value, {
2258
- "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => emit("update:modelValue", $event)),
2259
- onBlur: _cache[5] || (_cache[5] = ($event) => emit("blur", $event))
2260
- }), null, 16)) : isDateType.value ? (openBlock(), createBlock(DateInput, mergeProps({ key: 5 }, dateBindings.value, {
2261
- "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => emit("update:modelValue", $event)),
2262
- onBlur: _cache[7] || (_cache[7] = ($event) => emit("blur", $event))
2263
- }), null, 16)) : isTextLikeType.value ? (openBlock(), createBlock(_sfc_main$G, mergeProps({ key: 6 }, textInputBindings.value, {
2264
- "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => emit("update:modelValue", $event)),
2265
- onBlur: _cache[9] || (_cache[9] = ($event) => emit("blur", $event))
2266
- }), null, 16)) : isImageType.value ? (openBlock(), createBlock(_sfc_main$B, mergeProps({ key: 7 }, imageBindings.value, {
2267
- "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => emit("update:modelValue", $event)),
2268
- onBlur: _cache[11] || (_cache[11] = ($event) => emit("blur", $event))
2269
- }), null, 16)) : isCheckboxSingleType.value ? (openBlock(), createBlock(_sfc_main$H, mergeProps({ key: 8 }, checkboxSingleBindings.value, {
2270
- "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => emit("update:modelValue", $event)),
2271
- onBlur: _cache[13] || (_cache[13] = ($event) => emit("blur", $event))
2272
- }), null, 16)) : isRadioSingleType.value ? (openBlock(), createBlock(_sfc_main$z, mergeProps({ key: 9 }, radioSingleBindings.value, {
2273
- "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => emit("update:modelValue", $event)),
2274
- onBlur: _cache[15] || (_cache[15] = ($event) => emit("blur", $event))
2275
- }), null, 16)) : isToggleSingleType.value ? (openBlock(), createBlock(_sfc_main$y, mergeProps({ key: 10 }, toggleSingleBindings.value, {
2276
- "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => emit("update:modelValue", $event)),
2277
- onBlur: _cache[17] || (_cache[17] = ($event) => emit("blur", $event))
2278
- }), null, 16)) : isNotationType.value ? (openBlock(), createBlock(_sfc_main$A, mergeProps({ key: 11 }, notationBindings.value, {
2279
- "onUpdate:modelValue": _cache[18] || (_cache[18] = ($event) => emit("update:modelValue", $event)),
2280
- onBlur: _cache[19] || (_cache[19] = ($event) => emit("blur", $event))
2281
- }), null, 16)) : isCheckboxType.value ? (openBlock(), createBlock(_sfc_main$u, mergeProps({ key: 12 }, checkboxBindings.value, {
2282
- "onUpdate:modelValue": _cache[20] || (_cache[20] = ($event) => emit("update:modelValue", $event)),
2283
- onBlur: _cache[21] || (_cache[21] = ($event) => emit("blur", $event))
2284
- }), null, 16)) : isRadioType.value ? (openBlock(), createBlock(_sfc_main$x, mergeProps({ key: 13 }, radioBindings.value, {
2285
- "onUpdate:modelValue": _cache[22] || (_cache[22] = ($event) => emit("update:modelValue", $event)),
2286
- onBlur: _cache[23] || (_cache[23] = ($event) => emit("blur", $event))
2287
- }), null, 16)) : isNoComponentType.value ? renderSlot(_ctx.$slots, "unsupported-type", {
2288
- key: 14,
2289
- type: __props.type,
2290
- modelValue: __props.modelValue,
2291
- updateValue,
2292
- attrs: unref(attrs)
2293
- }) : renderSlot(_ctx.$slots, "unsupported-type", {
2294
- key: 15,
2295
- type: __props.type,
2296
- modelValue: __props.modelValue,
2297
- updateValue,
2298
- attrs: unref(attrs)
2299
- }),
2300
- hasError.value ? (openBlock(), createElementBlock("div", _hoisted_3$9, [
2301
- createVNode(unref(ExclamationCircleIcon), { class: "mr-1 h-4 w-4 flex-shrink-0" }),
2302
- createElementVNode("span", null, toDisplayString(__props.errorMessage), 1)
2303
- ])) : createCommentVNode("", true)
2304
- ]);
2305
- };
2306
- }
2307
- });
2308
- const _hoisted_1$i = { class: "flex flex-wrap gap-3" };
2309
- const _sfc_main$u = {
2310
- __name: "CheckboxMultipleInput",
2311
- props: {
2312
- modelValue: {
2313
- type: Array,
2314
- default: () => []
2315
- },
2316
- options: {
2317
- type: Array,
2318
- default: () => []
2319
- },
2320
- name: {
2321
- type: String,
2322
- default: void 0
2323
- },
2324
- disabled: {
2325
- type: Boolean,
2326
- default: false
2327
- }
2328
- },
2329
- emits: ["update:modelValue"],
2330
- setup(__props, { emit: __emit }) {
2331
- const emit = __emit;
2332
- const props = __props;
2333
- const normalizedOptions = computed(() => {
2334
- return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
2335
- });
2336
- const isChecked = (option) => {
2337
- return Array.isArray(props.modelValue) && props.modelValue.includes(option);
2338
- };
2339
- const updateSelection = (option, checked) => {
2340
- const nextSelection = Array.isArray(props.modelValue) ? [...props.modelValue] : [];
2341
- const index = nextSelection.indexOf(option);
2342
- if (checked && index === -1) {
2343
- nextSelection.push(option);
2344
- } else if (!checked && index !== -1) {
2345
- nextSelection.splice(index, 1);
2346
- }
2347
- emit("update:modelValue", nextSelection);
2348
- };
2349
- return (_ctx, _cache) => {
2350
- return openBlock(), createElementBlock("div", _hoisted_1$i, [
2351
- (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
2352
- return openBlock(), createBlock(_sfc_main$v, {
2353
- key: `checkbox-${option}`,
2354
- type: "checkbox-input",
2355
- name: __props.name,
2356
- "model-value": isChecked(option),
2357
- value: true,
2358
- "unchecked-value": false,
2359
- label: option,
2360
- disabled: __props.disabled,
2361
- "onUpdate:modelValue": (checked) => updateSelection(option, checked)
2362
- }, null, 8, ["name", "model-value", "label", "disabled", "onUpdate:modelValue"]);
2363
- }), 128))
2364
- ]);
2365
- };
2366
- }
2367
- };
2368
- const _sfc_main$t = {
2369
- __name: "Modal",
2370
- props: {
2371
- show: {
2372
- type: Boolean,
2373
- default: false
2374
- },
2375
- maxWidth: {
2376
- type: String,
2377
- default: "2xl"
2378
- },
2379
- closeable: {
2380
- type: Boolean,
2381
- default: true
2382
- },
2383
- position: {
2384
- type: String,
2385
- default: "center",
2386
- validator: (value) => ["top", "center", "bottom"].includes(value)
2387
- }
2388
- },
2389
- emits: ["close"],
2390
- setup(__props, { emit: __emit }) {
2391
- const props = __props;
2392
- const emit = __emit;
2393
- const dialog = ref();
2394
- const showSlot = ref(props.show);
2395
- const openModal = () => {
2396
- document.body.style.overflow = "hidden";
2397
- showSlot.value = true;
2398
- dialog.value?.showModal();
2399
- };
2400
- const closeModal = () => {
2401
- document.body.style.overflow = null;
2402
- setTimeout(() => {
2403
- dialog.value?.close();
2404
- showSlot.value = false;
2405
- }, 200);
2406
- };
2407
- watch(() => props.show, () => {
2408
- if (props.show) {
2409
- openModal();
2410
- } else {
2411
- closeModal();
2412
- }
2413
- });
2414
- onMounted(() => {
2415
- if (props.show) {
2416
- openModal();
2417
- }
2418
- });
2419
- const close = () => {
2420
- if (props.closeable) {
2421
- emit("close");
2422
- }
2423
- };
2424
- const closeOnEscape = (e) => {
2425
- if (e.key === "Escape") {
2426
- e.preventDefault();
2427
- if (props.show) {
2428
- close();
2429
- }
2430
- }
2431
- };
2432
- onMounted(() => document.addEventListener("keydown", closeOnEscape));
2433
- onUnmounted(() => {
2434
- document.removeEventListener("keydown", closeOnEscape);
2435
- document.body.style.overflow = null;
2436
- });
2437
- const maxWidthClass = computed(() => {
2438
- return {
2439
- "sm": "sm:max-w-sm",
2440
- "md": "sm:max-w-md",
2441
- "lg": "sm:max-w-lg",
2442
- "xl": "sm:max-w-xl",
2443
- "2xl": "sm:max-w-2xl"
2444
- }[props.maxWidth];
2445
- });
2446
- const positionClasses = computed(() => {
2447
- switch (props.position) {
2448
- case "top":
2449
- return "flex-col items-center pt-16";
2450
- case "bottom":
2451
- return "flex-col items-center justify-end pb-16";
2452
- default:
2453
- return "items-center justify-center";
2454
- }
2455
- });
2456
- return (_ctx, _cache) => {
2457
- return openBlock(), createElementBlock("dialog", {
2458
- class: "z-50 m-0 min-h-full min-w-full overflow-y-auto bg-transparent backdrop:bg-transparent",
2459
- ref_key: "dialog",
2460
- ref: dialog
2461
- }, [
2462
- createElementVNode("div", {
2463
- class: normalizeClass(["fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50 flex", positionClasses.value])
2464
- }, [
2465
- createVNode(Transition, {
2466
- "enter-active-class": "ease-out duration-300",
2467
- "enter-from-class": "opacity-0",
2468
- "enter-to-class": "opacity-100",
2469
- "leave-active-class": "ease-in duration-200",
2470
- "leave-from-class": "opacity-100",
2471
- "leave-to-class": "opacity-0"
2472
- }, {
2473
- default: withCtx(() => [
2474
- withDirectives(createElementVNode("div", {
2475
- class: "fixed inset-0 z-40 transform transition-all",
2476
- onClick: close
2477
- }, [..._cache[0] || (_cache[0] = [
2478
- createElementVNode("div", { class: "absolute inset-0 bg-neutral-950/55 backdrop-blur-[2px]" }, null, -1)
2479
- ])], 512), [
2480
- [vShow, __props.show]
2481
- ])
2482
- ]),
2483
- _: 1
2484
- }),
2485
- createVNode(Transition, {
2486
- "enter-active-class": "ease-out duration-300",
2487
- "enter-from-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
2488
- "enter-to-class": "opacity-100 translate-y-0 sm:scale-100",
2489
- "leave-active-class": "ease-in duration-200",
2490
- "leave-from-class": "opacity-100 translate-y-0 sm:scale-100",
2491
- "leave-to-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
2492
- }, {
2493
- default: withCtx(() => [
2494
- withDirectives(createElementVNode("div", {
2495
- class: normalizeClass(["relative z-50 mb-6 overflow-hidden rounded-lg border border-neutral-200 bg-white shadow-xl transform transition-all dark:border-neutral-800 dark:bg-neutral-950 sm:mx-auto sm:w-full", maxWidthClass.value])
2496
- }, [
2497
- showSlot.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
2498
- ], 2), [
2499
- [vShow, __props.show]
2500
- ])
2501
- ]),
2502
- _: 3
2503
- })
2504
- ], 2)
2505
- ], 512);
2506
- };
2507
- }
2508
- };
2509
- const _hoisted_1$h = { class: "bg-white px-4 pb-4 pt-5 dark:bg-neutral-950 sm:p-6 sm:pb-4" };
2510
- const _hoisted_2$c = { class: "sm:flex sm:items-start" };
2511
- const _hoisted_3$8 = { class: "mx-auto flex size-12 shrink-0 items-center justify-center rounded-full bg-red-100 dark:bg-red-950/60 sm:mx-0 sm:size-10" };
2512
- const _hoisted_4$6 = { class: "mt-3 text-center sm:mt-0 sm:ms-4 sm:text-start" };
2513
- const _hoisted_5$4 = { class: "text-lg font-medium text-neutral-950 dark:text-neutral-50" };
2514
- const _hoisted_6$4 = { class: "mt-4 text-sm text-neutral-600 dark:text-neutral-200" };
2515
- const _hoisted_7$4 = { class: "flex flex-col-reverse gap-4 border-t border-neutral-200 bg-neutral-50 px-6 py-4 text-end dark:border-neutral-800 dark:bg-neutral-900/60 lg:flex-row lg:justify-end lg:gap-0" };
2516
- const _sfc_main$s = {
2517
- __name: "ConfirmationModal",
2518
- props: {
2519
- show: {
2520
- type: Boolean,
2521
- default: false
2522
- },
2523
- maxWidth: {
2524
- type: String,
2525
- default: "2xl"
2526
- },
2527
- closeable: {
2528
- type: Boolean,
2529
- default: true
2530
- },
2531
- position: {
2532
- type: String,
2533
- default: "center",
2534
- validator: (value) => ["top", "center", "bottom"].includes(value)
2535
- }
2536
- },
2537
- emits: ["close"],
2538
- setup(__props, { emit: __emit }) {
2539
- const emit = __emit;
2540
- const close = () => {
2541
- emit("close");
2542
- };
2543
- return (_ctx, _cache) => {
2544
- return openBlock(), createBlock(_sfc_main$t, {
2545
- show: __props.show,
2546
- "max-width": __props.maxWidth,
2547
- closeable: __props.closeable,
2548
- position: __props.position,
2549
- onClose: close
2550
- }, {
2551
- default: withCtx(() => [
2552
- createElementVNode("div", _hoisted_1$h, [
2553
- createElementVNode("div", _hoisted_2$c, [
2554
- createElementVNode("div", _hoisted_3$8, [
2555
- createVNode(unref(ExclamationTriangleIcon), { class: "size-6 text-red-600 dark:text-neutral-100" })
2556
- ]),
2557
- createElementVNode("div", _hoisted_4$6, [
2558
- createElementVNode("h3", _hoisted_5$4, [
2559
- renderSlot(_ctx.$slots, "title")
2560
- ]),
2561
- createElementVNode("div", _hoisted_6$4, [
2562
- renderSlot(_ctx.$slots, "content")
2563
- ])
2564
- ])
2565
- ])
2566
- ]),
2567
- createElementVNode("div", _hoisted_7$4, [
2568
- renderSlot(_ctx.$slots, "footer")
2569
- ])
2570
- ]),
2571
- _: 3
2572
- }, 8, ["show", "max-width", "closeable", "position"]);
2573
- };
2574
- }
2575
- };
2576
- const _hoisted_1$g = { class: "px-6 py-4" };
2577
- const _hoisted_2$b = { class: "text-lg font-medium text-neutral-950 dark:text-neutral-50" };
2578
- const _hoisted_3$7 = { class: "mt-4 text-sm text-neutral-600 dark:text-neutral-200" };
2579
- const _hoisted_4$5 = { class: "flex flex-row justify-end border-t border-neutral-200 bg-neutral-50 px-6 py-4 text-end dark:border-neutral-800 dark:bg-neutral-900/60" };
2580
- const _sfc_main$r = {
2581
- __name: "DialogModal",
2582
- props: {
2583
- show: {
2584
- type: Boolean,
2585
- default: false
2586
- },
2587
- maxWidth: {
2588
- type: String,
2589
- default: "2xl"
2590
- },
2591
- closeable: {
2592
- type: Boolean,
2593
- default: true
2594
- }
2595
- },
2596
- emits: ["close"],
2597
- setup(__props, { emit: __emit }) {
2598
- const emit = __emit;
2599
- const close = () => {
2600
- emit("close");
2601
- };
2602
- return (_ctx, _cache) => {
2603
- return openBlock(), createBlock(_sfc_main$t, {
2604
- show: __props.show,
2605
- "max-width": __props.maxWidth,
2606
- closeable: __props.closeable,
2607
- onClose: close
2608
- }, {
2609
- default: withCtx(() => [
2610
- createElementVNode("div", _hoisted_1$g, [
2611
- createElementVNode("div", _hoisted_2$b, [
2612
- renderSlot(_ctx.$slots, "title")
2613
- ]),
2614
- createElementVNode("div", _hoisted_3$7, [
2615
- renderSlot(_ctx.$slots, "content")
2616
- ])
2617
- ]),
2618
- createElementVNode("div", _hoisted_4$5, [
2619
- renderSlot(_ctx.$slots, "footer")
2620
- ])
2621
- ]),
2622
- _: 3
2623
- }, 8, ["show", "max-width", "closeable"]);
2624
- };
2625
- }
2626
- };
2627
- const _hoisted_1$f = { class: "relative inline-block w-fit" };
2628
- const _sfc_main$q = {
2629
- __name: "Dropdown",
2630
- props: {
2631
- align: {
2632
- type: String,
2633
- default: "right"
2634
- },
2635
- width: {
2636
- type: String,
2637
- default: "48"
2638
- },
2639
- contentClasses: {
2640
- type: Array,
2641
- default: () => ["py-1", "bg-white", "dark:bg-neutral-950"]
2642
- }
2643
- },
2644
- setup(__props) {
2645
- const props = __props;
2646
- const open = ref(false);
2647
- const triggerRef = ref(null);
2648
- const menuRef = ref(null);
2649
- const menuStyle = ref({
2650
- position: "fixed",
2651
- left: "0px",
2652
- top: "0px",
2653
- visibility: "hidden"
2654
- });
2655
- const menuOriginClass = ref("ltr:origin-top-right rtl:origin-top-left");
2656
- let revealFrame = null;
2657
- const closeOnEscape = (e) => {
2658
- if (open.value && e.key === "Escape") {
2659
- open.value = false;
2660
- }
2661
- };
2662
- const closeOnOutsideClick = (event) => {
2663
- if (!open.value) {
2664
- return;
2665
- }
2666
- const target = event.target;
2667
- if (!(target instanceof Node)) {
2668
- return;
2669
- }
2670
- if (triggerRef.value?.contains(target) || menuRef.value?.contains(target)) {
2671
- return;
2672
- }
2673
- open.value = false;
2674
- };
2675
- const setOriginClass = (alignRight, openUpward) => {
2676
- const horizontal = alignRight ? "ltr:origin-top-right rtl:origin-top-left" : "ltr:origin-top-left rtl:origin-top-right";
2677
- menuOriginClass.value = `${horizontal} ${openUpward ? "origin-bottom" : "origin-top"}`;
2678
- };
2679
- const widthClass = computed(() => {
2680
- return {
2681
- "48": "w-48"
2682
- }[props.width.toString()];
2683
- });
2684
- const alignmentClasses = computed(() => {
2685
- return menuOriginClass.value;
2686
- });
2687
- const updateDropdownPosition = () => {
2688
- if (!triggerRef.value || !menuRef.value) {
2689
- return;
2690
- }
2691
- const rect = triggerRef.value.getBoundingClientRect();
2692
- const viewportWidth = window.innerWidth;
2693
- const viewportHeight = window.innerHeight;
2694
- const menuWidth = menuRef.value.offsetWidth;
2695
- const menuHeight = menuRef.value.offsetHeight;
2696
- const gap = 8;
2697
- const spaceLeft = rect.left - gap;
2698
- const spaceRight = viewportWidth - rect.right - gap;
2699
- let alignRight = props.align === "right";
2700
- if (alignRight && rect.right + menuWidth > viewportWidth - gap && spaceLeft > spaceRight) {
2701
- alignRight = false;
2702
- } else if (!alignRight && rect.left + menuWidth > viewportWidth - gap && spaceRight > spaceLeft) {
2703
- alignRight = true;
2704
- }
2705
- let left = alignRight ? rect.right - menuWidth : rect.left;
2706
- left = Math.max(gap, Math.min(left, viewportWidth - menuWidth - gap));
2707
- const spaceBelow = viewportHeight - rect.bottom - gap;
2708
- const spaceAbove = rect.top - gap;
2709
- const openUpward = spaceBelow < menuHeight && spaceAbove > spaceBelow;
2710
- menuStyle.value = {
2711
- position: "fixed",
2712
- left: `${left}px`,
2713
- ...openUpward ? { bottom: `${viewportHeight - rect.top + gap}px` } : { top: `${rect.bottom + gap}px` },
2714
- zIndex: "9999",
2715
- maxHeight: `${Math.max(Math.min(openUpward ? spaceAbove : spaceBelow, 320), 160)}px`
2716
- };
2717
- setOriginClass(alignRight, openUpward);
2718
- };
2719
- const refreshPosition = async () => {
2720
- if (!open.value) {
2721
- return;
2722
- }
2723
- if (revealFrame !== null) {
2724
- cancelAnimationFrame(revealFrame);
2725
- revealFrame = null;
2726
- }
2727
- menuStyle.value = {
2728
- ...menuStyle.value,
2729
- visibility: "hidden"
2730
- };
2731
- await nextTick();
2732
- updateDropdownPosition();
2733
- revealFrame = requestAnimationFrame(() => {
2734
- if (!open.value) {
2735
- return;
2736
- }
2737
- menuStyle.value = {
2738
- ...menuStyle.value,
2739
- visibility: "visible"
2740
- };
2741
- });
2742
- };
2743
- const handleViewportChange = () => {
2744
- if (open.value) {
2745
- updateDropdownPosition();
2746
- }
2747
- };
2748
- watch(open, (value) => {
2749
- if (value) {
2750
- refreshPosition();
2751
- }
2752
- });
2753
- onMounted(() => {
2754
- document.addEventListener("keydown", closeOnEscape);
2755
- document.addEventListener("pointerdown", closeOnOutsideClick, true);
2756
- window.addEventListener("resize", handleViewportChange);
2757
- window.addEventListener("scroll", handleViewportChange, true);
2758
- });
2759
- onUnmounted(() => {
2760
- if (revealFrame !== null) {
2761
- cancelAnimationFrame(revealFrame);
2762
- }
2763
- document.removeEventListener("keydown", closeOnEscape);
2764
- document.removeEventListener("pointerdown", closeOnOutsideClick, true);
2765
- window.removeEventListener("resize", handleViewportChange);
2766
- window.removeEventListener("scroll", handleViewportChange, true);
2767
- });
2768
- return (_ctx, _cache) => {
2769
- return openBlock(), createElementBlock("div", _hoisted_1$f, [
2770
- createElementVNode("div", {
2771
- ref_key: "triggerRef",
2772
- ref: triggerRef,
2773
- onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
2774
- }, [
2775
- renderSlot(_ctx.$slots, "trigger", { open: open.value })
2776
- ], 512),
2777
- (openBlock(), createBlock(Teleport, { to: "body" }, [
2778
- createVNode(Transition, {
2779
- "enter-active-class": "transition-opacity duration-150 ease-out",
2780
- "enter-from-class": "opacity-0",
2781
- "enter-to-class": "opacity-100",
2782
- "leave-active-class": "transition-opacity duration-100 ease-in",
2783
- "leave-from-class": "opacity-100",
2784
- "leave-to-class": "opacity-0"
2785
- }, {
2786
- default: withCtx(() => [
2787
- open.value ? (openBlock(), createElementBlock("div", {
2788
- key: 0,
2789
- ref_key: "menuRef",
2790
- ref: menuRef,
2791
- class: normalizeClass(["z-50 rounded-xl shadow-xl shadow-neutral-950/10 dark:shadow-black/30", [widthClass.value, alignmentClasses.value]]),
2792
- style: normalizeStyle(menuStyle.value),
2793
- onClick: _cache[1] || (_cache[1] = ($event) => open.value = false)
2794
- }, [
2795
- createElementVNode("div", {
2796
- class: normalizeClass(["rounded-xl border border-neutral-200 bg-white/95 backdrop-blur-sm dark:border-neutral-800 dark:bg-neutral-950/95", __props.contentClasses])
2797
- }, [
2798
- renderSlot(_ctx.$slots, "content")
2799
- ], 2)
2800
- ], 6)) : createCommentVNode("", true)
2801
- ]),
2802
- _: 3
2803
- })
2804
- ]))
2805
- ]);
2806
- };
2807
- }
2808
- };
2809
- const _hoisted_1$e = {
2810
- key: 0,
2811
- type: "submit",
2812
- class: "block w-full px-4 py-2 text-start text-sm leading-5 text-neutral-700 transition duration-150 ease-in-out hover:bg-neutral-100 focus:bg-neutral-100 focus:outline-none dark:text-neutral-100 dark:hover:bg-neutral-900 dark:focus:bg-neutral-900"
2813
- };
2814
- const _hoisted_2$a = ["href"];
2815
- const _sfc_main$p = {
2816
- __name: "DropdownLink",
2817
- props: {
2818
- href: String,
2819
- as: String
2820
- },
2821
- setup(__props) {
2822
- return (_ctx, _cache) => {
2823
- return openBlock(), createElementBlock("div", null, [
2824
- __props.as == "button" ? (openBlock(), createElementBlock("button", _hoisted_1$e, [
2825
- renderSlot(_ctx.$slots, "default")
2826
- ])) : __props.as == "a" ? (openBlock(), createElementBlock("a", {
2827
- key: 1,
2828
- href: __props.href,
2829
- class: "block px-4 py-2 text-sm leading-5 text-neutral-700 transition duration-150 ease-in-out hover:bg-neutral-100 focus:bg-neutral-100 focus:outline-none dark:text-neutral-100 dark:hover:bg-neutral-900 dark:focus:bg-neutral-900"
2830
- }, [
2831
- renderSlot(_ctx.$slots, "default")
2832
- ], 8, _hoisted_2$a)) : (openBlock(), createBlock(unref(Link), {
2833
- key: 2,
2834
- href: __props.href,
2835
- class: "block px-4 py-2 text-sm leading-5 text-neutral-700 transition duration-150 ease-in-out hover:bg-neutral-100 focus:bg-neutral-100 focus:outline-none dark:text-neutral-100 dark:hover:bg-neutral-900 dark:focus:bg-neutral-900"
2836
- }, {
2837
- default: withCtx(() => [
2838
- renderSlot(_ctx.$slots, "default")
2839
- ]),
2840
- _: 3
2841
- }, 8, ["href"]))
2842
- ]);
2843
- };
2844
- }
2845
- };
2846
- const _hoisted_1$d = { class: "md:grid md:grid-cols-3 md:gap-6" };
2847
- const _hoisted_2$9 = { class: "mt-5 md:col-span-2 md:mt-0" };
2848
- const _hoisted_3$6 = { class: "grid grid-cols-6 gap-6" };
2849
- const _hoisted_4$4 = {
2850
- key: 0,
2851
- class: "flex items-center justify-start rounded-b-lg border border-t-0 border-neutral-200 bg-neutral-50 px-3 pb-6 text-end dark:border-neutral-800 dark:bg-neutral-900/60 sm:rounded-bl-md sm:rounded-br-md"
2852
- };
2853
- const _sfc_main$o = {
2854
- __name: "FormSection",
2855
- emits: ["submitted"],
2856
- setup(__props) {
2857
- const hasActions = computed(() => !!useSlots().actions);
2858
- return (_ctx, _cache) => {
2859
- return openBlock(), createElementBlock("div", _hoisted_1$d, [
2860
- createVNode(SectionTitle, null, {
2861
- title: withCtx(() => [
2862
- renderSlot(_ctx.$slots, "title")
2863
- ]),
2864
- description: withCtx(() => [
2865
- renderSlot(_ctx.$slots, "description")
2866
- ]),
2867
- _: 3
2868
- }),
2869
- createElementVNode("div", _hoisted_2$9, [
2870
- createElementVNode("form", {
2871
- onSubmit: _cache[0] || (_cache[0] = withModifiers(($event) => _ctx.$emit("submitted"), ["prevent"]))
2872
- }, [
2873
- createElementVNode("div", {
2874
- class: normalizeClass(["rounded-lg border border-neutral-200 bg-white px-4 py-5 shadow-sm dark:border-neutral-800 dark:bg-neutral-950 sm:p-6", hasActions.value ? "sm:rounded-tl-md sm:rounded-tr-md" : "sm:rounded-md"])
2875
- }, [
2876
- createElementVNode("div", _hoisted_3$6, [
2877
- renderSlot(_ctx.$slots, "form")
2878
- ])
2879
- ], 2),
2880
- hasActions.value ? (openBlock(), createElementBlock("div", _hoisted_4$4, [
2881
- renderSlot(_ctx.$slots, "actions")
2882
- ])) : createCommentVNode("", true)
2883
- ], 32)
2884
- ])
2885
- ]);
2886
- };
2887
- }
2888
- };
2889
- const _hoisted_1$c = { class: "text-sm text-red-600 dark:text-neutral-100" };
2890
- const _sfc_main$n = {
2891
- __name: "InputError",
2892
- props: {
2893
- message: String
2894
- },
2895
- setup(__props) {
2896
- return (_ctx, _cache) => {
2897
- return withDirectives((openBlock(), createElementBlock("div", null, [
2898
- createElementVNode("p", _hoisted_1$c, toDisplayString(__props.message), 1)
2899
- ], 512)), [
2900
- [vShow, __props.message]
2901
- ]);
2902
- };
2903
- }
2904
- };
2905
- const _hoisted_1$b = { class: "block text-sm font-medium text-neutral-700 dark:text-neutral-100" };
2906
- const _hoisted_2$8 = { key: 0 };
2907
- const _hoisted_3$5 = { key: 1 };
2908
- const _sfc_main$m = {
2909
- __name: "InputLabel",
2910
- props: {
2911
- value: String
2912
- },
2913
- setup(__props) {
2914
- return (_ctx, _cache) => {
2915
- return openBlock(), createElementBlock("label", _hoisted_1$b, [
2916
- __props.value ? (openBlock(), createElementBlock("span", _hoisted_2$8, toDisplayString(__props.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_3$5, [
2917
- renderSlot(_ctx.$slots, "default")
2918
- ]))
2919
- ]);
2920
- };
2921
- }
2922
- };
2923
- const _hoisted_1$a = ["href", "title", "target", "rel"];
2924
- const _sfc_main$l = /* @__PURE__ */ Object.assign({
2925
- inheritAttrs: false
2926
- }, {
2927
- __name: "LinkButton",
2928
- props: {
2929
- href: {
2930
- type: String,
2931
- required: true
2932
- },
2933
- title: {
2934
- type: String,
2935
- default: null
2936
- },
2937
- external: {
2938
- type: Boolean,
2939
- default: false
2940
- },
2941
- target: {
2942
- type: String,
2943
- default: null
2944
- },
2945
- rel: {
2946
- type: String,
2947
- default: null
2948
- },
2949
- variant: {
2950
- type: String,
2951
- default: "primary"
2952
- }
2953
- },
2954
- setup(__props) {
2955
- const attrs = useAttrs();
2956
- const props = __props;
2957
- const variantClasses = {
2958
- primary: "bg-neutral-900 text-neutral-50 hover:bg-neutral-900/90 dark:bg-neutral-800 dark:text-neutral-50 dark:hover:bg-neutral-700",
2959
- success: "bg-emerald-600 text-white hover:bg-emerald-600/90 dark:bg-emerald-600 dark:text-white dark:hover:bg-emerald-600/90",
2960
- secondary: "bg-gray-300 text-gray-900 hover:bg-gray-300/80 dark:bg-gray-500 dark:text-gray-50 dark:hover:bg-gray-500/80",
2961
- tertiary: "border border-neutral-200 bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
2962
- warning: "bg-amber-100 text-amber-700 hover:bg-amber-100/90 focus-visible:ring-amber-500/20 dark:bg-amber-600/20 dark:text-neutral-50 dark:hover:bg-amber-600/30 dark:focus-visible:ring-amber-500/40",
2963
- danger: "bg-red-100 text-red-700 hover:bg-red-100/90 focus-visible:ring-red-500/20 dark:bg-red-600/20 dark:text-neutral-50 dark:hover:bg-red-600/30 dark:focus-visible:ring-red-500/40",
2964
- "warning-solid": "bg-amber-500 text-white hover:bg-amber-500/90 dark:bg-amber-500 dark:text-white dark:hover:bg-amber-500/90",
2965
- "danger-solid": "bg-red-600 text-white hover:bg-red-600/90 focus-visible:ring-red-500/20 dark:bg-red-600/60 dark:text-white dark:hover:bg-red-600/50 dark:focus-visible:ring-red-500/40"
2966
- };
2967
- const resolvedVariant = computed(() => {
2968
- return variantClasses[props.variant] ? props.variant : "primary";
2969
- });
2970
- const linkClasses = computed(() => [
2971
- "inline-flex h-9 min-w-[40px] shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium shadow-xs outline-none transition-all aria-invalid:border-red-500 aria-invalid:ring-red-500/20 dark:aria-invalid:ring-red-500/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
2972
- variantClasses[resolvedVariant.value],
2973
- attrs.class
2974
- ]);
2975
- return (_ctx, _cache) => {
2976
- return !__props.external ? (openBlock(), createBlock(unref(Link), mergeProps({ key: 0 }, unref(attrs), {
2977
- href: __props.href,
2978
- title: __props.title,
2979
- class: linkClasses.value
2980
- }), {
2981
- default: withCtx(() => [
2982
- renderSlot(_ctx.$slots, "default")
2983
- ]),
2984
- _: 3
2985
- }, 16, ["href", "title", "class"])) : (openBlock(), createElementBlock("a", mergeProps({ key: 1 }, unref(attrs), {
2986
- href: __props.href,
2987
- title: __props.title,
2988
- target: __props.target,
2989
- rel: __props.rel,
2990
- class: linkClasses.value
2991
- }), [
2992
- renderSlot(_ctx.$slots, "default")
2993
- ], 16, _hoisted_1$a));
2994
- };
2995
- }
2996
- });
2997
- const _hoisted_1$9 = { class: "hidden sm:block" };
2998
- const _hoisted_2$7 = { class: "py-8" };
2999
- const _sfc_main$k = {
3000
- __name: "SectionBorder",
3001
- setup(__props) {
3002
- return (_ctx, _cache) => {
3003
- return openBlock(), createElementBlock("div", _hoisted_1$9, [
3004
- createElementVNode("div", _hoisted_2$7, [
3005
- createVNode(_sfc_main$P)
3006
- ])
3007
- ]);
3008
- };
3009
- }
3010
- };
3011
- const SIDEBAR_CONTEXT_KEY = /* @__PURE__ */ Symbol("SidebarContext");
3012
- const fallbackOpen = ref(true);
3013
- const fallbackContext = {
3014
- state: computed(() => fallbackOpen.value ? "expanded" : "collapsed"),
3015
- open: fallbackOpen,
3016
- setOpen: (value) => {
3017
- fallbackOpen.value = value;
3018
- },
3019
- toggleSidebar: () => {
3020
- fallbackOpen.value = !fallbackOpen.value;
3021
- },
3022
- expand: () => {
3023
- fallbackOpen.value = true;
3024
- },
3025
- collapse: () => {
3026
- fallbackOpen.value = false;
3027
- }
3028
- };
3029
- function provideSidebarContext(defaultOpen = true) {
3030
- const open = ref(defaultOpen);
3031
- const state = computed(() => open.value ? "expanded" : "collapsed");
3032
- const context = {
3033
- state,
3034
- open,
3035
- setOpen: (value) => {
3036
- open.value = value;
3037
- },
3038
- toggleSidebar: () => {
3039
- open.value = !open.value;
3040
- },
3041
- expand: () => {
3042
- open.value = true;
3043
- },
3044
- collapse: () => {
3045
- open.value = false;
3046
- }
3047
- };
3048
- provide(SIDEBAR_CONTEXT_KEY, context);
3049
- return context;
3050
- }
3051
- function useSidebar() {
3052
- return inject(SIDEBAR_CONTEXT_KEY, fallbackContext);
3053
- }
3054
- const _hoisted_1$8 = ["data-state", "data-collapsible", "data-variant", "data-side"];
3055
- const _hoisted_2$6 = {
3056
- "data-sidebar": "sidebar",
3057
- class: "bg-sidebar text-sidebar-foreground flex h-full w-full flex-col group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
3058
- };
3059
- const _sfc_main$j = /* @__PURE__ */ defineComponent({
3060
- ...{ inheritAttrs: false },
3061
- __name: "Sidebar",
3062
- props: {
3063
- side: { default: "left" },
3064
- variant: { default: "sidebar" },
3065
- collapsible: { default: "offcanvas" },
3066
- class: { type: [Boolean, null, String, Object, Array], default: void 0 }
3067
- },
3068
- setup(__props) {
3069
- const props = __props;
3070
- const { state } = useSidebar();
3071
- return (_ctx, _cache) => {
3072
- return __props.collapsible === "none" ? (openBlock(), createElementBlock("div", mergeProps({
3073
- key: 0,
3074
- "data-slot": "sidebar",
3075
- "data-sidebar": "sidebar",
3076
- class: [
3077
- "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
3078
- props.class
3079
- ]
3080
- }, _ctx.$attrs), [
3081
- renderSlot(_ctx.$slots, "default")
3082
- ], 16)) : (openBlock(), createElementBlock("div", {
3083
- key: 1,
3084
- class: "group peer text-sidebar-foreground hidden md:block",
3085
- "data-slot": "sidebar",
3086
- "data-state": unref(state),
3087
- "data-collapsible": unref(state) === "collapsed" ? __props.collapsible : "",
3088
- "data-variant": __props.variant,
3089
- "data-side": __props.side
3090
- }, [
3091
- createElementVNode("div", {
3092
- class: normalizeClass([
3093
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
3094
- "group-data-[collapsible=offcanvas]:w-0",
3095
- "group-data-[side=right]:rotate-180",
3096
- __props.variant === "floating" || __props.variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
3097
- ])
3098
- }, null, 2),
3099
- createElementVNode("div", mergeProps({
3100
- class: [
3101
- "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
3102
- __props.side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
3103
- __props.variant === "floating" || __props.variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
3104
- props.class
3105
- ]
3106
- }, _ctx.$attrs), [
3107
- createElementVNode("div", _hoisted_2$6, [
3108
- renderSlot(_ctx.$slots, "default")
3109
- ])
3110
- ], 16)
3111
- ], 8, _hoisted_1$8));
3112
- };
3113
- }
3114
- });
3115
- const _sfc_main$i = /* @__PURE__ */ defineComponent({
3116
- __name: "SidebarContent",
3117
- props: {
3118
- class: { type: [Boolean, null, String, Object, Array] }
3119
- },
3120
- setup(__props) {
3121
- const props = __props;
3122
- return (_ctx, _cache) => {
3123
- return openBlock(), createElementBlock("div", {
3124
- "data-slot": "sidebar-content",
3125
- "data-sidebar": "content",
3126
- class: normalizeClass(["flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", props.class])
3127
- }, [
3128
- renderSlot(_ctx.$slots, "default")
3129
- ], 2);
3130
- };
3131
- }
3132
- });
3133
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
3134
- __name: "SidebarFooter",
3135
- props: {
3136
- class: { type: [Boolean, null, String, Object, Array] }
3137
- },
3138
- setup(__props) {
3139
- const props = __props;
3140
- return (_ctx, _cache) => {
3141
- return openBlock(), createElementBlock("div", {
3142
- "data-slot": "sidebar-footer",
3143
- "data-sidebar": "footer",
3144
- class: normalizeClass(["flex flex-col gap-2 p-2", props.class])
3145
- }, [
3146
- renderSlot(_ctx.$slots, "default")
3147
- ], 2);
3148
- };
3149
- }
3150
- });
3151
- const _sfc_main$g = /* @__PURE__ */ defineComponent({
3152
- __name: "SidebarGroup",
3153
- props: {
3154
- class: { type: [Boolean, null, String, Object, Array] }
3155
- },
3156
- setup(__props) {
3157
- const props = __props;
3158
- return (_ctx, _cache) => {
3159
- return openBlock(), createElementBlock("div", {
3160
- "data-slot": "sidebar-group",
3161
- "data-sidebar": "group",
3162
- class: normalizeClass(["relative flex w-full min-w-0 flex-col p-2", props.class])
3163
- }, [
3164
- renderSlot(_ctx.$slots, "default")
3165
- ], 2);
3166
- };
3167
- }
3168
- });
3169
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
3170
- __name: "SidebarGroupContent",
3171
- props: {
3172
- class: { type: [Boolean, null, String, Object, Array] }
3173
- },
3174
- setup(__props) {
3175
- const props = __props;
3176
- return (_ctx, _cache) => {
3177
- return openBlock(), createElementBlock("div", {
3178
- "data-slot": "sidebar-group-content",
3179
- "data-sidebar": "group-content",
3180
- class: normalizeClass(["w-full text-sm", props.class])
3181
- }, [
3182
- renderSlot(_ctx.$slots, "default")
3183
- ], 2);
3184
- };
3185
- }
3186
- });
3187
- const _sfc_main$e = /* @__PURE__ */ defineComponent({
3188
- ...{ inheritAttrs: false },
3189
- __name: "SidebarGroupLabel",
3190
- props: {
3191
- as: { default: "div" },
3192
- asChild: { type: Boolean, default: false },
3193
- class: { type: [Boolean, null, String, Object, Array], default: void 0 }
3194
- },
3195
- setup(__props) {
3196
- const props = __props;
3197
- const attrs = useAttrs();
3198
- const slots = useSlots();
3199
- const baseClass = computed(() => [
3200
- "text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-none transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
3201
- "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
3202
- props.class
3203
- ]);
3204
- const childVNode = computed(() => {
3205
- if (!props.asChild) {
3206
- return null;
3207
- }
3208
- const content = slots.default?.() ?? [];
3209
- const firstVNode = content.find((entry) => isVNode(entry));
3210
- if (!firstVNode) {
3211
- return null;
3212
- }
3213
- return cloneVNode(firstVNode, {
3214
- ...attrs,
3215
- class: [baseClass.value, firstVNode.props?.class]
3216
- });
3217
- });
3218
- return (_ctx, _cache) => {
3219
- return !__props.asChild ? (openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps({
3220
- key: 0,
3221
- "data-slot": "sidebar-group-label",
3222
- "data-sidebar": "group-label",
3223
- class: baseClass.value
3224
- }, unref(attrs)), {
3225
- default: withCtx(() => [
3226
- renderSlot(_ctx.$slots, "default")
3227
- ]),
3228
- _: 3
3229
- }, 16, ["class"])) : childVNode.value ? (openBlock(), createBlock(resolveDynamicComponent(childVNode.value), { key: 1 })) : createCommentVNode("", true);
3230
- };
3231
- }
3232
- });
3233
- const _sfc_main$d = /* @__PURE__ */ defineComponent({
3234
- __name: "SidebarHeader",
3235
- props: {
3236
- class: { type: [Boolean, null, String, Object, Array] }
3237
- },
3238
- setup(__props) {
3239
- const props = __props;
3240
- return (_ctx, _cache) => {
3241
- return openBlock(), createElementBlock("div", {
3242
- "data-slot": "sidebar-header",
3243
- "data-sidebar": "header",
3244
- class: normalizeClass(["flex flex-col gap-2 p-2", props.class])
3245
- }, [
3246
- renderSlot(_ctx.$slots, "default")
3247
- ], 2);
3248
- };
3249
- }
3250
- });
3251
- const _sfc_main$c = /* @__PURE__ */ defineComponent({
3252
- __name: "SidebarInset",
3253
- props: {
3254
- class: { type: [Boolean, null, String, Object, Array] }
3255
- },
3256
- setup(__props) {
3257
- const props = __props;
3258
- return (_ctx, _cache) => {
3259
- return openBlock(), createElementBlock("main", {
3260
- "data-slot": "sidebar-inset",
3261
- class: normalizeClass([
3262
- "bg-background relative flex w-full flex-1 flex-col",
3263
- "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
3264
- props.class
3265
- ])
3266
- }, [
3267
- renderSlot(_ctx.$slots, "default")
3268
- ], 2);
3269
- };
3270
- }
3271
- });
3272
- const _sfc_main$b = /* @__PURE__ */ defineComponent({
3273
- __name: "SidebarMenu",
3274
- props: {
3275
- class: { type: [Boolean, null, String, Object, Array] }
3276
- },
3277
- setup(__props) {
3278
- const props = __props;
3279
- return (_ctx, _cache) => {
3280
- return openBlock(), createElementBlock("ul", {
3281
- "data-slot": "sidebar-menu",
3282
- "data-sidebar": "menu",
3283
- class: normalizeClass(["flex w-full min-w-0 flex-col gap-1", props.class])
3284
- }, [
3285
- renderSlot(_ctx.$slots, "default")
3286
- ], 2);
3287
- };
3288
- }
3289
- });
3290
- const _hoisted_1$7 = ["href", "target", "rel"];
3291
- const _sfc_main$a = /* @__PURE__ */ defineComponent({
3292
- ...{ inheritAttrs: false },
3293
- __name: "SidebarMenuButton",
3294
- props: {
3295
- href: { default: void 0 },
3296
- title: { default: "" },
3297
- active: { type: Boolean, default: void 0 },
3298
- isActive: { type: Boolean, default: void 0 },
3299
- icon: { default: void 0 },
3300
- external: { type: Boolean, default: false },
3301
- target: { default: void 0 },
3302
- rel: { default: void 0 },
3303
- variant: { default: "default" },
3304
- size: { default: "default" },
3305
- as: { default: void 0 },
3306
- asChild: { type: Boolean, default: false },
3307
- tooltip: { default: void 0 },
3308
- class: { type: [Boolean, null, String, Object, Array], default: void 0 }
3309
- },
3310
- setup(__props) {
3311
- const props = __props;
3312
- const attrs = useAttrs();
3313
- const slots = useSlots();
3314
- const resolvedActive = computed(() => props.active ?? props.isActive ?? false);
3315
- const baseClass = computed(() => [
3316
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:gap-0 group-data-[collapsible=icon]:p-2! group-data-[collapsible=icon]:[&>*:first-child]:mx-auto group-data-[collapsible=icon]:[&>*:first-child]:flex group-data-[collapsible=icon]:[&>*:first-child]:items-center group-data-[collapsible=icon]:[&>*:first-child]:justify-center [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
3317
- props.variant === "outline" ? "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]" : "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
3318
- props.size === "sm" ? "h-7 text-xs" : props.size === "lg" ? "h-12 text-sm group-data-[collapsible=icon]:p-0!" : "h-8 text-sm",
3319
- props.class
3320
- ]);
3321
- const sharedAttrs = computed(() => ({
3322
- ...attrs,
3323
- title: props.tooltip ?? (props.title || void 0),
3324
- "data-slot": "sidebar-menu-button",
3325
- "data-sidebar": "menu-button",
3326
- "data-size": props.size,
3327
- "data-active": resolvedActive.value ? "true" : void 0,
3328
- "aria-current": resolvedActive.value ? "page" : void 0,
3329
- class: baseClass.value
3330
- }));
3331
- const childVNode = computed(() => {
3332
- if (!props.asChild) {
3333
- return null;
3334
- }
3335
- const content = slots.default?.() ?? [];
3336
- const firstVNode = content.find((entry) => isVNode(entry));
3337
- if (!firstVNode) {
3338
- return null;
3339
- }
3340
- return cloneVNode(firstVNode, mergeProps(sharedAttrs.value, firstVNode.props ?? {}));
3341
- });
3342
- return (_ctx, _cache) => {
3343
- return __props.asChild && childVNode.value ? (openBlock(), createBlock(resolveDynamicComponent(childVNode.value), { key: 0 })) : (__props.as === "link" || !__props.as) && __props.href && !__props.external ? (openBlock(), createBlock(unref(Link), mergeProps({
3344
- key: 1,
3345
- href: __props.href
3346
- }, sharedAttrs.value), {
3347
- default: withCtx(() => [
3348
- __props.icon ? (openBlock(), createBlock(resolveDynamicComponent(__props.icon), { key: 0 })) : createCommentVNode("", true),
3349
- renderSlot(_ctx.$slots, "default", {}, () => [
3350
- createTextVNode(toDisplayString(__props.title), 1)
3351
- ])
3352
- ]),
3353
- _: 3
3354
- }, 16, ["href"])) : __props.href && (__props.external || __props.as === "a") ? (openBlock(), createElementBlock("a", mergeProps({
3355
- key: 2,
3356
- href: __props.href,
3357
- target: __props.target,
3358
- rel: __props.rel
3359
- }, sharedAttrs.value), [
3360
- __props.icon ? (openBlock(), createBlock(resolveDynamicComponent(__props.icon), { key: 0 })) : createCommentVNode("", true),
3361
- renderSlot(_ctx.$slots, "default", {}, () => [
3362
- createTextVNode(toDisplayString(__props.title), 1)
3363
- ])
3364
- ], 16, _hoisted_1$7)) : (openBlock(), createElementBlock("button", mergeProps({
3365
- key: 3,
3366
- type: "button"
3367
- }, sharedAttrs.value), [
3368
- __props.icon ? (openBlock(), createBlock(resolveDynamicComponent(__props.icon), { key: 0 })) : createCommentVNode("", true),
3369
- renderSlot(_ctx.$slots, "default", {}, () => [
3370
- createTextVNode(toDisplayString(__props.title), 1)
3371
- ])
3372
- ], 16));
3373
- };
3374
- }
3375
- });
3376
- const _sfc_main$9 = /* @__PURE__ */ defineComponent({
3377
- __name: "SidebarMenuItem",
3378
- props: {
3379
- class: { type: [Boolean, null, String, Object, Array] }
3380
- },
3381
- setup(__props) {
3382
- const props = __props;
3383
- return (_ctx, _cache) => {
3384
- return openBlock(), createElementBlock("li", {
3385
- "data-slot": "sidebar-menu-item",
3386
- "data-sidebar": "menu-item",
3387
- class: normalizeClass(["group/menu-item relative", props.class])
3388
- }, [
3389
- renderSlot(_ctx.$slots, "default")
3390
- ], 2);
3391
- };
3392
- }
3393
- });
3394
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
3395
- ...{ inheritAttrs: false },
3396
- __name: "SidebarProvider",
3397
- props: {
3398
- defaultOpen: { type: Boolean, default: true },
3399
- width: { default: "16rem" },
3400
- iconWidth: { default: "3rem" },
3401
- class: { type: [Boolean, null, String, Object, Array], default: void 0 }
3402
- },
3403
- setup(__props) {
3404
- const props = __props;
3405
- provideSidebarContext(props.defaultOpen);
3406
- return (_ctx, _cache) => {
3407
- return openBlock(), createElementBlock("div", mergeProps({
3408
- "data-slot": "sidebar-wrapper",
3409
- style: {
3410
- "--sidebar-width": props.width,
3411
- "--sidebar-width-icon": props.iconWidth
3412
- },
3413
- class: [
3414
- "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
3415
- props.class
3416
- ]
3417
- }, _ctx.$attrs), [
3418
- renderSlot(_ctx.$slots, "default")
3419
- ], 16);
3420
- };
3421
- }
3422
- });
3423
- const isEmptyString = (value) => value === "";
3424
- const mergeClasses = (...classes) => classes.filter((className, index, array) => {
3425
- return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
3426
- }).join(" ").trim();
3427
- const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
3428
- const toCamelCase = (string) => string.replace(
3429
- /^([A-Z])|[\s-_]+(\w)/g,
3430
- (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
3431
- );
3432
- const toPascalCase = (string) => {
3433
- const camelCase = toCamelCase(string);
3434
- return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
3435
- };
3436
- var defaultAttributes = {
3437
- xmlns: "http://www.w3.org/2000/svg",
3438
- width: 24,
3439
- height: 24,
3440
- viewBox: "0 0 24 24",
3441
- fill: "none",
3442
- stroke: "currentColor",
3443
- "stroke-width": 2,
3444
- "stroke-linecap": "round",
3445
- "stroke-linejoin": "round"
3446
- };
3447
- const LUCIDE_CONTEXT = /* @__PURE__ */ Symbol("lucide-icons");
3448
- function useLucideProps() {
3449
- return inject(LUCIDE_CONTEXT, {});
3450
- }
3451
- const Icon = ({
3452
- name,
3453
- iconNode,
3454
- absoluteStrokeWidth,
3455
- "absolute-stroke-width": absoluteStrokeWidthKebabCase,
3456
- strokeWidth,
3457
- "stroke-width": strokeWidthKebabCase,
3458
- size,
3459
- color,
3460
- ...props
3461
- }, { slots }) => {
3462
- const {
3463
- size: contextSize,
3464
- color: contextColor,
3465
- strokeWidth: contextStrokeWidth = 2,
3466
- absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,
3467
- class: contextClass = ""
3468
- } = useLucideProps();
3469
- const calculatedStrokeWidth = computed(() => {
3470
- const isAbsoluteStrokeWidth = isEmptyString(absoluteStrokeWidth) || isEmptyString(absoluteStrokeWidthKebabCase) || absoluteStrokeWidth === true || absoluteStrokeWidthKebabCase === true || contextAbsoluteStrokeWidth === true;
3471
- const strokeWidthValue = strokeWidth || strokeWidthKebabCase || contextStrokeWidth || defaultAttributes["stroke-width"];
3472
- if (isAbsoluteStrokeWidth) {
3473
- return Number(strokeWidthValue) * 24 / Number(size ?? contextSize ?? defaultAttributes.width);
3474
- }
3475
- return strokeWidthValue;
3476
- });
3477
- return h(
3478
- "svg",
3479
- {
3480
- ...defaultAttributes,
3481
- ...props,
3482
- width: size ?? contextSize ?? defaultAttributes.width,
3483
- height: size ?? contextSize ?? defaultAttributes.height,
3484
- stroke: color ?? contextColor ?? defaultAttributes.stroke,
3485
- "stroke-width": calculatedStrokeWidth.value,
3486
- class: mergeClasses(
3487
- "lucide",
3488
- contextClass,
3489
- ...name ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] : ["lucide-icon"]
3490
- )
3491
- },
3492
- [...iconNode.map((child) => h(...child)), ...slots.default ? [slots.default()] : []]
3493
- );
3494
- };
3495
- const createLucideIcon = (iconName, iconNode) => (props, { slots, attrs }) => h(
3496
- Icon,
3497
- {
3498
- ...attrs,
3499
- ...props,
3500
- iconNode,
3501
- name: iconName
3502
- },
3503
- slots
3504
- );
3505
- const __iconNode$2 = [
3506
- ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
3507
- ["path", { d: "M9 3v18", key: "fh3hqa" }],
3508
- ["path", { d: "m16 15-3-3 3-3", key: "14y99z" }]
3509
- ];
3510
- const PanelLeftClose = createLucideIcon("panel-left-close", __iconNode$2);
3511
- const __iconNode$1 = [
3512
- ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
3513
- ["path", { d: "M9 3v18", key: "fh3hqa" }],
3514
- ["path", { d: "m14 9 3 3-3 3", key: "8010ee" }]
3515
- ];
3516
- const PanelLeftOpen = createLucideIcon("panel-left-open", __iconNode$1);
3517
- const __iconNode = [
3518
- ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
3519
- ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
3520
- ];
3521
- const Search = createLucideIcon("search", __iconNode);
3522
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
3523
- __name: "SidebarTrigger",
3524
- props: {
3525
- class: { type: [Boolean, null, String, Object, Array] }
3526
- },
3527
- setup(__props) {
3528
- const props = __props;
3529
- const { state, toggleSidebar } = useSidebar();
3530
- return (_ctx, _cache) => {
3531
- return openBlock(), createBlock(_sfc_main$J, {
3532
- "data-sidebar": "trigger",
3533
- "data-slot": "sidebar-trigger",
3534
- variant: "ghost",
3535
- size: "icon",
3536
- class: normalizeClass(["h-7 w-7", props.class]),
3537
- onClick: unref(toggleSidebar)
3538
- }, {
3539
- default: withCtx(() => [
3540
- unref(state) === "collapsed" ? (openBlock(), createBlock(unref(PanelLeftOpen), { key: 0 })) : (openBlock(), createBlock(unref(PanelLeftClose), { key: 1 })),
3541
- _cache[0] || (_cache[0] = createElementVNode("span", { class: "sr-only" }, "Basculer la barre latérale", -1))
3542
- ]),
3543
- _: 1
3544
- }, 8, ["class", "onClick"]);
3545
- };
3546
- }
3547
- });
3548
- const _hoisted_1$6 = { class: "rounded-xl border border-neutral-200 bg-white/80 px-6 py-4 backdrop-blur-sm dark:border-neutral-800 dark:bg-neutral-950/80" };
3549
- const _hoisted_2$5 = { class: "flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center" };
3550
- const _hoisted_3$4 = { class: "flex items-center gap-3" };
3551
- const _hoisted_4$3 = { class: "text-sm font-medium text-neutral-700 dark:text-neutral-100" };
3552
- const _hoisted_5$3 = { class: "flex flex-wrap items-center gap-2" };
3553
- const _hoisted_6$3 = ["onClick"];
3554
- const _hoisted_7$3 = { class: "text-xs text-neutral-500 dark:text-neutral-200" };
3555
- const _sfc_main$6 = {
3556
- __name: "SortControls",
3557
- props: {
3558
- fields: {
3559
- type: Array,
3560
- required: true,
3561
- validator: (value) => {
3562
- return value.every(
3563
- (field) => typeof field === "object" && field.key && field.label
3564
- );
3565
- }
3566
- },
3567
- currentSortField: {
3568
- type: String,
3569
- default: ""
3570
- },
3571
- currentDirection: {
3572
- type: String,
3573
- default: "asc",
3574
- validator: (value) => ["asc", "desc"].includes(value)
3575
- },
3576
- count: {
3577
- type: Number,
3578
- default: 0
3579
- },
3580
- countLabel: {
3581
- type: String,
3582
- default: "items"
3583
- },
3584
- sortByLabel: {
3585
- type: String,
3586
- default: "Sort by"
3587
- }
3588
- },
3589
- emits: ["sort"],
3590
- setup(__props, { emit: __emit }) {
3591
- const emit = __emit;
3592
- const handleSort = (fieldKey) => {
3593
- emit("sort", fieldKey);
3594
- };
3595
- return (_ctx, _cache) => {
3596
- return openBlock(), createElementBlock("div", _hoisted_1$6, [
3597
- createElementVNode("div", _hoisted_2$5, [
3598
- createElementVNode("div", _hoisted_3$4, [
3599
- createElementVNode("label", _hoisted_4$3, toDisplayString(__props.sortByLabel) + ":", 1),
3600
- createElementVNode("div", _hoisted_5$3, [
3601
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.fields, (field) => {
3602
- return openBlock(), createElementBlock("button", {
3603
- key: field.key,
3604
- onClick: ($event) => handleSort(field.key),
3605
- class: normalizeClass([
3606
- "px-3 py-1.5 text-sm font-medium rounded-lg transition-all duration-200",
3607
- __props.currentSortField === field.key ? "bg-neutral-900 text-neutral-50 shadow-sm dark:bg-neutral-800 dark:text-neutral-50" : "bg-neutral-100 text-neutral-700 hover:bg-neutral-200 dark:bg-neutral-900 dark:text-neutral-100 dark:hover:bg-neutral-800"
3608
- ])
3609
- }, [
3610
- createTextVNode(toDisplayString(field.label) + " ", 1),
3611
- __props.currentSortField === field.key && __props.currentDirection === "asc" ? (openBlock(), createBlock(unref(ChevronUpIcon), {
3612
- key: 0,
3613
- class: "w-3 h-3 ml-1 inline"
3614
- })) : createCommentVNode("", true),
3615
- __props.currentSortField === field.key && __props.currentDirection === "desc" ? (openBlock(), createBlock(unref(ChevronDownIcon), {
3616
- key: 1,
3617
- class: "w-3 h-3 ml-1 inline"
3618
- })) : createCommentVNode("", true)
3619
- ], 10, _hoisted_6$3);
3620
- }), 128))
3621
- ])
3622
- ]),
3623
- createElementVNode("div", _hoisted_7$3, toDisplayString(__props.count) + " " + toDisplayString(__props.countLabel), 1)
3624
- ])
3625
- ]);
3626
- };
3627
- }
3628
- };
3629
- const _hoisted_1$5 = { class: "flex items-center space-x-1" };
3630
- const _hoisted_2$4 = { class: "flex flex-col" };
3631
- const _sfc_main$5 = {
3632
- __name: "ThSortable",
3633
- props: {
3634
- field: {
3635
- type: String,
3636
- required: true
3637
- },
3638
- currentSortField: {
3639
- type: String,
3640
- default: ""
3641
- },
3642
- currentDirection: {
3643
- type: String,
3644
- default: "asc"
3645
- }
3646
- },
3647
- setup(__props) {
3648
- const props = __props;
3649
- const isCurrentSort = computed(() => {
3650
- return props.field === props.currentSortField;
3651
- });
3652
- const sortIconClass = computed(() => {
3653
- if (!isCurrentSort.value) {
3654
- return "text-neutral-400 dark:text-neutral-200";
3655
- }
3656
- return "text-neutral-900 dark:text-neutral-100";
3657
- });
3658
- return (_ctx, _cache) => {
3659
- return openBlock(), createElementBlock("th", {
3660
- class: "cursor-pointer px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 transition-colors duration-150 hover:bg-neutral-100 dark:text-neutral-200 dark:hover:bg-neutral-900",
3661
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("sort", __props.field))
3662
- }, [
3663
- createElementVNode("div", _hoisted_1$5, [
3664
- createElementVNode("span", null, [
3665
- renderSlot(_ctx.$slots, "default")
3666
- ]),
3667
- createElementVNode("div", _hoisted_2$4, [
3668
- isCurrentSort.value && __props.currentDirection === "asc" ? (openBlock(), createBlock(unref(ChevronUpIcon), {
3669
- key: 0,
3670
- class: normalizeClass([sortIconClass.value, "w-3 h-3"])
3671
- }, null, 8, ["class"])) : createCommentVNode("", true),
3672
- isCurrentSort.value && __props.currentDirection === "desc" ? (openBlock(), createBlock(unref(ChevronDownIcon), {
3673
- key: 1,
3674
- class: normalizeClass([sortIconClass.value, "w-3 h-3"])
3675
- }, null, 8, ["class"])) : createCommentVNode("", true)
3676
- ])
3677
- ])
3678
- ]);
3679
- };
3680
- }
3681
- };
3682
- const _hoisted_1$4 = { class: "flex flex-col items-start gap-4 lg:flex-row lg:flex-wrap lg:items-center lg:justify-between" };
3683
- const _hoisted_2$3 = { class: "flex w-full min-w-0 flex-1 flex-col gap-3 lg:flex-row lg:items-center" };
3684
- const _hoisted_3$3 = { class: "relative w-full lg:max-w-md" };
3685
- const _hoisted_4$2 = { class: "pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3" };
3686
- const _hoisted_5$2 = ["placeholder"];
3687
- const _hoisted_6$2 = { class: "min-w-0 flex-1" };
3688
- const _hoisted_7$2 = {
3689
- key: 0,
3690
- class: "flex shrink-0 flex-col items-start gap-3 sm:flex-row sm:items-center lg:w-auto"
3691
- };
3692
- const _hoisted_8$2 = {
3693
- key: 0,
3694
- class: "flex items-center"
3695
- };
3696
- const _hoisted_9$2 = {
3697
- key: 1,
3698
- class: "flex items-center text-xs text-neutral-500 dark:text-neutral-400 sm:w-auto sm:text-sm lg:w-auto"
3699
- };
3700
- const _hoisted_10$2 = {
3701
- key: 0,
3702
- class: "ml-2"
3703
- };
3704
- const _hoisted_11$2 = { class: "font-medium text-neutral-700 dark:text-neutral-200" };
3705
- const _sfc_main$4 = {
3706
- __name: "TableSearch",
3707
- props: {
3708
- modelValue: {
3709
- type: String,
3710
- default: ""
3711
- },
3712
- placeholder: {
3713
- type: String,
3714
- default: "Search..."
3715
- },
3716
- count: {
3717
- type: Number,
3718
- default: null
3719
- },
3720
- countLabel: {
3721
- type: String,
3722
- default: "results"
3723
- },
3724
- queryLabel: {
3725
- type: String,
3726
- default: "for"
3727
- },
3728
- showDeleted: {
3729
- type: Boolean,
3730
- default: false
3731
- },
3732
- showDeletedToggle: {
3733
- type: Boolean,
3734
- default: false
3735
- },
3736
- showDeletedLabel: {
3737
- type: String,
3738
- default: "Show deleted"
3739
- },
3740
- cardClass: {
3741
- type: String,
3742
- default: "rounded-xl border border-neutral-200 bg-white/90 px-6 py-4 shadow-sm dark:border-neutral-800 dark:bg-neutral-950/90"
3743
- }
3744
- },
3745
- emits: ["update:modelValue", "update:showDeleted"],
3746
- setup(__props, { emit: __emit }) {
3747
- const props = __props;
3748
- const emit = __emit;
3749
- const model = computed({
3750
- get: () => props.modelValue,
3751
- set: (value) => emit("update:modelValue", value)
3752
- });
3753
- const showDeletedModel = computed({
3754
- get: () => props.showDeleted,
3755
- set: (value) => emit("update:showDeleted", value)
3756
- });
3757
- return (_ctx, _cache) => {
3758
- return openBlock(), createElementBlock("div", {
3759
- class: normalizeClass(__props.cardClass)
3760
- }, [
3761
- createElementVNode("div", _hoisted_1$4, [
3762
- createElementVNode("div", _hoisted_2$3, [
3763
- createElementVNode("div", _hoisted_3$3, [
3764
- createElementVNode("div", _hoisted_4$2, [
3765
- createVNode(unref(Search), { class: "h-5 w-5 text-neutral-400 dark:text-neutral-500" })
3766
- ]),
3767
- withDirectives(createElementVNode("input", {
3768
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
3769
- type: "text",
3770
- placeholder: __props.placeholder,
3771
- class: "block w-full rounded-lg border border-neutral-300 bg-white py-2 pr-3 pl-10 text-sm text-neutral-900 placeholder:text-neutral-500 transition-all duration-200 focus:border-neutral-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100 dark:placeholder:text-neutral-500 dark:focus:border-neutral-500"
3772
- }, null, 8, _hoisted_5$2), [
3773
- [vModelText, model.value]
3774
- ])
3775
- ]),
3776
- createElementVNode("div", _hoisted_6$2, [
3777
- renderSlot(_ctx.$slots, "search-fields")
3778
- ])
3779
- ]),
3780
- __props.showDeletedToggle || __props.count !== null || _ctx.$slots.controls ? (openBlock(), createElementBlock("div", _hoisted_7$2, [
3781
- __props.showDeletedToggle ? (openBlock(), createElementBlock("div", _hoisted_8$2, [
3782
- createVNode(_sfc_main$y, {
3783
- modelValue: showDeletedModel.value,
3784
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => showDeletedModel.value = $event),
3785
- label: __props.showDeletedLabel
3786
- }, null, 8, ["modelValue", "label"])
3787
- ])) : createCommentVNode("", true),
3788
- renderSlot(_ctx.$slots, "controls"),
3789
- __props.count !== null ? (openBlock(), createElementBlock("div", _hoisted_9$2, [
3790
- createElementVNode("span", null, toDisplayString(__props.count) + " " + toDisplayString(__props.countLabel), 1),
3791
- model.value ? (openBlock(), createElementBlock("span", _hoisted_10$2, [
3792
- createTextVNode(toDisplayString(__props.queryLabel) + " ", 1),
3793
- createElementVNode("span", _hoisted_11$2, ' "' + toDisplayString(model.value) + '" ', 1)
3794
- ])) : createCommentVNode("", true)
3795
- ])) : createCommentVNode("", true)
3796
- ])) : createCommentVNode("", true)
3797
- ])
3798
- ], 2);
3799
- };
3800
- }
3801
- };
3802
- const _hoisted_1$3 = { class: "space-y-6" };
3803
- const _hoisted_2$2 = { class: "min-w-full divide-y divide-neutral-200 dark:divide-neutral-800" };
3804
- const _hoisted_3$2 = { class: "bg-neutral-50/80 dark:bg-neutral-900/80" };
3805
- const _hoisted_4$1 = {
3806
- key: 0,
3807
- class: "px-6 py-3 text-right text-[11px] font-semibold tracking-[0.12em] text-neutral-600 uppercase dark:text-neutral-200"
3808
- };
3809
- const _hoisted_5$1 = { class: "divide-y divide-neutral-200 bg-white dark:divide-neutral-800 dark:bg-neutral-950" };
3810
- const _hoisted_6$1 = {
3811
- key: 0,
3812
- class: "flex items-center"
3813
- };
3814
- const _hoisted_7$1 = ["title"];
3815
- const _hoisted_8$1 = {
3816
- key: 0,
3817
- class: "ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-1 text-xs font-medium text-red-700 dark:bg-red-950/60 dark:text-neutral-100"
3818
- };
3819
- const _hoisted_9$1 = ["innerHTML"];
3820
- const _hoisted_10$1 = { key: 3 };
3821
- const _hoisted_11$1 = {
3822
- key: 0,
3823
- class: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
3824
- };
3825
- const _hoisted_12$1 = {
3826
- key: 0,
3827
- class: "py-12 text-center"
3828
- };
3829
- const _hoisted_13$1 = { class: "mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-neutral-100 dark:bg-neutral-900" };
3830
- const _hoisted_14$1 = { class: "mb-2 text-lg font-semibold text-neutral-950 dark:text-neutral-50" };
3831
- const _hoisted_15$1 = { class: "mb-4 text-neutral-600 dark:text-neutral-200" };
3832
- const _sfc_main$3 = {
3833
- __name: "TableList",
3834
- props: {
3835
- data: {
3836
- type: Array,
3837
- required: true
3838
- },
3839
- columns: {
3840
- type: Array,
3841
- required: true
3842
- },
3843
- sortField: {
3844
- type: String,
3845
- default: ""
3846
- },
3847
- sortDirection: {
3848
- type: String,
3849
- default: "asc"
3850
- },
3851
- emptyState: {
3852
- type: Object,
3853
- default: () => ({
3854
- icon: "UsersIcon",
3855
- title: "No data found",
3856
- description: "No items to display.",
3857
- actionText: null,
3858
- actionUrl: null
3859
- })
3860
- },
3861
- rowClasses: {
3862
- type: Function,
3863
- default: (item, index) => [
3864
- "transition-colors duration-150",
3865
- item.deleted_at ? "bg-red-50 hover:bg-red-100 dark:bg-red-950/30 dark:hover:bg-red-950/50" : "odd:bg-white even:bg-neutral-50 hover:bg-neutral-100 dark:odd:bg-neutral-950 dark:even:bg-neutral-900/70 dark:hover:bg-neutral-900"
3866
- ]
3867
- },
3868
- maxTextLength: {
3869
- type: Number,
3870
- default: 40
3871
- },
3872
- isCard: {
3873
- type: Boolean,
3874
- default: true
3875
- },
3876
- actionsLabel: {
3877
- type: String,
3878
- default: "Actions"
3879
- },
3880
- deletedLabel: {
3881
- type: String,
3882
- default: "Deleted"
3883
- },
3884
- search: {
3885
- type: Boolean,
3886
- default: false
3887
- },
3888
- searchPlaceholder: {
3889
- type: String,
3890
- default: "Search..."
3891
- },
3892
- searchCountLabel: {
3893
- type: String,
3894
- default: "results"
3895
- },
3896
- searchQueryLabel: {
3897
- type: String,
3898
- default: "for"
3899
- },
3900
- searchShowDeleted: {
3901
- type: Boolean,
3902
- default: false
3903
- },
3904
- searchShowDeletedToggle: {
3905
- type: Boolean,
3906
- default: false
3907
- },
3908
- searchShowDeletedLabel: {
3909
- type: String,
3910
- default: "Show deleted"
3911
- }
3912
- },
3913
- emits: ["sort", "update:searchShowDeleted"],
3914
- setup(__props, { emit: __emit }) {
3915
- const slots = useSlots();
3916
- const props = __props;
3917
- const emit = __emit;
3918
- computed(() => !!slots.actions);
3919
- const searchQuery = ref("");
3920
- const filteredData = computed(() => {
3921
- if (!props.search || !searchQuery.value.trim()) {
3922
- return props.data;
3923
- }
3924
- const query = searchQuery.value.toLowerCase().trim();
3925
- return props.data.filter((item) => {
3926
- return props.columns.some((column) => {
3927
- if (column.searchable === false || column.slot) {
3928
- return false;
3929
- }
3930
- const value = column.key.split(".").reduce((obj, key) => obj?.[key], item);
3931
- if (value === null || value === void 0 || value === "") {
3932
- return false;
3933
- }
3934
- return String(value).toLowerCase().includes(query);
3935
- });
3936
- });
3937
- });
3938
- const hasData = computed(() => filteredData.value && filteredData.value.length > 0);
3939
- const sortBy = (field) => {
3940
- emit("sort", field);
3941
- };
3942
- const updateSearchShowDeleted = (value) => {
3943
- emit("update:searchShowDeleted", value);
3944
- };
3945
- const truncateText = (value) => {
3946
- const stringValue = String(value ?? "");
3947
- const maxLength = Number(props.maxTextLength);
3948
- if (!Number.isFinite(maxLength) || maxLength <= 0 || stringValue.length <= maxLength) {
3949
- return stringValue;
3950
- }
3951
- return `${stringValue.slice(0, maxLength)}...`;
3952
- };
3953
- const getCellContent = (item, column) => {
3954
- if (column.slot) {
3955
- return null;
3956
- }
3957
- if (column.render) {
3958
- return column.render(item);
3959
- }
3960
- const value = column.key.split(".").reduce((obj, key) => obj?.[key], item);
3961
- if (value === null || value === void 0 || value === "") {
3962
- return "-";
3963
- }
3964
- return truncateText(value);
3965
- };
3966
- const isDeleted = (item) => {
3967
- return item.deleted_at || item.deleted;
3968
- };
3969
- const getColumnClass = (column) => {
3970
- if (column.class) {
3971
- return column.class;
3972
- }
3973
- let classes = "px-6 py-4 text-sm truncate";
3974
- if (!column.isSecondary) {
3975
- classes += " font-medium";
3976
- }
3977
- if (column.isSecondary) {
3978
- classes += " text-neutral-600 dark:text-neutral-200";
3979
- }
3980
- return classes;
3981
- };
3982
- const getHeaderClass = (column) => {
3983
- if (column.sortable) {
3984
- return "";
3985
- }
3986
- return "px-6 py-3 text-left text-[11px] font-semibold tracking-[0.12em] text-neutral-600 uppercase dark:text-neutral-200";
3987
- };
3988
- return (_ctx, _cache) => {
3989
- return openBlock(), createElementBlock("div", _hoisted_1$3, [
3990
- __props.search ? (openBlock(), createBlock(_sfc_main$4, {
3991
- key: 0,
3992
- "model-value": searchQuery.value,
3993
- placeholder: __props.searchPlaceholder,
3994
- count: filteredData.value.length,
3995
- "count-label": __props.searchCountLabel,
3996
- "query-label": __props.searchQueryLabel,
3997
- "show-deleted": __props.searchShowDeleted,
3998
- "show-deleted-toggle": __props.searchShowDeletedToggle,
3999
- "show-deleted-label": __props.searchShowDeletedLabel,
4000
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
4001
- "onUpdate:showDeleted": updateSearchShowDeleted
4002
- }, createSlots({ _: 2 }, [
4003
- _ctx.$slots["search-fields"] ? {
4004
- name: "search-fields",
4005
- fn: withCtx(() => [
4006
- renderSlot(_ctx.$slots, "search-fields")
4007
- ]),
4008
- key: "0"
4009
- } : void 0,
4010
- _ctx.$slots.controls ? {
4011
- name: "controls",
4012
- fn: withCtx(() => [
4013
- renderSlot(_ctx.$slots, "controls")
4014
- ]),
4015
- key: "1"
4016
- } : void 0
4017
- ]), 1032, ["model-value", "placeholder", "count", "count-label", "query-label", "show-deleted", "show-deleted-toggle", "show-deleted-label"])) : createCommentVNode("", true),
4018
- createElementVNode("div", {
4019
- class: normalizeClass([
4020
- "bg-white/90 backdrop-blur-sm dark:bg-neutral-950/90",
4021
- __props.isCard ? "mx-4 animate-fadeIn rounded-2xl border border-neutral-200 shadow-sm dark:border-neutral-800 md:mx-0" : ""
4022
- ])
4023
- }, [
4024
- createElementVNode("div", {
4025
- class: normalizeClass(["overflow-x-auto", __props.isCard ? "rounded-xl" : ""])
4026
- }, [
4027
- createElementVNode("table", _hoisted_2$2, [
4028
- createElementVNode("thead", _hoisted_3$2, [
4029
- createElementVNode("tr", null, [
4030
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
4031
- return openBlock(), createElementBlock(Fragment, {
4032
- key: column.key
4033
- }, [
4034
- column.sortable ? (openBlock(), createBlock(_sfc_main$5, {
4035
- key: 0,
4036
- field: column.key,
4037
- "current-sort-field": __props.sortField,
4038
- "current-direction": __props.sortDirection,
4039
- onSort: sortBy
4040
- }, {
4041
- default: withCtx(() => [
4042
- createTextVNode(toDisplayString(column.label), 1)
4043
- ]),
4044
- _: 2
4045
- }, 1032, ["field", "current-sort-field", "current-direction"])) : (openBlock(), createElementBlock("th", {
4046
- key: 1,
4047
- class: normalizeClass([getHeaderClass(column), { "text-right": column.align === "right" }])
4048
- }, toDisplayString(column.label), 3))
4049
- ], 64);
4050
- }), 128)),
4051
- _ctx.$slots.actions ? (openBlock(), createElementBlock("th", _hoisted_4$1, toDisplayString(__props.actionsLabel), 1)) : createCommentVNode("", true)
4052
- ])
4053
- ]),
4054
- createElementVNode("tbody", _hoisted_5$1, [
4055
- (openBlock(true), createElementBlock(Fragment, null, renderList(filteredData.value, (item, index) => {
4056
- return openBlock(), createElementBlock("tr", {
4057
- key: item.id,
4058
- class: normalizeClass(__props.rowClasses(item, index))
4059
- }, [
4060
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
4061
- return openBlock(), createElementBlock("td", {
4062
- key: column.key,
4063
- class: normalizeClass(getColumnClass(column))
4064
- }, [
4065
- column.key === "name" && !column.slot ? (openBlock(), createElementBlock("div", _hoisted_6$1, [
4066
- createElementVNode("div", {
4067
- class: "truncate text-sm font-medium text-neutral-950 dark:text-neutral-50",
4068
- title: getCellContent(item, column)
4069
- }, toDisplayString(getCellContent(item, column)), 9, _hoisted_7$1),
4070
- isDeleted(item) ? (openBlock(), createElementBlock("span", _hoisted_8$1, toDisplayString(__props.deletedLabel), 1)) : createCommentVNode("", true)
4071
- ])) : column.slot ? renderSlot(_ctx.$slots, column.slot, {
4072
- key: 1,
4073
- item,
4074
- column,
4075
- index
4076
- }) : column.render ? (openBlock(), createElementBlock("div", {
4077
- key: 2,
4078
- innerHTML: column.render(item)
4079
- }, null, 8, _hoisted_9$1)) : (openBlock(), createElementBlock("div", _hoisted_10$1, toDisplayString(getCellContent(item, column)), 1))
4080
- ], 2);
4081
- }), 128)),
4082
- _ctx.$slots.actions ? (openBlock(), createElementBlock("td", _hoisted_11$1, [
4083
- renderSlot(_ctx.$slots, "actions", {
4084
- item,
4085
- index
4086
- })
4087
- ])) : createCommentVNode("", true)
4088
- ], 2);
4089
- }), 128))
4090
- ])
4091
- ])
4092
- ], 2),
4093
- !hasData.value ? (openBlock(), createElementBlock("div", _hoisted_12$1, [
4094
- createElementVNode("div", _hoisted_13$1, [
4095
- (openBlock(), createBlock(resolveDynamicComponent(__props.emptyState.icon), { class: "h-8 w-8 text-neutral-400 dark:text-neutral-200" }))
4096
- ]),
4097
- createElementVNode("h3", _hoisted_14$1, toDisplayString(__props.emptyState.title), 1),
4098
- createElementVNode("p", _hoisted_15$1, toDisplayString(__props.emptyState.description), 1),
4099
- __props.emptyState.actionText && __props.emptyState.actionUrl ? (openBlock(), createBlock(_sfc_main$l, {
4100
- key: 0,
4101
- href: __props.emptyState.actionUrl,
4102
- variant: "primary"
4103
- }, {
4104
- default: withCtx(() => [
4105
- createTextVNode(toDisplayString(__props.emptyState.actionText), 1)
4106
- ]),
4107
- _: 1
4108
- }, 8, ["href"])) : createCommentVNode("", true)
4109
- ])) : createCommentVNode("", true)
4110
- ], 2)
4111
- ]);
4112
- };
4113
- }
4114
- };
4115
- const _hoisted_1$2 = { class: "relative max-w-sm" };
4116
- const _hoisted_2$1 = { class: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none" };
4117
- const _hoisted_3$1 = ["placeholder"];
4118
- const _hoisted_4 = { class: "min-w-full divide-y divide-neutral-200 dark:divide-neutral-800" };
4119
- const _hoisted_5 = { class: "bg-neutral-50 dark:bg-neutral-900" };
4120
- const _hoisted_6 = {
4121
- key: 0,
4122
- class: "px-6 py-3 text-right text-xs font-medium uppercase tracking-wider text-neutral-500 dark:text-neutral-200"
4123
- };
4124
- const _hoisted_7 = { class: "divide-y divide-neutral-200 bg-white dark:divide-neutral-800 dark:bg-neutral-950" };
4125
- const _hoisted_8 = {
4126
- key: 2,
4127
- class: "flex items-center"
4128
- };
4129
- const _hoisted_9 = ["title"];
4130
- const _hoisted_10 = {
4131
- key: 0,
4132
- class: "ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-1 text-xs font-medium text-red-800 dark:bg-red-950/60 dark:text-neutral-100"
4133
- };
4134
- const _hoisted_11 = ["innerHTML"];
4135
- const _hoisted_12 = { key: 5 };
4136
- const _hoisted_13 = {
4137
- key: 0,
4138
- class: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
4139
- };
4140
- const _hoisted_14 = { class: "flex items-center justify-end gap-2" };
4141
- const _hoisted_15 = {
4142
- key: 2,
4143
- class: "py-12 text-center"
4144
- };
4145
- const _hoisted_16 = { class: "mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-neutral-100 dark:bg-neutral-900" };
4146
- const _hoisted_17 = { class: "mb-2 text-lg font-medium text-neutral-950 dark:text-neutral-50" };
4147
- const _hoisted_18 = { class: "mb-4 text-neutral-500 dark:text-neutral-200" };
4148
- const _sfc_main$2 = {
4149
- __name: "TableListForm",
4150
- props: {
4151
- data: {
4152
- type: Array,
4153
- required: true
4154
- },
4155
- columns: {
4156
- type: Array,
4157
- required: true
4158
- },
4159
- sortField: {
4160
- type: String,
4161
- default: ""
4162
- },
4163
- sortDirection: {
4164
- type: String,
4165
- default: "asc"
4166
- },
4167
- emptyState: {
4168
- type: Object,
4169
- default: () => ({
4170
- icon: "UsersIcon",
4171
- title: "No data found",
4172
- description: "No items to display.",
4173
- actionText: null,
4174
- actionUrl: null
4175
- })
4176
- },
4177
- rowClasses: {
4178
- type: Function,
4179
- default: (item) => [
4180
- "transition-colors duration-150",
4181
- item.deleted_at ? "bg-red-50 hover:bg-red-100 dark:bg-red-950/30 dark:hover:bg-red-950/50" : "odd:bg-white even:bg-neutral-50 hover:bg-neutral-100 dark:odd:bg-neutral-950 dark:even:bg-neutral-900/70 dark:hover:bg-neutral-900"
4182
- ]
4183
- },
4184
- getErrorMessage: {
4185
- type: Function,
4186
- default: () => null
4187
- },
4188
- search: {
4189
- type: Boolean,
4190
- default: true
4191
- },
4192
- searchPlaceholder: {
4193
- type: String,
4194
- default: "Search..."
4195
- },
4196
- rowKey: {
4197
- type: [String, Function],
4198
- default: "id"
4199
- },
4200
- isDeletedFn: {
4201
- type: Function,
4202
- default: (item) => Boolean(item?.deleted_at || item?.deleted)
4203
- },
4204
- mutateRows: {
4205
- type: Boolean,
4206
- default: true
4207
- },
4208
- isCard: {
4209
- type: Boolean,
4210
- default: true
4211
- },
4212
- actionsLabel: {
4213
- type: String,
4214
- default: "Actions"
4215
- },
4216
- deletedLabel: {
4217
- type: String,
4218
- default: "Deleted"
4219
- },
4220
- maxTextLength: {
4221
- type: Number,
4222
- default: 40
4223
- },
4224
- rowEditing: {
4225
- type: Boolean,
4226
- default: true
4227
- },
4228
- editingRowKey: {
4229
- type: [String, Number, null],
4230
- default: void 0
4231
- },
4232
- canEditRow: {
4233
- type: Function,
4234
- default: () => true
4235
- },
4236
- editLabel: {
4237
- type: String,
4238
- default: "Edit row"
4239
- },
4240
- cancelLabel: {
4241
- type: String,
4242
- default: "Done editing"
4243
- }
4244
- },
4245
- emits: ["sort", "update", "update:editingRowKey", "edit-start", "edit-cancel"],
4246
- setup(__props, { emit: __emit }) {
4247
- const slots = useSlots();
4248
- const props = __props;
4249
- const emit = __emit;
4250
- const localSortField = ref(props.sortField);
4251
- const localSortDirection = ref(props.sortDirection);
4252
- const searchQuery = ref("");
4253
- const internalEditingRowKey = ref(null);
4254
- const editingDraft = ref({});
4255
- const resolvedEditingRowKey = computed(() => {
4256
- return props.editingRowKey !== void 0 ? props.editingRowKey : internalEditingRowKey.value;
4257
- });
4258
- watch(() => props.sortField, (value) => {
4259
- localSortField.value = value;
4260
- });
4261
- watch(() => props.sortDirection, (value) => {
4262
- localSortDirection.value = value;
4263
- });
4264
- watch(() => props.rowEditing, (value) => {
4265
- if (!value) {
4266
- resetEditState();
4267
- }
4268
- });
4269
- watch(resolvedEditingRowKey, (nextKey, previousKey) => {
4270
- if (nextKey === previousKey) {
4271
- return;
4272
- }
4273
- if (nextKey === null || nextKey === void 0 || nextKey === "") {
4274
- editingDraft.value = {};
4275
- return;
4276
- }
4277
- const activeItem = props.data.find((item, index) => getRowKey(item, index) === nextKey);
4278
- editingDraft.value = activeItem ? cloneValue(activeItem) : {};
4279
- });
4280
- watch(
4281
- () => props.data,
4282
- () => {
4283
- if (resolvedEditingRowKey.value === null || resolvedEditingRowKey.value === void 0) {
4284
- return;
4285
- }
4286
- const activeItem = props.data.find((item, index) => getRowKey(item, index) === resolvedEditingRowKey.value);
4287
- if (!activeItem) {
4288
- resetEditState();
4289
- }
4290
- },
4291
- { deep: true }
4292
- );
4293
- const sortedData = computed(() => {
4294
- let filteredData = props.data;
4295
- if (props.search && searchQuery.value.trim()) {
4296
- const query = searchQuery.value.toLowerCase().trim();
4297
- filteredData = props.data.filter((item) => {
4298
- return props.columns.some((column) => {
4299
- if (!column.searchable) {
4300
- return false;
4301
- }
4302
- const value = getNestedValue(item, column.key);
4303
- if (value === null || value === void 0 || value === "") {
4304
- return false;
4305
- }
4306
- return String(value).toLowerCase().includes(query);
4307
- });
4308
- });
4309
- }
4310
- if (!localSortField.value) {
4311
- return filteredData;
4312
- }
4313
- return [...filteredData].sort((a, b) => {
4314
- const aValue = getNestedValue(a, localSortField.value);
4315
- const bValue = getNestedValue(b, localSortField.value);
4316
- if (aValue === null || aValue === void 0 || aValue === "") return 1;
4317
- if (bValue === null || bValue === void 0 || bValue === "") return -1;
4318
- let comparison = 0;
4319
- if (aValue < bValue) comparison = -1;
4320
- if (aValue > bValue) comparison = 1;
4321
- return localSortDirection.value === "desc" ? -comparison : comparison;
4322
- });
4323
- });
4324
- const hasActionsSlot = computed(() => Boolean(slots.actions));
4325
- const hasActionsColumn = computed(() => hasActionsSlot.value || props.rowEditing);
4326
- const hasData = computed(() => sortedData.value && sortedData.value.length > 0);
4327
- const sortBy = (field) => {
4328
- if (localSortField.value === field) {
4329
- localSortDirection.value = localSortDirection.value === "asc" ? "desc" : "asc";
4330
- } else {
4331
- localSortField.value = field;
4332
- localSortDirection.value = "asc";
4333
- }
4334
- emit("sort", { field, direction: localSortDirection.value });
4335
- };
4336
- const cloneValue = (value) => {
4337
- if (Array.isArray(value)) {
4338
- return value.map((entry) => cloneValue(entry));
4339
- }
4340
- if (value && typeof value === "object") {
4341
- return Object.fromEntries(
4342
- Object.entries(value).map(([key, entry]) => [key, cloneValue(entry)])
4343
- );
4344
- }
4345
- return value;
4346
- };
4347
- const truncateText = (value) => {
4348
- const stringValue = String(value ?? "");
4349
- const maxLength = Number(props.maxTextLength);
4350
- if (!Number.isFinite(maxLength) || maxLength <= 0 || stringValue.length <= maxLength) {
4351
- return stringValue;
4352
- }
4353
- return `${stringValue.slice(0, maxLength)}...`;
4354
- };
4355
- const getNestedValue = (obj, path) => {
4356
- if (!path || typeof path !== "string") {
4357
- return obj;
4358
- }
4359
- return path.split(".").reduce((current, key) => current?.[key], obj);
4360
- };
4361
- const setNestedValue = (obj, path, value) => {
4362
- if (!path || typeof path !== "string" || obj == null) {
4363
- return;
4364
- }
4365
- const keys = path.split(".");
4366
- const lastKey = keys.pop();
4367
- let current = obj;
4368
- for (const key of keys) {
4369
- if (current[key] === void 0 || current[key] === null || typeof current[key] !== "object") {
4370
- current[key] = {};
4371
- }
4372
- current = current[key];
4373
- }
4374
- if (lastKey !== void 0) {
4375
- current[lastKey] = value;
4376
- }
4377
- };
4378
- const getDataIndex = (item) => {
4379
- if (item?.id) {
4380
- return props.data.findIndex((row) => row?.id === item.id);
4381
- }
4382
- return props.data.findIndex((row) => row === item);
4383
- };
4384
- const getRowKey = (item, index) => {
4385
- if (typeof props.rowKey === "function") {
4386
- const customKey = props.rowKey(item, index);
4387
- return customKey ?? `row-${index}`;
4388
- }
4389
- const resolved = getNestedValue(item, props.rowKey);
4390
- return resolved ?? `row-${index}`;
4391
- };
4392
- const getEditSlotName = (column) => `${column.slot}-edit`;
4393
- const isDeleted = (item) => props.isDeletedFn(item);
4394
- const setEditingRowKey = (value) => {
4395
- if (props.editingRowKey === void 0) {
4396
- internalEditingRowKey.value = value;
4397
- }
4398
- emit("update:editingRowKey", value);
4399
- };
4400
- const isEditingRow = (item, index) => {
4401
- return props.rowEditing && resolvedEditingRowKey.value !== null && resolvedEditingRowKey.value === getRowKey(item, index);
4402
- };
4403
- const isRowEditDisabled = (item, index) => {
4404
- if (!props.rowEditing) {
4405
- return true;
4406
- }
4407
- if (!props.canEditRow(item, index) || isDeleted(item)) {
4408
- return true;
4409
- }
4410
- return resolvedEditingRowKey.value !== null && !isEditingRow(item, index);
4411
- };
4412
- const resetEditState = () => {
4413
- setEditingRowKey(null);
4414
- };
4415
- const startEdit = (item, index) => {
4416
- if (isRowEditDisabled(item, index)) {
4417
- return;
4418
- }
4419
- const rowKey = getRowKey(item, index);
4420
- setEditingRowKey(rowKey);
4421
- emit("edit-start", {
4422
- item,
4423
- index: getDataIndex(item),
4424
- rowKey
4425
- });
4426
- };
4427
- const cancelEdit = (item, index) => {
4428
- emit("edit-cancel", {
4429
- item,
4430
- index: getDataIndex(item),
4431
- rowKey: getRowKey(item, index)
4432
- });
4433
- resetEditState();
4434
- };
4435
- const updateDraft = (field, value, item, eventName = void 0) => {
4436
- setNestedValue(editingDraft.value, field, value);
4437
- if (props.mutateRows) {
4438
- setNestedValue(item, field, cloneValue(value));
4439
- }
4440
- emit("update", {
4441
- item,
4442
- draft: editingDraft.value,
4443
- field,
4444
- value,
4445
- index: getDataIndex(item),
4446
- rowKey: resolvedEditingRowKey.value,
4447
- event: eventName
4448
- });
4449
- };
4450
- const getCellContent = (item, column) => {
4451
- if (column.slot) {
4452
- return null;
4453
- }
4454
- if (column.render) {
4455
- return column.render(item);
4456
- }
4457
- const value = getNestedValue(item, column.key);
4458
- if (value === null || value === void 0 || value === "") {
4459
- return "-";
4460
- }
4461
- return truncateText(value);
4462
- };
4463
- const getColumnClass = (column, item, index) => {
4464
- if (column.class) {
4465
- return column.class;
4466
- }
4467
- const isEditing = isEditingRow(item, index) && (column.input || slots[getEditSlotName(column)]);
4468
- let classes = isEditing ? "px-6 py-3 text-sm align-top" : "px-6 py-4 text-sm truncate";
4469
- if (!column.isSecondary) {
4470
- classes += " font-medium";
4471
- }
4472
- if (column.isSecondary) {
4473
- classes += " text-neutral-600 dark:text-neutral-200";
4474
- }
4475
- return classes;
4476
- };
4477
- const getHeaderClass = (column) => {
4478
- if (column.sortable) {
4479
- return "";
4480
- }
4481
- return "px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 dark:text-neutral-200";
4482
- };
4483
- const getInputType = (column) => column.inputType || "text";
4484
- const getInputClass = (column) => {
4485
- let classes = "block w-full max-w-xs min-w-[12rem] rounded-lg border border-neutral-200 bg-neutral-50 px-3 py-2 text-sm text-neutral-900 shadow-none placeholder:text-neutral-400 transition-colors duration-200 focus:border-neutral-900 focus:bg-white focus:outline-none focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-50 dark:placeholder:text-neutral-500 dark:focus:border-neutral-100 dark:focus:bg-neutral-950 dark:focus:ring-neutral-100/10 sm:min-w-[10rem]";
4486
- if (column.inputClass) {
4487
- classes += ` ${column.inputClass}`;
4488
- }
4489
- if (column.isSecondary) {
4490
- classes += " text-neutral-600 dark:text-neutral-200";
4491
- }
4492
- return classes;
4493
- };
4494
- const getInputPlaceholder = (column) => column.placeholder || column.label || "";
4495
- const getInputValue = (item, column, index) => {
4496
- if (isEditingRow(item, index)) {
4497
- return getNestedValue(editingDraft.value, column.key) ?? "";
4498
- }
4499
- return getNestedValue(item, column.key) ?? "";
4500
- };
4501
- const getColumnError = (item, column) => {
4502
- const arrayIndex = getDataIndex(item);
4503
- if (arrayIndex === -1) {
4504
- return null;
4505
- }
4506
- return props.getErrorMessage(arrayIndex, column.key);
4507
- };
4508
- const getSlotBindings = (item, column, index) => ({
4509
- item,
4510
- column,
4511
- index,
4512
- isEditing: isEditingRow(item, index),
4513
- draft: editingDraft.value,
4514
- rowKey: getRowKey(item, index),
4515
- updateDraft: (field, value) => updateDraft(field, value, item),
4516
- startEdit: () => startEdit(item, index),
4517
- cancelEdit: () => cancelEdit(item, index)
4518
- });
4519
- const resolveColumnDisabled = (column, item, index) => {
4520
- const disabled = typeof column.disabled === "function" ? column.disabled(item, index) : column.disabled;
4521
- return Boolean(disabled || isDeleted(item));
4522
- };
4523
- return (_ctx, _cache) => {
4524
- return openBlock(), createElementBlock("div", {
4525
- class: normalizeClass(["bg-white dark:bg-neutral-950", __props.isCard ? "mx-4 animate-fadeIn rounded-xl border border-neutral-200 shadow-sm dark:border-neutral-800 md:mx-0" : ""])
4526
- }, [
4527
- __props.search ? (openBlock(), createElementBlock("div", {
4528
- key: 0,
4529
- class: normalizeClass([
4530
- "px-6 py-4",
4531
- __props.isCard ? "rounded-t-xl border-b border-neutral-200 bg-neutral-50/80 dark:border-neutral-800 dark:bg-neutral-900/80" : "mb-4 bg-white/80 backdrop-blur-sm dark:bg-neutral-950/80"
4532
- ])
4533
- }, [
4534
- createElementVNode("div", _hoisted_1$2, [
4535
- createElementVNode("div", _hoisted_2$1, [
4536
- createVNode(unref(MagnifyingGlassIcon), { class: "h-4 w-4 text-neutral-400 dark:text-neutral-200" })
4537
- ]),
4538
- withDirectives(createElementVNode("input", {
4539
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
4540
- type: "text",
4541
- placeholder: __props.searchPlaceholder,
4542
- class: "block w-full rounded-lg border border-neutral-200 bg-white py-2 pl-9 pr-3 text-sm text-neutral-900 placeholder:text-neutral-500 transition-colors duration-200 focus:border-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-950/10 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50 dark:placeholder:text-neutral-500 dark:focus:border-neutral-100 dark:focus:ring-neutral-100/10"
4543
- }, null, 8, _hoisted_3$1), [
4544
- [vModelText, searchQuery.value]
4545
- ])
4546
- ])
4547
- ], 2)) : createCommentVNode("", true),
4548
- hasData.value ? (openBlock(), createElementBlock("div", {
4549
- key: 1,
4550
- class: normalizeClass(["overflow-x-auto", __props.isCard ? "rounded-xl" : ""])
4551
- }, [
4552
- createElementVNode("table", _hoisted_4, [
4553
- createElementVNode("thead", _hoisted_5, [
4554
- createElementVNode("tr", null, [
4555
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
4556
- return openBlock(), createElementBlock(Fragment, {
4557
- key: column.key
4558
- }, [
4559
- column.sortable ? (openBlock(), createBlock(_sfc_main$5, {
4560
- key: 0,
4561
- field: column.key,
4562
- "current-sort-field": localSortField.value,
4563
- "current-direction": localSortDirection.value,
4564
- onSort: sortBy
4565
- }, {
4566
- default: withCtx(() => [
4567
- createTextVNode(toDisplayString(column.label), 1)
4568
- ]),
4569
- _: 2
4570
- }, 1032, ["field", "current-sort-field", "current-direction"])) : (openBlock(), createElementBlock("th", {
4571
- key: 1,
4572
- class: normalizeClass([getHeaderClass(column), { "text-right": column.align === "right" }])
4573
- }, toDisplayString(column.label), 3))
4574
- ], 64);
4575
- }), 128)),
4576
- hasActionsColumn.value ? (openBlock(), createElementBlock("th", _hoisted_6, toDisplayString(__props.actionsLabel), 1)) : createCommentVNode("", true)
4577
- ])
4578
- ]),
4579
- createElementVNode("tbody", _hoisted_7, [
4580
- (openBlock(true), createElementBlock(Fragment, null, renderList(sortedData.value, (item, index) => {
4581
- return openBlock(), createElementBlock("tr", {
4582
- key: getRowKey(item, index),
4583
- class: normalizeClass(__props.rowClasses(item, index))
4584
- }, [
4585
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
4586
- return openBlock(), createElementBlock("td", {
4587
- key: column.key,
4588
- class: normalizeClass([getColumnClass(column, item, index), { "text-right": column.align === "right" }])
4589
- }, [
4590
- isEditingRow(item, index) && column.slot && unref(slots)[getEditSlotName(column)] ? renderSlot(_ctx.$slots, getEditSlotName(column), mergeProps({
4591
- key: 0,
4592
- ref_for: true
4593
- }, getSlotBindings(item, column, index))) : isEditingRow(item, index) && column.input ? (openBlock(), createBlock(_sfc_main$v, {
4594
- key: 1,
4595
- type: getInputType(column),
4596
- class: normalizeClass(getInputClass(column)),
4597
- placeholder: getInputPlaceholder(column),
4598
- "model-value": getInputValue(item, column, index),
4599
- disabled: resolveColumnDisabled(column, item, index),
4600
- maxlength: column.maxlength,
4601
- "error-message": getColumnError(item, column),
4602
- "helper-text": "",
4603
- "onUpdate:modelValue": (value) => updateDraft(column.key, value, item),
4604
- onBlur: (event) => updateDraft(column.key, event?.target?.value ?? getInputValue(item, column, index), item, "blur")
4605
- }, null, 8, ["type", "class", "placeholder", "model-value", "disabled", "maxlength", "error-message", "onUpdate:modelValue", "onBlur"])) : column.key === "name" && !column.slot ? (openBlock(), createElementBlock("div", _hoisted_8, [
4606
- createElementVNode("div", {
4607
- class: "text-sm font-medium truncate",
4608
- title: getCellContent(item, column)
4609
- }, toDisplayString(getCellContent(item, column)), 9, _hoisted_9),
4610
- isDeleted(item) ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(__props.deletedLabel), 1)) : createCommentVNode("", true)
4611
- ])) : column.slot ? renderSlot(_ctx.$slots, column.slot, mergeProps({
4612
- key: 3,
4613
- ref_for: true
4614
- }, getSlotBindings(item, column, index))) : column.render ? (openBlock(), createElementBlock("div", {
4615
- key: 4,
4616
- innerHTML: column.render(item)
4617
- }, null, 8, _hoisted_11)) : (openBlock(), createElementBlock("div", _hoisted_12, toDisplayString(getCellContent(item, column)), 1))
4618
- ], 2);
4619
- }), 128)),
4620
- hasActionsColumn.value ? (openBlock(), createElementBlock("td", _hoisted_13, [
4621
- createElementVNode("div", _hoisted_14, [
4622
- hasActionsSlot.value ? renderSlot(_ctx.$slots, "actions", mergeProps({
4623
- key: 0,
4624
- ref_for: true
4625
- }, getSlotBindings(item, null, index))) : createCommentVNode("", true),
4626
- __props.rowEditing && isEditingRow(item, index) ? (openBlock(), createBlock(_sfc_main$J, {
4627
- key: 1,
4628
- type: "button",
4629
- variant: "outline",
4630
- size: "icon",
4631
- title: __props.cancelLabel,
4632
- "aria-label": __props.cancelLabel,
4633
- onClick: ($event) => cancelEdit(item, index)
4634
- }, {
4635
- default: withCtx(() => [
4636
- createVNode(unref(CheckIcon), { class: "size-4" })
4637
- ]),
4638
- _: 1
4639
- }, 8, ["title", "aria-label", "onClick"])) : __props.rowEditing ? (openBlock(), createBlock(_sfc_main$J, {
4640
- key: 2,
4641
- type: "button",
4642
- variant: "secondary",
4643
- size: "icon",
4644
- disabled: isRowEditDisabled(item, index),
4645
- title: __props.editLabel,
4646
- "aria-label": __props.editLabel,
4647
- onClick: ($event) => startEdit(item, index)
4648
- }, {
4649
- default: withCtx(() => [
4650
- createVNode(unref(PencilSquareIcon), { class: "size-4" })
4651
- ]),
4652
- _: 1
4653
- }, 8, ["disabled", "title", "aria-label", "onClick"])) : createCommentVNode("", true)
4654
- ])
4655
- ])) : createCommentVNode("", true)
4656
- ], 2);
4657
- }), 128))
4658
- ])
4659
- ])
4660
- ], 2)) : (openBlock(), createElementBlock("div", _hoisted_15, [
4661
- createElementVNode("div", _hoisted_16, [
4662
- (openBlock(), createBlock(resolveDynamicComponent(__props.emptyState.icon), { class: "h-8 w-8 text-neutral-400 dark:text-neutral-200" }))
4663
- ]),
4664
- createElementVNode("h3", _hoisted_17, toDisplayString(__props.emptyState.title), 1),
4665
- createElementVNode("p", _hoisted_18, toDisplayString(__props.emptyState.description), 1),
4666
- __props.emptyState.actionText && __props.emptyState.actionUrl ? (openBlock(), createBlock(_sfc_main$l, {
4667
- key: 0,
4668
- href: __props.emptyState.actionUrl,
4669
- variant: "primary"
4670
- }, {
4671
- default: withCtx(() => [
4672
- createTextVNode(toDisplayString(__props.emptyState.actionText), 1)
4673
- ]),
4674
- _: 1
4675
- }, 8, ["href"])) : createCommentVNode("", true)
4676
- ]))
4677
- ], 2);
4678
- };
4679
- }
4680
- };
4681
- const _hoisted_1$1 = { class: "grid gap-1" };
4682
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
4683
- __name: "Toast",
4684
- props: {
4685
- class: { type: [Boolean, null, String, Object, Array] },
4686
- variant: {}
4687
- },
4688
- emits: ["close"],
4689
- setup(__props) {
4690
- const props = __props;
4691
- const variants = {
4692
- default: "bg-background border-border text-foreground",
4693
- destructive: "bg-destructive text-destructive-foreground border-destructive",
4694
- success: "bg-green-500 text-white border-green-600 dark:bg-green-700 dark:border-green-800",
4695
- error: "bg-red-500 text-white border-red-600 dark:bg-red-900 dark:border-red-950"
4696
- };
4697
- return (_ctx, _cache) => {
4698
- return openBlock(), createElementBlock("div", {
4699
- class: normalizeClass([
4700
- "relative flex w-full max-w-sm items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all",
4701
- variants[__props.variant || "default"],
4702
- props.class
4703
- ]),
4704
- role: "alert"
4705
- }, [
4706
- createElementVNode("div", _hoisted_1$1, [
4707
- renderSlot(_ctx.$slots, "default")
4708
- ]),
4709
- createElementVNode("button", {
4710
- class: "absolute top-2 right-2 rounded-md opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
4711
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("close"))
4712
- }, [..._cache[1] || (_cache[1] = [
4713
- createElementVNode("svg", {
4714
- xmlns: "http://www.w3.org/2000/svg",
4715
- width: "24",
4716
- height: "24",
4717
- viewBox: "0 0 24 24",
4718
- fill: "none",
4719
- stroke: "currentColor",
4720
- "stroke-width": "2",
4721
- "stroke-linecap": "round",
4722
- "stroke-linejoin": "round",
4723
- class: "h-4 w-4"
4724
- }, [
4725
- createElementVNode("line", {
4726
- x1: "18",
4727
- y1: "6",
4728
- x2: "6",
4729
- y2: "18"
4730
- }),
4731
- createElementVNode("line", {
4732
- x1: "6",
4733
- y1: "6",
4734
- x2: "18",
4735
- y2: "18"
4736
- })
4737
- ], -1),
4738
- createElementVNode("span", { class: "sr-only" }, "Close", -1)
4739
- ])])
4740
- ], 2);
4741
- };
4742
- }
4743
- });
4744
- const _hoisted_1 = { class: "fixed top-4 right-4 z-50 space-y-2" };
4745
- const _hoisted_2 = {
4746
- key: 0,
4747
- class: "font-semibold"
4748
- };
4749
- const _hoisted_3 = { class: "text-sm opacity-90" };
4750
- const _sfc_main = /* @__PURE__ */ defineComponent({
4751
- __name: "ToastContainer",
4752
- props: {
4753
- maxToasts: {},
4754
- position: {},
4755
- variant: {},
4756
- defaultTitle: {}
4757
- },
4758
- setup(__props, { expose: __expose }) {
4759
- const props = __props;
4760
- const toasts = ref([]);
4761
- const addToast = (message, options = {}) => {
4762
- const {
4763
- variant = "success",
4764
- duration = 5e3,
4765
- title
4766
- } = options;
4767
- const id = Date.now().toString();
4768
- const toast = {
4769
- id,
4770
- title: title ?? (props.defaultTitle || void 0),
4771
- message,
4772
- variant,
4773
- duration
4774
- };
4775
- toasts.value.push(toast);
4776
- if (duration > 0) {
4777
- setTimeout(() => {
4778
- removeToast(id);
4779
- }, duration);
4780
- }
4781
- };
4782
- const removeToast = (id) => {
4783
- const index = toasts.value.findIndex((toast) => toast.id === id);
4784
- if (index > -1) {
4785
- toasts.value.splice(index, 1);
4786
- }
4787
- };
4788
- __expose({
4789
- addToast
4790
- });
4791
- return (_ctx, _cache) => {
4792
- return openBlock(), createElementBlock("div", _hoisted_1, [
4793
- (openBlock(true), createElementBlock(Fragment, null, renderList(toasts.value, (toast) => {
4794
- return openBlock(), createBlock(_sfc_main$1, {
4795
- key: toast.id,
4796
- variant: toast.variant || props.variant,
4797
- onClose: ($event) => removeToast(toast.id)
4798
- }, {
4799
- default: withCtx(() => [
4800
- toast.title ? (openBlock(), createElementBlock("div", _hoisted_2, toDisplayString(toast.title), 1)) : createCommentVNode("", true),
4801
- createElementVNode("div", _hoisted_3, toDisplayString(toast.message), 1)
4802
- ]),
4803
- _: 2
4804
- }, 1032, ["variant", "onClose"]);
4805
- }), 128))
4806
- ]);
4807
- };
4808
- }
4809
- });
4810
- const plugin = {
4811
- install(app) {
4812
- for (const [name, component] of Object.entries(components)) {
4813
- if (name === "EnosVueDefault") {
4814
- continue;
4815
- }
4816
- app.component(name, component);
4817
- }
4818
- }
4819
- };
1
+ import './styles.css';
2
+ import { _, a, b, c, d, e, f, g, h, i, j, k, D, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, S, B, C, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, T, U, V, W, X, Y, Z, $, a0, a1 } from "./plugin-CtVat25d.js";
4820
3
  export {
4821
- _sfc_main$O as ActionCard,
4822
- _sfc_main$N as ActionMessage,
4823
- _sfc_main$L as ActionSection,
4824
- _sfc_main$K as Badge,
4825
- _sfc_main$J as Button,
4826
- _sfc_main$Q as Card,
4827
- _sfc_main$R as CardTabs,
4828
- _sfc_main$I as Checkbox,
4829
- _sfc_main$H as CheckboxInput,
4830
- _sfc_main$u as CheckboxMultipleInput,
4831
- _sfc_main$s as ConfirmationModal,
4832
- _sfc_main$E as CustomSelect,
4833
- DateInput,
4834
- _sfc_main$r as DialogModal,
4835
- _sfc_main$P as Divider,
4836
- _sfc_main$q as Dropdown,
4837
- _sfc_main$p as DropdownLink,
4838
- plugin as EnosVueDefault,
4839
- _sfc_main$o as FormSection,
4840
- _sfc_main$B as ImageInput,
4841
- _sfc_main$n as InputError,
4842
- _sfc_main$v as InputGroup,
4843
- _sfc_main$m as InputLabel,
4844
- _sfc_main$l as LinkButton,
4845
- _sfc_main$t as Modal,
4846
- _sfc_main$A as NotationInput,
4847
- _sfc_main$z as RadioInput,
4848
- _sfc_main$x as RadioMultipleInput,
4849
- _sfc_main$k as SectionBorder,
4850
- SectionTitle,
4851
- _sfc_main$D as SelectInput,
4852
- _sfc_main$j as Sidebar,
4853
- _sfc_main$i as SidebarContent,
4854
- _sfc_main$h as SidebarFooter,
4855
- _sfc_main$g as SidebarGroup,
4856
- _sfc_main$f as SidebarGroupContent,
4857
- _sfc_main$e as SidebarGroupLabel,
4858
- _sfc_main$d as SidebarHeader,
4859
- _sfc_main$c as SidebarInset,
4860
- _sfc_main$b as SidebarMenu,
4861
- _sfc_main$a as SidebarMenuButton,
4862
- _sfc_main$9 as SidebarMenuItem,
4863
- _sfc_main$8 as SidebarProvider,
4864
- _sfc_main$7 as SidebarTrigger,
4865
- _sfc_main$6 as SortControls,
4866
- _sfc_main$3 as TableList,
4867
- _sfc_main$2 as TableListForm,
4868
- _sfc_main$4 as TableSearch,
4869
- _sfc_main$F as TextArea,
4870
- _sfc_main$G as TextInput,
4871
- _sfc_main$5 as ThSortable,
4872
- _sfc_main$w as TinyEditor,
4873
- _sfc_main$1 as Toast,
4874
- _sfc_main as ToastContainer,
4875
- _sfc_main$y as ToggleInput,
4876
- useSidebar
4
+ _ as ActionCard,
5
+ a as ActionMessage,
6
+ b as ActionSection,
7
+ c as Badge,
8
+ d as Button,
9
+ e as Card,
10
+ f as CardTabs,
11
+ g as Checkbox,
12
+ h as CheckboxInput,
13
+ i as CheckboxMultipleInput,
14
+ j as ConfirmationModal,
15
+ k as CustomSelect,
16
+ D as DateInput,
17
+ l as DialogModal,
18
+ m as Divider,
19
+ n as Dropdown,
20
+ o as DropdownLink,
21
+ p as EnosVueDefault,
22
+ q as FormSection,
23
+ r as ImageInput,
24
+ s as InputError,
25
+ t as InputGroup,
26
+ u as InputLabel,
27
+ v as LinkButton,
28
+ w as Modal,
29
+ x as NotationInput,
30
+ y as RadioInput,
31
+ z as RadioMultipleInput,
32
+ A as SectionBorder,
33
+ S as SectionTitle,
34
+ B as SelectInput,
35
+ C as Sidebar,
36
+ E as SidebarContent,
37
+ F as SidebarFooter,
38
+ G as SidebarGroup,
39
+ H as SidebarGroupContent,
40
+ I as SidebarGroupLabel,
41
+ J as SidebarHeader,
42
+ K as SidebarInset,
43
+ L as SidebarMenu,
44
+ M as SidebarMenuButton,
45
+ N as SidebarMenuItem,
46
+ O as SidebarProvider,
47
+ P as SidebarTrigger,
48
+ Q as SortControls,
49
+ R as TableList,
50
+ T as TableListForm,
51
+ U as TableSearch,
52
+ V as TextArea,
53
+ W as TextInput,
54
+ X as ThSortable,
55
+ Y as TinyEditor,
56
+ Z as Toast,
57
+ $ as ToastContainer,
58
+ a0 as ToggleInput,
59
+ a1 as useSidebar
4877
60
  };
4878
61
  //# sourceMappingURL=index.js.map