cisse-vue-ui 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +435 -6
- package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DQD2I1Wk.cjs +621 -0
- package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DQD2I1Wk.cjs.map +1 -0
- package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DVkcMcSN.js +622 -0
- package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DVkcMcSN.js.map +1 -0
- package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-D2MeLTRV.cjs +1133 -0
- package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-D2MeLTRV.cjs.map +1 -0
- package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-Ixih38V0.js +1134 -0
- package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-Ixih38V0.js.map +1 -0
- package/dist/{NotificationList.vue_vue_type_script_setup_true_lang-B2hjbMm4.js → EmptyState.vue_vue_type_script_setup_true_lang-CrVvFwXA.js} +163 -44
- package/dist/EmptyState.vue_vue_type_script_setup_true_lang-CrVvFwXA.js.map +1 -0
- package/dist/{NotificationList.vue_vue_type_script_setup_true_lang-Ci3zIvrv.cjs → EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs} +163 -44
- package/dist/EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs.map +1 -0
- package/dist/MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs +86 -0
- package/dist/MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs.map +1 -0
- package/dist/MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js +87 -0
- package/dist/MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js.map +1 -0
- package/dist/PageLayout.vue_vue_type_script_setup_true_lang-DTlUENg3.js +265 -0
- package/dist/PageLayout.vue_vue_type_script_setup_true_lang-DTlUENg3.js.map +1 -0
- package/dist/PageLayout.vue_vue_type_script_setup_true_lang-IcouTz4C.cjs +264 -0
- package/dist/PageLayout.vue_vue_type_script_setup_true_lang-IcouTz4C.cjs.map +1 -0
- package/dist/components/core/AutocompleteComponent.vue.d.ts +7 -1
- package/dist/components/core/Avatar.vue.d.ts +20 -0
- package/dist/components/core/Button.vue.d.ts +49 -0
- package/dist/components/core/CollapsibleCard.vue.d.ts +28 -0
- package/dist/components/core/Dropdown.vue.d.ts +52 -0
- package/dist/components/core/MenuItem.vue.d.ts +11 -1
- package/dist/components/core/Stepper.vue.d.ts +22 -0
- package/dist/components/core/TabPanel.vue.d.ts +21 -0
- package/dist/components/core/Tabs.vue.d.ts +39 -0
- package/dist/components/core/index.cjs +14 -6
- package/dist/components/core/index.cjs.map +1 -1
- package/dist/components/core/index.d.ts +12 -0
- package/dist/components/core/index.js +14 -6
- package/dist/components/core/index.js.map +1 -1
- package/dist/components/feedback/Alert.vue.d.ts +34 -0
- package/dist/components/feedback/EmptyState.vue.d.ts +29 -0
- package/dist/components/feedback/index.cjs +8 -6
- package/dist/components/feedback/index.cjs.map +1 -1
- package/dist/components/feedback/index.d.ts +3 -0
- package/dist/components/feedback/index.js +3 -1
- package/dist/components/form/Checkbox.vue.d.ts +20 -0
- package/dist/components/form/FormSelect.vue.d.ts +35 -6
- package/dist/components/form/Switch.vue.d.ts +21 -0
- package/dist/components/form/index.cjs +9 -7
- package/dist/components/form/index.cjs.map +1 -1
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +4 -2
- package/dist/components/index.cjs +34 -19
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +26 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/layout/BaseLayout.vue.d.ts +58 -0
- package/dist/components/layout/PageLayout.vue.d.ts +37 -0
- package/dist/components/layout/index.cjs +6 -0
- package/dist/components/layout/index.cjs.map +1 -0
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +6 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/index-Bt9enqyq.cjs +47 -0
- package/dist/index-Bt9enqyq.cjs.map +1 -0
- package/dist/index-CxPY8Qb7.js +48 -0
- package/dist/index-CxPY8Qb7.js.map +1 -0
- package/dist/index.cjs +35 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +29 -14
- package/dist/index.js.map +1 -1
- package/dist/style.css +2 -0
- package/dist/types/components.d.ts +7 -0
- package/package.json +12 -3
- package/dist/NotificationList.vue_vue_type_script_setup_true_lang-B2hjbMm4.js.map +0 -1
- package/dist/NotificationList.vue_vue_type_script_setup_true_lang-Ci3zIvrv.cjs.map +0 -1
- package/dist/SearchInput.vue_vue_type_script_setup_true_lang-Be73hShP.cjs +0 -234
- package/dist/SearchInput.vue_vue_type_script_setup_true_lang-Be73hShP.cjs.map +0 -1
- package/dist/SearchInput.vue_vue_type_script_setup_true_lang-DjT2qdcp.js +0 -235
- package/dist/SearchInput.vue_vue_type_script_setup_true_lang-DjT2qdcp.js.map +0 -1
- package/dist/TableAction.vue_vue_type_script_setup_true_lang-BHskhVhK.js +0 -540
- package/dist/TableAction.vue_vue_type_script_setup_true_lang-BHskhVhK.js.map +0 -1
- package/dist/TableAction.vue_vue_type_script_setup_true_lang-CojbKn7E.cjs +0 -539
- package/dist/TableAction.vue_vue_type_script_setup_true_lang-CojbKn7E.cjs.map +0 -1
- package/dist/index-BoCtJCg0.cjs +0 -32
- package/dist/index-BoCtJCg0.cjs.map +0 -1
- package/dist/index-CGhDI10m.js +0 -33
- package/dist/index-CGhDI10m.js.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const vue = require("vue");
|
|
3
3
|
const vue$1 = require("@iconify/vue");
|
|
4
|
-
const _hoisted_1$
|
|
5
|
-
const _hoisted_2$
|
|
6
|
-
const _hoisted_3$
|
|
4
|
+
const _hoisted_1$6 = { class: "flex items-center justify-center py-12" };
|
|
5
|
+
const _hoisted_2$5 = { class: "text-center" };
|
|
6
|
+
const _hoisted_3$5 = {
|
|
7
7
|
key: 0,
|
|
8
8
|
class: "mt-4 text-gray-600 dark:text-gray-400"
|
|
9
9
|
};
|
|
10
|
-
const _sfc_main$
|
|
10
|
+
const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
|
|
11
11
|
__name: "LoadingSpinner",
|
|
12
12
|
props: {
|
|
13
13
|
text: {},
|
|
@@ -20,29 +20,29 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20
20
|
lg: "h-16 w-16"
|
|
21
21
|
};
|
|
22
22
|
return (_ctx, _cache) => {
|
|
23
|
-
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$
|
|
24
|
-
vue.createElementVNode("div", _hoisted_2$
|
|
23
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
|
|
24
|
+
vue.createElementVNode("div", _hoisted_2$5, [
|
|
25
25
|
vue.createElementVNode("div", {
|
|
26
26
|
class: vue.normalizeClass([sizeClasses[__props.size], "border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent"])
|
|
27
27
|
}, null, 2),
|
|
28
|
-
__props.text ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_3$
|
|
28
|
+
__props.text ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_3$5, vue.toDisplayString(__props.text), 1)) : vue.createCommentVNode("", true)
|
|
29
29
|
])
|
|
30
30
|
]);
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
|
-
const _hoisted_1$
|
|
34
|
+
const _hoisted_1$5 = {
|
|
35
35
|
key: 0,
|
|
36
36
|
class: "flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700"
|
|
37
37
|
};
|
|
38
|
-
const _hoisted_2$
|
|
39
|
-
const _hoisted_3$
|
|
40
|
-
const _hoisted_4$
|
|
38
|
+
const _hoisted_2$4 = { class: "text-xl font-semibold text-gray-900 dark:text-gray-100" };
|
|
39
|
+
const _hoisted_3$4 = { class: "sr-only" };
|
|
40
|
+
const _hoisted_4$3 = { class: "flex-1 overflow-y-auto px-6 py-4" };
|
|
41
41
|
const _hoisted_5$1 = {
|
|
42
42
|
key: 1,
|
|
43
43
|
class: "flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700"
|
|
44
44
|
};
|
|
45
|
-
const _sfc_main$
|
|
45
|
+
const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
|
|
46
46
|
__name: "Modal",
|
|
47
47
|
props: {
|
|
48
48
|
title: { default: "" },
|
|
@@ -87,8 +87,8 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
|
|
|
87
87
|
vue.createElementVNode("div", {
|
|
88
88
|
class: vue.normalizeClass([sizeClasses[__props.size], "flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900"])
|
|
89
89
|
}, [
|
|
90
|
-
__props.title || _ctx.$slots.header || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$
|
|
91
|
-
vue.createElementVNode("h3", _hoisted_2$
|
|
90
|
+
__props.title || _ctx.$slots.header || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
|
|
91
|
+
vue.createElementVNode("h3", _hoisted_2$4, [
|
|
92
92
|
vue.renderSlot(_ctx.$slots, "header", {}, () => [
|
|
93
93
|
vue.renderSlot(_ctx.$slots, "title", {}, () => [
|
|
94
94
|
vue.createTextVNode(vue.toDisplayString(__props.title), 1)
|
|
@@ -104,10 +104,10 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
|
|
|
104
104
|
class: "h-5 w-5",
|
|
105
105
|
icon: "lucide:x"
|
|
106
106
|
}),
|
|
107
|
-
vue.createElementVNode("span", _hoisted_3$
|
|
107
|
+
vue.createElementVNode("span", _hoisted_3$4, vue.toDisplayString(__props.closeButtonLabel), 1)
|
|
108
108
|
])
|
|
109
109
|
])) : vue.createCommentVNode("", true),
|
|
110
|
-
vue.createElementVNode("div", _hoisted_4$
|
|
110
|
+
vue.createElementVNode("div", _hoisted_4$3, [
|
|
111
111
|
vue.renderSlot(_ctx.$slots, "default")
|
|
112
112
|
]),
|
|
113
113
|
_ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$1, [
|
|
@@ -118,13 +118,13 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
|
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
|
-
const _hoisted_1$
|
|
121
|
+
const _hoisted_1$4 = {
|
|
122
122
|
key: 0,
|
|
123
123
|
class: "flex items-center justify-between border-t border-gray-200 px-6 py-4 dark:border-gray-700"
|
|
124
124
|
};
|
|
125
|
-
const _hoisted_2$
|
|
126
|
-
const _hoisted_3$
|
|
127
|
-
const _hoisted_4$
|
|
125
|
+
const _hoisted_2$3 = { class: "flex items-center gap-4" };
|
|
126
|
+
const _hoisted_3$3 = { class: "text-sm text-gray-700 dark:text-gray-300" };
|
|
127
|
+
const _hoisted_4$2 = {
|
|
128
128
|
key: 0,
|
|
129
129
|
class: "flex items-center gap-2"
|
|
130
130
|
};
|
|
@@ -137,7 +137,7 @@ const _hoisted_7 = ["value"];
|
|
|
137
137
|
const _hoisted_8 = { class: "flex gap-2" };
|
|
138
138
|
const _hoisted_9 = ["disabled"];
|
|
139
139
|
const _hoisted_10 = ["disabled"];
|
|
140
|
-
const _sfc_main$
|
|
140
|
+
const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
|
|
141
141
|
__name: "PaginationControls",
|
|
142
142
|
props: {
|
|
143
143
|
currentPage: {},
|
|
@@ -165,10 +165,10 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
|
|
|
165
165
|
emit("update:pageSize", Number(target.value));
|
|
166
166
|
};
|
|
167
167
|
return (_ctx, _cache) => {
|
|
168
|
-
return __props.totalPages > 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$
|
|
169
|
-
vue.createElementVNode("div", _hoisted_2$
|
|
170
|
-
vue.createElementVNode("div", _hoisted_3$
|
|
171
|
-
__props.showPageSize ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$
|
|
168
|
+
return __props.totalPages > 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, [
|
|
169
|
+
vue.createElementVNode("div", _hoisted_2$3, [
|
|
170
|
+
vue.createElementVNode("div", _hoisted_3$3, vue.toDisplayString(__props.pageLabel) + " " + vue.toDisplayString(__props.currentPage) + " " + vue.toDisplayString(__props.ofLabel) + " " + vue.toDisplayString(__props.totalPages), 1),
|
|
171
|
+
__props.showPageSize ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$2, [
|
|
172
172
|
vue.createElementVNode("label", _hoisted_5, vue.toDisplayString(__props.itemsPerPageLabel), 1),
|
|
173
173
|
vue.createElementVNode("select", {
|
|
174
174
|
id: "page-size",
|
|
@@ -213,17 +213,17 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
|
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
|
-
const _hoisted_1$
|
|
217
|
-
const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
|
|
218
|
-
const _hoisted_3 = {
|
|
216
|
+
const _hoisted_1$3 = { class: "flex max-w-md items-start space-x-3 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-800 dark:bg-black" };
|
|
217
|
+
const _hoisted_2$2 = { class: "flex min-w-0 flex-1 flex-col" };
|
|
218
|
+
const _hoisted_3$2 = {
|
|
219
219
|
key: 0,
|
|
220
220
|
class: "text-sm font-semibold text-gray-900 dark:text-gray-100"
|
|
221
221
|
};
|
|
222
|
-
const _hoisted_4 = {
|
|
222
|
+
const _hoisted_4$1 = {
|
|
223
223
|
key: 1,
|
|
224
224
|
class: "mt-1 text-sm text-gray-600 dark:text-gray-400"
|
|
225
225
|
};
|
|
226
|
-
const _sfc_main$
|
|
226
|
+
const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
|
|
227
227
|
__name: "NotificationComponent",
|
|
228
228
|
props: {
|
|
229
229
|
notification: {},
|
|
@@ -290,7 +290,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
return (_ctx, _cache) => {
|
|
293
|
-
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$
|
|
293
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
|
|
294
294
|
vue.createElementVNode("div", {
|
|
295
295
|
class: vue.normalizeClass([bgColor.value, "flex items-center justify-center rounded-full p-2"])
|
|
296
296
|
}, [
|
|
@@ -299,9 +299,9 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
|
299
299
|
icon: iconName.value
|
|
300
300
|
}, null, 8, ["class", "icon"])
|
|
301
301
|
], 2),
|
|
302
|
-
vue.createElementVNode("div", _hoisted_2, [
|
|
303
|
-
__props.notification.title ? (vue.openBlock(), vue.createElementBlock("h4", _hoisted_3, vue.toDisplayString(__props.notification.title), 1)) : vue.createCommentVNode("", true),
|
|
304
|
-
__props.notification.message ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_4, vue.toDisplayString(__props.notification.message), 1)) : vue.createCommentVNode("", true)
|
|
302
|
+
vue.createElementVNode("div", _hoisted_2$2, [
|
|
303
|
+
__props.notification.title ? (vue.openBlock(), vue.createElementBlock("h4", _hoisted_3$2, vue.toDisplayString(__props.notification.title), 1)) : vue.createCommentVNode("", true),
|
|
304
|
+
__props.notification.message ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_4$1, vue.toDisplayString(__props.notification.message), 1)) : vue.createCommentVNode("", true)
|
|
305
305
|
]),
|
|
306
306
|
vue.createElementVNode("button", {
|
|
307
307
|
class: "shrink-0 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-600 dark:hover:text-gray-400",
|
|
@@ -316,8 +316,8 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
|
316
316
|
};
|
|
317
317
|
}
|
|
318
318
|
});
|
|
319
|
-
const _hoisted_1 = { class: "fixed top-5 right-5 z-50 flex flex-col gap-3" };
|
|
320
|
-
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
319
|
+
const _hoisted_1$2 = { class: "fixed top-5 right-5 z-50 flex flex-col gap-3" };
|
|
320
|
+
const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
|
|
321
321
|
__name: "NotificationList",
|
|
322
322
|
props: {
|
|
323
323
|
notifications: {},
|
|
@@ -328,9 +328,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
328
328
|
setup(__props, { emit: __emit }) {
|
|
329
329
|
const emit = __emit;
|
|
330
330
|
return (_ctx, _cache) => {
|
|
331
|
-
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
331
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
|
|
332
332
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.notifications, (notification) => {
|
|
333
|
-
return vue.openBlock(), vue.createBlock(_sfc_main$
|
|
333
|
+
return vue.openBlock(), vue.createBlock(_sfc_main$3, {
|
|
334
334
|
key: notification.id,
|
|
335
335
|
notification,
|
|
336
336
|
"auto-dismiss": __props.autoDismiss,
|
|
@@ -342,9 +342,128 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
342
342
|
};
|
|
343
343
|
}
|
|
344
344
|
});
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
345
|
+
const _hoisted_1$1 = { class: "flex-1" };
|
|
346
|
+
const _hoisted_2$1 = {
|
|
347
|
+
key: 0,
|
|
348
|
+
class: "mb-1 font-medium text-gray-900 dark:text-white"
|
|
349
|
+
};
|
|
350
|
+
const _hoisted_3$1 = { class: "text-sm text-gray-700 dark:text-gray-300" };
|
|
351
|
+
const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
352
|
+
__name: "Alert",
|
|
353
|
+
props: {
|
|
354
|
+
variant: { default: "info" },
|
|
355
|
+
title: {},
|
|
356
|
+
dismissible: { type: Boolean },
|
|
357
|
+
icon: {}
|
|
358
|
+
},
|
|
359
|
+
emits: ["dismiss"],
|
|
360
|
+
setup(__props, { emit: __emit }) {
|
|
361
|
+
const props = __props;
|
|
362
|
+
const emit = __emit;
|
|
363
|
+
const variantStyles = {
|
|
364
|
+
info: {
|
|
365
|
+
bg: "bg-blue-50 dark:bg-blue-900/20",
|
|
366
|
+
border: "border-blue-200 dark:border-blue-800",
|
|
367
|
+
icon: "lucide:info",
|
|
368
|
+
iconColor: "text-blue-500"
|
|
369
|
+
},
|
|
370
|
+
success: {
|
|
371
|
+
bg: "bg-green-50 dark:bg-green-900/20",
|
|
372
|
+
border: "border-green-200 dark:border-green-800",
|
|
373
|
+
icon: "lucide:check-circle",
|
|
374
|
+
iconColor: "text-green-500"
|
|
375
|
+
},
|
|
376
|
+
warning: {
|
|
377
|
+
bg: "bg-yellow-50 dark:bg-yellow-900/20",
|
|
378
|
+
border: "border-yellow-200 dark:border-yellow-800",
|
|
379
|
+
icon: "lucide:alert-triangle",
|
|
380
|
+
iconColor: "text-yellow-500"
|
|
381
|
+
},
|
|
382
|
+
error: {
|
|
383
|
+
bg: "bg-red-50 dark:bg-red-900/20",
|
|
384
|
+
border: "border-red-200 dark:border-red-800",
|
|
385
|
+
icon: "lucide:alert-circle",
|
|
386
|
+
iconColor: "text-red-500"
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
const styles = variantStyles[props.variant];
|
|
390
|
+
return (_ctx, _cache) => {
|
|
391
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
392
|
+
class: vue.normalizeClass([
|
|
393
|
+
"flex gap-3 rounded-lg border p-4",
|
|
394
|
+
vue.unref(styles).bg,
|
|
395
|
+
vue.unref(styles).border
|
|
396
|
+
]),
|
|
397
|
+
role: "alert"
|
|
398
|
+
}, [
|
|
399
|
+
vue.createVNode(vue.unref(vue$1.Icon), {
|
|
400
|
+
icon: __props.icon || vue.unref(styles).icon,
|
|
401
|
+
class: vue.normalizeClass(["size-5 shrink-0", vue.unref(styles).iconColor])
|
|
402
|
+
}, null, 8, ["icon", "class"]),
|
|
403
|
+
vue.createElementVNode("div", _hoisted_1$1, [
|
|
404
|
+
__props.title ? (vue.openBlock(), vue.createElementBlock("h4", _hoisted_2$1, vue.toDisplayString(__props.title), 1)) : vue.createCommentVNode("", true),
|
|
405
|
+
vue.createElementVNode("div", _hoisted_3$1, [
|
|
406
|
+
vue.renderSlot(_ctx.$slots, "default")
|
|
407
|
+
])
|
|
408
|
+
]),
|
|
409
|
+
__props.dismissible ? (vue.openBlock(), vue.createElementBlock("button", {
|
|
410
|
+
key: 0,
|
|
411
|
+
type: "button",
|
|
412
|
+
class: "shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300",
|
|
413
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("dismiss"))
|
|
414
|
+
}, [
|
|
415
|
+
vue.createVNode(vue.unref(vue$1.Icon), {
|
|
416
|
+
icon: "lucide:x",
|
|
417
|
+
class: "size-4"
|
|
418
|
+
})
|
|
419
|
+
])) : vue.createCommentVNode("", true)
|
|
420
|
+
], 2);
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
const _hoisted_1 = { class: "py-12 text-center" };
|
|
425
|
+
const _hoisted_2 = {
|
|
426
|
+
key: 1,
|
|
427
|
+
class: "mb-2 text-lg font-medium text-gray-900 dark:text-white"
|
|
428
|
+
};
|
|
429
|
+
const _hoisted_3 = { class: "text-gray-500 dark:text-gray-400" };
|
|
430
|
+
const _hoisted_4 = {
|
|
431
|
+
key: 2,
|
|
432
|
+
class: "mt-4"
|
|
433
|
+
};
|
|
434
|
+
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
435
|
+
__name: "EmptyState",
|
|
436
|
+
props: {
|
|
437
|
+
message: { default: "No results found" },
|
|
438
|
+
icon: { default: "lucide:inbox" },
|
|
439
|
+
title: {}
|
|
440
|
+
},
|
|
441
|
+
setup(__props) {
|
|
442
|
+
return (_ctx, _cache) => {
|
|
443
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
444
|
+
__props.icon ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Icon), {
|
|
445
|
+
key: 0,
|
|
446
|
+
icon: __props.icon,
|
|
447
|
+
class: "mx-auto mb-4 size-12 text-gray-400 dark:text-gray-500"
|
|
448
|
+
}, null, 8, ["icon"])) : vue.createCommentVNode("", true),
|
|
449
|
+
__props.title ? (vue.openBlock(), vue.createElementBlock("h3", _hoisted_2, vue.toDisplayString(__props.title), 1)) : vue.createCommentVNode("", true),
|
|
450
|
+
vue.createElementVNode("p", _hoisted_3, [
|
|
451
|
+
vue.renderSlot(_ctx.$slots, "default", {}, () => [
|
|
452
|
+
vue.createTextVNode(vue.toDisplayString(__props.message), 1)
|
|
453
|
+
])
|
|
454
|
+
]),
|
|
455
|
+
_ctx.$slots.action ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, [
|
|
456
|
+
vue.renderSlot(_ctx.$slots, "action")
|
|
457
|
+
])) : vue.createCommentVNode("", true)
|
|
458
|
+
]);
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
exports._sfc_main = _sfc_main$6;
|
|
463
|
+
exports._sfc_main$1 = _sfc_main$5;
|
|
464
|
+
exports._sfc_main$2 = _sfc_main$4;
|
|
465
|
+
exports._sfc_main$3 = _sfc_main$3;
|
|
466
|
+
exports._sfc_main$4 = _sfc_main$2;
|
|
467
|
+
exports._sfc_main$5 = _sfc_main$1;
|
|
468
|
+
exports._sfc_main$6 = _sfc_main;
|
|
469
|
+
//# sourceMappingURL=EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs","sources":["../src/components/feedback/LoadingSpinner.vue","../src/components/feedback/Modal.vue","../src/components/feedback/PaginationControls.vue","../src/components/feedback/NotificationComponent.vue","../src/components/feedback/NotificationList.vue","../src/components/feedback/Alert.vue","../src/components/feedback/EmptyState.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { SpinnerSize } from '@/types'\n\nconst { text, size = 'md' } = defineProps<{\n text?: string\n size?: SpinnerSize\n}>()\n\nconst sizeClasses: Record<SpinnerSize, string> = {\n sm: 'h-8 w-8',\n md: 'h-12 w-12',\n lg: 'h-16 w-16',\n}\n</script>\n\n<template>\n <div class=\"flex items-center justify-center py-12\">\n <div class=\"text-center\">\n <div\n :class=\"sizeClasses[size]\"\n class=\"border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent\"\n ></div>\n <p v-if=\"text\" class=\"mt-4 text-gray-600 dark:text-gray-400\">{{ text }}</p>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\nimport { onMounted, onUnmounted } from 'vue'\nimport type { ModalSize } from '@/types'\n\nconst {\n title = '',\n size = 'default',\n closeOnBackdrop = true,\n closeOnEscape = true,\n closeButtonLabel = 'Close',\n} = defineProps<{\n title?: string\n size?: ModalSize\n closeOnBackdrop?: boolean\n closeOnEscape?: boolean\n closeButtonLabel?: string\n}>()\n\nconst emit = defineEmits<{\n close: []\n}>()\n\nconst sizeClasses: Record<ModalSize, string> = {\n sm: 'max-w-md',\n default: 'max-w-3xl',\n lg: 'max-w-5xl',\n xl: 'max-w-7xl',\n full: 'max-w-full mx-4',\n}\n\nconst handleBackdropClick = () => {\n if (closeOnBackdrop) {\n emit('close')\n }\n}\n\nconst handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && closeOnEscape) {\n emit('close')\n }\n}\n\nonMounted(() => {\n document.addEventListener('keydown', handleEscape)\n document.body.style.overflow = 'hidden'\n})\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleEscape)\n document.body.style.overflow = ''\n})\n</script>\n\n<template>\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n @click.self=\"handleBackdropClick\"\n >\n <div\n :class=\"sizeClasses[size]\"\n class=\"flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900\"\n >\n <!-- Header -->\n <div\n v-if=\"title || $slots.header || $slots.title\"\n class=\"flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700\"\n >\n <h3 class=\"text-xl font-semibold text-gray-900 dark:text-gray-100\">\n <slot name=\"header\">\n <slot name=\"title\">\n {{ title }}\n </slot>\n </slot>\n </h3>\n <button\n class=\"rounded-lg p-1.5 text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100\"\n type=\"button\"\n @click=\"emit('close')\"\n >\n <Icon class=\"h-5 w-5\" icon=\"lucide:x\" />\n <span class=\"sr-only\">{{ closeButtonLabel }}</span>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"flex-1 overflow-y-auto px-6 py-4\">\n <slot />\n </div>\n\n <!-- Footer -->\n <div\n v-if=\"$slots.footer\"\n class=\"flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nconst {\n currentPage,\n totalPages,\n loading = false,\n pageSize = 10,\n pageSizeOptions = [10, 20, 50, 100],\n showPageSize = true,\n pageLabel = 'Page',\n ofLabel = 'of',\n itemsPerPageLabel = 'Items per page:',\n previousLabel = 'Previous',\n nextLabel = 'Next',\n} = defineProps<{\n currentPage: number\n totalPages: number\n loading?: boolean\n pageSize?: number\n pageSizeOptions?: number[]\n showPageSize?: boolean\n pageLabel?: string\n ofLabel?: string\n itemsPerPageLabel?: string\n previousLabel?: string\n nextLabel?: string\n}>()\n\nconst emit = defineEmits<{\n 'update:page': [page: number]\n 'update:pageSize': [size: number]\n}>()\n\nconst changePage = (page: number) => {\n if (page >= 1 && page <= totalPages && !loading) {\n emit('update:page', page)\n }\n}\n\nconst changePageSize = (event: Event) => {\n const target = event.target as HTMLSelectElement\n emit('update:pageSize', Number(target.value))\n}\n</script>\n\n<template>\n <div\n v-if=\"totalPages > 1\"\n class=\"flex items-center justify-between border-t border-gray-200 px-6 py-4 dark:border-gray-700\"\n >\n <div class=\"flex items-center gap-4\">\n <div class=\"text-sm text-gray-700 dark:text-gray-300\">\n {{ pageLabel }} {{ currentPage }} {{ ofLabel }} {{ totalPages }}\n </div>\n <div v-if=\"showPageSize\" class=\"flex items-center gap-2\">\n <label class=\"text-sm text-gray-600 dark:text-gray-400\" for=\"page-size\">\n {{ itemsPerPageLabel }}\n </label>\n <select\n id=\"page-size\"\n :value=\"pageSize\"\n class=\"focus:border-primary focus:ring-primary rounded border border-gray-300 bg-white px-2 py-1 text-sm text-gray-900 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\n @change=\"changePageSize\"\n >\n <option v-for=\"size in pageSizeOptions\" :key=\"size\" :value=\"size\">\n {{ size }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"flex gap-2\">\n <button\n :disabled=\"currentPage === 1 || loading\"\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\n @click=\"changePage(currentPage - 1)\"\n >\n <Icon class=\"h-4 w-4\" icon=\"lucide:chevron-left\" />\n {{ previousLabel }}\n </button>\n <button\n :disabled=\"currentPage === totalPages || loading\"\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\n @click=\"changePage(currentPage + 1)\"\n >\n {{ nextLabel }}\n <Icon class=\"h-4 w-4\" icon=\"lucide:chevron-right\" />\n </button>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport { computed, onMounted } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nconst props = defineProps<{\n notification: Notification\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n\nconst iconName = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'lucide:check-circle'\n case 'info':\n return 'lucide:info'\n case 'warning':\n return 'lucide:alert-triangle'\n case 'error':\n return 'lucide:x-circle'\n default:\n return 'lucide:bell'\n }\n})\n\nconst iconColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'text-green-600 dark:text-green-400'\n case 'info':\n return 'text-blue-600 dark:text-blue-400'\n case 'warning':\n return 'text-yellow-600 dark:text-yellow-400'\n case 'error':\n return 'text-red-600 dark:text-red-400'\n default:\n return 'text-gray-600 dark:text-gray-400'\n }\n})\n\nconst bgColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'bg-green-50 dark:bg-green-950'\n case 'info':\n return 'bg-blue-50 dark:bg-blue-950'\n case 'warning':\n return 'bg-yellow-50 dark:bg-yellow-950'\n case 'error':\n return 'bg-red-50 dark:bg-red-950'\n default:\n return 'bg-gray-50 dark:bg-gray-950'\n }\n})\n\nconst handleDismiss = () => {\n if (props.notification.id) {\n emit('dismiss', props.notification.id)\n }\n}\n\nonMounted(() => {\n const duration = props.notification.duration ?? props.duration ?? 5000\n if (props.autoDismiss !== false && duration > 0) {\n setTimeout(() => {\n handleDismiss()\n }, duration)\n }\n})\n</script>\n\n<template>\n <div\n class=\"flex max-w-md items-start space-x-3 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-800 dark:bg-black\"\n >\n <div :class=\"[bgColor, 'flex items-center justify-center rounded-full p-2']\">\n <Icon :class=\"iconColor\" :icon=\"iconName\" class=\"h-5 w-5\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <h4 v-if=\"notification.title\" class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\">\n {{ notification.title }}\n </h4>\n <p v-if=\"notification.message\" class=\"mt-1 text-sm text-gray-600 dark:text-gray-400\">\n {{ notification.message }}\n </p>\n </div>\n\n <button\n class=\"shrink-0 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-600 dark:hover:text-gray-400\"\n @click=\"handleDismiss\"\n >\n <Icon class=\"h-4 w-4\" icon=\"lucide:x\" />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport NotificationComponent from './NotificationComponent.vue'\n\ndefineProps<{\n notifications: Notification[]\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n</script>\n\n<template>\n <div class=\"fixed top-5 right-5 z-50 flex flex-col gap-3\">\n <NotificationComponent\n v-for=\"notification in notifications\"\n :key=\"notification.id\"\n :notification=\"notification\"\n :auto-dismiss=\"autoDismiss\"\n :duration=\"duration\"\n @dismiss=\"emit('dismiss', $event)\"\n />\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'error'\n\nconst props = withDefaults(\n defineProps<{\n /** Alert variant */\n variant?: AlertVariant\n /** Title text */\n title?: string\n /** Show close button */\n dismissible?: boolean\n /** Custom icon */\n icon?: string\n }>(),\n {\n variant: 'info',\n },\n)\n\nconst emit = defineEmits<{\n dismiss: []\n}>()\n\nconst variantStyles: Record<AlertVariant, { bg: string; border: string; icon: string; iconColor: string }> = {\n info: {\n bg: 'bg-blue-50 dark:bg-blue-900/20',\n border: 'border-blue-200 dark:border-blue-800',\n icon: 'lucide:info',\n iconColor: 'text-blue-500',\n },\n success: {\n bg: 'bg-green-50 dark:bg-green-900/20',\n border: 'border-green-200 dark:border-green-800',\n icon: 'lucide:check-circle',\n iconColor: 'text-green-500',\n },\n warning: {\n bg: 'bg-yellow-50 dark:bg-yellow-900/20',\n border: 'border-yellow-200 dark:border-yellow-800',\n icon: 'lucide:alert-triangle',\n iconColor: 'text-yellow-500',\n },\n error: {\n bg: 'bg-red-50 dark:bg-red-900/20',\n border: 'border-red-200 dark:border-red-800',\n icon: 'lucide:alert-circle',\n iconColor: 'text-red-500',\n },\n}\n\nconst styles = variantStyles[props.variant]\n</script>\n\n<template>\n <div\n :class=\"[\n 'flex gap-3 rounded-lg border p-4',\n styles.bg,\n styles.border,\n ]\"\n role=\"alert\"\n >\n <Icon\n :icon=\"icon || styles.icon\"\n :class=\"['size-5 shrink-0', styles.iconColor]\"\n />\n <div class=\"flex-1\">\n <h4\n v-if=\"title\"\n class=\"mb-1 font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h4>\n <div class=\"text-sm text-gray-700 dark:text-gray-300\">\n <slot />\n </div>\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\n @click=\"emit('dismiss')\"\n >\n <Icon icon=\"lucide:x\" class=\"size-4\" />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nwithDefaults(\n defineProps<{\n /** Message to display */\n message?: string\n /** Icon name (iconify format) */\n icon?: string\n /** Title text */\n title?: string\n }>(),\n {\n message: 'No results found',\n icon: 'lucide:inbox',\n },\n)\n</script>\n\n<template>\n <div class=\"py-12 text-center\">\n <Icon\n v-if=\"icon\"\n :icon=\"icon\"\n class=\"mx-auto mb-4 size-12 text-gray-400 dark:text-gray-500\"\n />\n <h3 v-if=\"title\" class=\"mb-2 text-lg font-medium text-gray-900 dark:text-white\">\n {{ title }}\n </h3>\n <p class=\"text-gray-500 dark:text-gray-400\">\n <slot>{{ message }}</slot>\n </p>\n <div v-if=\"$slots.action\" class=\"mt-4\">\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_normalizeClass","_hoisted_3","_toDisplayString","onMounted","onUnmounted","$slots","_renderSlot","_createVNode","_unref","Icon","_hoisted_4","_hoisted_5","_Fragment","_renderList","_createTextVNode","computed","_createBlock","NotificationComponent"],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const vue = require("vue");
|
|
3
|
+
const vue$1 = require("@iconify/vue");
|
|
4
|
+
const _hoisted_1 = { class: "relative" };
|
|
5
|
+
const _hoisted_2 = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600"
|
|
8
|
+
};
|
|
9
|
+
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
10
|
+
__name: "MenuItem",
|
|
11
|
+
props: {
|
|
12
|
+
menuItem: {},
|
|
13
|
+
expanded: { type: Boolean, default: true },
|
|
14
|
+
active: { type: Boolean, default: void 0 },
|
|
15
|
+
currentPath: { default: void 0 }
|
|
16
|
+
},
|
|
17
|
+
setup(__props) {
|
|
18
|
+
const props = __props;
|
|
19
|
+
const isRouteActive = vue.computed(() => {
|
|
20
|
+
if (props.active !== void 0) {
|
|
21
|
+
return props.active;
|
|
22
|
+
}
|
|
23
|
+
const path = props.currentPath ?? (typeof window !== "undefined" ? window.location.pathname : "/");
|
|
24
|
+
if (props.menuItem.link === "/") {
|
|
25
|
+
return path === "/";
|
|
26
|
+
}
|
|
27
|
+
return path === props.menuItem.link || path.startsWith(props.menuItem.link + "/");
|
|
28
|
+
});
|
|
29
|
+
const linkComponent = vue.computed(() => {
|
|
30
|
+
try {
|
|
31
|
+
const RouterLink = vue.resolveComponent("RouterLink");
|
|
32
|
+
if (typeof RouterLink !== "string") {
|
|
33
|
+
return RouterLink;
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
return "a";
|
|
38
|
+
});
|
|
39
|
+
const linkProps = vue.computed(() => {
|
|
40
|
+
if (linkComponent.value === "a") {
|
|
41
|
+
return { href: props.menuItem.link };
|
|
42
|
+
}
|
|
43
|
+
return { to: props.menuItem.link };
|
|
44
|
+
});
|
|
45
|
+
return (_ctx, _cache) => {
|
|
46
|
+
return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(linkComponent.value), vue.mergeProps(linkProps.value, {
|
|
47
|
+
class: [__props.expanded ? "flex-row" : "flex-col", "group relative flex items-center justify-center gap-2 px-5"]
|
|
48
|
+
}), {
|
|
49
|
+
default: vue.withCtx(() => [
|
|
50
|
+
vue.createElementVNode("div", _hoisted_1, [
|
|
51
|
+
vue.createVNode(vue.unref(vue$1.Icon), {
|
|
52
|
+
class: vue.normalizeClass([[
|
|
53
|
+
isRouteActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
|
|
54
|
+
__props.expanded ? "size-6" : "size-8"
|
|
55
|
+
], "transition-all duration-300"]),
|
|
56
|
+
icon: __props.menuItem.icon
|
|
57
|
+
}, null, 8, ["class", "icon"]),
|
|
58
|
+
__props.menuItem.notification ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2)) : vue.createCommentVNode("", true)
|
|
59
|
+
]),
|
|
60
|
+
vue.createVNode(vue.Transition, {
|
|
61
|
+
"enter-active-class": "transition-all duration-300 ease-out",
|
|
62
|
+
"enter-from-class": "opacity-0 -translate-x-2",
|
|
63
|
+
"enter-to-class": "opacity-100 translate-x-0",
|
|
64
|
+
"leave-active-class": "transition-all duration-200 ease-in",
|
|
65
|
+
"leave-from-class": "opacity-100 translate-x-0",
|
|
66
|
+
"leave-to-class": "opacity-0 -translate-x-2"
|
|
67
|
+
}, {
|
|
68
|
+
default: vue.withCtx(() => [
|
|
69
|
+
__props.expanded ? (vue.openBlock(), vue.createElementBlock("span", {
|
|
70
|
+
key: 0,
|
|
71
|
+
class: vue.normalizeClass([
|
|
72
|
+
isRouteActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
|
|
73
|
+
"text-sm font-semibold whitespace-nowrap"
|
|
74
|
+
])
|
|
75
|
+
}, vue.toDisplayString(__props.menuItem.label), 3)) : vue.createCommentVNode("", true)
|
|
76
|
+
]),
|
|
77
|
+
_: 1
|
|
78
|
+
})
|
|
79
|
+
]),
|
|
80
|
+
_: 1
|
|
81
|
+
}, 16, ["class"]);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
exports._sfc_main = _sfc_main;
|
|
86
|
+
//# sourceMappingURL=MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs","sources":["../src/components/core/MenuItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, resolveComponent } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport type { MenuItemProps } from '@/types'\n\nconst props = withDefaults(\n defineProps<{\n menuItem: MenuItemProps\n /** Whether sidebar is expanded (shows labels) */\n expanded?: boolean\n /** Override active state directly */\n active?: boolean\n /** Current route path (pass from parent using useRoute().path) */\n currentPath?: string\n }>(),\n {\n expanded: true,\n active: undefined,\n currentPath: undefined,\n },\n)\n\nconst isRouteActive = computed(() => {\n // If active prop is explicitly set, use it\n if (props.active !== undefined) {\n return props.active\n }\n\n // Use currentPath prop if provided, otherwise fall back to window.location\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n if (props.menuItem.link === '/') {\n return path === '/'\n }\n return path === props.menuItem.link || path.startsWith(props.menuItem.link + '/')\n})\n\n// Try to resolve RouterLink, fallback to 'a' tag\nconst linkComponent = computed(() => {\n try {\n const RouterLink = resolveComponent('RouterLink')\n if (typeof RouterLink !== 'string') {\n return RouterLink\n }\n } catch {\n // RouterLink not available\n }\n return 'a'\n})\n\nconst linkProps = computed(() => {\n if (linkComponent.value === 'a') {\n return { href: props.menuItem.link }\n }\n return { to: props.menuItem.link }\n})\n</script>\n\n<template>\n <component\n :is=\"linkComponent\"\n v-bind=\"linkProps\"\n :class=\"expanded ? 'flex-row' : 'flex-col'\"\n class=\"group relative flex items-center justify-center gap-2 px-5\"\n >\n <div class=\"relative\">\n <Icon\n :class=\"[\n isRouteActive\n ? 'text-white'\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\n expanded ? 'size-6' : 'size-8',\n ]\"\n class=\"transition-all duration-300\"\n :icon=\"menuItem.icon\"\n />\n\n <span\n v-if=\"menuItem.notification\"\n class=\"absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600\"\n ></span>\n </div>\n\n <Transition\n enter-active-class=\"transition-all duration-300 ease-out\"\n enter-from-class=\"opacity-0 -translate-x-2\"\n enter-to-class=\"opacity-100 translate-x-0\"\n leave-active-class=\"transition-all duration-200 ease-in\"\n leave-from-class=\"opacity-100 translate-x-0\"\n leave-to-class=\"opacity-0 -translate-x-2\"\n >\n <span\n v-if=\"expanded\"\n :class=\"\n isRouteActive\n ? 'text-white'\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500'\n \"\n class=\"text-sm font-semibold whitespace-nowrap\"\n >{{ menuItem.label }}</span\n >\n </Transition>\n </component>\n</template>\n"],"names":["computed","resolveComponent","_openBlock","_createBlock","_resolveDynamicComponent","_mergeProps","_createElementVNode","_createVNode","_unref","Icon","_normalizeClass","_createElementBlock","_Transition","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;;AAKA,UAAM,QAAQ;AAiBd,UAAM,gBAAgBA,IAAAA,SAAS,MAAM;AAEnC,UAAI,MAAM,WAAW,QAAW;AAC9B,eAAO,MAAM;AAAA,MACf;AAGA,YAAM,OAAO,MAAM,gBAAgB,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAE9F,UAAI,MAAM,SAAS,SAAS,KAAK;AAC/B,eAAO,SAAS;AAAA,MAClB;AACA,aAAO,SAAS,MAAM,SAAS,QAAQ,KAAK,WAAW,MAAM,SAAS,OAAO,GAAG;AAAA,IAClF,CAAC;AAGD,UAAM,gBAAgBA,IAAAA,SAAS,MAAM;AACnC,UAAI;AACF,cAAM,aAAaC,IAAAA,iBAAiB,YAAY;AAChD,YAAI,OAAO,eAAe,UAAU;AAClC,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,YAAYD,IAAAA,SAAS,MAAM;AAC/B,UAAI,cAAc,UAAU,KAAK;AAC/B,eAAO,EAAE,MAAM,MAAM,SAAS,KAAA;AAAA,MAChC;AACA,aAAO,EAAE,IAAI,MAAM,SAAS,KAAA;AAAA,IAC9B,CAAC;;AAIC,aAAAE,IAAAA,UAAA,GAAAC,IAAAA,YA2CYC,4BA1CL,cAAA,KAAa,GADpBC,IAAAA,WAEU,UAyCE,OAzCO;AAAA,QAChB,OAAK,CAAE,QAAA,WAAQ,aAAA,YACV,4DAA4D;AAAA,MAAA;6BAElE,MAgBM;AAAA,UAhBNC,IAAAA,mBAgBM,OAhBN,YAgBM;AAAA,YAfJC,gBASEC,IAAAA,MAAAC,MAAAA,IAAA,GAAA;AAAA,cARC,OAAKC,IAAAA,eAAA,CAAA;AAAA,gBAAc,cAAA;gBAA8J,QAAA,WAAQ,WAAA;AAAA,cAAA,GAMpL,6BAA6B,CAAA;AAAA,cAClC,MAAM,QAAA,SAAS;AAAA,YAAA;YAIV,QAAA,SAAS,gBADjBR,IAAAA,aAAAS,IAAAA,mBAGQ,QAHR,UAGQ;;UAGVJ,IAAAA,YAkBaK,IAAAA,YAAA;AAAA,YAjBX,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,YACf,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,UAAA;iCAEf,MASC;AAAA,cARO,QAAA,6BADRD,IAAAA,mBASC,QAAA;AAAA;gBAPE,OAAKD,IAAAA,eAAA;AAAA,kBAAa,cAAA;kBAKb;AAAA,gBAAA,CAAyC;AAAA,cAAA,GAC3CG,IAAAA,gBAAA,QAAA,SAAS,KAAK,GAAA,CAAA;;;;;;;;;;;"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { defineComponent, computed, resolveComponent, createBlock, openBlock, resolveDynamicComponent, mergeProps, withCtx, createElementVNode, createVNode, createElementBlock, createCommentVNode, unref, normalizeClass, Transition, toDisplayString } from "vue";
|
|
2
|
+
import { Icon } from "@iconify/vue";
|
|
3
|
+
const _hoisted_1 = { class: "relative" };
|
|
4
|
+
const _hoisted_2 = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600"
|
|
7
|
+
};
|
|
8
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
9
|
+
__name: "MenuItem",
|
|
10
|
+
props: {
|
|
11
|
+
menuItem: {},
|
|
12
|
+
expanded: { type: Boolean, default: true },
|
|
13
|
+
active: { type: Boolean, default: void 0 },
|
|
14
|
+
currentPath: { default: void 0 }
|
|
15
|
+
},
|
|
16
|
+
setup(__props) {
|
|
17
|
+
const props = __props;
|
|
18
|
+
const isRouteActive = computed(() => {
|
|
19
|
+
if (props.active !== void 0) {
|
|
20
|
+
return props.active;
|
|
21
|
+
}
|
|
22
|
+
const path = props.currentPath ?? (typeof window !== "undefined" ? window.location.pathname : "/");
|
|
23
|
+
if (props.menuItem.link === "/") {
|
|
24
|
+
return path === "/";
|
|
25
|
+
}
|
|
26
|
+
return path === props.menuItem.link || path.startsWith(props.menuItem.link + "/");
|
|
27
|
+
});
|
|
28
|
+
const linkComponent = computed(() => {
|
|
29
|
+
try {
|
|
30
|
+
const RouterLink = resolveComponent("RouterLink");
|
|
31
|
+
if (typeof RouterLink !== "string") {
|
|
32
|
+
return RouterLink;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
return "a";
|
|
37
|
+
});
|
|
38
|
+
const linkProps = computed(() => {
|
|
39
|
+
if (linkComponent.value === "a") {
|
|
40
|
+
return { href: props.menuItem.link };
|
|
41
|
+
}
|
|
42
|
+
return { to: props.menuItem.link };
|
|
43
|
+
});
|
|
44
|
+
return (_ctx, _cache) => {
|
|
45
|
+
return openBlock(), createBlock(resolveDynamicComponent(linkComponent.value), mergeProps(linkProps.value, {
|
|
46
|
+
class: [__props.expanded ? "flex-row" : "flex-col", "group relative flex items-center justify-center gap-2 px-5"]
|
|
47
|
+
}), {
|
|
48
|
+
default: withCtx(() => [
|
|
49
|
+
createElementVNode("div", _hoisted_1, [
|
|
50
|
+
createVNode(unref(Icon), {
|
|
51
|
+
class: normalizeClass([[
|
|
52
|
+
isRouteActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
|
|
53
|
+
__props.expanded ? "size-6" : "size-8"
|
|
54
|
+
], "transition-all duration-300"]),
|
|
55
|
+
icon: __props.menuItem.icon
|
|
56
|
+
}, null, 8, ["class", "icon"]),
|
|
57
|
+
__props.menuItem.notification ? (openBlock(), createElementBlock("span", _hoisted_2)) : createCommentVNode("", true)
|
|
58
|
+
]),
|
|
59
|
+
createVNode(Transition, {
|
|
60
|
+
"enter-active-class": "transition-all duration-300 ease-out",
|
|
61
|
+
"enter-from-class": "opacity-0 -translate-x-2",
|
|
62
|
+
"enter-to-class": "opacity-100 translate-x-0",
|
|
63
|
+
"leave-active-class": "transition-all duration-200 ease-in",
|
|
64
|
+
"leave-from-class": "opacity-100 translate-x-0",
|
|
65
|
+
"leave-to-class": "opacity-0 -translate-x-2"
|
|
66
|
+
}, {
|
|
67
|
+
default: withCtx(() => [
|
|
68
|
+
__props.expanded ? (openBlock(), createElementBlock("span", {
|
|
69
|
+
key: 0,
|
|
70
|
+
class: normalizeClass([
|
|
71
|
+
isRouteActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
|
|
72
|
+
"text-sm font-semibold whitespace-nowrap"
|
|
73
|
+
])
|
|
74
|
+
}, toDisplayString(__props.menuItem.label), 3)) : createCommentVNode("", true)
|
|
75
|
+
]),
|
|
76
|
+
_: 1
|
|
77
|
+
})
|
|
78
|
+
]),
|
|
79
|
+
_: 1
|
|
80
|
+
}, 16, ["class"]);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
export {
|
|
85
|
+
_sfc_main as _
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js","sources":["../src/components/core/MenuItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed, resolveComponent } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport type { MenuItemProps } from '@/types'\n\nconst props = withDefaults(\n defineProps<{\n menuItem: MenuItemProps\n /** Whether sidebar is expanded (shows labels) */\n expanded?: boolean\n /** Override active state directly */\n active?: boolean\n /** Current route path (pass from parent using useRoute().path) */\n currentPath?: string\n }>(),\n {\n expanded: true,\n active: undefined,\n currentPath: undefined,\n },\n)\n\nconst isRouteActive = computed(() => {\n // If active prop is explicitly set, use it\n if (props.active !== undefined) {\n return props.active\n }\n\n // Use currentPath prop if provided, otherwise fall back to window.location\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n if (props.menuItem.link === '/') {\n return path === '/'\n }\n return path === props.menuItem.link || path.startsWith(props.menuItem.link + '/')\n})\n\n// Try to resolve RouterLink, fallback to 'a' tag\nconst linkComponent = computed(() => {\n try {\n const RouterLink = resolveComponent('RouterLink')\n if (typeof RouterLink !== 'string') {\n return RouterLink\n }\n } catch {\n // RouterLink not available\n }\n return 'a'\n})\n\nconst linkProps = computed(() => {\n if (linkComponent.value === 'a') {\n return { href: props.menuItem.link }\n }\n return { to: props.menuItem.link }\n})\n</script>\n\n<template>\n <component\n :is=\"linkComponent\"\n v-bind=\"linkProps\"\n :class=\"expanded ? 'flex-row' : 'flex-col'\"\n class=\"group relative flex items-center justify-center gap-2 px-5\"\n >\n <div class=\"relative\">\n <Icon\n :class=\"[\n isRouteActive\n ? 'text-white'\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\n expanded ? 'size-6' : 'size-8',\n ]\"\n class=\"transition-all duration-300\"\n :icon=\"menuItem.icon\"\n />\n\n <span\n v-if=\"menuItem.notification\"\n class=\"absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600\"\n ></span>\n </div>\n\n <Transition\n enter-active-class=\"transition-all duration-300 ease-out\"\n enter-from-class=\"opacity-0 -translate-x-2\"\n enter-to-class=\"opacity-100 translate-x-0\"\n leave-active-class=\"transition-all duration-200 ease-in\"\n leave-from-class=\"opacity-100 translate-x-0\"\n leave-to-class=\"opacity-0 -translate-x-2\"\n >\n <span\n v-if=\"expanded\"\n :class=\"\n isRouteActive\n ? 'text-white'\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500'\n \"\n class=\"text-sm font-semibold whitespace-nowrap\"\n >{{ menuItem.label }}</span\n >\n </Transition>\n </component>\n</template>\n"],"names":["_openBlock","_createBlock","_resolveDynamicComponent","_mergeProps","_createElementVNode","_createVNode","_unref","_normalizeClass","_createElementBlock","_Transition","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;AAKA,UAAM,QAAQ;AAiBd,UAAM,gBAAgB,SAAS,MAAM;AAEnC,UAAI,MAAM,WAAW,QAAW;AAC9B,eAAO,MAAM;AAAA,MACf;AAGA,YAAM,OAAO,MAAM,gBAAgB,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAE9F,UAAI,MAAM,SAAS,SAAS,KAAK;AAC/B,eAAO,SAAS;AAAA,MAClB;AACA,aAAO,SAAS,MAAM,SAAS,QAAQ,KAAK,WAAW,MAAM,SAAS,OAAO,GAAG;AAAA,IAClF,CAAC;AAGD,UAAM,gBAAgB,SAAS,MAAM;AACnC,UAAI;AACF,cAAM,aAAa,iBAAiB,YAAY;AAChD,YAAI,OAAO,eAAe,UAAU;AAClC,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,YAAY,SAAS,MAAM;AAC/B,UAAI,cAAc,UAAU,KAAK;AAC/B,eAAO,EAAE,MAAM,MAAM,SAAS,KAAA;AAAA,MAChC;AACA,aAAO,EAAE,IAAI,MAAM,SAAS,KAAA;AAAA,IAC9B,CAAC;;AAIC,aAAAA,UAAA,GAAAC,YA2CYC,wBA1CL,cAAA,KAAa,GADpBC,WAEU,UAyCE,OAzCO;AAAA,QAChB,OAAK,CAAE,QAAA,WAAQ,aAAA,YACV,4DAA4D;AAAA,MAAA;yBAElE,MAgBM;AAAA,UAhBNC,mBAgBM,OAhBN,YAgBM;AAAA,YAfJC,YASEC,MAAA,IAAA,GAAA;AAAA,cARC,OAAKC,eAAA,CAAA;AAAA,gBAAc,cAAA;gBAA8J,QAAA,WAAQ,WAAA;AAAA,cAAA,GAMpL,6BAA6B,CAAA;AAAA,cAClC,MAAM,QAAA,SAAS;AAAA,YAAA;YAIV,QAAA,SAAS,gBADjBP,aAAAQ,mBAGQ,QAHR,UAGQ;;UAGVH,YAkBaI,YAAA;AAAA,YAjBX,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,YACf,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,UAAA;6BAEf,MASC;AAAA,cARO,QAAA,yBADRD,mBASC,QAAA;AAAA;gBAPE,OAAKD,eAAA;AAAA,kBAAa,cAAA;kBAKb;AAAA,gBAAA,CAAyC;AAAA,cAAA,GAC3CG,gBAAA,QAAA,SAAS,KAAK,GAAA,CAAA;;;;;;;;;;"}
|