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.
Files changed (85) hide show
  1. package/README.md +435 -6
  2. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DQD2I1Wk.cjs +621 -0
  3. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DQD2I1Wk.cjs.map +1 -0
  4. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DVkcMcSN.js +622 -0
  5. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DVkcMcSN.js.map +1 -0
  6. package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-D2MeLTRV.cjs +1133 -0
  7. package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-D2MeLTRV.cjs.map +1 -0
  8. package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-Ixih38V0.js +1134 -0
  9. package/dist/CollapsibleCard.vue_vue_type_script_setup_true_lang-Ixih38V0.js.map +1 -0
  10. package/dist/{NotificationList.vue_vue_type_script_setup_true_lang-B2hjbMm4.js → EmptyState.vue_vue_type_script_setup_true_lang-CrVvFwXA.js} +163 -44
  11. package/dist/EmptyState.vue_vue_type_script_setup_true_lang-CrVvFwXA.js.map +1 -0
  12. package/dist/{NotificationList.vue_vue_type_script_setup_true_lang-Ci3zIvrv.cjs → EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs} +163 -44
  13. package/dist/EmptyState.vue_vue_type_script_setup_true_lang-mlqLBP5W.cjs.map +1 -0
  14. package/dist/MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs +86 -0
  15. package/dist/MenuItem.vue_vue_type_script_setup_true_lang-BWz86k7c.cjs.map +1 -0
  16. package/dist/MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js +87 -0
  17. package/dist/MenuItem.vue_vue_type_script_setup_true_lang-emN2qlfR.js.map +1 -0
  18. package/dist/PageLayout.vue_vue_type_script_setup_true_lang-DTlUENg3.js +265 -0
  19. package/dist/PageLayout.vue_vue_type_script_setup_true_lang-DTlUENg3.js.map +1 -0
  20. package/dist/PageLayout.vue_vue_type_script_setup_true_lang-IcouTz4C.cjs +264 -0
  21. package/dist/PageLayout.vue_vue_type_script_setup_true_lang-IcouTz4C.cjs.map +1 -0
  22. package/dist/components/core/AutocompleteComponent.vue.d.ts +7 -1
  23. package/dist/components/core/Avatar.vue.d.ts +20 -0
  24. package/dist/components/core/Button.vue.d.ts +49 -0
  25. package/dist/components/core/CollapsibleCard.vue.d.ts +28 -0
  26. package/dist/components/core/Dropdown.vue.d.ts +52 -0
  27. package/dist/components/core/MenuItem.vue.d.ts +11 -1
  28. package/dist/components/core/Stepper.vue.d.ts +22 -0
  29. package/dist/components/core/TabPanel.vue.d.ts +21 -0
  30. package/dist/components/core/Tabs.vue.d.ts +39 -0
  31. package/dist/components/core/index.cjs +14 -6
  32. package/dist/components/core/index.cjs.map +1 -1
  33. package/dist/components/core/index.d.ts +12 -0
  34. package/dist/components/core/index.js +14 -6
  35. package/dist/components/core/index.js.map +1 -1
  36. package/dist/components/feedback/Alert.vue.d.ts +34 -0
  37. package/dist/components/feedback/EmptyState.vue.d.ts +29 -0
  38. package/dist/components/feedback/index.cjs +8 -6
  39. package/dist/components/feedback/index.cjs.map +1 -1
  40. package/dist/components/feedback/index.d.ts +3 -0
  41. package/dist/components/feedback/index.js +3 -1
  42. package/dist/components/form/Checkbox.vue.d.ts +20 -0
  43. package/dist/components/form/FormSelect.vue.d.ts +35 -6
  44. package/dist/components/form/Switch.vue.d.ts +21 -0
  45. package/dist/components/form/index.cjs +9 -7
  46. package/dist/components/form/index.cjs.map +1 -1
  47. package/dist/components/form/index.d.ts +2 -0
  48. package/dist/components/form/index.js +4 -2
  49. package/dist/components/index.cjs +34 -19
  50. package/dist/components/index.cjs.map +1 -1
  51. package/dist/components/index.d.ts +1 -0
  52. package/dist/components/index.js +26 -11
  53. package/dist/components/index.js.map +1 -1
  54. package/dist/components/layout/BaseLayout.vue.d.ts +58 -0
  55. package/dist/components/layout/PageLayout.vue.d.ts +37 -0
  56. package/dist/components/layout/index.cjs +6 -0
  57. package/dist/components/layout/index.cjs.map +1 -0
  58. package/dist/components/layout/index.d.ts +3 -0
  59. package/dist/components/layout/index.js +6 -0
  60. package/dist/components/layout/index.js.map +1 -0
  61. package/dist/index-Bt9enqyq.cjs +47 -0
  62. package/dist/index-Bt9enqyq.cjs.map +1 -0
  63. package/dist/index-CxPY8Qb7.js +48 -0
  64. package/dist/index-CxPY8Qb7.js.map +1 -0
  65. package/dist/index.cjs +35 -20
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.js +29 -14
  68. package/dist/index.js.map +1 -1
  69. package/dist/style.css +2 -0
  70. package/dist/types/components.d.ts +7 -0
  71. package/package.json +12 -3
  72. package/dist/NotificationList.vue_vue_type_script_setup_true_lang-B2hjbMm4.js.map +0 -1
  73. package/dist/NotificationList.vue_vue_type_script_setup_true_lang-Ci3zIvrv.cjs.map +0 -1
  74. package/dist/SearchInput.vue_vue_type_script_setup_true_lang-Be73hShP.cjs +0 -234
  75. package/dist/SearchInput.vue_vue_type_script_setup_true_lang-Be73hShP.cjs.map +0 -1
  76. package/dist/SearchInput.vue_vue_type_script_setup_true_lang-DjT2qdcp.js +0 -235
  77. package/dist/SearchInput.vue_vue_type_script_setup_true_lang-DjT2qdcp.js.map +0 -1
  78. package/dist/TableAction.vue_vue_type_script_setup_true_lang-BHskhVhK.js +0 -540
  79. package/dist/TableAction.vue_vue_type_script_setup_true_lang-BHskhVhK.js.map +0 -1
  80. package/dist/TableAction.vue_vue_type_script_setup_true_lang-CojbKn7E.cjs +0 -539
  81. package/dist/TableAction.vue_vue_type_script_setup_true_lang-CojbKn7E.cjs.map +0 -1
  82. package/dist/index-BoCtJCg0.cjs +0 -32
  83. package/dist/index-BoCtJCg0.cjs.map +0 -1
  84. package/dist/index-CGhDI10m.js +0 -33
  85. 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$4 = { class: "flex items-center justify-center py-12" };
5
- const _hoisted_2$3 = { class: "text-center" };
6
- const _hoisted_3$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$4 = /* @__PURE__ */ vue.defineComponent({
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$4, [
24
- vue.createElementVNode("div", _hoisted_2$3, [
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$3, vue.toDisplayString(__props.text), 1)) : vue.createCommentVNode("", true)
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$3 = {
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$2 = { class: "text-xl font-semibold text-gray-900 dark:text-gray-100" };
39
- const _hoisted_3$2 = { class: "sr-only" };
40
- const _hoisted_4$2 = { class: "flex-1 overflow-y-auto px-6 py-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$3 = /* @__PURE__ */ vue.defineComponent({
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$3, [
91
- vue.createElementVNode("h3", _hoisted_2$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$2, vue.toDisplayString(__props.closeButtonLabel), 1)
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$2, [
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$2 = {
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$1 = { class: "flex items-center gap-4" };
126
- const _hoisted_3$1 = { class: "text-sm text-gray-700 dark:text-gray-300" };
127
- const _hoisted_4$1 = {
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$2 = /* @__PURE__ */ vue.defineComponent({
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$2, [
169
- vue.createElementVNode("div", _hoisted_2$1, [
170
- vue.createElementVNode("div", _hoisted_3$1, 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$1, [
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$1 = { 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 = { 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$1 = /* @__PURE__ */ vue.defineComponent({
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$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$1, {
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
- exports._sfc_main = _sfc_main$4;
346
- exports._sfc_main$1 = _sfc_main$3;
347
- exports._sfc_main$2 = _sfc_main$2;
348
- exports._sfc_main$3 = _sfc_main$1;
349
- exports._sfc_main$4 = _sfc_main;
350
- //# sourceMappingURL=NotificationList.vue_vue_type_script_setup_true_lang-Ci3zIvrv.cjs.map
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;;;;;;;;;;"}