@enos5/enos-vue-default 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +59 -6
  2. package/dist/_commonjsHelpers-CUmg6egw.js +7 -0
  3. package/dist/_commonjsHelpers-CUmg6egw.js.map +1 -0
  4. package/dist/components/ActionCard.vue.d.ts +33 -0
  5. package/dist/components/ActionMessage.vue.d.ts +16 -0
  6. package/dist/components/ActionSection.vue.d.ts +14 -0
  7. package/dist/components/Badge.vue.d.ts +59 -0
  8. package/dist/components/Button.vue.d.ts +40 -0
  9. package/dist/components/Card.vue.d.ts +95 -0
  10. package/dist/components/CardTabs.vue.d.ts +32 -0
  11. package/dist/components/Checkbox.vue.d.ts +28 -0
  12. package/dist/components/CheckboxInput.vue.d.ts +55 -0
  13. package/dist/components/CheckboxMultipleInput.vue.d.ts +37 -0
  14. package/dist/components/ConfirmationModal.vue.d.ts +59 -0
  15. package/dist/components/CustomSelect.vue.d.ts +190 -0
  16. package/dist/components/DateInput.vue.d.ts +48 -0
  17. package/dist/components/DialogModal.vue.d.ts +48 -0
  18. package/dist/components/Divider.vue.d.ts +10 -0
  19. package/dist/components/Dropdown.vue.d.ts +44 -0
  20. package/dist/components/DropdownLink.vue.d.ts +20 -0
  21. package/dist/components/FormSection.vue.d.ts +20 -0
  22. package/dist/components/ImageInput.vue.d.ts +55 -0
  23. package/dist/components/InputError.vue.d.ts +7 -0
  24. package/dist/components/InputGroup.vue.d.ts +345 -0
  25. package/dist/components/InputLabel.vue.d.ts +14 -0
  26. package/dist/components/LinkButton.vue.d.ts +68 -0
  27. package/dist/components/Modal.vue.d.ts +55 -0
  28. package/dist/components/NotationInput.vue.d.ts +37 -0
  29. package/dist/components/RadioInput.vue.d.ts +55 -0
  30. package/dist/components/RadioMultipleInput.vue.d.ts +46 -0
  31. package/dist/components/SectionBorder.vue.d.ts +3 -0
  32. package/dist/components/SectionTitle.vue.d.ts +17 -0
  33. package/dist/components/SelectInput.vue.d.ts +190 -0
  34. package/dist/components/SortControls.vue.d.ts +67 -0
  35. package/dist/components/TableList.vue.d.ts +126 -0
  36. package/dist/components/TableListForm.vue.d.ts +258 -0
  37. package/dist/components/TextArea.vue.d.ts +41 -0
  38. package/dist/components/TextInput.vue.d.ts +41 -0
  39. package/dist/components/ThSortable.vue.d.ts +39 -0
  40. package/dist/components/TinyEditor.vue.d.ts +93 -0
  41. package/dist/index-6eLEqodC.js +284 -0
  42. package/dist/index-6eLEqodC.js.map +1 -0
  43. package/dist/index-BHTvTOGk.js +3349 -0
  44. package/dist/index-BHTvTOGk.js.map +1 -0
  45. package/dist/index-BPcdR1qv.js +1580 -0
  46. package/dist/index-BPcdR1qv.js.map +1 -0
  47. package/dist/index-Ch9hFG6f.js +7805 -0
  48. package/dist/index-Ch9hFG6f.js.map +1 -0
  49. package/dist/index-CiFpmPug.js +122 -0
  50. package/dist/index-CiFpmPug.js.map +1 -0
  51. package/dist/index-Cjhk16SP.js +1579 -0
  52. package/dist/index-Cjhk16SP.js.map +1 -0
  53. package/dist/index-D7sesyMc.js +573 -0
  54. package/dist/index-D7sesyMc.js.map +1 -0
  55. package/dist/index-G1cAlO5C.js +31203 -0
  56. package/dist/index-G1cAlO5C.js.map +1 -0
  57. package/dist/index.css +5615 -0
  58. package/dist/index.d.ts +37 -0
  59. package/dist/index.js +3781 -2
  60. package/dist/index.js.map +1 -1
  61. package/dist/plugin.d.ts +1 -1
  62. package/dist/tinymce-WPdeGquX.js +35485 -0
  63. package/dist/tinymce-WPdeGquX.js.map +1 -0
  64. package/package.json +9 -2
package/dist/index.js CHANGED
@@ -1,8 +1,3787 @@
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, createTextVNode, resolveDynamicComponent, vModelText } 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$x;
9
+ },
10
+ get ActionMessage() {
11
+ return _sfc_main$w;
12
+ },
13
+ get ActionSection() {
14
+ return _sfc_main$u;
15
+ },
16
+ get Badge() {
17
+ return _sfc_main$t;
18
+ },
19
+ get Button() {
20
+ return _sfc_main$s;
21
+ },
22
+ get Card() {
23
+ return _sfc_main$z;
24
+ },
25
+ get CardTabs() {
26
+ return _sfc_main$A;
27
+ },
28
+ get Checkbox() {
29
+ return _sfc_main$r;
30
+ },
31
+ get CheckboxInput() {
32
+ return _sfc_main$q;
33
+ },
34
+ get CheckboxMultipleInput() {
35
+ return _sfc_main$e;
36
+ },
37
+ get ConfirmationModal() {
38
+ return _sfc_main$c;
39
+ },
40
+ get CustomSelect() {
41
+ return _sfc_main$n;
42
+ },
43
+ get DateInput() {
44
+ return _sfc_main$l;
45
+ },
46
+ get DialogModal() {
47
+ return _sfc_main$b;
48
+ },
49
+ get Divider() {
50
+ return _sfc_main$y;
51
+ },
52
+ get Dropdown() {
53
+ return _sfc_main$a;
54
+ },
55
+ get DropdownLink() {
56
+ return _sfc_main$9;
57
+ },
58
+ get EnosVueDefault() {
59
+ return plugin;
60
+ },
61
+ get FormSection() {
62
+ return _sfc_main$8;
63
+ },
64
+ get ImageInput() {
65
+ return _sfc_main$k;
66
+ },
67
+ get InputError() {
68
+ return _sfc_main$7;
69
+ },
70
+ get InputGroup() {
71
+ return _sfc_main$f;
72
+ },
73
+ get InputLabel() {
74
+ return _sfc_main$6;
75
+ },
76
+ get LinkButton() {
77
+ return _sfc_main$5;
78
+ },
79
+ get Modal() {
80
+ return _sfc_main$d;
81
+ },
82
+ get NotationInput() {
83
+ return _sfc_main$j;
84
+ },
85
+ get RadioInput() {
86
+ return _sfc_main$i;
87
+ },
88
+ get RadioMultipleInput() {
89
+ return _sfc_main$h;
90
+ },
91
+ get SectionBorder() {
92
+ return _sfc_main$4;
93
+ },
94
+ get SectionTitle() {
95
+ return SectionTitle;
96
+ },
97
+ get SelectInput() {
98
+ return _sfc_main$m;
99
+ },
100
+ get SortControls() {
101
+ return _sfc_main$3;
102
+ },
103
+ get TableList() {
104
+ return _sfc_main$1;
105
+ },
106
+ get TableListForm() {
107
+ return _sfc_main;
108
+ },
109
+ get TextArea() {
110
+ return _sfc_main$o;
111
+ },
112
+ get TextInput() {
113
+ return _sfc_main$p;
114
+ },
115
+ get ThSortable() {
116
+ return _sfc_main$2;
117
+ },
118
+ get TinyEditor() {
119
+ return _sfc_main$g;
120
+ }
121
+ }, Symbol.toStringTag, { value: "Module" }));
122
+ const _hoisted_1$w = { class: "border-b border-gray-200/80 bg-gray-50/80 p-2" };
123
+ const _hoisted_2$h = {
124
+ role: "tablist",
125
+ class: "flex rounded-lg bg-white shadow-sm ring-1 ring-gray-200/80 overflow-hidden"
126
+ };
127
+ const _hoisted_3$c = ["aria-selected", "tabindex", "onClick", "onKeydown"];
128
+ const _sfc_main$A = {
129
+ __name: "CardTabs",
130
+ props: {
131
+ tabs: {
132
+ type: Array,
133
+ default: () => [],
134
+ validator: (tabs) => tabs.every((tab) => typeof tab === "object" && tab !== null && typeof tab.value === "string" && tab.value.length > 0 && typeof tab.label === "string")
135
+ },
136
+ activeTab: {
137
+ type: String,
138
+ default: ""
139
+ }
140
+ },
141
+ emits: [
142
+ "update:activeTab",
143
+ "tab-click"
144
+ ],
145
+ setup(__props, { emit: __emit }) {
146
+ const props = __props;
147
+ const emit = __emit;
148
+ const tabButtons = ref([]);
149
+ const availableTabValues = computed(() => props.tabs.map((tab) => tab.value));
150
+ const currentActiveTab = computed(() => availableTabValues.value.includes(props.activeTab) ? props.activeTab : availableTabValues.value[0] ?? "");
151
+ watch(currentActiveTab, (value) => {
152
+ if (value !== props.activeTab) {
153
+ emit("update:activeTab", value);
154
+ }
155
+ }, { immediate: true });
156
+ const setTabButtonRef = (element, index) => {
157
+ tabButtons.value[index] = element;
158
+ };
159
+ const activateTab = (value) => {
160
+ if (!value || value === props.activeTab) {
161
+ return;
162
+ }
163
+ emit("update:activeTab", value);
164
+ emit("tab-click", value);
165
+ };
166
+ const focusTabAtIndex = (index) => {
167
+ tabButtons.value[index]?.focus();
168
+ };
169
+ const onTabKeydown = (event, index) => {
170
+ if (props.tabs.length === 0) {
171
+ return;
172
+ }
173
+ let targetIndex = index;
174
+ switch (event.key) {
175
+ case "ArrowRight":
176
+ case "ArrowDown":
177
+ targetIndex = (index + 1) % props.tabs.length;
178
+ break;
179
+ case "ArrowLeft":
180
+ case "ArrowUp":
181
+ targetIndex = (index - 1 + props.tabs.length) % props.tabs.length;
182
+ break;
183
+ case "Home":
184
+ targetIndex = 0;
185
+ break;
186
+ case "End":
187
+ targetIndex = props.tabs.length - 1;
188
+ break;
189
+ default:
190
+ return;
191
+ }
192
+ event.preventDefault();
193
+ activateTab(props.tabs[targetIndex].value);
194
+ focusTabAtIndex(targetIndex);
195
+ };
196
+ return (_ctx, _cache) => {
197
+ return openBlock(), createElementBlock("div", _hoisted_1$w, [
198
+ createElementVNode("div", _hoisted_2$h, [
199
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab, index) => {
200
+ return openBlock(), createElementBlock("button", {
201
+ key: tab.value,
202
+ ref_for: true,
203
+ ref: (element) => setTabButtonRef(element, index),
204
+ type: "button",
205
+ style: normalizeStyle({ width: `${100 / __props.tabs.length}%` }),
206
+ role: "tab",
207
+ "aria-selected": currentActiveTab.value === tab.value,
208
+ tabindex: currentActiveTab.value === tab.value ? 0 : -1,
209
+ class: normalizeClass([
210
+ "px-4 py-3 text-center text-sm font-semibold tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-inset",
211
+ currentActiveTab.value === tab.value ? "bg-blue-50 text-blue-700 shadow-[inset_0_-2px_0_0_rgb(37_99_235)]" : "text-gray-700 hover:bg-gray-50",
212
+ {
213
+ "border-r border-gray-200/80": index !== __props.tabs.length - 1
214
+ }
215
+ ]),
216
+ onClick: ($event) => activateTab(tab.value),
217
+ onKeydown: ($event) => onTabKeydown($event, index)
218
+ }, toDisplayString(tab.label), 47, _hoisted_3$c);
219
+ }), 128))
220
+ ])
221
+ ]);
222
+ };
223
+ }
224
+ };
225
+ const _hoisted_1$v = {
226
+ key: 0,
227
+ class: "mb-4"
228
+ };
229
+ const _hoisted_2$g = {
230
+ key: 1,
231
+ class: "mb-4 text-xl font-semibold tracking-tight text-slate-900"
232
+ };
233
+ const _sfc_main$z = {
234
+ __name: "Card",
235
+ props: {
236
+ title: {
237
+ type: String,
238
+ default: ""
239
+ },
240
+ sticky: {
241
+ type: Boolean,
242
+ default: false
243
+ },
244
+ paddingClass: {
245
+ type: String,
246
+ default: "p-6 lg:p-8"
247
+ },
248
+ cardClass: {
249
+ type: String,
250
+ default: ""
251
+ },
252
+ overflowClass: {
253
+ type: String,
254
+ default: "overflow-visible"
255
+ },
256
+ contentClass: {
257
+ type: String,
258
+ default: ""
259
+ },
260
+ tabs: {
261
+ type: Array,
262
+ default: () => [],
263
+ validator: (tabs) => tabs.every((tab) => typeof tab === "object" && tab !== null && typeof tab.value === "string" && tab.value.length > 0 && typeof tab.label === "string")
264
+ },
265
+ activeTab: {
266
+ type: String,
267
+ default: ""
268
+ }
269
+ },
270
+ emits: [
271
+ "update:activeTab",
272
+ "tab-click"
273
+ ],
274
+ setup(__props) {
275
+ const props = __props;
276
+ const previousActiveTab = ref("");
277
+ const slideDirection = ref("right");
278
+ const currentTabIndex = computed(() => {
279
+ return props.tabs.findIndex((tab) => tab.value === props.activeTab);
280
+ });
281
+ computed(() => {
282
+ return props.tabs.findIndex((tab) => tab.value === previousActiveTab.value);
283
+ });
284
+ watch(currentTabIndex, (newIndex, oldIndex) => {
285
+ if (oldIndex !== void 0 && oldIndex !== -1 && newIndex !== -1 && newIndex !== oldIndex) {
286
+ slideDirection.value = newIndex > oldIndex ? "right" : "left";
287
+ previousActiveTab.value = props.activeTab;
288
+ }
289
+ });
290
+ return (_ctx, _cache) => {
291
+ return openBlock(), createElementBlock("div", {
292
+ class: normalizeClass(["bg-white border border-slate-200/70 rounded-2xl shadow-[0_12px_30px_rgba(15,23,42,0.06)]", __props.overflowClass, { "sticky top-6 self-start": __props.sticky }, __props.cardClass])
293
+ }, [
294
+ __props.tabs.length > 0 ? (openBlock(), createBlock(_sfc_main$A, {
295
+ key: 0,
296
+ tabs: __props.tabs,
297
+ "active-tab": __props.activeTab,
298
+ "onUpdate:activeTab": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:activeTab", $event)),
299
+ onTabClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("tab-click", $event))
300
+ }, null, 8, ["tabs", "active-tab"])) : createCommentVNode("", true),
301
+ createElementVNode("div", {
302
+ class: normalizeClass(__props.paddingClass)
303
+ }, [
304
+ _ctx.$slots.customTitle ? (openBlock(), createElementBlock("div", _hoisted_1$v, [
305
+ renderSlot(_ctx.$slots, "customTitle")
306
+ ])) : __props.title ? (openBlock(), createElementBlock("h3", _hoisted_2$g, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
307
+ createElementVNode("div", {
308
+ class: normalizeClass(["relative", __props.tabs.length > 0 ? "overflow-hidden" : "overflow-visible"])
309
+ }, [
310
+ createVNode(Transition, {
311
+ "enter-active-class": "transition-all duration-200 ease-in-out",
312
+ "enter-from-class": slideDirection.value === "right" ? "translate-x-full opacity-0" : "-translate-x-full opacity-0",
313
+ "enter-to-class": "translate-x-0 opacity-100",
314
+ "leave-active-class": "transition-all duration-200 ease-in-out",
315
+ "leave-from-class": "translate-x-0 opacity-100",
316
+ "leave-to-class": slideDirection.value === "right" ? "-translate-x-full opacity-0" : "translate-x-full opacity-0",
317
+ mode: "out-in"
318
+ }, {
319
+ default: withCtx(() => [
320
+ (openBlock(), createElementBlock("div", {
321
+ key: __props.activeTab,
322
+ class: normalizeClass([__props.tabs.length > 0 ? "p-2" : "", __props.contentClass])
323
+ }, [
324
+ renderSlot(_ctx.$slots, "default")
325
+ ], 2))
326
+ ]),
327
+ _: 3
328
+ }, 8, ["enter-from-class", "leave-to-class"])
329
+ ], 2)
330
+ ], 2)
331
+ ], 2);
332
+ };
333
+ }
334
+ };
335
+ const _sfc_main$y = /* @__PURE__ */ Object.assign({
336
+ inheritAttrs: false
337
+ }, {
338
+ __name: "Divider",
339
+ setup(__props) {
340
+ return (_ctx, _cache) => {
341
+ return openBlock(), createElementBlock("div", mergeProps({ class: "border-t border-gray-200" }, _ctx.$attrs), [
342
+ renderSlot(_ctx.$slots, "default")
343
+ ], 16);
344
+ };
345
+ }
346
+ });
347
+ const _sfc_main$x = {
348
+ __name: "ActionCard",
349
+ props: {
350
+ title: {
351
+ type: String,
352
+ default: ""
353
+ },
354
+ actionsClass: {
355
+ type: String,
356
+ default: "space-y-3"
357
+ }
358
+ },
359
+ setup(__props) {
360
+ const slots = useSlots();
361
+ return (_ctx, _cache) => {
362
+ return openBlock(), createBlock(_sfc_main$z, {
363
+ title: __props.title,
364
+ "content-class": __props.actionsClass
365
+ }, {
366
+ default: withCtx(() => [
367
+ renderSlot(_ctx.$slots, "default"),
368
+ unref(slots).danger ? (openBlock(), createBlock(_sfc_main$y, {
369
+ key: 0,
370
+ class: "mt-6 pt-4"
371
+ }, {
372
+ default: withCtx(() => [
373
+ renderSlot(_ctx.$slots, "danger")
374
+ ]),
375
+ _: 3
376
+ })) : createCommentVNode("", true)
377
+ ]),
378
+ _: 3
379
+ }, 8, ["title", "content-class"]);
380
+ };
381
+ }
382
+ };
383
+ const _hoisted_1$u = { class: "text-sm text-gray-600" };
384
+ const _sfc_main$w = {
385
+ __name: "ActionMessage",
386
+ props: {
387
+ on: Boolean
388
+ },
389
+ setup(__props) {
390
+ return (_ctx, _cache) => {
391
+ return openBlock(), createElementBlock("div", null, [
392
+ createVNode(Transition, {
393
+ "leave-active-class": "transition ease-in duration-1000",
394
+ "leave-from-class": "opacity-100",
395
+ "leave-to-class": "opacity-0"
396
+ }, {
397
+ default: withCtx(() => [
398
+ withDirectives(createElementVNode("div", _hoisted_1$u, [
399
+ renderSlot(_ctx.$slots, "default")
400
+ ], 512), [
401
+ [vShow, __props.on]
402
+ ])
403
+ ]),
404
+ _: 3
405
+ })
406
+ ]);
407
+ };
408
+ }
409
+ };
410
+ const _export_sfc = (sfc, props) => {
411
+ const target = sfc.__vccOpts || sfc;
412
+ for (const [key, val] of props) {
413
+ target[key] = val;
414
+ }
415
+ return target;
416
+ };
417
+ const _sfc_main$v = {};
418
+ const _hoisted_1$t = { class: "md:col-span-1 flex justify-between" };
419
+ const _hoisted_2$f = { class: "px-4 sm:px-0" };
420
+ const _hoisted_3$b = { class: "text-xl font-semibold tracking-tight text-slate-900" };
421
+ const _hoisted_4$8 = { class: "mt-1 max-w-2xl text-sm text-slate-600" };
422
+ const _hoisted_5$6 = { class: "px-4 sm:px-0" };
423
+ function _sfc_render(_ctx, _cache) {
424
+ return openBlock(), createElementBlock("div", _hoisted_1$t, [
425
+ createElementVNode("div", _hoisted_2$f, [
426
+ createElementVNode("h3", _hoisted_3$b, [
427
+ renderSlot(_ctx.$slots, "title")
428
+ ]),
429
+ createElementVNode("p", _hoisted_4$8, [
430
+ renderSlot(_ctx.$slots, "description")
431
+ ])
432
+ ]),
433
+ createElementVNode("div", _hoisted_5$6, [
434
+ renderSlot(_ctx.$slots, "aside")
435
+ ])
436
+ ]);
437
+ }
438
+ const SectionTitle = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["render", _sfc_render]]);
439
+ const _hoisted_1$s = { class: "md:grid md:grid-cols-3 md:gap-6" };
440
+ const _hoisted_2$e = { class: "mt-5 md:mt-0 md:col-span-2" };
441
+ const _hoisted_3$a = { class: "px-4 py-5 sm:p-6 bg-white shadow sm:rounded-lg" };
442
+ const _sfc_main$u = {
443
+ __name: "ActionSection",
444
+ setup(__props) {
445
+ return (_ctx, _cache) => {
446
+ return openBlock(), createElementBlock("div", _hoisted_1$s, [
447
+ createVNode(SectionTitle, null, {
448
+ title: withCtx(() => [
449
+ renderSlot(_ctx.$slots, "title")
450
+ ]),
451
+ description: withCtx(() => [
452
+ renderSlot(_ctx.$slots, "description")
453
+ ]),
454
+ _: 3
455
+ }),
456
+ createElementVNode("div", _hoisted_2$e, [
457
+ createElementVNode("div", _hoisted_3$a, [
458
+ renderSlot(_ctx.$slots, "content")
459
+ ])
460
+ ])
461
+ ]);
462
+ };
463
+ }
464
+ };
465
+ const _hoisted_1$r = { class: "sr-only" };
466
+ const _sfc_main$t = {
467
+ __name: "Badge",
468
+ props: {
469
+ type: {
470
+ type: String,
471
+ default: "default",
472
+ validator: (value) => ["default", "dot"].includes(value)
473
+ },
474
+ color: {
475
+ type: String,
476
+ default: "default",
477
+ validator: (value) => [
478
+ "default",
479
+ "primary",
480
+ "secondary",
481
+ "success",
482
+ "warning",
483
+ "danger",
484
+ "info",
485
+ "gray"
486
+ ].includes(value)
487
+ },
488
+ size: {
489
+ type: String,
490
+ default: "md",
491
+ validator: (value) => ["xs", "sm", "md", "lg"].includes(value)
492
+ },
493
+ rounded: {
494
+ type: String,
495
+ default: "full",
496
+ validator: (value) => ["none", "sm", "md", "lg", "full"].includes(value)
497
+ }
498
+ },
499
+ setup(__props) {
500
+ const colorClasses = {
501
+ default: { bg: "bg-slate-100", text: "text-slate-700", dot: "bg-slate-600" },
502
+ primary: { bg: "bg-blue-100", text: "text-blue-700", dot: "bg-blue-600" },
503
+ secondary: { bg: "bg-slate-100", text: "text-slate-700", dot: "bg-slate-600" },
504
+ success: { bg: "bg-emerald-100", text: "text-emerald-700", dot: "bg-emerald-600" },
505
+ warning: { bg: "bg-amber-100", text: "text-amber-700", dot: "bg-amber-600" },
506
+ danger: { bg: "bg-rose-100", text: "text-rose-700", dot: "bg-rose-600" },
507
+ info: { bg: "bg-cyan-100", text: "text-cyan-700", dot: "bg-cyan-600" },
508
+ gray: { bg: "bg-slate-100", text: "text-slate-600", dot: "bg-slate-600" }
509
+ };
510
+ const sizeClasses = {
511
+ xs: "px-1.5 py-0.5 text-xs",
512
+ sm: "px-2 py-0.5 text-xs",
513
+ md: "px-2.5 py-0.5 text-xs",
514
+ lg: "px-3 py-1 text-sm"
515
+ };
516
+ const roundedClasses = {
517
+ none: "rounded-none",
518
+ sm: "rounded-sm",
519
+ md: "rounded-md",
520
+ lg: "rounded-lg",
521
+ full: "rounded-full"
522
+ };
523
+ return (_ctx, _cache) => {
524
+ return __props.type === "dot" ? (openBlock(), createElementBlock("span", {
525
+ key: 0,
526
+ class: normalizeClass(["inline-flex items-center justify-center w-6 h-6 rounded-full", colorClasses[__props.color].bg])
527
+ }, [
528
+ createElementVNode("span", {
529
+ class: normalizeClass(["w-2 h-2 rounded-full", colorClasses[__props.color].dot])
530
+ }, null, 2),
531
+ createElementVNode("span", _hoisted_1$r, [
532
+ renderSlot(_ctx.$slots, "default")
533
+ ])
534
+ ], 2)) : (openBlock(), createElementBlock("span", {
535
+ key: 1,
536
+ class: normalizeClass(["inline-flex items-center font-medium", [
537
+ colorClasses[__props.color].bg,
538
+ colorClasses[__props.color].text,
539
+ sizeClasses[__props.size],
540
+ roundedClasses[__props.rounded]
541
+ ]])
542
+ }, [
543
+ renderSlot(_ctx.$slots, "default")
544
+ ], 2));
545
+ };
546
+ }
547
+ };
548
+ const _hoisted_1$q = ["type", "disabled"];
549
+ const _sfc_main$s = /* @__PURE__ */ Object.assign({
550
+ inheritAttrs: false
551
+ }, {
552
+ __name: "Button",
553
+ props: {
554
+ type: {
555
+ type: String,
556
+ default: "submit"
557
+ },
558
+ disabled: {
559
+ type: Boolean,
560
+ default: false
561
+ },
562
+ variant: {
563
+ type: String,
564
+ default: "primary"
565
+ }
566
+ },
567
+ setup(__props) {
568
+ const attrs = useAttrs();
569
+ const props = __props;
570
+ const variantClasses = {
571
+ primary: "bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-[0_6px_14px_rgba(37,99,235,0.14)] hover:from-blue-600 hover:to-blue-700 hover:shadow-[0_8px_18px_rgba(37,99,235,0.18)] focus:ring-blue-500 disabled:hover:from-blue-500 disabled:hover:to-blue-600",
572
+ success: "bg-gradient-to-r from-green-500 to-green-600 text-white shadow-[0_6px_14px_rgba(34,197,94,0.14)] hover:from-green-600 hover:to-green-700 hover:shadow-[0_8px_18px_rgba(34,197,94,0.18)] focus:ring-green-500 disabled:hover:from-green-500 disabled:hover:to-green-600",
573
+ secondary: "bg-gradient-to-r from-slate-700 to-slate-800 text-white shadow-[0_8px_18px_rgba(15,23,42,0.16)] hover:from-slate-800 hover:to-slate-900 hover:shadow-[0_10px_22px_rgba(15,23,42,0.22)] focus:ring-slate-500 disabled:hover:from-slate-700 disabled:hover:to-slate-800",
574
+ tertiary: "border border-slate-300 bg-white text-slate-700 shadow-sm hover:bg-slate-50 hover:border-slate-400 hover:shadow focus:ring-slate-500 disabled:hover:bg-white",
575
+ warning: "border border-amber-300 bg-amber-50 text-amber-800 shadow-sm hover:bg-amber-100 focus:ring-amber-500 disabled:hover:bg-amber-50",
576
+ danger: "border border-rose-300 bg-rose-50 text-rose-700 shadow-sm hover:bg-rose-100 focus:ring-rose-500 disabled:hover:bg-rose-50",
577
+ "warning-solid": "bg-gradient-to-r from-yellow-500 to-yellow-600 text-white shadow-[0_6px_14px_rgba(251,206,3,0.14)] hover:from-yellow-600 hover:to-yellow-700 hover:shadow-[0_8px_18px_rgba(251,206,3,0.18)] focus:ring-yellow-500 disabled:hover:from-yellow-500 disabled:hover:to-yellow-600",
578
+ "danger-solid": "bg-gradient-to-r from-red-500 to-red-600 text-white shadow-[0_6px_14px_rgba(239,68,68,0.14)] hover:from-red-600 hover:to-red-700 hover:shadow-[0_8px_18px_rgba(239,68,68,0.18)] focus:ring-red-500 disabled:hover:from-red-500 disabled:hover:to-red-600"
579
+ };
580
+ const resolvedVariant = computed(() => {
581
+ return variantClasses[props.variant] ? props.variant : "primary";
582
+ });
583
+ const buttonClasses = computed(() => [
584
+ "min-w-[40px] min-h-[35px] inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-semibold tracking-tight transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-50 disabled:cursor-not-allowed disabled:opacity-50",
585
+ variantClasses[resolvedVariant.value],
586
+ attrs.class
587
+ ]);
588
+ return (_ctx, _cache) => {
589
+ return openBlock(), createElementBlock("button", mergeProps(unref(attrs), {
590
+ type: __props.type,
591
+ disabled: __props.disabled,
592
+ class: buttonClasses.value
593
+ }), [
594
+ renderSlot(_ctx.$slots, "default")
595
+ ], 16, _hoisted_1$q);
596
+ };
597
+ }
598
+ });
599
+ const _hoisted_1$p = ["value"];
600
+ const _sfc_main$r = {
601
+ __name: "Checkbox",
602
+ props: {
603
+ checked: {
604
+ type: [Array, Boolean],
605
+ default: false
606
+ },
607
+ value: {
608
+ type: String,
609
+ default: null
610
+ }
611
+ },
612
+ emits: ["update:checked"],
613
+ setup(__props, { emit: __emit }) {
614
+ const emit = __emit;
615
+ const props = __props;
616
+ const proxyChecked = computed({
617
+ get() {
618
+ return props.checked;
619
+ },
620
+ set(val) {
621
+ emit("update:checked", val);
622
+ }
623
+ });
624
+ return (_ctx, _cache) => {
625
+ return withDirectives((openBlock(), createElementBlock("input", {
626
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => proxyChecked.value = $event),
627
+ type: "checkbox",
628
+ value: __props.value,
629
+ class: "rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500"
630
+ }, null, 8, _hoisted_1$p)), [
631
+ [vModelCheckbox, proxyChecked.value]
632
+ ]);
633
+ };
634
+ }
635
+ };
636
+ const _hoisted_1$o = ["checked", "disabled"];
637
+ const _sfc_main$q = {
638
+ __name: "CheckboxInput",
639
+ props: {
640
+ modelValue: {
641
+ type: [Boolean, String, Number, null],
642
+ default: false
643
+ },
644
+ value: {
645
+ type: [Boolean, String, Number],
646
+ default: true
647
+ },
648
+ uncheckedValue: {
649
+ type: [Boolean, String, Number, null],
650
+ default: false
651
+ },
652
+ label: {
653
+ type: String,
654
+ default: ""
655
+ },
656
+ disabled: {
657
+ type: Boolean,
658
+ default: false
659
+ }
660
+ },
661
+ emits: ["update:modelValue"],
662
+ setup(__props, { emit: __emit }) {
663
+ const emit = __emit;
664
+ const props = __props;
665
+ const isChecked = computed(() => props.modelValue === props.value);
666
+ const hasFocus = ref(false);
667
+ const handleFocus = () => {
668
+ hasFocus.value = true;
669
+ };
670
+ const handleBlur = () => {
671
+ hasFocus.value = false;
672
+ };
673
+ const onChange = (event) => {
674
+ emit("update:modelValue", event.target.checked ? props.value : props.uncheckedValue);
675
+ };
676
+ return (_ctx, _cache) => {
677
+ return openBlock(), createElementBlock("label", {
678
+ class: normalizeClass(["inline-flex items-center gap-2 rounded-full border px-3 py-1 text-sm font-medium select-none transition-colors", [
679
+ isChecked.value ? "bg-indigo-600 text-white border-indigo-600" : "text-gray-600 border-gray-200",
680
+ __props.disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer",
681
+ hasFocus.value && !__props.disabled ? "ring-2 ring-indigo-500/80 ring-offset-2 ring-offset-white" : ""
682
+ ]])
683
+ }, [
684
+ createElementVNode("input", {
685
+ type: "checkbox",
686
+ class: "sr-only",
687
+ checked: isChecked.value,
688
+ disabled: __props.disabled,
689
+ onChange,
690
+ onFocus: handleFocus,
691
+ onBlur: handleBlur
692
+ }, null, 40, _hoisted_1$o),
693
+ createElementVNode("span", {
694
+ class: normalizeClass(["inline-flex h-4 w-4 items-center justify-center border text-[10px] font-bold leading-none", [
695
+ isChecked.value ? "border-current bg-white/15 text-current" : "border-current/70 text-transparent",
696
+ "rounded"
697
+ ]])
698
+ }, " ✓ ", 2),
699
+ createElementVNode("span", null, toDisplayString(__props.label), 1)
700
+ ], 2);
701
+ };
702
+ }
703
+ };
704
+ const _hoisted_1$n = { class: "relative flex items-center" };
705
+ const _hoisted_2$d = {
706
+ key: 0,
707
+ class: "absolute inset-y-0 left-0 flex items-center pointer-events-none pl-3"
708
+ };
709
+ const _hoisted_3$9 = ["type", "value", "disabled"];
710
+ const _hoisted_4$7 = ["aria-label"];
711
+ const _hoisted_5$5 = {
712
+ key: 0,
713
+ class: "h-5 w-5",
714
+ fill: "none",
715
+ stroke: "currentColor",
716
+ viewBox: "0 0 24 24"
717
+ };
718
+ const _hoisted_6$5 = {
719
+ key: 1,
720
+ class: "h-5 w-5",
721
+ fill: "none",
722
+ stroke: "currentColor",
723
+ viewBox: "0 0 24 24"
724
+ };
725
+ const DEFAULT_MAX_LENGTH$1 = 254;
726
+ const _sfc_main$p = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
727
+ __name: "TextInput",
728
+ props: {
729
+ modelValue: {
730
+ type: [String, Number, null],
731
+ default: ""
732
+ },
733
+ disabled: {
734
+ type: Boolean,
735
+ default: false
736
+ },
737
+ disabledClass: {
738
+ type: String,
739
+ default: "!bg-slate-100"
740
+ }
741
+ },
742
+ emits: ["update:modelValue", "blur"],
743
+ setup(__props, { expose: __expose, emit: __emit }) {
744
+ const props = __props;
745
+ const emit = __emit;
746
+ const attrs = useAttrs();
747
+ const input = ref(null);
748
+ const revealed = ref(false);
749
+ const baseType = computed(() => String(attrs.type ?? "text"));
750
+ const isPasswordField = computed(() => baseType.value === "password");
751
+ const inputType = computed(() => isPasswordField.value && revealed.value ? "text" : baseType.value);
752
+ const normalizedValue = computed(() => props.modelValue ?? "");
753
+ const inputAttrs = computed(() => {
754
+ const { class: _class, type: _type, ...rest } = attrs;
755
+ if (rest.maxlength === void 0) {
756
+ rest.maxlength = DEFAULT_MAX_LENGTH$1;
757
+ }
758
+ return rest;
759
+ });
760
+ const inputClasses = computed(() => [
761
+ "w-full min-w-0 max-w-full rounded-lg border border-slate-300 bg-white text-slate-900 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 placeholder:text-slate-400",
762
+ attrs.class,
763
+ isPasswordField.value ? "pr-10 pl-10" : ""
764
+ ]);
765
+ const toggleVisibility = () => {
766
+ revealed.value = !revealed.value;
767
+ };
768
+ const handleWheel = (event) => {
769
+ if (inputType.value !== "number") {
770
+ return;
771
+ }
772
+ event.preventDefault();
773
+ const scrollTarget = document.scrollingElement ?? document.documentElement ?? document.body;
774
+ if (scrollTarget) {
775
+ scrollTarget.scrollTop += event.deltaY;
776
+ }
777
+ };
778
+ onMounted(() => {
779
+ if (input.value?.hasAttribute("autofocus")) {
780
+ input.value.focus();
781
+ }
782
+ });
783
+ __expose({ focus: () => input.value?.focus() });
784
+ return (_ctx, _cache) => {
785
+ return openBlock(), createElementBlock("div", _hoisted_1$n, [
786
+ isPasswordField.value ? (openBlock(), createElementBlock("div", _hoisted_2$d, [
787
+ createVNode(unref(LockClosedIcon), { class: "h-5 w-5 text-slate-400" })
788
+ ])) : createCommentVNode("", true),
789
+ createElementVNode("input", mergeProps({
790
+ ref_key: "input",
791
+ ref: input
792
+ }, inputAttrs.value, {
793
+ type: inputType.value,
794
+ class: [inputClasses.value, props.disabled ? props.disabledClass : null],
795
+ value: normalizedValue.value,
796
+ disabled: props.disabled,
797
+ onInput: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event.target.value)),
798
+ onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event)),
799
+ onWheel: handleWheel
800
+ }), null, 16, _hoisted_3$9),
801
+ isPasswordField.value ? (openBlock(), createElementBlock("button", {
802
+ key: 1,
803
+ type: "button",
804
+ class: "absolute inset-y-0 right-0 flex items-center pr-3 text-slate-400 hover:text-slate-600 focus:outline-none",
805
+ "aria-label": revealed.value ? "Hide password" : "Show password",
806
+ onClick: toggleVisibility
807
+ }, [
808
+ revealed.value ? (openBlock(), createElementBlock("svg", _hoisted_5$5, [..._cache[2] || (_cache[2] = [
809
+ createElementVNode("path", {
810
+ "stroke-linecap": "round",
811
+ "stroke-linejoin": "round",
812
+ "stroke-width": "2",
813
+ 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"
814
+ }, null, -1)
815
+ ])])) : (openBlock(), createElementBlock("svg", _hoisted_6$5, [..._cache[3] || (_cache[3] = [
816
+ createElementVNode("path", {
817
+ "stroke-linecap": "round",
818
+ "stroke-linejoin": "round",
819
+ "stroke-width": "2",
820
+ d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
821
+ }, null, -1),
822
+ createElementVNode("path", {
823
+ "stroke-linecap": "round",
824
+ "stroke-linejoin": "round",
825
+ "stroke-width": "2",
826
+ 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"
827
+ }, null, -1)
828
+ ])]))
829
+ ], 8, _hoisted_4$7)) : createCommentVNode("", true)
830
+ ]);
831
+ };
832
+ }
833
+ });
834
+ const _hoisted_1$m = ["value", "disabled"];
835
+ const DEFAULT_MAX_LENGTH = 1e3;
836
+ const _sfc_main$o = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
837
+ __name: "TextArea",
838
+ props: {
839
+ modelValue: String,
840
+ disabled: {
841
+ type: Boolean,
842
+ default: false
843
+ },
844
+ disabledClass: {
845
+ type: String,
846
+ default: "!bg-gray-200"
847
+ },
848
+ autoResize: {
849
+ type: Boolean,
850
+ default: true
851
+ }
852
+ },
853
+ emits: ["update:modelValue"],
854
+ setup(__props, { expose: __expose, emit: __emit }) {
855
+ const props = __props;
856
+ const emit = __emit;
857
+ const attrs = useAttrs();
858
+ const textarea = ref(null);
859
+ const textareaAttrs = computed(() => {
860
+ const { class: _class, ...rest } = attrs;
861
+ if (rest.maxlength === void 0) {
862
+ rest.maxlength = DEFAULT_MAX_LENGTH;
863
+ }
864
+ return rest;
865
+ });
866
+ const textareaClasses = computed(() => [
867
+ "w-full min-w-0 max-w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm",
868
+ props.autoResize ? "resize-none overflow-y-auto" : "resize-y",
869
+ attrs.class
870
+ ]);
871
+ const resizeTextarea = () => {
872
+ if (!props.autoResize || !textarea.value) {
873
+ return;
874
+ }
875
+ textarea.value.style.height = "auto";
876
+ textarea.value.style.height = `${textarea.value.scrollHeight}px`;
877
+ };
878
+ const updateValue = (event) => {
879
+ emit("update:modelValue", event.target.value);
880
+ resizeTextarea();
881
+ };
882
+ onMounted(() => {
883
+ if (textarea.value?.hasAttribute("autofocus")) {
884
+ textarea.value.focus();
885
+ }
886
+ nextTick(() => {
887
+ resizeTextarea();
888
+ });
889
+ });
890
+ watch(() => props.modelValue, () => {
891
+ nextTick(() => {
892
+ resizeTextarea();
893
+ });
894
+ });
895
+ __expose({ focus: () => textarea.value?.focus() });
896
+ return (_ctx, _cache) => {
897
+ return openBlock(), createElementBlock("div", null, [
898
+ createElementVNode("textarea", mergeProps({
899
+ ref_key: "textarea",
900
+ ref: textarea
901
+ }, textareaAttrs.value, {
902
+ class: [textareaClasses.value, props.disabled ? props.disabledClass : ""],
903
+ value: props.modelValue,
904
+ disabled: props.disabled,
905
+ onInput: updateValue
906
+ }), null, 16, _hoisted_1$m)
907
+ ]);
908
+ };
909
+ }
910
+ });
911
+ const _hoisted_1$l = ["onClick"];
912
+ const _sfc_main$n = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
913
+ __name: "CustomSelect",
914
+ props: {
915
+ modelValue: {
916
+ type: [String, Number, Boolean, null],
917
+ default: ""
918
+ },
919
+ modelModifiers: {
920
+ type: Object,
921
+ default: () => ({})
922
+ },
923
+ options: {
924
+ type: Array,
925
+ default: () => []
926
+ },
927
+ placeholder: {
928
+ type: String,
929
+ default: ""
930
+ },
931
+ placeholderDisabled: {
932
+ type: Boolean,
933
+ default: false
934
+ },
935
+ disabled: {
936
+ type: Boolean,
937
+ default: false
938
+ },
939
+ softDeleteAware: {
940
+ type: Boolean,
941
+ default: false
942
+ },
943
+ labelKey: {
944
+ type: String,
945
+ default: "name"
946
+ },
947
+ valueKey: {
948
+ type: String,
949
+ default: "id"
950
+ },
951
+ deletedKey: {
952
+ type: String,
953
+ default: "deleted_at"
954
+ },
955
+ optionLabel: {
956
+ type: Function,
957
+ default: null
958
+ },
959
+ baseClass: {
960
+ type: [String, Array, Object],
961
+ default: "block w-full rounded-md border border-gray-300 bg-white px-4 py-3 text-sm focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500"
962
+ },
963
+ normalTextClass: {
964
+ type: [String, Array, Object],
965
+ default: "text-gray-900"
966
+ },
967
+ deletedSelectedClass: {
968
+ type: [String, Array, Object],
969
+ default: "text-red-600"
970
+ },
971
+ optionClass: {
972
+ type: [String, Array, Object],
973
+ default: "text-[#111827]"
974
+ },
975
+ deletedOptionClass: {
976
+ type: [String, Array, Object],
977
+ default: "text-[#dc2626]"
978
+ },
979
+ placeholderClass: {
980
+ type: [String, Array, Object],
981
+ default: "text-[#111827]"
982
+ },
983
+ dropdownClass: {
984
+ type: [String, Array, Object],
985
+ default: "bg-white border border-gray-300 rounded-lg shadow-lg max-h-60 overflow-auto z-50"
986
+ },
987
+ dropdownOptionClass: {
988
+ type: [String, Array, Object],
989
+ default: "px-4 py-3 hover:bg-gray-100 cursor-pointer transition-colors"
990
+ },
991
+ dropdownSelectedClass: {
992
+ type: [String, Array, Object],
993
+ default: "bg-blue-50 text-blue-600 font-medium"
994
+ }
995
+ },
996
+ emits: ["update:modelValue"],
997
+ setup(__props, { emit: __emit }) {
998
+ const props = __props;
999
+ const emit = __emit;
1000
+ const attrs = useAttrs();
1001
+ const isOpen = ref(false);
1002
+ const rootRef = ref(null);
1003
+ const triggerRef = ref(null);
1004
+ const dropdownMenuRef = ref(null);
1005
+ const dropdownStyle = ref({});
1006
+ const isObjectOption = (option) => typeof option === "object" && option !== null;
1007
+ const optionValue = (option) => {
1008
+ if (isObjectOption(option)) {
1009
+ return option[props.valueKey];
1010
+ }
1011
+ return option;
1012
+ };
1013
+ const optionText = (option) => {
1014
+ if (props.optionLabel) {
1015
+ return props.optionLabel(option);
1016
+ }
1017
+ if (isObjectOption(option)) {
1018
+ return option[props.labelKey] ?? option[props.valueKey] ?? "";
1019
+ }
1020
+ return option;
1021
+ };
1022
+ const optionDeleted = (option) => {
1023
+ if (!props.softDeleteAware || !isObjectOption(option)) {
1024
+ return false;
1025
+ }
1026
+ return Boolean(option[props.deletedKey]);
1027
+ };
1028
+ const modelValueAsString = computed(() => String(props.modelValue ?? ""));
1029
+ const selectedDeletedOption = computed(() => {
1030
+ if (!props.softDeleteAware || modelValueAsString.value === "") {
1031
+ return null;
1032
+ }
1033
+ return props.options.find((option) => optionDeleted(option) && String(optionValue(option) ?? "") === modelValueAsString.value) ?? null;
1034
+ });
1035
+ const availableOptions = computed(() => {
1036
+ if (!props.softDeleteAware) {
1037
+ return props.options;
1038
+ }
1039
+ return props.options.filter((option) => !optionDeleted(option));
1040
+ });
1041
+ const displayText = computed(() => {
1042
+ if (props.modelValue === null || props.modelValue === void 0 || props.modelValue === "" && !props.options.some((option) => optionValue(option) === "")) {
1043
+ return props.placeholder;
1044
+ }
1045
+ const selectedOption = props.options.find((option) => {
1046
+ const optionVal = optionValue(option);
1047
+ return optionVal === props.modelValue || String(optionVal) === String(props.modelValue);
1048
+ });
1049
+ return selectedOption ? optionText(selectedOption) : props.modelValue;
1050
+ });
1051
+ const normalizeEmittedValue = (value) => {
1052
+ if (props.modelModifiers.number) {
1053
+ if (value === "") {
1054
+ return "";
1055
+ }
1056
+ return Number(value);
1057
+ }
1058
+ return value;
1059
+ };
1060
+ const toggleDropdown = () => {
1061
+ if (!props.disabled) {
1062
+ isOpen.value = !isOpen.value;
1063
+ }
1064
+ };
1065
+ const selectOption = (option) => {
1066
+ const value = optionValue(option);
1067
+ emit("update:modelValue", normalizeEmittedValue(value));
1068
+ isOpen.value = false;
1069
+ };
1070
+ const selectPlaceholder = () => {
1071
+ if (!props.placeholderDisabled) {
1072
+ emit("update:modelValue", normalizeEmittedValue(""));
1073
+ isOpen.value = false;
1074
+ }
1075
+ };
1076
+ const updateDropdownPosition = () => {
1077
+ if (!triggerRef.value) {
1078
+ return;
1079
+ }
1080
+ const rect = triggerRef.value.getBoundingClientRect();
1081
+ const viewportWidth = window.innerWidth;
1082
+ const viewportHeight = window.innerHeight;
1083
+ const spaceBelow = viewportHeight - rect.bottom - 8;
1084
+ const spaceAbove = rect.top - 8;
1085
+ const shouldOpenUpward = spaceBelow < 240 && spaceAbove > spaceBelow;
1086
+ const width = Math.min(rect.width, Math.max(viewportWidth - rect.left - 16, 160));
1087
+ const maxHeight = Math.max(Math.min(240, shouldOpenUpward ? spaceAbove : spaceBelow), 120);
1088
+ dropdownStyle.value = {
1089
+ position: "fixed",
1090
+ left: `${Math.max(rect.left, 8)}px`,
1091
+ width: `${width}px`,
1092
+ maxHeight: `${maxHeight}px`,
1093
+ zIndex: "9999",
1094
+ ...shouldOpenUpward ? { bottom: `${viewportHeight - rect.top + 1}px` } : { top: `${rect.bottom - 1}px` }
1095
+ };
1096
+ };
1097
+ const closeDropdown = (event) => {
1098
+ const clickedInsideTrigger = rootRef.value?.contains(event.target);
1099
+ const clickedInsideMenu = dropdownMenuRef.value?.contains(event.target);
1100
+ if (!clickedInsideTrigger && !clickedInsideMenu) {
1101
+ isOpen.value = false;
1102
+ }
1103
+ };
1104
+ onMounted(() => {
1105
+ document.addEventListener("click", closeDropdown);
1106
+ window.addEventListener("resize", updateDropdownPosition);
1107
+ window.addEventListener("scroll", updateDropdownPosition, true);
1108
+ });
1109
+ onBeforeUnmount(() => {
1110
+ document.removeEventListener("click", closeDropdown);
1111
+ window.removeEventListener("resize", updateDropdownPosition);
1112
+ window.removeEventListener("scroll", updateDropdownPosition, true);
1113
+ });
1114
+ watch(isOpen, async (open) => {
1115
+ if (!open) {
1116
+ return;
1117
+ }
1118
+ await nextTick();
1119
+ updateDropdownPosition();
1120
+ });
1121
+ return (_ctx, _cache) => {
1122
+ return openBlock(), createElementBlock("div", {
1123
+ ref_key: "rootRef",
1124
+ ref: rootRef,
1125
+ class: "relative",
1126
+ onClick: toggleDropdown
1127
+ }, [
1128
+ createElementVNode("div", mergeProps({
1129
+ ref_key: "triggerRef",
1130
+ ref: triggerRef,
1131
+ class: [
1132
+ __props.baseClass,
1133
+ selectedDeletedOption.value ? __props.deletedSelectedClass : __props.normalTextClass,
1134
+ "flex items-center justify-between cursor-pointer",
1135
+ unref(attrs).class
1136
+ ]
1137
+ }, unref(attrs), { tabindex: "0" }), [
1138
+ createElementVNode("span", {
1139
+ class: normalizeClass({ "text-gray-400": !__props.modelValue && __props.placeholder })
1140
+ }, toDisplayString(displayText.value), 3),
1141
+ createVNode(unref(ChevronDownIcon), {
1142
+ class: normalizeClass(["size-5 text-gray-400 transition-transform", { "rotate-180": isOpen.value }])
1143
+ }, null, 8, ["class"])
1144
+ ], 16),
1145
+ createVNode(Transition, {
1146
+ "enter-active-class": "transition-all duration-200 ease-out",
1147
+ "enter-from-class": "opacity-0 transform scale-95 -translate-y-2",
1148
+ "enter-to-class": "opacity-100 transform scale-100 translate-y-0",
1149
+ "leave-active-class": "transition-all duration-150 ease-in",
1150
+ "leave-from-class": "opacity-100 transform scale-100 translate-y-0",
1151
+ "leave-to-class": "opacity-0 transform scale-95 -translate-y-2"
1152
+ }, {
1153
+ default: withCtx(() => [
1154
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
1155
+ isOpen.value ? (openBlock(), createElementBlock("div", {
1156
+ key: 0,
1157
+ ref_key: "dropdownMenuRef",
1158
+ ref: dropdownMenuRef,
1159
+ class: normalizeClass(__props.dropdownClass),
1160
+ style: normalizeStyle(dropdownStyle.value)
1161
+ }, [
1162
+ __props.placeholder ? (openBlock(), createElementBlock("div", {
1163
+ key: 0,
1164
+ class: normalizeClass([
1165
+ __props.dropdownOptionClass,
1166
+ __props.placeholderClass,
1167
+ { "text-gray-400": !__props.modelValue }
1168
+ ]),
1169
+ onClick: withModifiers(selectPlaceholder, ["stop"])
1170
+ }, toDisplayString(__props.placeholder), 3)) : createCommentVNode("", true),
1171
+ selectedDeletedOption.value ? (openBlock(), createElementBlock("div", {
1172
+ key: 1,
1173
+ class: normalizeClass([
1174
+ __props.dropdownOptionClass,
1175
+ __props.deletedOptionClass,
1176
+ __props.dropdownSelectedClass
1177
+ ])
1178
+ }, toDisplayString(optionText(selectedDeletedOption.value)), 3)) : createCommentVNode("", true),
1179
+ (openBlock(true), createElementBlock(Fragment, null, renderList(availableOptions.value, (option) => {
1180
+ return openBlock(), createElementBlock("div", {
1181
+ key: String(optionValue(option)),
1182
+ class: normalizeClass([
1183
+ __props.dropdownOptionClass,
1184
+ __props.optionClass,
1185
+ {
1186
+ [__props.dropdownSelectedClass]: optionValue(option) === __props.modelValue || String(optionValue(option)) === String(__props.modelValue),
1187
+ "rounded-b-lg": option === availableOptions.value[availableOptions.value.length - 1] && !__props.placeholder,
1188
+ "rounded-lg": !__props.placeholder && availableOptions.value.length === 1
1189
+ }
1190
+ ]),
1191
+ onClick: withModifiers(($event) => selectOption(option), ["stop"])
1192
+ }, toDisplayString(optionText(option)), 11, _hoisted_1$l);
1193
+ }), 128))
1194
+ ], 6)) : createCommentVNode("", true)
1195
+ ]))
1196
+ ]),
1197
+ _: 1
1198
+ })
1199
+ ], 512);
1200
+ };
1201
+ }
1202
+ });
1203
+ const _sfc_main$m = {
1204
+ __name: "SelectInput",
1205
+ props: {
1206
+ modelValue: {
1207
+ type: [String, Number, Boolean, null],
1208
+ default: ""
1209
+ },
1210
+ modelModifiers: {
1211
+ type: Object,
1212
+ default: () => ({})
1213
+ },
1214
+ options: {
1215
+ type: Array,
1216
+ default: () => []
1217
+ },
1218
+ placeholder: {
1219
+ type: String,
1220
+ default: ""
1221
+ },
1222
+ placeholderDisabled: {
1223
+ type: Boolean,
1224
+ default: false
1225
+ },
1226
+ disabled: {
1227
+ type: Boolean,
1228
+ default: false
1229
+ },
1230
+ softDeleteAware: {
1231
+ type: Boolean,
1232
+ default: false
1233
+ },
1234
+ labelKey: {
1235
+ type: String,
1236
+ default: "name"
1237
+ },
1238
+ valueKey: {
1239
+ type: String,
1240
+ default: "id"
1241
+ },
1242
+ deletedKey: {
1243
+ type: String,
1244
+ default: "deleted_at"
1245
+ },
1246
+ optionLabel: {
1247
+ type: Function,
1248
+ default: null
1249
+ },
1250
+ baseClass: {
1251
+ type: [String, Array, Object],
1252
+ 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"
1253
+ },
1254
+ normalTextClass: {
1255
+ type: [String, Array, Object],
1256
+ default: "text-slate-900"
1257
+ },
1258
+ deletedSelectedClass: {
1259
+ type: [String, Array, Object],
1260
+ default: "text-red-600"
1261
+ },
1262
+ optionClass: {
1263
+ type: [String, Array, Object],
1264
+ default: "text-slate-900"
1265
+ },
1266
+ deletedOptionClass: {
1267
+ type: [String, Array, Object],
1268
+ default: "text-rose-700"
1269
+ },
1270
+ placeholderClass: {
1271
+ type: [String, Array, Object],
1272
+ default: "text-slate-500"
1273
+ },
1274
+ dropdownClass: {
1275
+ type: [String, Array, Object],
1276
+ default: "bg-white/95 border border-slate-200 rounded-xl shadow-xl max-h-60 overflow-auto z-50 backdrop-blur-sm"
1277
+ },
1278
+ dropdownOptionClass: {
1279
+ type: [String, Array, Object],
1280
+ default: "px-4 py-3 hover:bg-slate-100 cursor-pointer transition-colors"
1281
+ },
1282
+ dropdownSelectedClass: {
1283
+ type: [String, Array, Object],
1284
+ default: "bg-blue-50 text-blue-700 font-medium"
1285
+ }
1286
+ },
1287
+ emits: ["update:modelValue"],
1288
+ setup(__props, { emit: __emit }) {
1289
+ const emit = __emit;
1290
+ return (_ctx, _cache) => {
1291
+ return openBlock(), createBlock(_sfc_main$n, mergeProps({
1292
+ "model-value": __props.modelValue,
1293
+ "model-modifiers": __props.modelModifiers,
1294
+ options: __props.options,
1295
+ placeholder: __props.placeholder,
1296
+ "placeholder-disabled": __props.placeholderDisabled,
1297
+ disabled: __props.disabled,
1298
+ "soft-delete-aware": __props.softDeleteAware,
1299
+ "label-key": __props.labelKey,
1300
+ "value-key": __props.valueKey,
1301
+ "deleted-key": __props.deletedKey,
1302
+ "option-label": __props.optionLabel,
1303
+ "base-class": __props.baseClass,
1304
+ "normal-text-class": __props.normalTextClass,
1305
+ "deleted-selected-class": __props.deletedSelectedClass,
1306
+ "option-class": __props.optionClass,
1307
+ "deleted-option-class": __props.deletedOptionClass,
1308
+ "placeholder-class": __props.placeholderClass,
1309
+ "dropdown-class": __props.dropdownClass,
1310
+ "dropdown-option-class": __props.dropdownOptionClass,
1311
+ "dropdown-selected-class": __props.dropdownSelectedClass,
1312
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event))
1313
+ }, _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"]);
1314
+ };
1315
+ }
1316
+ };
1317
+ const _hoisted_1$k = ["type", "max", "value", "disabled"];
1318
+ const _sfc_main$l = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
1319
+ __name: "DateInput",
1320
+ props: {
1321
+ modelValue: {
1322
+ type: [String, Number, null],
1323
+ default: ""
1324
+ },
1325
+ withTimestamp: {
1326
+ type: Boolean,
1327
+ default: false
1328
+ },
1329
+ disabled: {
1330
+ type: Boolean,
1331
+ default: false
1332
+ },
1333
+ disabledClass: {
1334
+ type: String,
1335
+ default: "!bg-gray-200"
1336
+ }
1337
+ },
1338
+ emits: ["update:modelValue"],
1339
+ setup(__props, { expose: __expose, emit: __emit }) {
1340
+ const props = __props;
1341
+ const emit = __emit;
1342
+ const attrs = useAttrs();
1343
+ const input = ref(null);
1344
+ const inputType = computed(() => props.withTimestamp ? "datetime-local" : "date");
1345
+ const normalizedValue = computed(() => props.modelValue ?? "");
1346
+ const cappedMax = computed(() => {
1347
+ const limit = props.withTimestamp ? "9999-12-31T23:59" : "9999-12-31";
1348
+ const incoming = attrs.max;
1349
+ if (typeof incoming !== "string" || incoming === "") {
1350
+ return limit;
1351
+ }
1352
+ return incoming > limit ? limit : incoming;
1353
+ });
1354
+ const inputAttrs = computed(() => {
1355
+ const { class: _class, type: _type, ...rest } = attrs;
1356
+ return rest;
1357
+ });
1358
+ const inputClasses = computed(() => [
1359
+ "w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm",
1360
+ attrs.class
1361
+ ]);
1362
+ const normalizeDateValue = (rawValue) => {
1363
+ if (typeof rawValue !== "string") {
1364
+ return "";
1365
+ }
1366
+ return rawValue.replace(/^(\d{4})\d+/, "$1");
1367
+ };
1368
+ const handleDateInput = (event) => {
1369
+ const target = event.target;
1370
+ if (!target) {
1371
+ return;
1372
+ }
1373
+ const rawValue = String(target.value ?? "");
1374
+ const normalized = normalizeDateValue(rawValue);
1375
+ if (normalized !== rawValue) {
1376
+ target.value = normalized;
1377
+ }
1378
+ emit("update:modelValue", normalized);
1379
+ };
1380
+ onMounted(() => {
1381
+ if (input.value?.hasAttribute("autofocus")) {
1382
+ input.value.focus();
1383
+ }
1384
+ });
1385
+ __expose({ focus: () => input.value?.focus() });
1386
+ return (_ctx, _cache) => {
1387
+ return openBlock(), createElementBlock("input", mergeProps({
1388
+ ref_key: "input",
1389
+ ref: input
1390
+ }, inputAttrs.value, {
1391
+ type: inputType.value,
1392
+ max: cappedMax.value,
1393
+ class: [inputClasses.value, props.disabled ? props.disabledClass : null],
1394
+ value: normalizedValue.value,
1395
+ disabled: props.disabled,
1396
+ onInput: handleDateInput,
1397
+ onChange: handleDateInput
1398
+ }), null, 16, _hoisted_1$k);
1399
+ };
1400
+ }
1401
+ });
1402
+ const _hoisted_1$j = { class: "relative" };
1403
+ const _hoisted_2$c = { class: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" };
1404
+ const _hoisted_3$8 = ["accept"];
1405
+ const _hoisted_4$6 = {
1406
+ key: 0,
1407
+ class: "mt-4 p-4 bg-gray-50 rounded-lg border border-gray-200"
1408
+ };
1409
+ const _hoisted_5$4 = { class: "flex items-center space-x-4" };
1410
+ const _hoisted_6$4 = ["src"];
1411
+ const _hoisted_7$4 = { class: "text-sm font-medium text-gray-900" };
1412
+ const _hoisted_8$2 = { class: "text-xs text-gray-500" };
1413
+ const _sfc_main$k = {
1414
+ __name: "ImageInput",
1415
+ props: {
1416
+ currentImageUrl: {
1417
+ type: String,
1418
+ default: ""
1419
+ },
1420
+ accept: {
1421
+ type: String,
1422
+ default: "image/*"
1423
+ },
1424
+ currentLabel: {
1425
+ type: String,
1426
+ default: "Current logo"
1427
+ },
1428
+ currentSubtext: {
1429
+ type: String,
1430
+ default: "Upload a new logo to replace this one"
1431
+ },
1432
+ attrs: {
1433
+ type: Object,
1434
+ default: () => ({})
1435
+ }
1436
+ },
1437
+ emits: ["update:modelValue"],
1438
+ setup(__props, { emit: __emit }) {
1439
+ const emit = __emit;
1440
+ const props = __props;
1441
+ const handleFileChange = (event) => {
1442
+ const file = event.target.files?.[0] ?? null;
1443
+ emit("update:modelValue", file);
1444
+ };
1445
+ return (_ctx, _cache) => {
1446
+ return openBlock(), createElementBlock("div", null, [
1447
+ createElementVNode("div", _hoisted_1$j, [
1448
+ createElementVNode("div", _hoisted_2$c, [
1449
+ createVNode(unref(PhotoIcon), { class: "size-5 text-gray-400" })
1450
+ ]),
1451
+ createElementVNode("input", mergeProps(__props.attrs, {
1452
+ type: "file",
1453
+ accept: __props.accept,
1454
+ class: "block w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg bg-white text-sm file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 cursor-pointer",
1455
+ onChange: handleFileChange
1456
+ }), null, 16, _hoisted_3$8)
1457
+ ]),
1458
+ props.currentImageUrl ? (openBlock(), createElementBlock("div", _hoisted_4$6, [
1459
+ createElementVNode("div", _hoisted_5$4, [
1460
+ createElementVNode("img", {
1461
+ src: props.currentImageUrl,
1462
+ alt: "Current logo",
1463
+ class: "h-16 w-auto max-w-24 object-contain rounded-lg shadow-sm"
1464
+ }, null, 8, _hoisted_6$4),
1465
+ createElementVNode("div", null, [
1466
+ createElementVNode("p", _hoisted_7$4, toDisplayString(props.currentLabel), 1),
1467
+ createElementVNode("p", _hoisted_8$2, toDisplayString(props.currentSubtext), 1)
1468
+ ])
1469
+ ])
1470
+ ])) : createCommentVNode("", true)
1471
+ ]);
1472
+ };
1473
+ }
1474
+ };
1475
+ const _hoisted_1$i = { class: "flex h-12 overflow-hidden rounded-lg border border-gray-300 text-sm" };
1476
+ const _hoisted_2$b = ["disabled", "onClick"];
1477
+ const _sfc_main$j = {
1478
+ __name: "NotationInput",
1479
+ props: {
1480
+ modelValue: {
1481
+ type: [String, Number, null],
1482
+ default: ""
1483
+ },
1484
+ options: {
1485
+ type: Array,
1486
+ default: () => []
1487
+ },
1488
+ disabled: {
1489
+ type: Boolean,
1490
+ default: false
1491
+ }
1492
+ },
1493
+ emits: ["update:modelValue"],
1494
+ setup(__props, { emit: __emit }) {
1495
+ const emit = __emit;
1496
+ const props = __props;
1497
+ const normalizedOptions = computed(() => {
1498
+ return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
1499
+ });
1500
+ const isSelected = (option) => String(option) === String(props.modelValue ?? "");
1501
+ const selectOption = (option) => emit("update:modelValue", option);
1502
+ return (_ctx, _cache) => {
1503
+ return openBlock(), createElementBlock("div", _hoisted_1$i, [
1504
+ (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option, idx) => {
1505
+ return openBlock(), createElementBlock("button", {
1506
+ key: `notation-${idx}-${option}`,
1507
+ type: "button",
1508
+ class: normalizeClass(["flex-1 border-l border-gray-300 px-2 text-center font-semibold transition-colors duration-150 first:border-l-0", [
1509
+ idx === 0 ? "rounded-l-lg" : "",
1510
+ idx === normalizedOptions.value.length - 1 ? "rounded-r-lg" : "",
1511
+ isSelected(option) ? "bg-indigo-600 text-white" : "bg-white text-gray-700 hover:bg-gray-50",
1512
+ "focus-visible:ring-2 "
1513
+ ]]),
1514
+ disabled: __props.disabled,
1515
+ onClick: ($event) => selectOption(option)
1516
+ }, toDisplayString(option), 11, _hoisted_2$b);
1517
+ }), 128))
1518
+ ]);
1519
+ };
1520
+ }
1521
+ };
1522
+ const _hoisted_1$h = ["name", "value", "checked", "disabled"];
1523
+ const _sfc_main$i = {
1524
+ __name: "RadioInput",
1525
+ props: {
1526
+ modelValue: {
1527
+ type: [String, Number, Boolean, null],
1528
+ default: null
1529
+ },
1530
+ value: {
1531
+ type: [String, Number, Boolean],
1532
+ default: true
1533
+ },
1534
+ label: {
1535
+ type: String,
1536
+ default: ""
1537
+ },
1538
+ name: {
1539
+ type: String,
1540
+ default: void 0
1541
+ },
1542
+ disabled: {
1543
+ type: Boolean,
1544
+ default: false
1545
+ }
1546
+ },
1547
+ emits: ["update:modelValue"],
1548
+ setup(__props, { emit: __emit }) {
1549
+ const emit = __emit;
1550
+ const props = __props;
1551
+ const isChecked = computed(() => String(props.modelValue ?? "") === String(props.value));
1552
+ const hasFocus = ref(false);
1553
+ const handleFocus = () => {
1554
+ hasFocus.value = true;
1555
+ };
1556
+ const handleBlur = () => {
1557
+ hasFocus.value = false;
1558
+ };
1559
+ const onChange = () => emit("update:modelValue", props.value);
1560
+ return (_ctx, _cache) => {
1561
+ return openBlock(), createElementBlock("label", {
1562
+ class: normalizeClass(["inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium select-none transition-colors", [
1563
+ isChecked.value ? "bg-indigo-600 text-white border-indigo-600" : "text-gray-600 border-gray-200",
1564
+ __props.disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer",
1565
+ hasFocus.value && !__props.disabled ? "ring-2 ring-indigo-500/80 ring-offset-2 ring-offset-white" : ""
1566
+ ]])
1567
+ }, [
1568
+ createElementVNode("input", {
1569
+ type: "radio",
1570
+ class: "sr-only",
1571
+ name: __props.name,
1572
+ value: __props.value,
1573
+ checked: isChecked.value,
1574
+ disabled: __props.disabled,
1575
+ onChange,
1576
+ onFocus: handleFocus,
1577
+ onBlur: handleBlur
1578
+ }, null, 40, _hoisted_1$h),
1579
+ createElementVNode("span", null, toDisplayString(isChecked.value ? "✓" : "○") + " " + toDisplayString(__props.label), 1)
1580
+ ], 2);
1581
+ };
1582
+ }
1583
+ };
1584
+ const _hoisted_1$g = { class: "flex flex-wrap gap-3" };
1585
+ const _sfc_main$h = {
1586
+ __name: "RadioMultipleInput",
1587
+ props: {
1588
+ modelValue: {
1589
+ type: [String, Number, null],
1590
+ default: ""
1591
+ },
1592
+ options: {
1593
+ type: Array,
1594
+ default: () => []
1595
+ },
1596
+ name: {
1597
+ type: String,
1598
+ default: void 0
1599
+ },
1600
+ disabled: {
1601
+ type: Boolean,
1602
+ default: false
1603
+ }
1604
+ },
1605
+ emits: ["update:modelValue"],
1606
+ setup(__props, { emit: __emit }) {
1607
+ const emit = __emit;
1608
+ const props = __props;
1609
+ const normalizedOptions = computed(() => {
1610
+ return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
1611
+ });
1612
+ const selectOption = (option) => emit("update:modelValue", option);
1613
+ return (_ctx, _cache) => {
1614
+ return openBlock(), createElementBlock("div", _hoisted_1$g, [
1615
+ (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1616
+ return openBlock(), createBlock(_sfc_main$f, {
1617
+ key: `radio-${__props.name ?? "group"}-${option}`,
1618
+ type: "radio-input",
1619
+ "model-value": props.modelValue,
1620
+ name: __props.name,
1621
+ value: option,
1622
+ label: option,
1623
+ disabled: __props.disabled,
1624
+ "onUpdate:modelValue": selectOption
1625
+ }, null, 8, ["model-value", "name", "value", "label", "disabled"]);
1626
+ }), 128))
1627
+ ]);
1628
+ };
1629
+ }
1630
+ };
1631
+ const _hoisted_1$f = {
1632
+ key: 0,
1633
+ class: "min-h-[12rem] w-full rounded-lg border border-slate-300 bg-slate-50"
1634
+ };
1635
+ const _sfc_main$g = {
1636
+ __name: "TinyEditor",
1637
+ props: {
1638
+ modelValue: {
1639
+ type: String,
1640
+ default: ""
1641
+ },
1642
+ readonly: {
1643
+ type: Boolean,
1644
+ default: false
1645
+ },
1646
+ height: {
1647
+ type: Number,
1648
+ default: 300
1649
+ },
1650
+ menubar: {
1651
+ type: [Boolean, String],
1652
+ default: false
1653
+ },
1654
+ toolbar: {
1655
+ type: [String, Array],
1656
+ default: "undo redo | bold italic underline | bullist numlist | link image | alignleft aligncenter alignright | code"
1657
+ },
1658
+ plugins: {
1659
+ type: [String, Array],
1660
+ default: () => ["link", "table", "code", "lists", "image"]
1661
+ },
1662
+ init: {
1663
+ type: Object,
1664
+ default: () => ({})
1665
+ },
1666
+ licenseKey: {
1667
+ type: String,
1668
+ default: "gpl"
1669
+ },
1670
+ outputFormat: {
1671
+ type: String,
1672
+ default: "html"
1673
+ }
1674
+ },
1675
+ emits: ["update:modelValue", "blur"],
1676
+ setup(__props, { emit: __emit }) {
1677
+ const props = __props;
1678
+ const emit = __emit;
1679
+ const content = ref(props.modelValue ?? "");
1680
+ const isEditorReady = ref(false);
1681
+ const editorRevision = ref(0);
1682
+ const loadTinyMce = async () => {
1683
+ const tinymceModule = await import("./tinymce-WPdeGquX.js").then((n) => n.t);
1684
+ const tinymce = tinymceModule.default ?? tinymceModule;
1685
+ if (typeof globalThis !== "undefined" && !globalThis.tinymce) {
1686
+ globalThis.tinymce = tinymce;
1687
+ }
1688
+ await Promise.all([
1689
+ import("./index-Ch9hFG6f.js").then((n) => n.i),
1690
+ import("./index-6eLEqodC.js").then((n) => n.i),
1691
+ import("./index-G1cAlO5C.js").then((n) => n.i),
1692
+ import("./index-CiFpmPug.js").then((n) => n.i),
1693
+ import("./index-BPcdR1qv.js").then((n) => n.i),
1694
+ import("./index-Cjhk16SP.js").then((n) => n.i),
1695
+ import("./index-D7sesyMc.js").then((n) => n.i),
1696
+ import("./index-BHTvTOGk.js").then((n) => n.i)
1697
+ ]);
1698
+ isEditorReady.value = true;
1699
+ };
1700
+ watch(
1701
+ () => props.modelValue,
1702
+ (value) => {
1703
+ const nextValue = value ?? "";
1704
+ if (nextValue === content.value) {
1705
+ return;
1706
+ }
1707
+ content.value = nextValue;
1708
+ editorRevision.value += 1;
1709
+ }
1710
+ );
1711
+ const normalizedToolbar = computed(() => Array.isArray(props.toolbar) ? props.toolbar.join(" | ") : props.toolbar);
1712
+ const normalizedPlugins = computed(() => Array.isArray(props.plugins) ? [...props.plugins] : props.plugins);
1713
+ const editorKey = computed(() => {
1714
+ const mode = props.readonly ? "tiny-editor-readonly" : "tiny-editor-editable";
1715
+ const menubarKey = props.menubar === void 0 ? "menubar-undefined" : `menubar-${String(props.menubar)}`;
1716
+ return `${mode}-${menubarKey}-${editorRevision.value}`;
1717
+ });
1718
+ const editorInit = computed(() => ({
1719
+ height: props.height,
1720
+ menubar: props.menubar,
1721
+ plugins: normalizedPlugins.value,
1722
+ toolbar: normalizedToolbar.value,
1723
+ skin: false,
1724
+ content_css: false,
1725
+ ...props.init
1726
+ }));
1727
+ onMounted(() => {
1728
+ void loadTinyMce();
1729
+ });
1730
+ const handleEditorInput = (_event, editor) => {
1731
+ const nextValue = editor.getContent({ format: props.outputFormat });
1732
+ content.value = nextValue;
1733
+ emit("update:modelValue", nextValue);
1734
+ };
1735
+ const handleEditorBlur = (_event, editor) => {
1736
+ emit("blur", editor.getContent({ format: props.outputFormat }));
1737
+ };
1738
+ return (_ctx, _cache) => {
1739
+ return openBlock(), createElementBlock("div", { key: editorKey.value }, [
1740
+ !isEditorReady.value ? (openBlock(), createElementBlock("div", _hoisted_1$f)) : (openBlock(), createBlock(unref(Editor), {
1741
+ key: 1,
1742
+ "initial-value": content.value,
1743
+ "license-key": __props.licenseKey,
1744
+ readonly: __props.readonly,
1745
+ "output-format": __props.outputFormat,
1746
+ init: editorInit.value,
1747
+ onInput: handleEditorInput,
1748
+ onBlur: handleEditorBlur
1749
+ }, null, 8, ["initial-value", "license-key", "readonly", "output-format", "init"]))
1750
+ ]);
1751
+ };
1752
+ }
1753
+ };
1754
+ const _hoisted_1$e = ["for"];
1755
+ const _hoisted_2$a = {
1756
+ key: 1,
1757
+ class: "text-xs text-gray-500 mb-1 block break-all"
1758
+ };
1759
+ const _hoisted_3$7 = {
1760
+ key: 15,
1761
+ class: "flex items-center mt-2 text-sm text-red-600"
1762
+ };
1763
+ const defaultFieldClass = "block w-full rounded-lg border border-slate-300 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-400 shadow-sm transition-all duration-200 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20";
1764
+ const _sfc_main$f = /* @__PURE__ */ Object.assign({ inheritAttrs: false }, {
1765
+ __name: "InputGroup",
1766
+ props: {
1767
+ type: {
1768
+ type: String,
1769
+ required: true
1770
+ },
1771
+ label: {
1772
+ type: String,
1773
+ default: ""
1774
+ },
1775
+ helperText: {
1776
+ type: String,
1777
+ default: ""
1778
+ },
1779
+ name: {
1780
+ type: String,
1781
+ default: void 0
1782
+ },
1783
+ errorMessage: {
1784
+ type: String,
1785
+ default: ""
1786
+ },
1787
+ modelValue: {
1788
+ type: [String, Number, Boolean, Array, null],
1789
+ default: ""
1790
+ },
1791
+ disabled: {
1792
+ type: Boolean,
1793
+ default: false
1794
+ },
1795
+ disabledClass: {
1796
+ type: String,
1797
+ default: "!bg-gray-200"
1798
+ },
1799
+ modelModifiers: {
1800
+ type: Object,
1801
+ default: () => ({})
1802
+ },
1803
+ withTimestamp: {
1804
+ type: Boolean,
1805
+ default: false
1806
+ },
1807
+ options: {
1808
+ type: Array,
1809
+ default: () => []
1810
+ },
1811
+ placeholder: {
1812
+ type: String,
1813
+ default: ""
1814
+ },
1815
+ placeholderDisabled: {
1816
+ type: Boolean,
1817
+ default: false
1818
+ },
1819
+ softDeleteAware: {
1820
+ type: Boolean,
1821
+ default: false
1822
+ },
1823
+ labelKey: {
1824
+ type: String,
1825
+ default: "name"
1826
+ },
1827
+ valueKey: {
1828
+ type: String,
1829
+ default: "id"
1830
+ },
1831
+ deletedKey: {
1832
+ type: String,
1833
+ default: "deleted_at"
1834
+ },
1835
+ optionLabel: {
1836
+ type: Function,
1837
+ default: null
1838
+ },
1839
+ baseClass: {
1840
+ type: [String, Array, Object],
1841
+ default: void 0
1842
+ },
1843
+ normalTextClass: {
1844
+ type: [String, Array, Object],
1845
+ default: void 0
1846
+ },
1847
+ deletedSelectedClass: {
1848
+ type: [String, Array, Object],
1849
+ default: void 0
1850
+ },
1851
+ optionClass: {
1852
+ type: [String, Array, Object],
1853
+ default: void 0
1854
+ },
1855
+ deletedOptionClass: {
1856
+ type: [String, Array, Object],
1857
+ default: void 0
1858
+ },
1859
+ placeholderClass: {
1860
+ type: [String, Array, Object],
1861
+ default: void 0
1862
+ },
1863
+ accept: {
1864
+ type: String,
1865
+ default: void 0
1866
+ },
1867
+ currentImageUrl: {
1868
+ type: String,
1869
+ default: ""
1870
+ },
1871
+ currentLabel: {
1872
+ type: String,
1873
+ default: "Current logo"
1874
+ },
1875
+ currentSubtext: {
1876
+ type: String,
1877
+ default: "Upload a new logo to replace this one"
1878
+ },
1879
+ height: {
1880
+ type: Number,
1881
+ default: 300
1882
+ },
1883
+ menubar: {
1884
+ type: [Boolean, String],
1885
+ default: false
1886
+ },
1887
+ toolbar: {
1888
+ type: [String, Array],
1889
+ default: void 0
1890
+ },
1891
+ plugins: {
1892
+ type: [String, Array],
1893
+ default: void 0
1894
+ },
1895
+ init: {
1896
+ type: Object,
1897
+ default: void 0
1898
+ },
1899
+ licenseKey: {
1900
+ type: String,
1901
+ default: "gpl"
1902
+ },
1903
+ outputFormat: {
1904
+ type: String,
1905
+ default: "html"
1906
+ }
1907
+ },
1908
+ emits: ["update:modelValue", "blur"],
1909
+ setup(__props, { emit: __emit }) {
1910
+ const props = __props;
1911
+ const emit = __emit;
1912
+ const attrs = useAttrs();
1913
+ const updateValue = (value) => emit("update:modelValue", value);
1914
+ const hasError = computed(() => Boolean(props.errorMessage));
1915
+ const showsInlineChoiceControl = computed(() => isCheckboxSingleType.value || isRadioSingleType.value);
1916
+ const fieldId = computed(() => {
1917
+ const id = attrs.id;
1918
+ return typeof id === "string" && id !== "" ? id : void 0;
1919
+ });
1920
+ const textLikeTypes = [
1921
+ "text",
1922
+ "email",
1923
+ "password",
1924
+ "number",
1925
+ "time",
1926
+ "url",
1927
+ "tel",
1928
+ "search",
1929
+ "month",
1930
+ "week",
1931
+ "color"
1932
+ ];
1933
+ const noComponentTypes = [];
1934
+ const isImageType = computed(() => props.type === "image");
1935
+ const isNotationType = computed(() => props.type === "notation");
1936
+ const isCheckboxSingleType = computed(() => props.type === "checkbox-input");
1937
+ const isRadioSingleType = computed(() => props.type === "radio-input");
1938
+ const isCheckboxType = computed(() => props.type === "checkbox");
1939
+ const isRadioType = computed(() => props.type === "radio");
1940
+ const isDateType = computed(() => props.type === "date" || props.type === "datetime-local");
1941
+ const isTextareaType = computed(() => props.type === "textarea");
1942
+ const isTinyEditorType = computed(() => props.type === "tiny-editor");
1943
+ const isSelectType = computed(() => props.type === "select");
1944
+ const isTextLikeType = computed(() => textLikeTypes.includes(props.type));
1945
+ const isNoComponentType = computed(() => noComponentTypes.includes(props.type));
1946
+ const textInputBindings = computed(() => ({
1947
+ ...attrs,
1948
+ class: [defaultFieldClass, attrs.class],
1949
+ type: props.type,
1950
+ modelValue: props.modelValue,
1951
+ disabled: props.disabled,
1952
+ disabledClass: props.disabledClass
1953
+ }));
1954
+ const textAreaBindings = computed(() => ({
1955
+ ...attrs,
1956
+ class: [defaultFieldClass, attrs.class],
1957
+ modelValue: props.modelValue,
1958
+ disabled: props.disabled,
1959
+ disabledClass: props.disabledClass
1960
+ }));
1961
+ const dateBindings = computed(() => ({
1962
+ ...attrs,
1963
+ class: [defaultFieldClass, attrs.class],
1964
+ modelValue: props.modelValue,
1965
+ withTimestamp: props.type === "datetime-local" || props.withTimestamp,
1966
+ disabled: props.disabled,
1967
+ disabledClass: props.disabledClass
1968
+ }));
1969
+ const selectBindings = computed(() => {
1970
+ const inputProps = {
1971
+ ...attrs,
1972
+ class: [defaultFieldClass, attrs.class],
1973
+ modelValue: props.modelValue,
1974
+ modelModifiers: props.modelModifiers,
1975
+ options: props.options,
1976
+ placeholder: props.placeholder,
1977
+ placeholderDisabled: props.placeholderDisabled,
1978
+ disabled: props.disabled,
1979
+ softDeleteAware: props.softDeleteAware,
1980
+ labelKey: props.labelKey,
1981
+ valueKey: props.valueKey,
1982
+ deletedKey: props.deletedKey,
1983
+ optionLabel: props.optionLabel
1984
+ };
1985
+ if (props.baseClass !== void 0) inputProps.baseClass = props.baseClass;
1986
+ if (props.normalTextClass !== void 0) inputProps.normalTextClass = props.normalTextClass;
1987
+ if (props.deletedSelectedClass !== void 0) inputProps.deletedSelectedClass = props.deletedSelectedClass;
1988
+ if (props.optionClass !== void 0) inputProps.optionClass = props.optionClass;
1989
+ if (props.deletedOptionClass !== void 0) inputProps.deletedOptionClass = props.deletedOptionClass;
1990
+ if (props.placeholderClass !== void 0) inputProps.placeholderClass = props.placeholderClass;
1991
+ return inputProps;
1992
+ });
1993
+ const notationBindings = computed(() => ({
1994
+ ...attrs,
1995
+ modelValue: props.modelValue,
1996
+ options: props.options,
1997
+ disabled: props.disabled
1998
+ }));
1999
+ const checkboxBindings = computed(() => ({
2000
+ ...attrs,
2001
+ modelValue: props.modelValue,
2002
+ options: props.options,
2003
+ disabled: props.disabled
2004
+ }));
2005
+ const radioBindings = computed(() => ({
2006
+ ...attrs,
2007
+ modelValue: props.modelValue,
2008
+ options: props.options,
2009
+ name: props.name ?? attrs.name,
2010
+ disabled: props.disabled
2011
+ }));
2012
+ const checkboxSingleBindings = computed(() => ({
2013
+ ...attrs,
2014
+ modelValue: props.modelValue,
2015
+ label: props.label || attrs.label || "",
2016
+ disabled: props.disabled
2017
+ }));
2018
+ const radioSingleBindings = computed(() => ({
2019
+ ...attrs,
2020
+ modelValue: props.modelValue,
2021
+ label: props.label || attrs.label || "",
2022
+ name: props.name ?? attrs.name,
2023
+ disabled: props.disabled
2024
+ }));
2025
+ const imageBindings = computed(() => {
2026
+ return {
2027
+ ...attrs,
2028
+ accept: props.accept ?? attrs.accept ?? "image/*",
2029
+ modelValue: props.modelValue,
2030
+ currentImageUrl: props.currentImageUrl,
2031
+ currentLabel: props.currentLabel,
2032
+ currentSubtext: props.currentSubtext
2033
+ };
2034
+ });
2035
+ const tinyEditorBindings = computed(() => {
2036
+ const inputProps = {
2037
+ ...attrs,
2038
+ modelValue: typeof props.modelValue === "string" ? props.modelValue : "",
2039
+ readonly: props.disabled,
2040
+ height: props.height,
2041
+ menubar: props.menubar,
2042
+ licenseKey: props.licenseKey,
2043
+ outputFormat: props.outputFormat
2044
+ };
2045
+ if (props.toolbar !== void 0) inputProps.toolbar = props.toolbar;
2046
+ if (props.plugins !== void 0) inputProps.plugins = props.plugins;
2047
+ if (props.init !== void 0) inputProps.init = props.init;
2048
+ return inputProps;
2049
+ });
2050
+ return (_ctx, _cache) => {
2051
+ return openBlock(), createElementBlock("div", null, [
2052
+ __props.label && !showsInlineChoiceControl.value ? (openBlock(), createElementBlock("label", {
2053
+ key: 0,
2054
+ for: fieldId.value,
2055
+ class: "text-base font-semibold text-gray-900 mb-1 block"
2056
+ }, toDisplayString(__props.label), 9, _hoisted_1$e)) : createCommentVNode("", true),
2057
+ __props.helperText && !showsInlineChoiceControl.value ? (openBlock(), createElementBlock("span", _hoisted_2$a, toDisplayString(__props.helperText), 1)) : createCommentVNode("", true),
2058
+ isTextareaType.value ? (openBlock(), createBlock(_sfc_main$o, mergeProps({ key: 2 }, textAreaBindings.value, {
2059
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event)),
2060
+ onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event))
2061
+ }), null, 16)) : isTinyEditorType.value ? (openBlock(), createBlock(_sfc_main$g, mergeProps({ key: 3 }, tinyEditorBindings.value, {
2062
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => emit("update:modelValue", $event)),
2063
+ onBlur: _cache[3] || (_cache[3] = ($event) => emit("blur", $event))
2064
+ }), null, 16)) : isSelectType.value ? (openBlock(), createBlock(_sfc_main$m, mergeProps({ key: 4 }, selectBindings.value, {
2065
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => emit("update:modelValue", $event)),
2066
+ onBlur: _cache[5] || (_cache[5] = ($event) => emit("blur", $event))
2067
+ }), null, 16)) : isDateType.value ? (openBlock(), createBlock(_sfc_main$l, mergeProps({ key: 5 }, dateBindings.value, {
2068
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => emit("update:modelValue", $event)),
2069
+ onBlur: _cache[7] || (_cache[7] = ($event) => emit("blur", $event))
2070
+ }), null, 16)) : isTextLikeType.value ? (openBlock(), createBlock(_sfc_main$p, mergeProps({ key: 6 }, textInputBindings.value, {
2071
+ "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => emit("update:modelValue", $event)),
2072
+ onBlur: _cache[9] || (_cache[9] = ($event) => emit("blur", $event))
2073
+ }), null, 16)) : isImageType.value ? (openBlock(), createBlock(_sfc_main$k, mergeProps({ key: 7 }, imageBindings.value, {
2074
+ "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => emit("update:modelValue", $event)),
2075
+ onBlur: _cache[11] || (_cache[11] = ($event) => emit("blur", $event))
2076
+ }), null, 16)) : isCheckboxSingleType.value ? (openBlock(), createBlock(_sfc_main$q, mergeProps({ key: 8 }, checkboxSingleBindings.value, {
2077
+ "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => emit("update:modelValue", $event)),
2078
+ onBlur: _cache[13] || (_cache[13] = ($event) => emit("blur", $event))
2079
+ }), null, 16)) : isRadioSingleType.value ? (openBlock(), createBlock(_sfc_main$i, mergeProps({ key: 9 }, radioSingleBindings.value, {
2080
+ "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => emit("update:modelValue", $event)),
2081
+ onBlur: _cache[15] || (_cache[15] = ($event) => emit("blur", $event))
2082
+ }), null, 16)) : isNotationType.value ? (openBlock(), createBlock(_sfc_main$j, mergeProps({ key: 10 }, notationBindings.value, {
2083
+ "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => emit("update:modelValue", $event)),
2084
+ onBlur: _cache[17] || (_cache[17] = ($event) => emit("blur", $event))
2085
+ }), null, 16)) : isCheckboxType.value ? (openBlock(), createBlock(_sfc_main$e, mergeProps({ key: 11 }, checkboxBindings.value, {
2086
+ "onUpdate:modelValue": _cache[18] || (_cache[18] = ($event) => emit("update:modelValue", $event)),
2087
+ onBlur: _cache[19] || (_cache[19] = ($event) => emit("blur", $event))
2088
+ }), null, 16)) : isRadioType.value ? (openBlock(), createBlock(_sfc_main$h, mergeProps({ key: 12 }, radioBindings.value, {
2089
+ "onUpdate:modelValue": _cache[20] || (_cache[20] = ($event) => emit("update:modelValue", $event)),
2090
+ onBlur: _cache[21] || (_cache[21] = ($event) => emit("blur", $event))
2091
+ }), null, 16)) : isNoComponentType.value ? renderSlot(_ctx.$slots, "unsupported-type", {
2092
+ key: 13,
2093
+ type: __props.type,
2094
+ modelValue: __props.modelValue,
2095
+ updateValue,
2096
+ attrs: unref(attrs)
2097
+ }) : renderSlot(_ctx.$slots, "unsupported-type", {
2098
+ key: 14,
2099
+ type: __props.type,
2100
+ modelValue: __props.modelValue,
2101
+ updateValue,
2102
+ attrs: unref(attrs)
2103
+ }),
2104
+ hasError.value ? (openBlock(), createElementBlock("div", _hoisted_3$7, [
2105
+ createVNode(unref(ExclamationCircleIcon), { class: "mr-1 h-4 w-4 flex-shrink-0" }),
2106
+ createElementVNode("span", null, toDisplayString(__props.errorMessage), 1)
2107
+ ])) : createCommentVNode("", true)
2108
+ ]);
2109
+ };
2110
+ }
2111
+ });
2112
+ const _hoisted_1$d = { class: "flex flex-wrap gap-3" };
2113
+ const _sfc_main$e = {
2114
+ __name: "CheckboxMultipleInput",
2115
+ props: {
2116
+ modelValue: {
2117
+ type: Array,
2118
+ default: () => []
2119
+ },
2120
+ options: {
2121
+ type: Array,
2122
+ default: () => []
2123
+ },
2124
+ disabled: {
2125
+ type: Boolean,
2126
+ default: false
2127
+ }
2128
+ },
2129
+ emits: ["update:modelValue"],
2130
+ setup(__props, { emit: __emit }) {
2131
+ const emit = __emit;
2132
+ const props = __props;
2133
+ const normalizedOptions = computed(() => {
2134
+ return props.options.map((option) => option === null || option === void 0 ? "" : String(option).trim()).filter((option) => option !== "");
2135
+ });
2136
+ const isChecked = (option) => {
2137
+ return Array.isArray(props.modelValue) && props.modelValue.includes(option);
2138
+ };
2139
+ const updateSelection = (option, checked) => {
2140
+ const nextSelection = Array.isArray(props.modelValue) ? [...props.modelValue] : [];
2141
+ const index = nextSelection.indexOf(option);
2142
+ if (checked && index === -1) {
2143
+ nextSelection.push(option);
2144
+ } else if (!checked && index !== -1) {
2145
+ nextSelection.splice(index, 1);
2146
+ }
2147
+ emit("update:modelValue", nextSelection);
2148
+ };
2149
+ return (_ctx, _cache) => {
2150
+ return openBlock(), createElementBlock("div", _hoisted_1$d, [
2151
+ (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
2152
+ return openBlock(), createBlock(_sfc_main$f, {
2153
+ key: `checkbox-${option}`,
2154
+ type: "checkbox-input",
2155
+ "model-value": isChecked(option),
2156
+ value: true,
2157
+ "unchecked-value": false,
2158
+ label: option,
2159
+ disabled: __props.disabled,
2160
+ "onUpdate:modelValue": (checked) => updateSelection(option, checked)
2161
+ }, null, 8, ["model-value", "label", "disabled", "onUpdate:modelValue"]);
2162
+ }), 128))
2163
+ ]);
2164
+ };
2165
+ }
2166
+ };
2167
+ const _sfc_main$d = {
2168
+ __name: "Modal",
2169
+ props: {
2170
+ show: {
2171
+ type: Boolean,
2172
+ default: false
2173
+ },
2174
+ maxWidth: {
2175
+ type: String,
2176
+ default: "2xl"
2177
+ },
2178
+ closeable: {
2179
+ type: Boolean,
2180
+ default: true
2181
+ },
2182
+ position: {
2183
+ type: String,
2184
+ default: "center",
2185
+ validator: (value) => ["top", "center", "bottom"].includes(value)
2186
+ }
2187
+ },
2188
+ emits: ["close"],
2189
+ setup(__props, { emit: __emit }) {
2190
+ const props = __props;
2191
+ const emit = __emit;
2192
+ const dialog = ref();
2193
+ const showSlot = ref(props.show);
2194
+ const openModal = () => {
2195
+ document.body.style.overflow = "hidden";
2196
+ showSlot.value = true;
2197
+ dialog.value?.showModal();
2198
+ };
2199
+ const closeModal = () => {
2200
+ document.body.style.overflow = null;
2201
+ setTimeout(() => {
2202
+ dialog.value?.close();
2203
+ showSlot.value = false;
2204
+ }, 200);
2205
+ };
2206
+ watch(() => props.show, () => {
2207
+ if (props.show) {
2208
+ openModal();
2209
+ } else {
2210
+ closeModal();
2211
+ }
2212
+ });
2213
+ onMounted(() => {
2214
+ if (props.show) {
2215
+ openModal();
2216
+ }
2217
+ });
2218
+ const close = () => {
2219
+ if (props.closeable) {
2220
+ emit("close");
2221
+ }
2222
+ };
2223
+ const closeOnEscape = (e) => {
2224
+ if (e.key === "Escape") {
2225
+ e.preventDefault();
2226
+ if (props.show) {
2227
+ close();
2228
+ }
2229
+ }
2230
+ };
2231
+ onMounted(() => document.addEventListener("keydown", closeOnEscape));
2232
+ onUnmounted(() => {
2233
+ document.removeEventListener("keydown", closeOnEscape);
2234
+ document.body.style.overflow = null;
2235
+ });
2236
+ const maxWidthClass = computed(() => {
2237
+ return {
2238
+ "sm": "sm:max-w-sm",
2239
+ "md": "sm:max-w-md",
2240
+ "lg": "sm:max-w-lg",
2241
+ "xl": "sm:max-w-xl",
2242
+ "2xl": "sm:max-w-2xl"
2243
+ }[props.maxWidth];
2244
+ });
2245
+ const positionClasses = computed(() => {
2246
+ switch (props.position) {
2247
+ case "top":
2248
+ return "flex-col items-center pt-16";
2249
+ case "bottom":
2250
+ return "flex-col items-center justify-end pb-16";
2251
+ default:
2252
+ return "items-center justify-center";
2253
+ }
2254
+ });
2255
+ return (_ctx, _cache) => {
2256
+ return openBlock(), createElementBlock("dialog", {
2257
+ class: "z-50 m-0 min-h-full min-w-full overflow-y-auto bg-transparent backdrop:bg-transparent",
2258
+ ref_key: "dialog",
2259
+ ref: dialog
2260
+ }, [
2261
+ createElementVNode("div", {
2262
+ class: normalizeClass(["fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50 flex", positionClasses.value])
2263
+ }, [
2264
+ createVNode(Transition, {
2265
+ "enter-active-class": "ease-out duration-300",
2266
+ "enter-from-class": "opacity-0",
2267
+ "enter-to-class": "opacity-100",
2268
+ "leave-active-class": "ease-in duration-200",
2269
+ "leave-from-class": "opacity-100",
2270
+ "leave-to-class": "opacity-0"
2271
+ }, {
2272
+ default: withCtx(() => [
2273
+ withDirectives(createElementVNode("div", {
2274
+ class: "fixed inset-0 z-40 transform transition-all",
2275
+ onClick: close
2276
+ }, [..._cache[0] || (_cache[0] = [
2277
+ createElementVNode("div", { class: "absolute inset-0 bg-gray-500 opacity-75" }, null, -1)
2278
+ ])], 512), [
2279
+ [vShow, __props.show]
2280
+ ])
2281
+ ]),
2282
+ _: 1
2283
+ }),
2284
+ createVNode(Transition, {
2285
+ "enter-active-class": "ease-out duration-300",
2286
+ "enter-from-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
2287
+ "enter-to-class": "opacity-100 translate-y-0 sm:scale-100",
2288
+ "leave-active-class": "ease-in duration-200",
2289
+ "leave-from-class": "opacity-100 translate-y-0 sm:scale-100",
2290
+ "leave-to-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
2291
+ }, {
2292
+ default: withCtx(() => [
2293
+ withDirectives(createElementVNode("div", {
2294
+ class: normalizeClass(["relative z-50 mb-6 bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto", maxWidthClass.value])
2295
+ }, [
2296
+ showSlot.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
2297
+ ], 2), [
2298
+ [vShow, __props.show]
2299
+ ])
2300
+ ]),
2301
+ _: 3
2302
+ })
2303
+ ], 2)
2304
+ ], 512);
2305
+ };
2306
+ }
2307
+ };
2308
+ const _hoisted_1$c = { class: "bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4" };
2309
+ const _hoisted_2$9 = { class: "sm:flex sm:items-start" };
2310
+ const _hoisted_3$6 = { class: "mx-auto shrink-0 flex items-center justify-center size-12 rounded-full bg-red-100 sm:mx-0 sm:size-10" };
2311
+ const _hoisted_4$5 = { class: "mt-3 text-center sm:mt-0 sm:ms-4 sm:text-start" };
2312
+ const _hoisted_5$3 = { class: "text-lg font-medium text-gray-900" };
2313
+ const _hoisted_6$3 = { class: "mt-4 text-sm text-gray-600" };
2314
+ const _hoisted_7$3 = { class: "flex flex-col-reverse lg:flex-row lg:justify-end px-6 py-4 bg-gray-100 text-end gap-4 lg:gap-0" };
2315
+ const _sfc_main$c = {
2316
+ __name: "ConfirmationModal",
2317
+ props: {
2318
+ show: {
2319
+ type: Boolean,
2320
+ default: false
2321
+ },
2322
+ maxWidth: {
2323
+ type: String,
2324
+ default: "2xl"
2325
+ },
2326
+ closeable: {
2327
+ type: Boolean,
2328
+ default: true
2329
+ },
2330
+ position: {
2331
+ type: String,
2332
+ default: "center",
2333
+ validator: (value) => ["top", "center", "bottom"].includes(value)
2334
+ }
2335
+ },
2336
+ emits: ["close"],
2337
+ setup(__props, { emit: __emit }) {
2338
+ const emit = __emit;
2339
+ const close = () => {
2340
+ emit("close");
2341
+ };
2342
+ return (_ctx, _cache) => {
2343
+ return openBlock(), createBlock(_sfc_main$d, {
2344
+ show: __props.show,
2345
+ "max-width": __props.maxWidth,
2346
+ closeable: __props.closeable,
2347
+ position: __props.position,
2348
+ onClose: close
2349
+ }, {
2350
+ default: withCtx(() => [
2351
+ createElementVNode("div", _hoisted_1$c, [
2352
+ createElementVNode("div", _hoisted_2$9, [
2353
+ createElementVNode("div", _hoisted_3$6, [
2354
+ createVNode(unref(ExclamationTriangleIcon), { class: "size-6 text-red-600" })
2355
+ ]),
2356
+ createElementVNode("div", _hoisted_4$5, [
2357
+ createElementVNode("h3", _hoisted_5$3, [
2358
+ renderSlot(_ctx.$slots, "title")
2359
+ ]),
2360
+ createElementVNode("div", _hoisted_6$3, [
2361
+ renderSlot(_ctx.$slots, "content")
2362
+ ])
2363
+ ])
2364
+ ])
2365
+ ]),
2366
+ createElementVNode("div", _hoisted_7$3, [
2367
+ renderSlot(_ctx.$slots, "footer")
2368
+ ])
2369
+ ]),
2370
+ _: 3
2371
+ }, 8, ["show", "max-width", "closeable", "position"]);
2372
+ };
2373
+ }
2374
+ };
2375
+ const _hoisted_1$b = { class: "px-6 py-4" };
2376
+ const _hoisted_2$8 = { class: "text-lg font-medium text-gray-900" };
2377
+ const _hoisted_3$5 = { class: "mt-4 text-sm text-gray-600" };
2378
+ const _hoisted_4$4 = { class: "flex flex-row justify-end px-6 py-4 bg-gray-100 text-end" };
2379
+ const _sfc_main$b = {
2380
+ __name: "DialogModal",
2381
+ props: {
2382
+ show: {
2383
+ type: Boolean,
2384
+ default: false
2385
+ },
2386
+ maxWidth: {
2387
+ type: String,
2388
+ default: "2xl"
2389
+ },
2390
+ closeable: {
2391
+ type: Boolean,
2392
+ default: true
2393
+ }
2394
+ },
2395
+ emits: ["close"],
2396
+ setup(__props, { emit: __emit }) {
2397
+ const emit = __emit;
2398
+ const close = () => {
2399
+ emit("close");
2400
+ };
2401
+ return (_ctx, _cache) => {
2402
+ return openBlock(), createBlock(_sfc_main$d, {
2403
+ show: __props.show,
2404
+ "max-width": __props.maxWidth,
2405
+ closeable: __props.closeable,
2406
+ onClose: close
2407
+ }, {
2408
+ default: withCtx(() => [
2409
+ createElementVNode("div", _hoisted_1$b, [
2410
+ createElementVNode("div", _hoisted_2$8, [
2411
+ renderSlot(_ctx.$slots, "title")
2412
+ ]),
2413
+ createElementVNode("div", _hoisted_3$5, [
2414
+ renderSlot(_ctx.$slots, "content")
2415
+ ])
2416
+ ]),
2417
+ createElementVNode("div", _hoisted_4$4, [
2418
+ renderSlot(_ctx.$slots, "footer")
2419
+ ])
2420
+ ]),
2421
+ _: 3
2422
+ }, 8, ["show", "max-width", "closeable"]);
2423
+ };
2424
+ }
2425
+ };
2426
+ const _hoisted_1$a = { class: "relative inline-block w-fit" };
2427
+ const _sfc_main$a = {
2428
+ __name: "Dropdown",
2429
+ props: {
2430
+ align: {
2431
+ type: String,
2432
+ default: "right"
2433
+ },
2434
+ width: {
2435
+ type: String,
2436
+ default: "48"
2437
+ },
2438
+ contentClasses: {
2439
+ type: Array,
2440
+ default: () => ["py-1", "bg-white"]
2441
+ }
2442
+ },
2443
+ setup(__props) {
2444
+ const props = __props;
2445
+ const open = ref(false);
2446
+ const triggerRef = ref(null);
2447
+ const menuRef = ref(null);
2448
+ const menuStyle = ref({
2449
+ position: "fixed",
2450
+ left: "0px",
2451
+ top: "0px",
2452
+ visibility: "hidden"
2453
+ });
2454
+ const menuOriginClass = ref("ltr:origin-top-right rtl:origin-top-left");
2455
+ let revealFrame = null;
2456
+ const closeOnEscape = (e) => {
2457
+ if (open.value && e.key === "Escape") {
2458
+ open.value = false;
2459
+ }
2460
+ };
2461
+ const closeOnOutsideClick = (event) => {
2462
+ if (!open.value) {
2463
+ return;
2464
+ }
2465
+ const target = event.target;
2466
+ if (!(target instanceof Node)) {
2467
+ return;
2468
+ }
2469
+ if (triggerRef.value?.contains(target) || menuRef.value?.contains(target)) {
2470
+ return;
2471
+ }
2472
+ open.value = false;
2473
+ };
2474
+ const setOriginClass = (alignRight, openUpward) => {
2475
+ const horizontal = alignRight ? "ltr:origin-top-right rtl:origin-top-left" : "ltr:origin-top-left rtl:origin-top-right";
2476
+ menuOriginClass.value = `${horizontal} ${openUpward ? "origin-bottom" : "origin-top"}`;
2477
+ };
2478
+ const widthClass = computed(() => {
2479
+ return {
2480
+ "48": "w-48"
2481
+ }[props.width.toString()];
2482
+ });
2483
+ const alignmentClasses = computed(() => {
2484
+ return menuOriginClass.value;
2485
+ });
2486
+ const updateDropdownPosition = () => {
2487
+ if (!triggerRef.value || !menuRef.value) {
2488
+ return;
2489
+ }
2490
+ const rect = triggerRef.value.getBoundingClientRect();
2491
+ const viewportWidth = window.innerWidth;
2492
+ const viewportHeight = window.innerHeight;
2493
+ const menuWidth = menuRef.value.offsetWidth;
2494
+ const menuHeight = menuRef.value.offsetHeight;
2495
+ const gap = 8;
2496
+ const spaceLeft = rect.left - gap;
2497
+ const spaceRight = viewportWidth - rect.right - gap;
2498
+ let alignRight = props.align === "right";
2499
+ if (alignRight && rect.right + menuWidth > viewportWidth - gap && spaceLeft > spaceRight) {
2500
+ alignRight = false;
2501
+ } else if (!alignRight && rect.left + menuWidth > viewportWidth - gap && spaceRight > spaceLeft) {
2502
+ alignRight = true;
2503
+ }
2504
+ let left = alignRight ? rect.right - menuWidth : rect.left;
2505
+ left = Math.max(gap, Math.min(left, viewportWidth - menuWidth - gap));
2506
+ const spaceBelow = viewportHeight - rect.bottom - gap;
2507
+ const spaceAbove = rect.top - gap;
2508
+ const openUpward = spaceBelow < menuHeight && spaceAbove > spaceBelow;
2509
+ menuStyle.value = {
2510
+ position: "fixed",
2511
+ left: `${left}px`,
2512
+ ...openUpward ? { bottom: `${viewportHeight - rect.top + gap}px` } : { top: `${rect.bottom + gap}px` },
2513
+ zIndex: "9999",
2514
+ maxHeight: `${Math.max(Math.min(openUpward ? spaceAbove : spaceBelow, 320), 160)}px`
2515
+ };
2516
+ setOriginClass(alignRight, openUpward);
2517
+ };
2518
+ const refreshPosition = async () => {
2519
+ if (!open.value) {
2520
+ return;
2521
+ }
2522
+ if (revealFrame !== null) {
2523
+ cancelAnimationFrame(revealFrame);
2524
+ revealFrame = null;
2525
+ }
2526
+ menuStyle.value = {
2527
+ ...menuStyle.value,
2528
+ visibility: "hidden"
2529
+ };
2530
+ await nextTick();
2531
+ updateDropdownPosition();
2532
+ revealFrame = requestAnimationFrame(() => {
2533
+ if (!open.value) {
2534
+ return;
2535
+ }
2536
+ menuStyle.value = {
2537
+ ...menuStyle.value,
2538
+ visibility: "visible"
2539
+ };
2540
+ });
2541
+ };
2542
+ const handleViewportChange = () => {
2543
+ if (open.value) {
2544
+ updateDropdownPosition();
2545
+ }
2546
+ };
2547
+ watch(open, (value) => {
2548
+ if (value) {
2549
+ refreshPosition();
2550
+ }
2551
+ });
2552
+ onMounted(() => {
2553
+ document.addEventListener("keydown", closeOnEscape);
2554
+ document.addEventListener("pointerdown", closeOnOutsideClick, true);
2555
+ window.addEventListener("resize", handleViewportChange);
2556
+ window.addEventListener("scroll", handleViewportChange, true);
2557
+ });
2558
+ onUnmounted(() => {
2559
+ if (revealFrame !== null) {
2560
+ cancelAnimationFrame(revealFrame);
2561
+ }
2562
+ document.removeEventListener("keydown", closeOnEscape);
2563
+ document.removeEventListener("pointerdown", closeOnOutsideClick, true);
2564
+ window.removeEventListener("resize", handleViewportChange);
2565
+ window.removeEventListener("scroll", handleViewportChange, true);
2566
+ });
2567
+ return (_ctx, _cache) => {
2568
+ return openBlock(), createElementBlock("div", _hoisted_1$a, [
2569
+ createElementVNode("div", {
2570
+ ref_key: "triggerRef",
2571
+ ref: triggerRef,
2572
+ onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
2573
+ }, [
2574
+ renderSlot(_ctx.$slots, "trigger", { open: open.value })
2575
+ ], 512),
2576
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
2577
+ createVNode(Transition, {
2578
+ "enter-active-class": "transition-opacity duration-150 ease-out",
2579
+ "enter-from-class": "opacity-0",
2580
+ "enter-to-class": "opacity-100",
2581
+ "leave-active-class": "transition-opacity duration-100 ease-in",
2582
+ "leave-from-class": "opacity-100",
2583
+ "leave-to-class": "opacity-0"
2584
+ }, {
2585
+ default: withCtx(() => [
2586
+ open.value ? (openBlock(), createElementBlock("div", {
2587
+ key: 0,
2588
+ ref_key: "menuRef",
2589
+ ref: menuRef,
2590
+ class: normalizeClass(["z-50 rounded-xl shadow-xl shadow-gray-900/10", [widthClass.value, alignmentClasses.value]]),
2591
+ style: normalizeStyle(menuStyle.value),
2592
+ onClick: _cache[1] || (_cache[1] = ($event) => open.value = false)
2593
+ }, [
2594
+ createElementVNode("div", {
2595
+ class: normalizeClass(["rounded-xl ring-1 ring-gray-200/60 backdrop-blur-sm bg-white/95", __props.contentClasses])
2596
+ }, [
2597
+ renderSlot(_ctx.$slots, "content")
2598
+ ], 2)
2599
+ ], 6)) : createCommentVNode("", true)
2600
+ ]),
2601
+ _: 3
2602
+ })
2603
+ ]))
2604
+ ]);
2605
+ };
2606
+ }
2607
+ };
2608
+ const _hoisted_1$9 = {
2609
+ key: 0,
2610
+ type: "submit",
2611
+ class: "block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out"
2612
+ };
2613
+ const _hoisted_2$7 = ["href"];
2614
+ const _sfc_main$9 = {
2615
+ __name: "DropdownLink",
2616
+ props: {
2617
+ href: String,
2618
+ as: String
2619
+ },
2620
+ setup(__props) {
2621
+ return (_ctx, _cache) => {
2622
+ return openBlock(), createElementBlock("div", null, [
2623
+ __props.as == "button" ? (openBlock(), createElementBlock("button", _hoisted_1$9, [
2624
+ renderSlot(_ctx.$slots, "default")
2625
+ ])) : __props.as == "a" ? (openBlock(), createElementBlock("a", {
2626
+ key: 1,
2627
+ href: __props.href,
2628
+ class: "block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out"
2629
+ }, [
2630
+ renderSlot(_ctx.$slots, "default")
2631
+ ], 8, _hoisted_2$7)) : (openBlock(), createBlock(unref(Link), {
2632
+ key: 2,
2633
+ href: __props.href,
2634
+ class: "block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out"
2635
+ }, {
2636
+ default: withCtx(() => [
2637
+ renderSlot(_ctx.$slots, "default")
2638
+ ]),
2639
+ _: 3
2640
+ }, 8, ["href"]))
2641
+ ]);
2642
+ };
2643
+ }
2644
+ };
2645
+ const _hoisted_1$8 = { class: "md:grid md:grid-cols-3 md:gap-6" };
2646
+ const _hoisted_2$6 = { class: "mt-5 md:mt-0 md:col-span-2 shadow sm:rounded-lg" };
2647
+ const _hoisted_3$4 = { class: "grid grid-cols-6 gap-6" };
2648
+ const _hoisted_4$3 = {
2649
+ key: 0,
2650
+ class: "flex items-center justify-start px-3 pb-6 bg-white text-end sm:rounded-bl-md sm:rounded-br-md"
2651
+ };
2652
+ const _sfc_main$8 = {
2653
+ __name: "FormSection",
2654
+ emits: ["submitted"],
2655
+ setup(__props) {
2656
+ const hasActions = computed(() => !!useSlots().actions);
2657
+ return (_ctx, _cache) => {
2658
+ return openBlock(), createElementBlock("div", _hoisted_1$8, [
2659
+ createVNode(SectionTitle, null, {
2660
+ title: withCtx(() => [
2661
+ renderSlot(_ctx.$slots, "title")
2662
+ ]),
2663
+ description: withCtx(() => [
2664
+ renderSlot(_ctx.$slots, "description")
2665
+ ]),
2666
+ _: 3
2667
+ }),
2668
+ createElementVNode("div", _hoisted_2$6, [
2669
+ createElementVNode("form", {
2670
+ onSubmit: _cache[0] || (_cache[0] = withModifiers(($event) => _ctx.$emit("submitted"), ["prevent"]))
2671
+ }, [
2672
+ createElementVNode("div", {
2673
+ class: normalizeClass(["px-4 py-5 bg-white sm:p-6", hasActions.value ? "sm:rounded-tl-md sm:rounded-tr-md" : "sm:rounded-md"])
2674
+ }, [
2675
+ createElementVNode("div", _hoisted_3$4, [
2676
+ renderSlot(_ctx.$slots, "form")
2677
+ ])
2678
+ ], 2),
2679
+ hasActions.value ? (openBlock(), createElementBlock("div", _hoisted_4$3, [
2680
+ renderSlot(_ctx.$slots, "actions")
2681
+ ])) : createCommentVNode("", true)
2682
+ ], 32)
2683
+ ])
2684
+ ]);
2685
+ };
2686
+ }
2687
+ };
2688
+ const _hoisted_1$7 = { class: "text-sm text-red-600" };
2689
+ const _sfc_main$7 = {
2690
+ __name: "InputError",
2691
+ props: {
2692
+ message: String
2693
+ },
2694
+ setup(__props) {
2695
+ return (_ctx, _cache) => {
2696
+ return withDirectives((openBlock(), createElementBlock("div", null, [
2697
+ createElementVNode("p", _hoisted_1$7, toDisplayString(__props.message), 1)
2698
+ ], 512)), [
2699
+ [vShow, __props.message]
2700
+ ]);
2701
+ };
2702
+ }
2703
+ };
2704
+ const _hoisted_1$6 = { class: "block font-medium text-sm text-gray-700" };
2705
+ const _hoisted_2$5 = { key: 0 };
2706
+ const _hoisted_3$3 = { key: 1 };
2707
+ const _sfc_main$6 = {
2708
+ __name: "InputLabel",
2709
+ props: {
2710
+ value: String
2711
+ },
2712
+ setup(__props) {
2713
+ return (_ctx, _cache) => {
2714
+ return openBlock(), createElementBlock("label", _hoisted_1$6, [
2715
+ __props.value ? (openBlock(), createElementBlock("span", _hoisted_2$5, toDisplayString(__props.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_3$3, [
2716
+ renderSlot(_ctx.$slots, "default")
2717
+ ]))
2718
+ ]);
2719
+ };
2720
+ }
2721
+ };
2722
+ const _hoisted_1$5 = ["href", "title", "target", "rel"];
2723
+ const _sfc_main$5 = /* @__PURE__ */ Object.assign({
2724
+ inheritAttrs: false
2725
+ }, {
2726
+ __name: "LinkButton",
2727
+ props: {
2728
+ href: {
2729
+ type: String,
2730
+ required: true
2731
+ },
2732
+ title: {
2733
+ type: String,
2734
+ default: null
2735
+ },
2736
+ external: {
2737
+ type: Boolean,
2738
+ default: false
2739
+ },
2740
+ target: {
2741
+ type: String,
2742
+ default: null
2743
+ },
2744
+ rel: {
2745
+ type: String,
2746
+ default: null
2747
+ },
2748
+ variant: {
2749
+ type: String,
2750
+ default: "primary"
2751
+ }
2752
+ },
2753
+ setup(__props) {
2754
+ const attrs = useAttrs();
2755
+ const props = __props;
2756
+ const variantClasses = {
2757
+ primary: "bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-[0_6px_14px_rgba(37,99,235,0.14)] hover:from-blue-600 hover:to-blue-700 hover:shadow-[0_8px_18px_rgba(37,99,235,0.18)] focus:ring-blue-500",
2758
+ success: "bg-gradient-to-r from-green-500 to-green-600 text-white shadow-[0_6px_14px_rgba(34,197,94,0.14)] hover:from-green-600 hover:to-green-700 hover:shadow-[0_8px_18px_rgba(34,197,94,0.18)] focus:ring-green-500",
2759
+ secondary: "bg-gradient-to-r from-slate-700 to-slate-800 text-white shadow-[0_8px_18px_rgba(15,23,42,0.16)] hover:from-slate-800 hover:to-slate-900 hover:shadow-[0_10px_22px_rgba(15,23,42,0.22)] focus:ring-slate-500",
2760
+ tertiary: "border border-slate-300 bg-white text-slate-700 shadow-sm hover:bg-slate-50 hover:border-slate-400 hover:shadow focus:ring-slate-500",
2761
+ warning: "border border-amber-300 bg-amber-50 text-amber-800 shadow-sm hover:bg-amber-100 focus:ring-amber-500",
2762
+ danger: "border border-rose-300 bg-rose-50 text-rose-700 shadow-sm hover:bg-rose-100 focus:ring-rose-500",
2763
+ "warning-solid": "bg-gradient-to-r from-yellow-500 to-yellow-600 text-white shadow-[0_6px_14px_rgba(251,206,3,0.14)] hover:from-yellow-600 hover:to-yellow-700 hover:shadow-[0_8px_18px_rgba(251,206,3,0.18)] focus:ring-yellow-500 disabled:hover:from-yellow-500 disabled:hover:to-yellow-600",
2764
+ "danger-solid": "bg-gradient-to-r from-red-500 to-red-600 text-white shadow-[0_6px_14px_rgba(239,68,68,0.14)] hover:from-red-600 hover:to-red-700 hover:shadow-[0_8px_18px_rgba(239,68,68,0.18)] focus:ring-red-500 disabled:hover:from-red-500 disabled:hover:to-red-600"
2765
+ };
2766
+ const resolvedVariant = computed(() => {
2767
+ return variantClasses[props.variant] ? props.variant : "primary";
2768
+ });
2769
+ const linkClasses = computed(() => [
2770
+ "min-w-[40px] min-h-[35px] inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-semibold tracking-tight transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-50",
2771
+ variantClasses[resolvedVariant.value],
2772
+ attrs.class
2773
+ ]);
2774
+ return (_ctx, _cache) => {
2775
+ return !__props.external ? (openBlock(), createBlock(unref(Link), mergeProps({ key: 0 }, unref(attrs), {
2776
+ href: __props.href,
2777
+ title: __props.title,
2778
+ class: linkClasses.value
2779
+ }), {
2780
+ default: withCtx(() => [
2781
+ renderSlot(_ctx.$slots, "default")
2782
+ ]),
2783
+ _: 3
2784
+ }, 16, ["href", "title", "class"])) : (openBlock(), createElementBlock("a", mergeProps({ key: 1 }, unref(attrs), {
2785
+ href: __props.href,
2786
+ title: __props.title,
2787
+ target: __props.target,
2788
+ rel: __props.rel,
2789
+ class: linkClasses.value
2790
+ }), [
2791
+ renderSlot(_ctx.$slots, "default")
2792
+ ], 16, _hoisted_1$5));
2793
+ };
2794
+ }
2795
+ });
2796
+ const _hoisted_1$4 = { class: "hidden sm:block" };
2797
+ const _hoisted_2$4 = { class: "py-8" };
2798
+ const _sfc_main$4 = {
2799
+ __name: "SectionBorder",
2800
+ setup(__props) {
2801
+ return (_ctx, _cache) => {
2802
+ return openBlock(), createElementBlock("div", _hoisted_1$4, [
2803
+ createElementVNode("div", _hoisted_2$4, [
2804
+ createVNode(_sfc_main$y)
2805
+ ])
2806
+ ]);
2807
+ };
2808
+ }
2809
+ };
2810
+ const _hoisted_1$3 = { class: "bg-white/80 backdrop-blur-sm border border-gray-200/60 rounded-xl px-6 py-4" };
2811
+ const _hoisted_2$3 = { class: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4" };
2812
+ const _hoisted_3$2 = { class: "flex items-center gap-3" };
2813
+ const _hoisted_4$2 = { class: "text-sm font-medium text-gray-700" };
2814
+ const _hoisted_5$2 = { class: "flex flex-wrap items-center gap-2" };
2815
+ const _hoisted_6$2 = ["onClick"];
2816
+ const _hoisted_7$2 = { class: "text-xs text-gray-500" };
2817
+ const _sfc_main$3 = {
2818
+ __name: "SortControls",
2819
+ props: {
2820
+ fields: {
2821
+ type: Array,
2822
+ required: true,
2823
+ validator: (value) => {
2824
+ return value.every(
2825
+ (field) => typeof field === "object" && field.key && field.label
2826
+ );
2827
+ }
2828
+ },
2829
+ currentSortField: {
2830
+ type: String,
2831
+ default: ""
2832
+ },
2833
+ currentDirection: {
2834
+ type: String,
2835
+ default: "asc",
2836
+ validator: (value) => ["asc", "desc"].includes(value)
2837
+ },
2838
+ count: {
2839
+ type: Number,
2840
+ default: 0
2841
+ },
2842
+ countLabel: {
2843
+ type: String,
2844
+ default: "items"
2845
+ },
2846
+ sortByLabel: {
2847
+ type: String,
2848
+ default: "Sort by"
2849
+ }
2850
+ },
2851
+ emits: ["sort"],
2852
+ setup(__props, { emit: __emit }) {
2853
+ const emit = __emit;
2854
+ const handleSort = (fieldKey) => {
2855
+ emit("sort", fieldKey);
2856
+ };
2857
+ return (_ctx, _cache) => {
2858
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [
2859
+ createElementVNode("div", _hoisted_2$3, [
2860
+ createElementVNode("div", _hoisted_3$2, [
2861
+ createElementVNode("label", _hoisted_4$2, toDisplayString(__props.sortByLabel) + ":", 1),
2862
+ createElementVNode("div", _hoisted_5$2, [
2863
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.fields, (field) => {
2864
+ return openBlock(), createElementBlock("button", {
2865
+ key: field.key,
2866
+ onClick: ($event) => handleSort(field.key),
2867
+ class: normalizeClass([
2868
+ "px-3 py-1.5 text-sm font-medium rounded-lg transition-all duration-200",
2869
+ __props.currentSortField === field.key ? "bg-blue-500 text-white shadow-sm" : "bg-gray-100 text-gray-700 hover:bg-gray-200"
2870
+ ])
2871
+ }, [
2872
+ createTextVNode(toDisplayString(field.label) + " ", 1),
2873
+ __props.currentSortField === field.key && __props.currentDirection === "asc" ? (openBlock(), createBlock(unref(ChevronUpIcon), {
2874
+ key: 0,
2875
+ class: "w-3 h-3 ml-1 inline"
2876
+ })) : createCommentVNode("", true),
2877
+ __props.currentSortField === field.key && __props.currentDirection === "desc" ? (openBlock(), createBlock(unref(ChevronDownIcon), {
2878
+ key: 1,
2879
+ class: "w-3 h-3 ml-1 inline"
2880
+ })) : createCommentVNode("", true)
2881
+ ], 10, _hoisted_6$2);
2882
+ }), 128))
2883
+ ])
2884
+ ]),
2885
+ createElementVNode("div", _hoisted_7$2, toDisplayString(__props.count) + " " + toDisplayString(__props.countLabel), 1)
2886
+ ])
2887
+ ]);
2888
+ };
2889
+ }
2890
+ };
2891
+ const _hoisted_1$2 = { class: "flex items-center space-x-1" };
2892
+ const _hoisted_2$2 = { class: "flex flex-col" };
2893
+ const _sfc_main$2 = {
2894
+ __name: "ThSortable",
2895
+ props: {
2896
+ field: {
2897
+ type: String,
2898
+ required: true
2899
+ },
2900
+ currentSortField: {
2901
+ type: String,
2902
+ default: ""
2903
+ },
2904
+ currentDirection: {
2905
+ type: String,
2906
+ default: "asc"
2907
+ }
2908
+ },
2909
+ setup(__props) {
2910
+ const props = __props;
2911
+ const isCurrentSort = computed(() => {
2912
+ return props.field === props.currentSortField;
2913
+ });
2914
+ const sortIconClass = computed(() => {
2915
+ if (!isCurrentSort.value) {
2916
+ return "text-gray-400";
2917
+ }
2918
+ return "text-blue-600";
2919
+ });
2920
+ return (_ctx, _cache) => {
2921
+ return openBlock(), createElementBlock("th", {
2922
+ class: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100 transition-colors duration-150",
2923
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("sort", __props.field))
2924
+ }, [
2925
+ createElementVNode("div", _hoisted_1$2, [
2926
+ createElementVNode("span", null, [
2927
+ renderSlot(_ctx.$slots, "default")
2928
+ ]),
2929
+ createElementVNode("div", _hoisted_2$2, [
2930
+ isCurrentSort.value && __props.currentDirection === "asc" ? (openBlock(), createBlock(unref(ChevronUpIcon), {
2931
+ key: 0,
2932
+ class: normalizeClass([sortIconClass.value, "w-3 h-3"])
2933
+ }, null, 8, ["class"])) : createCommentVNode("", true),
2934
+ isCurrentSort.value && __props.currentDirection === "desc" ? (openBlock(), createBlock(unref(ChevronDownIcon), {
2935
+ key: 1,
2936
+ class: normalizeClass([sortIconClass.value, "w-3 h-3"])
2937
+ }, null, 8, ["class"])) : createCommentVNode("", true)
2938
+ ])
2939
+ ])
2940
+ ]);
2941
+ };
2942
+ }
2943
+ };
2944
+ const _hoisted_1$1 = { class: "min-w-full divide-y divide-slate-200/80" };
2945
+ const _hoisted_2$1 = { class: "bg-slate-50/80" };
2946
+ const _hoisted_3$1 = {
2947
+ key: 0,
2948
+ class: "px-6 py-3 text-right text-[11px] font-semibold tracking-[0.12em] text-slate-600 uppercase"
2949
+ };
2950
+ const _hoisted_4$1 = { class: "bg-white divide-y divide-slate-200/80" };
2951
+ const _hoisted_5$1 = {
2952
+ key: 0,
2953
+ class: "flex items-center"
2954
+ };
2955
+ const _hoisted_6$1 = ["title"];
2956
+ const _hoisted_7$1 = {
2957
+ key: 0,
2958
+ class: "ml-2 inline-flex items-center rounded-full bg-rose-100 px-2 py-1 text-xs font-medium text-rose-700"
2959
+ };
2960
+ const _hoisted_8$1 = ["innerHTML"];
2961
+ const _hoisted_9$1 = { key: 3 };
2962
+ const _hoisted_10$1 = {
2963
+ key: 0,
2964
+ class: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
2965
+ };
2966
+ const _hoisted_11$1 = {
2967
+ key: 0,
2968
+ class: "text-center py-12"
2969
+ };
2970
+ const _hoisted_12$1 = { class: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-slate-100 mb-4" };
2971
+ const _hoisted_13$1 = { class: "mb-2 text-lg font-semibold text-slate-900" };
2972
+ const _hoisted_14$1 = { class: "mb-4 text-slate-600" };
2973
+ const _sfc_main$1 = {
2974
+ __name: "TableList",
2975
+ props: {
2976
+ data: {
2977
+ type: Array,
2978
+ required: true
2979
+ },
2980
+ columns: {
2981
+ type: Array,
2982
+ required: true
2983
+ },
2984
+ sortField: {
2985
+ type: String,
2986
+ default: ""
2987
+ },
2988
+ sortDirection: {
2989
+ type: String,
2990
+ default: "asc"
2991
+ },
2992
+ emptyState: {
2993
+ type: Object,
2994
+ default: () => ({
2995
+ icon: "UsersIcon",
2996
+ title: "No data found",
2997
+ description: "No items to display.",
2998
+ actionText: null,
2999
+ actionUrl: null
3000
+ })
3001
+ },
3002
+ rowClasses: {
3003
+ type: Function,
3004
+ default: (item, index) => [
3005
+ "transition-colors duration-150",
3006
+ item.deleted_at ? "bg-rose-50 hover:bg-rose-100" : "odd:bg-white even:bg-slate-50 hover:bg-slate-100"
3007
+ ]
3008
+ },
3009
+ maxTextLength: {
3010
+ type: Number,
3011
+ default: 40
3012
+ },
3013
+ isCard: {
3014
+ type: Boolean,
3015
+ default: true
3016
+ },
3017
+ actionsLabel: {
3018
+ type: String,
3019
+ default: "Actions"
3020
+ },
3021
+ deletedLabel: {
3022
+ type: String,
3023
+ default: "Deleted"
3024
+ }
3025
+ },
3026
+ emits: ["sort"],
3027
+ setup(__props, { emit: __emit }) {
3028
+ const slots = useSlots();
3029
+ const props = __props;
3030
+ const emit = __emit;
3031
+ computed(() => !!slots.actions);
3032
+ const hasData = computed(() => props.data && props.data.length > 0);
3033
+ const sortBy = (field) => {
3034
+ emit("sort", field);
3035
+ };
3036
+ const truncateText = (value) => {
3037
+ const stringValue = String(value ?? "");
3038
+ const maxLength = Number(props.maxTextLength);
3039
+ if (!Number.isFinite(maxLength) || maxLength <= 0 || stringValue.length <= maxLength) {
3040
+ return stringValue;
3041
+ }
3042
+ return `${stringValue.slice(0, maxLength)}...`;
3043
+ };
3044
+ const getCellContent = (item, column) => {
3045
+ if (column.slot) {
3046
+ return null;
3047
+ }
3048
+ if (column.render) {
3049
+ return column.render(item);
3050
+ }
3051
+ const value = column.key.split(".").reduce((obj, key) => obj?.[key], item);
3052
+ if (value === null || value === void 0 || value === "") {
3053
+ return "-";
3054
+ }
3055
+ return truncateText(value);
3056
+ };
3057
+ const isDeleted = (item) => {
3058
+ return item.deleted_at || item.deleted;
3059
+ };
3060
+ const getColumnClass = (column) => {
3061
+ if (column.class) {
3062
+ return column.class;
3063
+ }
3064
+ let classes = "px-6 py-4 text-sm truncate";
3065
+ if (!column.isSecondary) {
3066
+ classes += " font-medium";
3067
+ }
3068
+ if (column.isSecondary) {
3069
+ classes += " text-slate-600";
3070
+ }
3071
+ return classes;
3072
+ };
3073
+ const getHeaderClass = (column) => {
3074
+ if (column.sortable) {
3075
+ return "";
3076
+ }
3077
+ return "px-6 py-3 text-left text-[11px] font-semibold tracking-[0.12em] text-slate-600 uppercase";
3078
+ };
3079
+ return (_ctx, _cache) => {
3080
+ return openBlock(), createElementBlock("div", {
3081
+ class: normalizeClass(["bg-white/90 backdrop-blur-sm", __props.isCard ? "border border-slate-200/70 rounded-2xl shadow-[0_12px_30px_rgba(15,23,42,0.06)] animate-fadeIn mx-4 md:mx-0" : ""])
3082
+ }, [
3083
+ createElementVNode("div", {
3084
+ class: normalizeClass(["overflow-x-auto", __props.isCard ? "rounded-xl" : ""])
3085
+ }, [
3086
+ createElementVNode("table", _hoisted_1$1, [
3087
+ createElementVNode("thead", _hoisted_2$1, [
3088
+ createElementVNode("tr", null, [
3089
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
3090
+ return openBlock(), createElementBlock(Fragment, {
3091
+ key: column.key
3092
+ }, [
3093
+ column.sortable ? (openBlock(), createBlock(_sfc_main$2, {
3094
+ key: 0,
3095
+ field: column.key,
3096
+ "current-sort-field": __props.sortField,
3097
+ "current-direction": __props.sortDirection,
3098
+ onSort: sortBy
3099
+ }, {
3100
+ default: withCtx(() => [
3101
+ createTextVNode(toDisplayString(column.label), 1)
3102
+ ]),
3103
+ _: 2
3104
+ }, 1032, ["field", "current-sort-field", "current-direction"])) : (openBlock(), createElementBlock("th", {
3105
+ key: 1,
3106
+ class: normalizeClass([getHeaderClass(column), { "text-right": column.align === "right" }])
3107
+ }, toDisplayString(column.label), 3))
3108
+ ], 64);
3109
+ }), 128)),
3110
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("th", _hoisted_3$1, toDisplayString(__props.actionsLabel), 1)) : createCommentVNode("", true)
3111
+ ])
3112
+ ]),
3113
+ createElementVNode("tbody", _hoisted_4$1, [
3114
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data, (item, index) => {
3115
+ return openBlock(), createElementBlock("tr", {
3116
+ key: item.id,
3117
+ class: normalizeClass(__props.rowClasses(item, index))
3118
+ }, [
3119
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
3120
+ return openBlock(), createElementBlock("td", {
3121
+ key: column.key,
3122
+ class: normalizeClass(getColumnClass(column))
3123
+ }, [
3124
+ column.key === "name" && !column.slot ? (openBlock(), createElementBlock("div", _hoisted_5$1, [
3125
+ createElementVNode("div", {
3126
+ class: "text-sm font-medium text-slate-900 truncate",
3127
+ title: getCellContent(item, column)
3128
+ }, toDisplayString(getCellContent(item, column)), 9, _hoisted_6$1),
3129
+ isDeleted(item) ? (openBlock(), createElementBlock("span", _hoisted_7$1, toDisplayString(__props.deletedLabel), 1)) : createCommentVNode("", true)
3130
+ ])) : column.slot ? renderSlot(_ctx.$slots, column.slot, {
3131
+ key: 1,
3132
+ item,
3133
+ column,
3134
+ index
3135
+ }) : column.render ? (openBlock(), createElementBlock("div", {
3136
+ key: 2,
3137
+ innerHTML: column.render(item)
3138
+ }, null, 8, _hoisted_8$1)) : (openBlock(), createElementBlock("div", _hoisted_9$1, toDisplayString(getCellContent(item, column)), 1))
3139
+ ], 2);
3140
+ }), 128)),
3141
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("td", _hoisted_10$1, [
3142
+ renderSlot(_ctx.$slots, "actions", {
3143
+ item,
3144
+ index
3145
+ })
3146
+ ])) : createCommentVNode("", true)
3147
+ ], 2);
3148
+ }), 128))
3149
+ ])
3150
+ ])
3151
+ ], 2),
3152
+ !hasData.value ? (openBlock(), createElementBlock("div", _hoisted_11$1, [
3153
+ createElementVNode("div", _hoisted_12$1, [
3154
+ (openBlock(), createBlock(resolveDynamicComponent(__props.emptyState.icon), { class: "w-8 h-8 text-slate-400" }))
3155
+ ]),
3156
+ createElementVNode("h3", _hoisted_13$1, toDisplayString(__props.emptyState.title), 1),
3157
+ createElementVNode("p", _hoisted_14$1, toDisplayString(__props.emptyState.description), 1),
3158
+ __props.emptyState.actionText && __props.emptyState.actionUrl ? (openBlock(), createBlock(_sfc_main$5, {
3159
+ key: 0,
3160
+ href: __props.emptyState.actionUrl,
3161
+ variant: "primary"
3162
+ }, {
3163
+ default: withCtx(() => [
3164
+ createTextVNode(toDisplayString(__props.emptyState.actionText), 1)
3165
+ ]),
3166
+ _: 1
3167
+ }, 8, ["href"])) : createCommentVNode("", true)
3168
+ ])) : createCommentVNode("", true)
3169
+ ], 2);
3170
+ };
3171
+ }
3172
+ };
3173
+ const _hoisted_1 = { class: "relative max-w-sm" };
3174
+ const _hoisted_2 = { class: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" };
3175
+ const _hoisted_3 = ["placeholder"];
3176
+ const _hoisted_4 = { class: "min-w-full divide-y divide-gray-200" };
3177
+ const _hoisted_5 = { class: "bg-gray-50" };
3178
+ const _hoisted_6 = {
3179
+ key: 0,
3180
+ class: "px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"
3181
+ };
3182
+ const _hoisted_7 = { class: "bg-white divide-y divide-gray-200" };
3183
+ const _hoisted_8 = {
3184
+ key: 2,
3185
+ class: "flex items-center"
3186
+ };
3187
+ const _hoisted_9 = ["title"];
3188
+ const _hoisted_10 = {
3189
+ key: 0,
3190
+ class: "ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-1 text-xs font-medium text-red-800"
3191
+ };
3192
+ const _hoisted_11 = ["innerHTML"];
3193
+ const _hoisted_12 = { key: 5 };
3194
+ const _hoisted_13 = {
3195
+ key: 0,
3196
+ class: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
3197
+ };
3198
+ const _hoisted_14 = { class: "flex items-center justify-end gap-2" };
3199
+ const _hoisted_15 = {
3200
+ key: 2,
3201
+ class: "py-12 text-center"
3202
+ };
3203
+ const _hoisted_16 = { class: "mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-gray-100" };
3204
+ const _hoisted_17 = { class: "mb-2 text-lg font-medium text-gray-900" };
3205
+ const _hoisted_18 = { class: "mb-4 text-gray-500" };
3206
+ const _sfc_main = {
3207
+ __name: "TableListForm",
3208
+ props: {
3209
+ data: {
3210
+ type: Array,
3211
+ required: true
3212
+ },
3213
+ columns: {
3214
+ type: Array,
3215
+ required: true
3216
+ },
3217
+ sortField: {
3218
+ type: String,
3219
+ default: ""
3220
+ },
3221
+ sortDirection: {
3222
+ type: String,
3223
+ default: "asc"
3224
+ },
3225
+ emptyState: {
3226
+ type: Object,
3227
+ default: () => ({
3228
+ icon: "UsersIcon",
3229
+ title: "No data found",
3230
+ description: "No items to display.",
3231
+ actionText: null,
3232
+ actionUrl: null
3233
+ })
3234
+ },
3235
+ rowClasses: {
3236
+ type: Function,
3237
+ default: (item) => [
3238
+ "transition-colors duration-150",
3239
+ item.deleted_at ? "bg-red-50 hover:bg-red-100" : "odd:bg-white even:bg-gray-50 hover:bg-gray-100"
3240
+ ]
3241
+ },
3242
+ getErrorMessage: {
3243
+ type: Function,
3244
+ default: () => null
3245
+ },
3246
+ search: {
3247
+ type: Boolean,
3248
+ default: true
3249
+ },
3250
+ searchPlaceholder: {
3251
+ type: String,
3252
+ default: "Search..."
3253
+ },
3254
+ rowKey: {
3255
+ type: [String, Function],
3256
+ default: "id"
3257
+ },
3258
+ isDeletedFn: {
3259
+ type: Function,
3260
+ default: (item) => Boolean(item?.deleted_at || item?.deleted)
3261
+ },
3262
+ mutateRows: {
3263
+ type: Boolean,
3264
+ default: true
3265
+ },
3266
+ isCard: {
3267
+ type: Boolean,
3268
+ default: true
3269
+ },
3270
+ actionsLabel: {
3271
+ type: String,
3272
+ default: "Actions"
3273
+ },
3274
+ deletedLabel: {
3275
+ type: String,
3276
+ default: "Deleted"
3277
+ },
3278
+ maxTextLength: {
3279
+ type: Number,
3280
+ default: 40
3281
+ },
3282
+ rowEditing: {
3283
+ type: Boolean,
3284
+ default: true
3285
+ },
3286
+ editingRowKey: {
3287
+ type: [String, Number, null],
3288
+ default: void 0
3289
+ },
3290
+ canEditRow: {
3291
+ type: Function,
3292
+ default: () => true
3293
+ },
3294
+ editLabel: {
3295
+ type: String,
3296
+ default: "Edit row"
3297
+ },
3298
+ cancelLabel: {
3299
+ type: String,
3300
+ default: "Done editing"
3301
+ }
3302
+ },
3303
+ emits: ["sort", "update", "update:editingRowKey", "edit-start", "edit-cancel"],
3304
+ setup(__props, { emit: __emit }) {
3305
+ const slots = useSlots();
3306
+ const props = __props;
3307
+ const emit = __emit;
3308
+ const localSortField = ref(props.sortField);
3309
+ const localSortDirection = ref(props.sortDirection);
3310
+ const searchQuery = ref("");
3311
+ const internalEditingRowKey = ref(null);
3312
+ const editingDraft = ref({});
3313
+ const resolvedEditingRowKey = computed(() => {
3314
+ return props.editingRowKey !== void 0 ? props.editingRowKey : internalEditingRowKey.value;
3315
+ });
3316
+ watch(() => props.sortField, (value) => {
3317
+ localSortField.value = value;
3318
+ });
3319
+ watch(() => props.sortDirection, (value) => {
3320
+ localSortDirection.value = value;
3321
+ });
3322
+ watch(() => props.rowEditing, (value) => {
3323
+ if (!value) {
3324
+ resetEditState();
3325
+ }
3326
+ });
3327
+ watch(resolvedEditingRowKey, (nextKey, previousKey) => {
3328
+ if (nextKey === previousKey) {
3329
+ return;
3330
+ }
3331
+ if (nextKey === null || nextKey === void 0 || nextKey === "") {
3332
+ editingDraft.value = {};
3333
+ return;
3334
+ }
3335
+ const activeItem = props.data.find((item, index) => getRowKey(item, index) === nextKey);
3336
+ editingDraft.value = activeItem ? cloneValue(activeItem) : {};
3337
+ });
3338
+ watch(
3339
+ () => props.data,
3340
+ () => {
3341
+ if (resolvedEditingRowKey.value === null || resolvedEditingRowKey.value === void 0) {
3342
+ return;
3343
+ }
3344
+ const activeItem = props.data.find((item, index) => getRowKey(item, index) === resolvedEditingRowKey.value);
3345
+ if (!activeItem) {
3346
+ resetEditState();
3347
+ }
3348
+ },
3349
+ { deep: true }
3350
+ );
3351
+ const sortedData = computed(() => {
3352
+ let filteredData = props.data;
3353
+ if (props.search && searchQuery.value.trim()) {
3354
+ const query = searchQuery.value.toLowerCase().trim();
3355
+ filteredData = props.data.filter((item) => {
3356
+ return props.columns.some((column) => {
3357
+ if (!column.searchable) {
3358
+ return false;
3359
+ }
3360
+ const value = getNestedValue(item, column.key);
3361
+ if (value === null || value === void 0 || value === "") {
3362
+ return false;
3363
+ }
3364
+ return String(value).toLowerCase().includes(query);
3365
+ });
3366
+ });
3367
+ }
3368
+ if (!localSortField.value) {
3369
+ return filteredData;
3370
+ }
3371
+ return [...filteredData].sort((a, b) => {
3372
+ const aValue = getNestedValue(a, localSortField.value);
3373
+ const bValue = getNestedValue(b, localSortField.value);
3374
+ if (aValue === null || aValue === void 0 || aValue === "") return 1;
3375
+ if (bValue === null || bValue === void 0 || bValue === "") return -1;
3376
+ let comparison = 0;
3377
+ if (aValue < bValue) comparison = -1;
3378
+ if (aValue > bValue) comparison = 1;
3379
+ return localSortDirection.value === "desc" ? -comparison : comparison;
3380
+ });
3381
+ });
3382
+ const hasActionsSlot = computed(() => Boolean(slots.actions));
3383
+ const hasActionsColumn = computed(() => hasActionsSlot.value || props.rowEditing);
3384
+ const hasData = computed(() => sortedData.value && sortedData.value.length > 0);
3385
+ const sortBy = (field) => {
3386
+ if (localSortField.value === field) {
3387
+ localSortDirection.value = localSortDirection.value === "asc" ? "desc" : "asc";
3388
+ } else {
3389
+ localSortField.value = field;
3390
+ localSortDirection.value = "asc";
3391
+ }
3392
+ emit("sort", { field, direction: localSortDirection.value });
3393
+ };
3394
+ const cloneValue = (value) => {
3395
+ if (Array.isArray(value)) {
3396
+ return value.map((entry) => cloneValue(entry));
3397
+ }
3398
+ if (value && typeof value === "object") {
3399
+ return Object.fromEntries(
3400
+ Object.entries(value).map(([key, entry]) => [key, cloneValue(entry)])
3401
+ );
3402
+ }
3403
+ return value;
3404
+ };
3405
+ const truncateText = (value) => {
3406
+ const stringValue = String(value ?? "");
3407
+ const maxLength = Number(props.maxTextLength);
3408
+ if (!Number.isFinite(maxLength) || maxLength <= 0 || stringValue.length <= maxLength) {
3409
+ return stringValue;
3410
+ }
3411
+ return `${stringValue.slice(0, maxLength)}...`;
3412
+ };
3413
+ const getNestedValue = (obj, path) => {
3414
+ if (!path || typeof path !== "string") {
3415
+ return obj;
3416
+ }
3417
+ return path.split(".").reduce((current, key) => current?.[key], obj);
3418
+ };
3419
+ const setNestedValue = (obj, path, value) => {
3420
+ if (!path || typeof path !== "string" || obj == null) {
3421
+ return;
3422
+ }
3423
+ const keys = path.split(".");
3424
+ const lastKey = keys.pop();
3425
+ let current = obj;
3426
+ for (const key of keys) {
3427
+ if (current[key] === void 0 || current[key] === null || typeof current[key] !== "object") {
3428
+ current[key] = {};
3429
+ }
3430
+ current = current[key];
3431
+ }
3432
+ if (lastKey !== void 0) {
3433
+ current[lastKey] = value;
3434
+ }
3435
+ };
3436
+ const getDataIndex = (item) => {
3437
+ if (item?.id) {
3438
+ return props.data.findIndex((row) => row?.id === item.id);
3439
+ }
3440
+ return props.data.findIndex((row) => row === item);
3441
+ };
3442
+ const getRowKey = (item, index) => {
3443
+ if (typeof props.rowKey === "function") {
3444
+ const customKey = props.rowKey(item, index);
3445
+ return customKey ?? `row-${index}`;
3446
+ }
3447
+ const resolved = getNestedValue(item, props.rowKey);
3448
+ return resolved ?? `row-${index}`;
3449
+ };
3450
+ const getEditSlotName = (column) => `${column.slot}-edit`;
3451
+ const isDeleted = (item) => props.isDeletedFn(item);
3452
+ const setEditingRowKey = (value) => {
3453
+ if (props.editingRowKey === void 0) {
3454
+ internalEditingRowKey.value = value;
3455
+ }
3456
+ emit("update:editingRowKey", value);
3457
+ };
3458
+ const isEditingRow = (item, index) => {
3459
+ return props.rowEditing && resolvedEditingRowKey.value !== null && resolvedEditingRowKey.value === getRowKey(item, index);
3460
+ };
3461
+ const isRowEditDisabled = (item, index) => {
3462
+ if (!props.rowEditing) {
3463
+ return true;
3464
+ }
3465
+ if (!props.canEditRow(item, index) || isDeleted(item)) {
3466
+ return true;
3467
+ }
3468
+ return resolvedEditingRowKey.value !== null && !isEditingRow(item, index);
3469
+ };
3470
+ const resetEditState = () => {
3471
+ setEditingRowKey(null);
3472
+ };
3473
+ const startEdit = (item, index) => {
3474
+ if (isRowEditDisabled(item, index)) {
3475
+ return;
3476
+ }
3477
+ const rowKey = getRowKey(item, index);
3478
+ setEditingRowKey(rowKey);
3479
+ emit("edit-start", {
3480
+ item,
3481
+ index: getDataIndex(item),
3482
+ rowKey
3483
+ });
3484
+ };
3485
+ const cancelEdit = (item, index) => {
3486
+ emit("edit-cancel", {
3487
+ item,
3488
+ index: getDataIndex(item),
3489
+ rowKey: getRowKey(item, index)
3490
+ });
3491
+ resetEditState();
3492
+ };
3493
+ const updateDraft = (field, value, item, eventName = void 0) => {
3494
+ setNestedValue(editingDraft.value, field, value);
3495
+ if (props.mutateRows) {
3496
+ setNestedValue(item, field, cloneValue(value));
3497
+ }
3498
+ emit("update", {
3499
+ item,
3500
+ draft: editingDraft.value,
3501
+ field,
3502
+ value,
3503
+ index: getDataIndex(item),
3504
+ rowKey: resolvedEditingRowKey.value,
3505
+ event: eventName
3506
+ });
3507
+ };
3508
+ const getCellContent = (item, column) => {
3509
+ if (column.slot) {
3510
+ return null;
3511
+ }
3512
+ if (column.render) {
3513
+ return column.render(item);
3514
+ }
3515
+ const value = getNestedValue(item, column.key);
3516
+ if (value === null || value === void 0 || value === "") {
3517
+ return "-";
3518
+ }
3519
+ return truncateText(value);
3520
+ };
3521
+ const getColumnClass = (column, item, index) => {
3522
+ if (column.class) {
3523
+ return column.class;
3524
+ }
3525
+ const isEditing = isEditingRow(item, index) && (column.input || slots[getEditSlotName(column)]);
3526
+ let classes = isEditing ? "px-6 py-3 text-sm align-top" : "px-6 py-4 text-sm truncate";
3527
+ if (!column.isSecondary) {
3528
+ classes += " font-medium";
3529
+ }
3530
+ if (column.isSecondary) {
3531
+ classes += " text-gray-600";
3532
+ }
3533
+ return classes;
3534
+ };
3535
+ const getHeaderClass = (column) => {
3536
+ if (column.sortable) {
3537
+ return "";
3538
+ }
3539
+ return "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider";
3540
+ };
3541
+ const getInputType = (column) => column.inputType || "text";
3542
+ const getInputClass = (column) => {
3543
+ let classes = "block w-full min-w-[12rem] sm:min-w-[10rem] max-w-xs rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-sm text-gray-900 shadow-none placeholder-gray-400 transition-colors duration-200 focus:border-blue-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500/20";
3544
+ if (column.inputClass) {
3545
+ classes += ` ${column.inputClass}`;
3546
+ }
3547
+ if (column.isSecondary) {
3548
+ classes += " text-gray-600";
3549
+ }
3550
+ return classes;
3551
+ };
3552
+ const getInputPlaceholder = (column) => column.placeholder || column.label || "";
3553
+ const getInputValue = (item, column, index) => {
3554
+ if (isEditingRow(item, index)) {
3555
+ return getNestedValue(editingDraft.value, column.key) ?? "";
3556
+ }
3557
+ return getNestedValue(item, column.key) ?? "";
3558
+ };
3559
+ const getColumnError = (item, column) => {
3560
+ const arrayIndex = getDataIndex(item);
3561
+ if (arrayIndex === -1) {
3562
+ return null;
3563
+ }
3564
+ return props.getErrorMessage(arrayIndex, column.key);
3565
+ };
3566
+ const getSlotBindings = (item, column, index) => ({
3567
+ item,
3568
+ column,
3569
+ index,
3570
+ isEditing: isEditingRow(item, index),
3571
+ draft: editingDraft.value,
3572
+ rowKey: getRowKey(item, index),
3573
+ updateDraft: (field, value) => updateDraft(field, value, item),
3574
+ startEdit: () => startEdit(item, index),
3575
+ cancelEdit: () => cancelEdit(item, index)
3576
+ });
3577
+ const resolveColumnDisabled = (column, item, index) => {
3578
+ const disabled = typeof column.disabled === "function" ? column.disabled(item, index) : column.disabled;
3579
+ return Boolean(disabled || isDeleted(item));
3580
+ };
3581
+ return (_ctx, _cache) => {
3582
+ return openBlock(), createElementBlock("div", {
3583
+ class: normalizeClass(["bg-white", __props.isCard ? "mx-4 md:mx-0 border border-gray-200/60 rounded-xl shadow-[0_1px_3px_rgba(0,0,0,0.1)] animate-fadeIn" : ""])
3584
+ }, [
3585
+ __props.search ? (openBlock(), createElementBlock("div", {
3586
+ key: 0,
3587
+ class: normalizeClass([
3588
+ "px-6 py-4",
3589
+ __props.isCard ? "border-b border-gray-200 bg-gray-50/80 rounded-t-xl" : "mb-4 bg-white/80 backdrop-blur-sm"
3590
+ ])
3591
+ }, [
3592
+ createElementVNode("div", _hoisted_1, [
3593
+ createElementVNode("div", _hoisted_2, [
3594
+ createVNode(unref(MagnifyingGlassIcon), { class: "h-4 w-4 text-gray-400" })
3595
+ ]),
3596
+ withDirectives(createElementVNode("input", {
3597
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
3598
+ type: "text",
3599
+ placeholder: __props.searchPlaceholder,
3600
+ class: "block w-full rounded-md border border-gray-200 bg-white pl-9 pr-3 py-2 text-sm text-gray-900 placeholder-gray-500 transition-colors duration-200 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
3601
+ }, null, 8, _hoisted_3), [
3602
+ [vModelText, searchQuery.value]
3603
+ ])
3604
+ ])
3605
+ ], 2)) : createCommentVNode("", true),
3606
+ hasData.value ? (openBlock(), createElementBlock("div", {
3607
+ key: 1,
3608
+ class: normalizeClass(["overflow-x-auto", __props.isCard ? "rounded-xl" : ""])
3609
+ }, [
3610
+ createElementVNode("table", _hoisted_4, [
3611
+ createElementVNode("thead", _hoisted_5, [
3612
+ createElementVNode("tr", null, [
3613
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
3614
+ return openBlock(), createElementBlock(Fragment, {
3615
+ key: column.key
3616
+ }, [
3617
+ column.sortable ? (openBlock(), createBlock(_sfc_main$2, {
3618
+ key: 0,
3619
+ field: column.key,
3620
+ "current-sort-field": localSortField.value,
3621
+ "current-direction": localSortDirection.value,
3622
+ onSort: sortBy
3623
+ }, {
3624
+ default: withCtx(() => [
3625
+ createTextVNode(toDisplayString(column.label), 1)
3626
+ ]),
3627
+ _: 2
3628
+ }, 1032, ["field", "current-sort-field", "current-direction"])) : (openBlock(), createElementBlock("th", {
3629
+ key: 1,
3630
+ class: normalizeClass([getHeaderClass(column), { "text-right": column.align === "right" }])
3631
+ }, toDisplayString(column.label), 3))
3632
+ ], 64);
3633
+ }), 128)),
3634
+ hasActionsColumn.value ? (openBlock(), createElementBlock("th", _hoisted_6, toDisplayString(__props.actionsLabel), 1)) : createCommentVNode("", true)
3635
+ ])
3636
+ ]),
3637
+ createElementVNode("tbody", _hoisted_7, [
3638
+ (openBlock(true), createElementBlock(Fragment, null, renderList(sortedData.value, (item, index) => {
3639
+ return openBlock(), createElementBlock("tr", {
3640
+ key: getRowKey(item, index),
3641
+ class: normalizeClass(__props.rowClasses(item, index))
3642
+ }, [
3643
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
3644
+ return openBlock(), createElementBlock("td", {
3645
+ key: column.key,
3646
+ class: normalizeClass([getColumnClass(column, item, index), { "text-right": column.align === "right" }])
3647
+ }, [
3648
+ isEditingRow(item, index) && column.slot && unref(slots)[getEditSlotName(column)] ? renderSlot(_ctx.$slots, getEditSlotName(column), mergeProps({
3649
+ key: 0,
3650
+ ref_for: true
3651
+ }, getSlotBindings(item, column, index))) : isEditingRow(item, index) && column.input ? (openBlock(), createBlock(_sfc_main$f, {
3652
+ key: 1,
3653
+ type: getInputType(column),
3654
+ class: normalizeClass(getInputClass(column)),
3655
+ placeholder: getInputPlaceholder(column),
3656
+ "model-value": getInputValue(item, column, index),
3657
+ disabled: resolveColumnDisabled(column, item, index),
3658
+ maxlength: column.maxlength,
3659
+ "error-message": getColumnError(item, column),
3660
+ "helper-text": "",
3661
+ "onUpdate:modelValue": (value) => updateDraft(column.key, value, item),
3662
+ onBlur: (event) => updateDraft(column.key, event?.target?.value ?? getInputValue(item, column, index), item, "blur")
3663
+ }, null, 8, ["type", "class", "placeholder", "model-value", "disabled", "maxlength", "error-message", "onUpdate:modelValue", "onBlur"])) : column.key === "name" && !column.slot ? (openBlock(), createElementBlock("div", _hoisted_8, [
3664
+ createElementVNode("div", {
3665
+ class: "text-sm font-medium truncate",
3666
+ title: getCellContent(item, column)
3667
+ }, toDisplayString(getCellContent(item, column)), 9, _hoisted_9),
3668
+ isDeleted(item) ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(__props.deletedLabel), 1)) : createCommentVNode("", true)
3669
+ ])) : column.slot ? renderSlot(_ctx.$slots, column.slot, mergeProps({
3670
+ key: 3,
3671
+ ref_for: true
3672
+ }, getSlotBindings(item, column, index))) : column.render ? (openBlock(), createElementBlock("div", {
3673
+ key: 4,
3674
+ innerHTML: column.render(item)
3675
+ }, null, 8, _hoisted_11)) : (openBlock(), createElementBlock("div", _hoisted_12, toDisplayString(getCellContent(item, column)), 1))
3676
+ ], 2);
3677
+ }), 128)),
3678
+ hasActionsColumn.value ? (openBlock(), createElementBlock("td", _hoisted_13, [
3679
+ createElementVNode("div", _hoisted_14, [
3680
+ hasActionsSlot.value ? renderSlot(_ctx.$slots, "actions", mergeProps({
3681
+ key: 0,
3682
+ ref_for: true
3683
+ }, getSlotBindings(item, null, index))) : createCommentVNode("", true),
3684
+ __props.rowEditing && isEditingRow(item, index) ? (openBlock(), createBlock(_sfc_main$s, {
3685
+ key: 1,
3686
+ type: "button",
3687
+ variant: "tertiary",
3688
+ title: __props.cancelLabel,
3689
+ "aria-label": __props.cancelLabel,
3690
+ onClick: ($event) => cancelEdit(item, index)
3691
+ }, {
3692
+ default: withCtx(() => [
3693
+ createVNode(unref(CheckIcon), { class: "size-4" })
3694
+ ]),
3695
+ _: 1
3696
+ }, 8, ["title", "aria-label", "onClick"])) : __props.rowEditing ? (openBlock(), createBlock(_sfc_main$s, {
3697
+ key: 2,
3698
+ type: "button",
3699
+ variant: "warning",
3700
+ disabled: isRowEditDisabled(item, index),
3701
+ title: __props.editLabel,
3702
+ "aria-label": __props.editLabel,
3703
+ onClick: ($event) => startEdit(item, index)
3704
+ }, {
3705
+ default: withCtx(() => [
3706
+ createVNode(unref(PencilSquareIcon), { class: "size-4" })
3707
+ ]),
3708
+ _: 1
3709
+ }, 8, ["disabled", "title", "aria-label", "onClick"])) : createCommentVNode("", true)
3710
+ ])
3711
+ ])) : createCommentVNode("", true)
3712
+ ], 2);
3713
+ }), 128))
3714
+ ])
3715
+ ])
3716
+ ], 2)) : (openBlock(), createElementBlock("div", _hoisted_15, [
3717
+ createElementVNode("div", _hoisted_16, [
3718
+ (openBlock(), createBlock(resolveDynamicComponent(__props.emptyState.icon), { class: "h-8 w-8 text-gray-400" }))
3719
+ ]),
3720
+ createElementVNode("h3", _hoisted_17, toDisplayString(__props.emptyState.title), 1),
3721
+ createElementVNode("p", _hoisted_18, toDisplayString(__props.emptyState.description), 1),
3722
+ __props.emptyState.actionText && __props.emptyState.actionUrl ? (openBlock(), createBlock(_sfc_main$5, {
3723
+ key: 0,
3724
+ href: __props.emptyState.actionUrl,
3725
+ variant: "primary"
3726
+ }, {
3727
+ default: withCtx(() => [
3728
+ createTextVNode(toDisplayString(__props.emptyState.actionText), 1)
3729
+ ]),
3730
+ _: 1
3731
+ }, 8, ["href"])) : createCommentVNode("", true)
3732
+ ]))
3733
+ ], 2);
3734
+ };
3735
+ }
3736
+ };
1
3737
  const plugin = {
2
- install(_app) {
3738
+ install(app) {
3739
+ for (const [name, component] of Object.entries(components)) {
3740
+ if (name === "EnosVueDefault") {
3741
+ continue;
3742
+ }
3743
+ app.component(name, component);
3744
+ }
3
3745
  }
4
3746
  };
5
3747
  export {
6
- plugin as EnosVueDefault
3748
+ _sfc_main$x as ActionCard,
3749
+ _sfc_main$w as ActionMessage,
3750
+ _sfc_main$u as ActionSection,
3751
+ _sfc_main$t as Badge,
3752
+ _sfc_main$s as Button,
3753
+ _sfc_main$z as Card,
3754
+ _sfc_main$A as CardTabs,
3755
+ _sfc_main$r as Checkbox,
3756
+ _sfc_main$q as CheckboxInput,
3757
+ _sfc_main$e as CheckboxMultipleInput,
3758
+ _sfc_main$c as ConfirmationModal,
3759
+ _sfc_main$n as CustomSelect,
3760
+ _sfc_main$l as DateInput,
3761
+ _sfc_main$b as DialogModal,
3762
+ _sfc_main$y as Divider,
3763
+ _sfc_main$a as Dropdown,
3764
+ _sfc_main$9 as DropdownLink,
3765
+ plugin as EnosVueDefault,
3766
+ _sfc_main$8 as FormSection,
3767
+ _sfc_main$k as ImageInput,
3768
+ _sfc_main$7 as InputError,
3769
+ _sfc_main$f as InputGroup,
3770
+ _sfc_main$6 as InputLabel,
3771
+ _sfc_main$5 as LinkButton,
3772
+ _sfc_main$d as Modal,
3773
+ _sfc_main$j as NotationInput,
3774
+ _sfc_main$i as RadioInput,
3775
+ _sfc_main$h as RadioMultipleInput,
3776
+ _sfc_main$4 as SectionBorder,
3777
+ SectionTitle,
3778
+ _sfc_main$m as SelectInput,
3779
+ _sfc_main$3 as SortControls,
3780
+ _sfc_main$1 as TableList,
3781
+ _sfc_main as TableListForm,
3782
+ _sfc_main$o as TextArea,
3783
+ _sfc_main$p as TextInput,
3784
+ _sfc_main$2 as ThSortable,
3785
+ _sfc_main$g as TinyEditor
7
3786
  };
8
3787
  //# sourceMappingURL=index.js.map