cisse-vue-ui 0.8.0 → 0.8.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 (72) hide show
  1. package/README.md +879 -879
  2. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-DJbuHoDj.cjs → CheckboxGroup.vue_vue_type_script_setup_true_lang-DuJr8cz3.cjs} +4 -4
  3. package/dist/CheckboxGroup.vue_vue_type_script_setup_true_lang-DuJr8cz3.cjs.map +1 -0
  4. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-hHJdvUYS.js → CheckboxGroup.vue_vue_type_script_setup_true_lang-N4oS_DJD.js} +4 -4
  5. package/dist/CheckboxGroup.vue_vue_type_script_setup_true_lang-N4oS_DJD.js.map +1 -0
  6. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-Bine-xfp.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs} +58 -9
  7. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs.map +1 -0
  8. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DqkA1Zr-.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js} +58 -9
  9. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js.map +1 -0
  10. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-56CxoSmj.js → Dropdown.vue_vue_type_script_setup_true_lang-A9Ax6iob.js} +110 -14
  11. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-A9Ax6iob.js.map +1 -0
  12. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-Dd3ySRNB.cjs → Dropdown.vue_vue_type_script_setup_true_lang-DoJKvn30.cjs} +109 -13
  13. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DoJKvn30.cjs.map +1 -0
  14. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-DzLwUVCW.js → FilterTabs.vue_vue_type_script_setup_true_lang-CcOgc2Y_.js} +2 -2
  15. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-CcOgc2Y_.js.map +1 -0
  16. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-Bj3I5Sn7.cjs → FilterTabs.vue_vue_type_script_setup_true_lang-jW6Ikbvy.cjs} +2 -2
  17. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-jW6Ikbvy.cjs.map +1 -0
  18. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js.map +1 -1
  19. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs.map +1 -1
  20. package/dist/{PageHero.vue_vue_type_script_setup_true_lang-DQQGYAw0.js → PageHero.vue_vue_type_script_setup_true_lang-Gvocjdqh.js} +2 -2
  21. package/dist/PageHero.vue_vue_type_script_setup_true_lang-Gvocjdqh.js.map +1 -0
  22. package/dist/{PageHero.vue_vue_type_script_setup_true_lang-Bi97ypMD.cjs → PageHero.vue_vue_type_script_setup_true_lang-rbvfGvll.cjs} +2 -2
  23. package/dist/PageHero.vue_vue_type_script_setup_true_lang-rbvfGvll.cjs.map +1 -0
  24. package/dist/cisse-vue-ui.css +57 -57
  25. package/dist/components/core/MenuItem.stories.d.ts +1 -0
  26. package/dist/components/core/MenuItem.vue.d.ts +2 -13
  27. package/dist/components/core/index.cjs +2 -2
  28. package/dist/components/core/index.js +2 -2
  29. package/dist/components/feedback/PaginationControls.stories.d.ts +5 -0
  30. package/dist/components/feedback/PaginationControls.vue.d.ts +2 -0
  31. package/dist/components/feedback/index.cjs +1 -1
  32. package/dist/components/feedback/index.js +1 -1
  33. package/dist/components/form/index.cjs +1 -1
  34. package/dist/components/form/index.js +1 -1
  35. package/dist/components/index.cjs +5 -5
  36. package/dist/components/index.js +5 -5
  37. package/dist/components/layout/index.cjs +1 -1
  38. package/dist/components/layout/index.js +1 -1
  39. package/dist/composables/index.cjs +1 -1
  40. package/dist/composables/index.js +1 -1
  41. package/dist/composables/useDropdown.d.ts +4 -1
  42. package/dist/{index-DwqCXgDx.cjs → index-5dQNEzd8.cjs} +6 -6
  43. package/dist/{index-DwqCXgDx.cjs.map → index-5dQNEzd8.cjs.map} +1 -1
  44. package/dist/{index-rBD1MYh-.js → index-CDDUEkXf.js} +6 -6
  45. package/dist/index-CDDUEkXf.js.map +1 -0
  46. package/dist/index.cjs +7 -7
  47. package/dist/index.js +7 -7
  48. package/dist/style.css +1 -1
  49. package/dist/{useDropdown-DHFnd259.cjs → useDropdown-DK4c5JGL.cjs} +66 -10
  50. package/dist/useDropdown-DK4c5JGL.cjs.map +1 -0
  51. package/dist/{useDropdown-iVu14E6s.js → useDropdown-De0cKI83.js} +66 -10
  52. package/dist/useDropdown-De0cKI83.js.map +1 -0
  53. package/dist/useFocusTrap-AnlJsihM.js.map +1 -1
  54. package/dist/useFocusTrap-kcxO8AeU.cjs.map +1 -1
  55. package/dist/useId-nxrBaIC9.cjs.map +1 -1
  56. package/dist/useId-xeHj7rkg.js.map +1 -1
  57. package/dist/useToast-Bk60GArg.cjs.map +1 -1
  58. package/dist/useToast-ina5g3mj.js.map +1 -1
  59. package/package.json +169 -169
  60. package/dist/CheckboxGroup.vue_vue_type_script_setup_true_lang-DJbuHoDj.cjs.map +0 -1
  61. package/dist/CheckboxGroup.vue_vue_type_script_setup_true_lang-hHJdvUYS.js.map +0 -1
  62. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-Bine-xfp.cjs.map +0 -1
  63. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DqkA1Zr-.js.map +0 -1
  64. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-56CxoSmj.js.map +0 -1
  65. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-Dd3ySRNB.cjs.map +0 -1
  66. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-Bj3I5Sn7.cjs.map +0 -1
  67. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-DzLwUVCW.js.map +0 -1
  68. package/dist/PageHero.vue_vue_type_script_setup_true_lang-Bi97ypMD.cjs.map +0 -1
  69. package/dist/PageHero.vue_vue_type_script_setup_true_lang-DQQGYAw0.js.map +0 -1
  70. package/dist/index-rBD1MYh-.js.map +0 -1
  71. package/dist/useDropdown-DHFnd259.cjs.map +0 -1
  72. package/dist/useDropdown-iVu14E6s.js.map +0 -1
@@ -1,17 +1,17 @@
1
- import { defineComponent, useSlots, ref, computed, resolveComponent, createElementBlock, openBlock, createBlock, createVNode, resolveDynamicComponent, mergeProps, withCtx, createElementVNode, createCommentVNode, unref, normalizeClass, Transition, toDisplayString, renderSlot, Fragment, renderList, createTextVNode, Teleport, normalizeStyle } from "vue";
1
+ import { defineComponent, useSlots, ref, computed, resolveComponent, createElementBlock, openBlock, unref, createBlock, createVNode, resolveDynamicComponent, mergeProps, withCtx, createElementVNode, createCommentVNode, normalizeClass, Transition, toDisplayString, renderSlot, Fragment, renderList, Teleport, normalizeStyle, createTextVNode } from "vue";
2
2
  import { Icon } from "@iconify/vue";
3
- import { u as useDropdown } from "./useDropdown-iVu14E6s.js";
3
+ import { u as useDropdown } from "./useDropdown-De0cKI83.js";
4
4
  import { u as useId } from "./useId-xeHj7rkg.js";
5
- const _hoisted_1$1 = { class: "w-full" };
6
- const _hoisted_2$1 = { class: "relative" };
7
- const _hoisted_3$1 = {
5
+ const _hoisted_1$1 = { class: "relative" };
6
+ const _hoisted_2$1 = {
8
7
  key: 0,
9
8
  class: "absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600"
10
9
  };
11
- const _hoisted_4$1 = {
10
+ const _hoisted_3$1 = {
12
11
  key: 0,
13
12
  class: "overflow-hidden"
14
13
  };
14
+ const _hoisted_4$1 = { class: "px-4 py-2 text-xs font-semibold text-gray-500 uppercase dark:text-gray-400" };
15
15
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
16
16
  __name: "MenuItem",
17
17
  props: {
@@ -25,6 +25,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
25
25
  const props = __props;
26
26
  const slots = useSlots();
27
27
  const submenuOpen = ref(false);
28
+ const triggerRef = ref();
29
+ const flyoutRef = ref();
30
+ const { isOpen: flyoutOpen, dropdownStyle, open: openFlyout, close: closeFlyout } = useDropdown(
31
+ triggerRef,
32
+ flyoutRef,
33
+ {
34
+ teleport: true,
35
+ gap: 8,
36
+ placement: "right-start"
37
+ }
38
+ );
28
39
  const hasSlotContent = computed(() => !!slots.submenu);
29
40
  const hasChildren = computed(() => {
30
41
  return props.menuItem.children && props.menuItem.children.length > 0;
@@ -89,16 +100,53 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
89
100
  const indentPerLevel = 16;
90
101
  return `${basePadding + props.depth * indentPerLevel}px`;
91
102
  });
103
+ const childLinkComponent = (child) => {
104
+ if (child.children && child.children.length > 0) {
105
+ return "button";
106
+ }
107
+ try {
108
+ const RouterLink = resolveComponent("RouterLink");
109
+ if (typeof RouterLink !== "string") {
110
+ return RouterLink;
111
+ }
112
+ } catch {
113
+ }
114
+ return "a";
115
+ };
116
+ const childLinkProps = (child) => {
117
+ if (child.children && child.children.length > 0) {
118
+ return { type: "button" };
119
+ }
120
+ const component = childLinkComponent(child);
121
+ if (component === "a") {
122
+ return { href: child.link };
123
+ }
124
+ return { to: child.link };
125
+ };
126
+ const isChildRouteActive = (child) => {
127
+ const path = props.currentPath ?? (typeof window !== "undefined" ? window.location.pathname : "/");
128
+ if (child.link === "/") {
129
+ return path === "/";
130
+ }
131
+ return path === child.link || path.startsWith(child.link + "/");
132
+ };
92
133
  return (_ctx, _cache) => {
93
134
  const _component_MenuItem = resolveComponent("MenuItem", true);
94
- return openBlock(), createElementBlock("div", _hoisted_1$1, [
95
- (openBlock(), createBlock(resolveDynamicComponent(linkComponent.value), mergeProps(linkProps.value, {
135
+ return openBlock(), createElementBlock("div", {
136
+ class: "w-full",
137
+ onMouseenter: _cache[3] || (_cache[3] = ($event) => !__props.expanded && hasSubmenu.value && unref(openFlyout)()),
138
+ onMouseleave: _cache[4] || (_cache[4] = ($event) => !__props.expanded && hasSubmenu.value && unref(closeFlyout)())
139
+ }, [
140
+ (openBlock(), createBlock(resolveDynamicComponent(linkComponent.value), mergeProps({
141
+ ref_key: "triggerRef",
142
+ ref: triggerRef
143
+ }, linkProps.value, {
96
144
  class: [__props.expanded ? "flex-row" : "flex-col", "group relative flex w-full items-center justify-center gap-2 pr-5 py-2"],
97
145
  style: __props.expanded ? { paddingLeft: paddingLeft.value } : void 0,
98
146
  onClick: toggleSubmenu
99
147
  }), {
100
148
  default: withCtx(() => [
101
- createElementVNode("div", _hoisted_2$1, [
149
+ createElementVNode("div", _hoisted_1$1, [
102
150
  createVNode(unref(Icon), {
103
151
  class: normalizeClass([[
104
152
  isRouteActive.value || isChildActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
@@ -106,7 +154,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
106
154
  ], "transition-all duration-300"]),
107
155
  icon: __props.menuItem.icon
108
156
  }, null, 8, ["class", "icon"]),
109
- __props.menuItem.notification ? (openBlock(), createElementBlock("span", _hoisted_3$1)) : createCommentVNode("", true)
157
+ __props.menuItem.notification ? (openBlock(), createElementBlock("span", _hoisted_2$1)) : createCommentVNode("", true)
110
158
  ]),
111
159
  createVNode(Transition, {
112
160
  "enter-active-class": "transition-all duration-300 ease-out",
@@ -147,7 +195,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
147
195
  "leave-to-class": "opacity-0 max-h-0"
148
196
  }, {
149
197
  default: withCtx(() => [
150
- hasSubmenu.value && submenuOpen.value && __props.expanded ? (openBlock(), createElementBlock("div", _hoisted_4$1, [
198
+ hasSubmenu.value && submenuOpen.value && __props.expanded ? (openBlock(), createElementBlock("div", _hoisted_3$1, [
151
199
  renderSlot(_ctx.$slots, "submenu", {
152
200
  depth: __props.depth + 1,
153
201
  expanded: __props.expanded,
@@ -165,8 +213,56 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
165
213
  ])) : createCommentVNode("", true)
166
214
  ]),
167
215
  _: 3
168
- })
169
- ]);
216
+ }),
217
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
218
+ createVNode(Transition, {
219
+ "enter-active-class": "transition duration-150 ease-out",
220
+ "enter-from-class": "opacity-0 scale-95",
221
+ "enter-to-class": "opacity-100 scale-100",
222
+ "leave-active-class": "transition duration-100 ease-in",
223
+ "leave-from-class": "opacity-100 scale-100",
224
+ "leave-to-class": "opacity-0 scale-95"
225
+ }, {
226
+ default: withCtx(() => [
227
+ hasSubmenu.value && unref(flyoutOpen) && !__props.expanded ? (openBlock(), createElementBlock("div", {
228
+ key: 0,
229
+ ref_key: "flyoutRef",
230
+ ref: flyoutRef,
231
+ style: normalizeStyle(unref(dropdownStyle)),
232
+ class: "z-9999 min-w-48 rounded-lg border border-gray-200 bg-white py-2 shadow-lg dark:border-gray-700 dark:bg-gray-800",
233
+ onMouseenter: _cache[1] || (_cache[1] = ($event) => unref(openFlyout)()),
234
+ onMouseleave: _cache[2] || (_cache[2] = ($event) => unref(closeFlyout)())
235
+ }, [
236
+ createElementVNode("div", _hoisted_4$1, toDisplayString(__props.menuItem.label), 1),
237
+ renderSlot(_ctx.$slots, "submenu", {
238
+ depth: 0,
239
+ expanded: true,
240
+ currentPath: __props.currentPath
241
+ }),
242
+ __props.menuItem.children ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.menuItem.children, (child, index) => {
243
+ return openBlock(), createBlock(resolveDynamicComponent(childLinkComponent(child)), mergeProps({ key: index }, { ref_for: true }, childLinkProps(child), {
244
+ class: [
245
+ "flex items-center gap-3 px-4 py-2 text-sm transition-colors",
246
+ isChildRouteActive(child) ? "bg-primary-50 text-primary-700 dark:bg-primary-900/20 dark:text-primary-400" : "text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
247
+ ],
248
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(closeFlyout)())
249
+ }), {
250
+ default: withCtx(() => [
251
+ createVNode(unref(Icon), {
252
+ icon: child.icon,
253
+ class: "size-4"
254
+ }, null, 8, ["icon"]),
255
+ createElementVNode("span", null, toDisplayString(child.label), 1)
256
+ ]),
257
+ _: 2
258
+ }, 1040, ["class"]);
259
+ }), 128)) : createCommentVNode("", true)
260
+ ], 36)) : createCommentVNode("", true)
261
+ ]),
262
+ _: 3
263
+ })
264
+ ]))
265
+ ], 32);
170
266
  };
171
267
  }
172
268
  });
@@ -313,4 +409,4 @@ export {
313
409
  _sfc_main$1 as _,
314
410
  _sfc_main as a
315
411
  };
316
- //# sourceMappingURL=Dropdown.vue_vue_type_script_setup_true_lang-56CxoSmj.js.map
412
+ //# sourceMappingURL=Dropdown.vue_vue_type_script_setup_true_lang-A9Ax6iob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dropdown.vue_vue_type_script_setup_true_lang-A9Ax6iob.js","sources":["../src/components/core/MenuItem.vue","../src/components/core/Dropdown.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent, ref, useSlots } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n menuItem: MenuItemProps\r\n /** Whether sidebar is expanded (shows labels) */\r\n expanded?: boolean\r\n /** Override active state directly */\r\n active?: boolean\r\n /** Current route path (pass from parent using useRoute().path) */\r\n currentPath?: string\r\n /** Nesting depth level (used internally for indentation) */\r\n depth?: number\r\n }>(),\r\n {\r\n expanded: true,\r\n active: undefined,\r\n currentPath: undefined,\r\n depth: 0,\r\n },\r\n)\r\n\r\nconst slots = useSlots()\r\nconst submenuOpen = ref(false)\r\n\r\n// Flyout popover for compacted mode\r\nconst triggerRef = ref<HTMLElement>()\r\nconst flyoutRef = ref<HTMLElement>()\r\nconst { isOpen: flyoutOpen, dropdownStyle, open: openFlyout, close: closeFlyout } = useDropdown(\r\n triggerRef,\r\n flyoutRef,\r\n {\r\n teleport: true,\r\n gap: 8,\r\n placement: 'right-start',\r\n },\r\n)\r\n\r\nconst hasSlotContent = computed(() => !!slots.submenu)\r\n\r\nconst hasChildren = computed(() => {\r\n return props.menuItem.children && props.menuItem.children.length > 0\r\n})\r\n\r\nconst hasSubmenu = computed(() => hasChildren.value || hasSlotContent.value)\r\n\r\nconst isRouteActive = computed(() => {\r\n // If active prop is explicitly set, use it\r\n if (props.active !== undefined) {\r\n return props.active\r\n }\r\n\r\n // Use currentPath prop if provided, otherwise fall back to window.location\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n\r\n if (props.menuItem.link === '/') {\r\n return path === '/'\r\n }\r\n return path === props.menuItem.link || path.startsWith(props.menuItem.link + '/')\r\n})\r\n\r\n// Check if any child is active (to highlight parent)\r\nconst isChildActive = computed(() => {\r\n if (!hasChildren.value) return false\r\n\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n\r\n const checkActive = (items: MenuItemProps[]): boolean => {\r\n return items.some((item) => {\r\n if (item.link === path || path.startsWith(item.link + '/')) {\r\n return true\r\n }\r\n if (item.children) {\r\n return checkActive(item.children)\r\n }\r\n return false\r\n })\r\n }\r\n\r\n return checkActive(props.menuItem.children!)\r\n})\r\n\r\n// Try to resolve RouterLink, fallback to 'a' tag\r\nconst linkComponent = computed(() => {\r\n if (hasSubmenu.value) {\r\n return 'button'\r\n }\r\n try {\r\n const RouterLink = resolveComponent('RouterLink')\r\n if (typeof RouterLink !== 'string') {\r\n return RouterLink\r\n }\r\n } catch {\r\n // RouterLink not available\r\n }\r\n return 'a'\r\n})\r\n\r\nconst linkProps = computed(() => {\r\n if (hasSubmenu.value) {\r\n return { type: 'button' as const }\r\n }\r\n if (linkComponent.value === 'a') {\r\n return { href: props.menuItem.link }\r\n }\r\n return { to: props.menuItem.link }\r\n})\r\n\r\nconst toggleSubmenu = () => {\r\n if (hasSubmenu.value) {\r\n submenuOpen.value = !submenuOpen.value\r\n }\r\n}\r\n\r\nconst paddingLeft = computed(() => {\r\n if (!props.expanded) return undefined\r\n const basePadding = 20 // px-5 = 20px\r\n const indentPerLevel = 16 // 16px per nesting level\r\n return `${basePadding + props.depth * indentPerLevel}px`\r\n})\r\n\r\n// Helper functions for flyout child items\r\nconst childLinkComponent = (child: MenuItemProps) => {\r\n if (child.children && child.children.length > 0) {\r\n return 'button'\r\n }\r\n try {\r\n const RouterLink = resolveComponent('RouterLink')\r\n if (typeof RouterLink !== 'string') {\r\n return RouterLink\r\n }\r\n } catch {\r\n // RouterLink not available\r\n }\r\n return 'a'\r\n}\r\n\r\nconst childLinkProps = (child: MenuItemProps) => {\r\n if (child.children && child.children.length > 0) {\r\n return { type: 'button' as const }\r\n }\r\n const component = childLinkComponent(child)\r\n if (component === 'a') {\r\n return { href: child.link }\r\n }\r\n return { to: child.link }\r\n}\r\n\r\nconst isChildRouteActive = (child: MenuItemProps) => {\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n if (child.link === '/') {\r\n return path === '/'\r\n }\r\n return path === child.link || path.startsWith(child.link + '/')\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n class=\"w-full\"\r\n @mouseenter=\"!expanded && hasSubmenu && openFlyout()\"\r\n @mouseleave=\"!expanded && hasSubmenu && closeFlyout()\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n ref=\"triggerRef\"\r\n v-bind=\"linkProps\"\r\n :class=\"expanded ? 'flex-row' : 'flex-col'\"\r\n :style=\"expanded ? { paddingLeft } : undefined\"\r\n class=\"group relative flex w-full items-center justify-center gap-2 pr-5 py-2\"\r\n @click=\"toggleSubmenu\"\r\n >\r\n <div class=\"relative\">\r\n <Icon\r\n :class=\"[\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\r\n expanded ? 'size-5' : 'size-8',\r\n ]\"\r\n class=\"transition-all duration-300\"\r\n :icon=\"menuItem.icon\"\r\n />\r\n\r\n <span\r\n v-if=\"menuItem.notification\"\r\n class=\"absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600\"\r\n />\r\n </div>\r\n\r\n <Transition\r\n enter-active-class=\"transition-all duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 -translate-x-2\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition-all duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 -translate-x-2\"\r\n >\r\n <span\r\n v-if=\"expanded\"\r\n :class=\"\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500'\r\n \"\r\n class=\"flex-1 text-left text-sm font-semibold whitespace-nowrap\"\r\n >{{ menuItem.label }}</span>\r\n </Transition>\r\n\r\n <!-- Chevron for submenu -->\r\n <Icon\r\n v-if=\"hasSubmenu && expanded\"\r\n :class=\"[\r\n submenuOpen ? 'rotate-90' : '',\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\r\n ]\"\r\n class=\"size-4 transition-transform duration-200\"\r\n icon=\"lucide:chevron-right\"\r\n />\r\n </component>\r\n\r\n <!-- Submenu content (expanded mode - inline) -->\r\n <Transition\r\n enter-active-class=\"transition-all duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 max-h-0\"\r\n enter-to-class=\"opacity-100 max-h-96\"\r\n leave-active-class=\"transition-all duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 max-h-96\"\r\n leave-to-class=\"opacity-0 max-h-0\"\r\n >\r\n <div\r\n v-if=\"hasSubmenu && submenuOpen && expanded\"\r\n class=\"overflow-hidden\"\r\n >\r\n <!-- Slot for custom submenu content -->\r\n <slot\r\n name=\"submenu\"\r\n :depth=\"depth + 1\"\r\n :expanded=\"expanded\"\r\n :current-path=\"currentPath\"\r\n />\r\n\r\n <!-- Default children from prop -->\r\n <MenuItem\r\n v-for=\"(child, index) in menuItem.children\"\r\n :key=\"index\"\r\n :menu-item=\"child\"\r\n :expanded=\"expanded\"\r\n :current-path=\"currentPath\"\r\n :depth=\"depth + 1\"\r\n />\r\n </div>\r\n </Transition>\r\n\r\n <!-- Flyout submenu (compacted mode - popover) -->\r\n <Teleport to=\"body\">\r\n <Transition\r\n enter-active-class=\"transition duration-150 ease-out\"\r\n enter-from-class=\"opacity-0 scale-95\"\r\n enter-to-class=\"opacity-100 scale-100\"\r\n leave-active-class=\"transition duration-100 ease-in\"\r\n leave-from-class=\"opacity-100 scale-100\"\r\n leave-to-class=\"opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"hasSubmenu && flyoutOpen && !expanded\"\r\n ref=\"flyoutRef\"\r\n :style=\"dropdownStyle\"\r\n class=\"z-9999 min-w-48 rounded-lg border border-gray-200 bg-white py-2 shadow-lg dark:border-gray-700 dark:bg-gray-800\"\r\n @mouseenter=\"openFlyout()\"\r\n @mouseleave=\"closeFlyout()\"\r\n >\r\n <!-- Label header -->\r\n <div class=\"px-4 py-2 text-xs font-semibold text-gray-500 uppercase dark:text-gray-400\">\r\n {{ menuItem.label }}\r\n </div>\r\n\r\n <!-- Slot for custom submenu content -->\r\n <slot\r\n name=\"submenu\"\r\n :depth=\"0\"\r\n :expanded=\"true\"\r\n :current-path=\"currentPath\"\r\n />\r\n\r\n <!-- Default children from prop -->\r\n <template v-if=\"menuItem.children\">\r\n <component\r\n :is=\"childLinkComponent(child)\"\r\n v-for=\"(child, index) in menuItem.children\"\r\n :key=\"index\"\r\n v-bind=\"childLinkProps(child)\"\r\n :class=\"[\r\n 'flex items-center gap-3 px-4 py-2 text-sm transition-colors',\r\n isChildRouteActive(child)\r\n ? 'bg-primary-50 text-primary-700 dark:bg-primary-900/20 dark:text-primary-400'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700',\r\n ]\"\r\n @click=\"closeFlyout()\"\r\n >\r\n <Icon\r\n :icon=\"child.icon\"\r\n class=\"size-4\"\r\n />\r\n <span>{{ child.label }}</span>\r\n </component>\r\n </template>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport { useId } from '@/composables/useId'\r\n\r\nexport interface DropdownItem {\r\n key: string\r\n label: string\r\n icon?: string\r\n disabled?: boolean\r\n danger?: boolean\r\n divider?: boolean\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Dropdown items (optional if using default slot) */\r\n items?: DropdownItem[]\r\n /** Align dropdown */\r\n align?: 'left' | 'right'\r\n /** Dropdown width */\r\n width?: 'auto' | 'full' | 'sm' | 'md' | 'lg'\r\n /** Use teleport to body to avoid overflow clipping */\r\n teleport?: boolean\r\n /** Custom ID for accessibility */\r\n id?: string\r\n }>(),\r\n {\r\n items: () => [],\r\n align: 'left',\r\n width: 'auto',\r\n teleport: true,\r\n },\r\n)\r\n\r\n// Generate unique IDs for accessibility\r\nconst { related } = useId({ prefix: 'dropdown', id: props.id })\r\nconst triggerId = computed(() => related('trigger'))\r\nconst menuId = computed(() => related('menu'))\r\n\r\nconst emit = defineEmits<{\r\n select: [item: DropdownItem]\r\n}>()\r\n\r\nconst triggerRef = ref<HTMLElement>()\r\nconst menuRef = ref<HTMLElement>()\r\n\r\nconst { isOpen, dropdownStyle, toggle, close } = useDropdown(triggerRef, menuRef, {\r\n teleport: props.teleport,\r\n align: props.align,\r\n})\r\n\r\nconst selectItem = (item: DropdownItem) => {\r\n if (item.disabled || item.divider) return\r\n emit('select', item)\r\n close()\r\n}\r\n\r\nconst widthClasses = {\r\n auto: 'w-auto min-w-40',\r\n full: 'w-full',\r\n sm: 'w-32',\r\n md: 'w-48',\r\n lg: 'w-64',\r\n}\r\n\r\nconst computedDropdownStyle = computed(() => {\r\n if (!props.teleport) return {}\r\n const { width: _, ...rest } = dropdownStyle.value\r\n return rest\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"relative inline-block\">\r\n <div\r\n ref=\"triggerRef\"\r\n @click=\"toggle\"\r\n >\r\n <slot name=\"trigger\">\r\n <button\r\n :id=\"triggerId\"\r\n type=\"button\"\r\n :aria-expanded=\"isOpen\"\r\n aria-haspopup=\"menu\"\r\n :aria-controls=\"menuId\"\r\n class=\"inline-flex items-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n >\r\n <slot name=\"trigger-label\">\r\n Options\r\n </slot>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n :class=\"['size-4 transition-transform', isOpen && 'rotate-180']\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </slot>\r\n </div>\r\n\r\n <Teleport\r\n to=\"body\"\r\n :disabled=\"!teleport\"\r\n >\r\n <Transition\r\n enter-active-class=\"transition ease-out duration-100\"\r\n enter-from-class=\"transform opacity-0 scale-95\"\r\n enter-to-class=\"transform opacity-100 scale-100\"\r\n leave-active-class=\"transition ease-in duration-75\"\r\n leave-from-class=\"transform opacity-100 scale-100\"\r\n leave-to-class=\"transform opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n :id=\"menuId\"\r\n ref=\"menuRef\"\r\n role=\"menu\"\r\n :aria-labelledby=\"triggerId\"\r\n :style=\"computedDropdownStyle\"\r\n :class=\"[\r\n 'z-9999 rounded-lg border border-gray-200 bg-white py-1 shadow-lg dark:border-gray-700 dark:bg-gray-800',\r\n widthClasses[width],\r\n !teleport && (align === 'right' ? 'absolute mt-2 right-0' : 'absolute mt-2 left-0'),\r\n ]\"\r\n >\r\n <!-- Custom content via default slot -->\r\n <slot :close=\"close\">\r\n <!-- Default items rendering -->\r\n <template\r\n v-for=\"item in items\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n v-if=\"item.divider\"\r\n role=\"separator\"\r\n class=\"my-1 border-t border-gray-200 dark:border-gray-700\"\r\n />\r\n <button\r\n v-else\r\n type=\"button\"\r\n role=\"menuitem\"\r\n :disabled=\"item.disabled\"\r\n :class=\"[\r\n 'flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors',\r\n item.disabled\r\n ? 'cursor-not-allowed opacity-50'\r\n : item.danger\r\n ? 'text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700',\r\n ]\"\r\n @click=\"selectItem(item)\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n aria-hidden=\"true\"\r\n />\r\n {{ item.label }}\r\n </button>\r\n </template>\r\n </slot>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n"],"names":["_createElementBlock","_unref","_createBlock","_resolveDynamicComponent","_mergeProps","_createElementVNode","_hoisted_1","_createVNode","_normalizeClass","_openBlock","_hoisted_2","_Transition","_toDisplayString","_hoisted_3","_renderSlot","_Fragment","_Teleport","_hoisted_4","_renderList"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAMA,UAAM,QAAQ;AAoBd,UAAM,QAAQ,SAAA;AACd,UAAM,cAAc,IAAI,KAAK;AAG7B,UAAM,aAAa,IAAA;AACnB,UAAM,YAAY,IAAA;AAClB,UAAM,EAAE,QAAQ,YAAY,eAAe,MAAM,YAAY,OAAO,gBAAgB;AAAA,MAClF;AAAA,MACA;AAAA,MACA;AAAA,QACE,UAAU;AAAA,QACV,KAAK;AAAA,QACL,WAAW;AAAA,MAAA;AAAA,IACb;AAGF,UAAM,iBAAiB,SAAS,MAAM,CAAC,CAAC,MAAM,OAAO;AAErD,UAAM,cAAc,SAAS,MAAM;AACjC,aAAO,MAAM,SAAS,YAAY,MAAM,SAAS,SAAS,SAAS;AAAA,IACrE,CAAC;AAED,UAAM,aAAa,SAAS,MAAM,YAAY,SAAS,eAAe,KAAK;AAE3E,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,CAAC,YAAY,MAAO,QAAO;AAE/B,YAAM,OAAO,MAAM,gBAAgB,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAE9F,YAAM,cAAc,CAAC,UAAoC;AACvD,eAAO,MAAM,KAAK,CAAC,SAAS;AAC1B,cAAI,KAAK,SAAS,QAAQ,KAAK,WAAW,KAAK,OAAO,GAAG,GAAG;AAC1D,mBAAO;AAAA,UACT;AACA,cAAI,KAAK,UAAU;AACjB,mBAAO,YAAY,KAAK,QAAQ;AAAA,UAClC;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,aAAO,YAAY,MAAM,SAAS,QAAS;AAAA,IAC7C,CAAC;AAGD,UAAM,gBAAgB,SAAS,MAAM;AACnC,UAAI,WAAW,OAAO;AACpB,eAAO;AAAA,MACT;AACA,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,WAAW,OAAO;AACpB,eAAO,EAAE,MAAM,SAAA;AAAA,MACjB;AACA,UAAI,cAAc,UAAU,KAAK;AAC/B,eAAO,EAAE,MAAM,MAAM,SAAS,KAAA;AAAA,MAChC;AACA,aAAO,EAAE,IAAI,MAAM,SAAS,KAAA;AAAA,IAC9B,CAAC;AAED,UAAM,gBAAgB,MAAM;AAC1B,UAAI,WAAW,OAAO;AACpB,oBAAY,QAAQ,CAAC,YAAY;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,cAAc,SAAS,MAAM;AACjC,UAAI,CAAC,MAAM,SAAU,QAAO;AAC5B,YAAM,cAAc;AACpB,YAAM,iBAAiB;AACvB,aAAO,GAAG,cAAc,MAAM,QAAQ,cAAc;AAAA,IACtD,CAAC;AAGD,UAAM,qBAAqB,CAAC,UAAyB;AACnD,UAAI,MAAM,YAAY,MAAM,SAAS,SAAS,GAAG;AAC/C,eAAO;AAAA,MACT;AACA,UAAI;AACF,cAAM,aAAa,iBAAiB,YAAY;AAChD,YAAI,OAAO,eAAe,UAAU;AAClC,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,CAAC,UAAyB;AAC/C,UAAI,MAAM,YAAY,MAAM,SAAS,SAAS,GAAG;AAC/C,eAAO,EAAE,MAAM,SAAA;AAAA,MACjB;AACA,YAAM,YAAY,mBAAmB,KAAK;AAC1C,UAAI,cAAc,KAAK;AACrB,eAAO,EAAE,MAAM,MAAM,KAAA;AAAA,MACvB;AACA,aAAO,EAAE,IAAI,MAAM,KAAA;AAAA,IACrB;AAEA,UAAM,qBAAqB,CAAC,UAAyB;AACnD,YAAM,OAAO,MAAM,gBAAgB,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAC9F,UAAI,MAAM,SAAS,KAAK;AACtB,eAAO,SAAS;AAAA,MAClB;AACA,aAAO,SAAS,MAAM,QAAQ,KAAK,WAAW,MAAM,OAAO,GAAG;AAAA,IAChE;;;0BAIEA,mBA0JM,OAAA;AAAA,QAzJJ,OAAM;AAAA,QACL,cAAU,OAAA,CAAA,MAAA,OAAA,CAAA,IAAA,CAAA,WAAA,CAAG,QAAA,YAAY,WAAA,SAAcC,MAAA,UAAA;QACvC,cAAU,OAAA,CAAA,MAAA,OAAA,CAAA,IAAA,CAAA,WAAA,CAAG,QAAA,YAAY,WAAA,SAAcA,MAAA,WAAA,EAAA;AAAA,MAAW;sBAEnDC,YA0DYC,wBAzDL,cAAA,KAAa,GADpBC,WA0DY;AAAA,mBAxDN;AAAA,UAAJ,KAAI;AAAA,QAAA,GACI,UAAA,OAAS;AAAA,UAChB,OAAK,CAAE,QAAA,WAAQ,aAAA,YAEV,wEAAwE;AAAA,UAD7E,OAAO,QAAA,WAAQ,EAAA,aAAK,YAAA,UAAgB;AAAA,UAEpC,SAAO;AAAA,QAAA;2BAER,MAgBM;AAAA,YAhBNC,mBAgBM,OAhBNC,cAgBM;AAAA,cAfJC,YASEN,MAAA,IAAA,GAAA;AAAA,gBARC,OAAKO,eAAA,CAAA;AAAA,kBAAiB,cAAA,SAAiB,cAAA;kBAAuK,QAAA,WAAQ,WAAA;AAAA,gBAAA,GAMjN,6BAA6B,CAAA;AAAA,gBAClC,MAAM,QAAA,SAAS;AAAA,cAAA;cAIV,QAAA,SAAS,gBADjBC,aAAAT,mBAGE,QAHFU,YAGE;;YAGJH,YAiBaI,YAAA;AAAA,cAhBX,sBAAmB;AAAA,cACnB,oBAAiB;AAAA,cACjB,kBAAe;AAAA,cACf,sBAAmB;AAAA,cACnB,oBAAiB;AAAA,cACjB,kBAAe;AAAA,YAAA;+BAEf,MAQ4B;AAAA,gBAPpB,QAAA,yBADRX,mBAQ4B,QAAA;AAAA;kBANzB,OAAKQ,eAAA;AAAA,oBAAgB,cAAA,SAAiB,cAAA;oBAKjC;AAAA,kBAAA,CAA0D;AAAA,gBAAA,GAC9DI,gBAAA,QAAA,SAAS,KAAK,GAAA,CAAA;;;;YAKZ,WAAA,SAAc,QAAA,yBADtBV,YAUED,MAAA,IAAA,GAAA;AAAA;cARC,OAAKO,eAAA,CAAA;AAAA,gBAAe,YAAA,QAAW,cAAA;AAAA,gBAAgC,cAAA,SAAiB,cAAA;iBAM3E,0CAA0C,CAAA;AAAA,cAChD,MAAK;AAAA,YAAA;;;;QAKTD,YA8BaI,YAAA;AAAA,UA7BX,sBAAmB;AAAA,UACnB,oBAAiB;AAAA,UACjB,kBAAe;AAAA,UACf,sBAAmB;AAAA,UACnB,oBAAiB;AAAA,UACjB,kBAAe;AAAA,QAAA;2BAEf,MAqBM;AAAA,YApBE,WAAA,SAAc,YAAA,SAAe,QAAA,YADrCF,aAAAT,mBAqBM,OArBNa,cAqBM;AAAA,cAhBJC,WAKE,KAAA,QAAA,WAAA;AAAA,gBAHC,OAAO,QAAA,QAAK;AAAA,gBACZ,UAAU,QAAA;AAAA,gBACV,aAAc,QAAA;AAAA,cAAA;eAIjBL,UAAA,IAAA,GAAAT,mBAOEe,2BANyB,QAAA,SAAS,UAAQ,CAAlC,OAAO,UAAK;oCADtBb,YAOE,qBAAA;AAAA,kBALC,KAAK;AAAA,kBACL,aAAW;AAAA,kBACX,UAAU,QAAA;AAAA,kBACV,gBAAc,QAAA;AAAA,kBACd,OAAO,QAAA,QAAK;AAAA,gBAAA;;;;;;sBAMnBA,YAsDWc,UAAA,EAtDD,IAAG,UAAM;AAAA,UACjBT,YAoDaI,YAAA;AAAA,YAnDX,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,YACf,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,UAAA;6BAEf,MA2CM;AAAA,cA1CE,WAAA,SAAcV,MAAA,UAAA,KAAU,CAAK,QAAA,yBADrCD,mBA2CM,OAAA;AAAA;yBAzCA;AAAA,gBAAJ,KAAI;AAAA,gBACH,sBAAOC,MAAA,aAAA,CAAa;AAAA,gBACrB,OAAM;AAAA,gBACL,oDAAYA,MAAA,UAAA;gBACZ,oDAAYA,MAAA,WAAA,EAAA;AAAA,cAAW;gBAGxBI,mBAEM,OAFNY,cAEML,gBADD,QAAA,SAAS,KAAK,GAAA,CAAA;AAAA,gBAInBE,WAKE,KAAA,QAAA,WAAA;AAAA,kBAHC,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,aAAc,QAAA;AAAA,gBAAA;gBAID,QAAA,SAAS,YACvBL,UAAA,IAAA,GAAAT,mBAkBYe,iCAhBe,QAAA,SAAS,UAAQ,CAAlC,OAAO,UAAK;AAFtB,yBAAAN,aAAAP,YAkBYC,wBAjBL,mBAAmB,KAAK,CAAA,GAD/BC,WAkBY,EAfT,KAAK,MAAA,GAAK,EAAA,SAAA,QACH,eAAe,KAAK,GAAA;AAAA,oBAC3B,OAAK;AAAA;sBAAqG,mBAAmB,KAAK;;oBAMlI,+CAAOH,MAAA,WAAA,EAAA;AAAA,kBAAW;qCAEnB,MAGE;AAAA,sBAHFM,YAGEN,MAAA,IAAA,GAAA;AAAA,wBAFC,MAAM,MAAM;AAAA,wBACb,OAAM;AAAA,sBAAA;sBAERI,mBAA8B,QAAA,MAAAO,gBAArB,MAAM,KAAK,GAAA,CAAA;AAAA,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvSlC,UAAM,QAAQ;AAsBd,UAAM,EAAE,YAAY,MAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,IAAI;AAC9D,UAAM,YAAY,SAAS,MAAM,QAAQ,SAAS,CAAC;AACnD,UAAM,SAAS,SAAS,MAAM,QAAQ,MAAM,CAAC;AAE7C,UAAM,OAAO;AAIb,UAAM,aAAa,IAAA;AACnB,UAAM,UAAU,IAAA;AAEhB,UAAM,EAAE,QAAQ,eAAe,QAAQ,UAAU,YAAY,YAAY,SAAS;AAAA,MAChF,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,IAAA,CACd;AAED,UAAM,aAAa,CAAC,SAAuB;AACzC,UAAI,KAAK,YAAY,KAAK,QAAS;AACnC,WAAK,UAAU,IAAI;AACnB,YAAA;AAAA,IACF;AAEA,UAAM,eAAe;AAAA,MACnB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAGN,UAAM,wBAAwB,SAAS,MAAM;AAC3C,UAAI,CAAC,MAAM,SAAU,QAAO,CAAA;AAC5B,YAAM,EAAE,OAAO,GAAG,GAAG,KAAA,IAAS,cAAc;AAC5C,aAAO;AAAA,IACT,CAAC;;AAIC,aAAAH,UAAA,GAAAT,mBA2FM,OA3FN,YA2FM;AAAA,QA1FJK,mBAuBM,OAAA;AAAA,mBAtBA;AAAA,UAAJ,KAAI;AAAA,UACH,SAAK,OAAA,CAAA,MAAA,OAAA,CAAA;AAAA,uBAAEJ,MAAA,MAAA,KAAAA,MAAA,MAAA,EAAA,GAAA,IAAA;AAAA,QAAA;UAERa,WAkBO,4BAlBP,MAkBO;AAAA,YAjBLT,mBAgBS,UAAA;AAAA,cAfN,IAAI,UAAA;AAAA,cACL,MAAK;AAAA,cACJ,iBAAeJ,MAAA,MAAA;AAAA,cAChB,iBAAc;AAAA,cACb,iBAAe,OAAA;AAAA,cAChB,OAAM;AAAA,YAAA;cAENa,WAEO,kCAFP,MAEO;AAAA,0DAFoB,aAE3B,EAAA;AAAA,cAAA;cACAP,YAIEN,MAAA,IAAA,GAAA;AAAA,gBAHA,MAAK;AAAA,gBACJ,sDAAuCA,MAAA,MAAA,KAAM,YAAA,CAAA;AAAA,gBAC9C,eAAY;AAAA,cAAA;;;;sBAMpBC,YAgEWc,UAAA;AAAA,UA/DT,IAAG;AAAA,UACF,WAAW,QAAA;AAAA,QAAA;UAEZT,YA2DaI,YAAA;AAAA,YA1DX,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,YACf,sBAAmB;AAAA,YACnB,oBAAiB;AAAA,YACjB,kBAAe;AAAA,UAAA;6BAEf,MAkDM;AAAA,cAjDEV,MAAA,MAAA,kBADRD,mBAkDM,OAAA;AAAA;gBAhDH,IAAI,OAAA;AAAA,yBACD;AAAA,gBAAJ,KAAI;AAAA,gBACJ,MAAK;AAAA,gBACJ,mBAAiB,UAAA;AAAA,gBACjB,sBAAO,sBAAA,KAAqB;AAAA,gBAC5B,OAAKQ,eAAA;AAAA;kBAAwI,aAAa,QAAA,KAAK;AAAA,kBAAiB,CAAA,QAAA,aAAa,QAAA,UAAK,UAAA,0BAAA;AAAA,gBAAA;;gBAOnMM,WAmCO,KAAA,QAAA,WAAA,EAnCA,OAAOb,MAAA,KAAA,EAAA,GAAd,MAmCO;AAAA,oCAjCLD,mBAgCWe,UAAA,MAAAG,WA/BM,QAAA,OAAK,CAAb,SAAI;;sBACL,KAAA,KAAK;AAAA,oBAAA;sBAGH,KAAK,WADbT,UAAA,GAAAT,mBAIE,OAJF,UAIE,mBACFA,mBAsBS,UAAA;AAAA;wBApBP,MAAK;AAAA,wBACL,MAAK;AAAA,wBACJ,UAAU,KAAK;AAAA,wBACf,OAAKQ,eAAA;AAAA;0BAA0H,KAAK,6CAAuF,KAAK;;wBAQhO,SAAK,CAAA,WAAE,WAAW,IAAI;AAAA,sBAAA;wBAGf,KAAK,qBADbN,YAKED,MAAA,IAAA,GAAA;AAAA;0BAHC,MAAM,KAAK;AAAA,0BACZ,OAAM;AAAA,0BACN,eAAY;AAAA,wBAAA;wCACZ,MACFW,gBAAG,KAAK,KAAK,GAAA,CAAA;AAAA,sBAAA;;;;;;;;;;;;;"}
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  const vue = require("vue");
3
3
  const vue$1 = require("@iconify/vue");
4
- const useDropdown = require("./useDropdown-DHFnd259.cjs");
4
+ const useDropdown = require("./useDropdown-DK4c5JGL.cjs");
5
5
  const useId = require("./useId-nxrBaIC9.cjs");
6
- const _hoisted_1$1 = { class: "w-full" };
7
- const _hoisted_2$1 = { class: "relative" };
8
- const _hoisted_3$1 = {
6
+ const _hoisted_1$1 = { class: "relative" };
7
+ const _hoisted_2$1 = {
9
8
  key: 0,
10
9
  class: "absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600"
11
10
  };
12
- const _hoisted_4$1 = {
11
+ const _hoisted_3$1 = {
13
12
  key: 0,
14
13
  class: "overflow-hidden"
15
14
  };
15
+ const _hoisted_4$1 = { class: "px-4 py-2 text-xs font-semibold text-gray-500 uppercase dark:text-gray-400" };
16
16
  const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
17
17
  __name: "MenuItem",
18
18
  props: {
@@ -26,6 +26,17 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
26
26
  const props = __props;
27
27
  const slots = vue.useSlots();
28
28
  const submenuOpen = vue.ref(false);
29
+ const triggerRef = vue.ref();
30
+ const flyoutRef = vue.ref();
31
+ const { isOpen: flyoutOpen, dropdownStyle, open: openFlyout, close: closeFlyout } = useDropdown.useDropdown(
32
+ triggerRef,
33
+ flyoutRef,
34
+ {
35
+ teleport: true,
36
+ gap: 8,
37
+ placement: "right-start"
38
+ }
39
+ );
29
40
  const hasSlotContent = vue.computed(() => !!slots.submenu);
30
41
  const hasChildren = vue.computed(() => {
31
42
  return props.menuItem.children && props.menuItem.children.length > 0;
@@ -90,16 +101,53 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
90
101
  const indentPerLevel = 16;
91
102
  return `${basePadding + props.depth * indentPerLevel}px`;
92
103
  });
104
+ const childLinkComponent = (child) => {
105
+ if (child.children && child.children.length > 0) {
106
+ return "button";
107
+ }
108
+ try {
109
+ const RouterLink = vue.resolveComponent("RouterLink");
110
+ if (typeof RouterLink !== "string") {
111
+ return RouterLink;
112
+ }
113
+ } catch {
114
+ }
115
+ return "a";
116
+ };
117
+ const childLinkProps = (child) => {
118
+ if (child.children && child.children.length > 0) {
119
+ return { type: "button" };
120
+ }
121
+ const component = childLinkComponent(child);
122
+ if (component === "a") {
123
+ return { href: child.link };
124
+ }
125
+ return { to: child.link };
126
+ };
127
+ const isChildRouteActive = (child) => {
128
+ const path = props.currentPath ?? (typeof window !== "undefined" ? window.location.pathname : "/");
129
+ if (child.link === "/") {
130
+ return path === "/";
131
+ }
132
+ return path === child.link || path.startsWith(child.link + "/");
133
+ };
93
134
  return (_ctx, _cache) => {
94
135
  const _component_MenuItem = vue.resolveComponent("MenuItem", true);
95
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
96
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(linkComponent.value), vue.mergeProps(linkProps.value, {
136
+ return vue.openBlock(), vue.createElementBlock("div", {
137
+ class: "w-full",
138
+ onMouseenter: _cache[3] || (_cache[3] = ($event) => !__props.expanded && hasSubmenu.value && vue.unref(openFlyout)()),
139
+ onMouseleave: _cache[4] || (_cache[4] = ($event) => !__props.expanded && hasSubmenu.value && vue.unref(closeFlyout)())
140
+ }, [
141
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(linkComponent.value), vue.mergeProps({
142
+ ref_key: "triggerRef",
143
+ ref: triggerRef
144
+ }, linkProps.value, {
97
145
  class: [__props.expanded ? "flex-row" : "flex-col", "group relative flex w-full items-center justify-center gap-2 pr-5 py-2"],
98
146
  style: __props.expanded ? { paddingLeft: paddingLeft.value } : void 0,
99
147
  onClick: toggleSubmenu
100
148
  }), {
101
149
  default: vue.withCtx(() => [
102
- vue.createElementVNode("div", _hoisted_2$1, [
150
+ vue.createElementVNode("div", _hoisted_1$1, [
103
151
  vue.createVNode(vue.unref(vue$1.Icon), {
104
152
  class: vue.normalizeClass([[
105
153
  isRouteActive.value || isChildActive.value ? "text-white" : "text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500",
@@ -107,7 +155,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
107
155
  ], "transition-all duration-300"]),
108
156
  icon: __props.menuItem.icon
109
157
  }, null, 8, ["class", "icon"]),
110
- __props.menuItem.notification ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$1)) : vue.createCommentVNode("", true)
158
+ __props.menuItem.notification ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$1)) : vue.createCommentVNode("", true)
111
159
  ]),
112
160
  vue.createVNode(vue.Transition, {
113
161
  "enter-active-class": "transition-all duration-300 ease-out",
@@ -148,7 +196,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
148
196
  "leave-to-class": "opacity-0 max-h-0"
149
197
  }, {
150
198
  default: vue.withCtx(() => [
151
- hasSubmenu.value && submenuOpen.value && __props.expanded ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$1, [
199
+ hasSubmenu.value && submenuOpen.value && __props.expanded ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$1, [
152
200
  vue.renderSlot(_ctx.$slots, "submenu", {
153
201
  depth: __props.depth + 1,
154
202
  expanded: __props.expanded,
@@ -166,8 +214,56 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
166
214
  ])) : vue.createCommentVNode("", true)
167
215
  ]),
168
216
  _: 3
169
- })
170
- ]);
217
+ }),
218
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
219
+ vue.createVNode(vue.Transition, {
220
+ "enter-active-class": "transition duration-150 ease-out",
221
+ "enter-from-class": "opacity-0 scale-95",
222
+ "enter-to-class": "opacity-100 scale-100",
223
+ "leave-active-class": "transition duration-100 ease-in",
224
+ "leave-from-class": "opacity-100 scale-100",
225
+ "leave-to-class": "opacity-0 scale-95"
226
+ }, {
227
+ default: vue.withCtx(() => [
228
+ hasSubmenu.value && vue.unref(flyoutOpen) && !__props.expanded ? (vue.openBlock(), vue.createElementBlock("div", {
229
+ key: 0,
230
+ ref_key: "flyoutRef",
231
+ ref: flyoutRef,
232
+ style: vue.normalizeStyle(vue.unref(dropdownStyle)),
233
+ class: "z-9999 min-w-48 rounded-lg border border-gray-200 bg-white py-2 shadow-lg dark:border-gray-700 dark:bg-gray-800",
234
+ onMouseenter: _cache[1] || (_cache[1] = ($event) => vue.unref(openFlyout)()),
235
+ onMouseleave: _cache[2] || (_cache[2] = ($event) => vue.unref(closeFlyout)())
236
+ }, [
237
+ vue.createElementVNode("div", _hoisted_4$1, vue.toDisplayString(__props.menuItem.label), 1),
238
+ vue.renderSlot(_ctx.$slots, "submenu", {
239
+ depth: 0,
240
+ expanded: true,
241
+ currentPath: __props.currentPath
242
+ }),
243
+ __props.menuItem.children ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(__props.menuItem.children, (child, index) => {
244
+ return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(childLinkComponent(child)), vue.mergeProps({ key: index }, { ref_for: true }, childLinkProps(child), {
245
+ class: [
246
+ "flex items-center gap-3 px-4 py-2 text-sm transition-colors",
247
+ isChildRouteActive(child) ? "bg-primary-50 text-primary-700 dark:bg-primary-900/20 dark:text-primary-400" : "text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
248
+ ],
249
+ onClick: _cache[0] || (_cache[0] = ($event) => vue.unref(closeFlyout)())
250
+ }), {
251
+ default: vue.withCtx(() => [
252
+ vue.createVNode(vue.unref(vue$1.Icon), {
253
+ icon: child.icon,
254
+ class: "size-4"
255
+ }, null, 8, ["icon"]),
256
+ vue.createElementVNode("span", null, vue.toDisplayString(child.label), 1)
257
+ ]),
258
+ _: 2
259
+ }, 1040, ["class"]);
260
+ }), 128)) : vue.createCommentVNode("", true)
261
+ ], 36)) : vue.createCommentVNode("", true)
262
+ ]),
263
+ _: 3
264
+ })
265
+ ]))
266
+ ], 32);
171
267
  };
172
268
  }
173
269
  });
@@ -312,4 +408,4 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
312
408
  });
313
409
  exports._sfc_main = _sfc_main$1;
314
410
  exports._sfc_main$1 = _sfc_main;
315
- //# sourceMappingURL=Dropdown.vue_vue_type_script_setup_true_lang-Dd3ySRNB.cjs.map
411
+ //# sourceMappingURL=Dropdown.vue_vue_type_script_setup_true_lang-DoJKvn30.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dropdown.vue_vue_type_script_setup_true_lang-DoJKvn30.cjs","sources":["../src/components/core/MenuItem.vue","../src/components/core/Dropdown.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent, ref, useSlots } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n menuItem: MenuItemProps\r\n /** Whether sidebar is expanded (shows labels) */\r\n expanded?: boolean\r\n /** Override active state directly */\r\n active?: boolean\r\n /** Current route path (pass from parent using useRoute().path) */\r\n currentPath?: string\r\n /** Nesting depth level (used internally for indentation) */\r\n depth?: number\r\n }>(),\r\n {\r\n expanded: true,\r\n active: undefined,\r\n currentPath: undefined,\r\n depth: 0,\r\n },\r\n)\r\n\r\nconst slots = useSlots()\r\nconst submenuOpen = ref(false)\r\n\r\n// Flyout popover for compacted mode\r\nconst triggerRef = ref<HTMLElement>()\r\nconst flyoutRef = ref<HTMLElement>()\r\nconst { isOpen: flyoutOpen, dropdownStyle, open: openFlyout, close: closeFlyout } = useDropdown(\r\n triggerRef,\r\n flyoutRef,\r\n {\r\n teleport: true,\r\n gap: 8,\r\n placement: 'right-start',\r\n },\r\n)\r\n\r\nconst hasSlotContent = computed(() => !!slots.submenu)\r\n\r\nconst hasChildren = computed(() => {\r\n return props.menuItem.children && props.menuItem.children.length > 0\r\n})\r\n\r\nconst hasSubmenu = computed(() => hasChildren.value || hasSlotContent.value)\r\n\r\nconst isRouteActive = computed(() => {\r\n // If active prop is explicitly set, use it\r\n if (props.active !== undefined) {\r\n return props.active\r\n }\r\n\r\n // Use currentPath prop if provided, otherwise fall back to window.location\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n\r\n if (props.menuItem.link === '/') {\r\n return path === '/'\r\n }\r\n return path === props.menuItem.link || path.startsWith(props.menuItem.link + '/')\r\n})\r\n\r\n// Check if any child is active (to highlight parent)\r\nconst isChildActive = computed(() => {\r\n if (!hasChildren.value) return false\r\n\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n\r\n const checkActive = (items: MenuItemProps[]): boolean => {\r\n return items.some((item) => {\r\n if (item.link === path || path.startsWith(item.link + '/')) {\r\n return true\r\n }\r\n if (item.children) {\r\n return checkActive(item.children)\r\n }\r\n return false\r\n })\r\n }\r\n\r\n return checkActive(props.menuItem.children!)\r\n})\r\n\r\n// Try to resolve RouterLink, fallback to 'a' tag\r\nconst linkComponent = computed(() => {\r\n if (hasSubmenu.value) {\r\n return 'button'\r\n }\r\n try {\r\n const RouterLink = resolveComponent('RouterLink')\r\n if (typeof RouterLink !== 'string') {\r\n return RouterLink\r\n }\r\n } catch {\r\n // RouterLink not available\r\n }\r\n return 'a'\r\n})\r\n\r\nconst linkProps = computed(() => {\r\n if (hasSubmenu.value) {\r\n return { type: 'button' as const }\r\n }\r\n if (linkComponent.value === 'a') {\r\n return { href: props.menuItem.link }\r\n }\r\n return { to: props.menuItem.link }\r\n})\r\n\r\nconst toggleSubmenu = () => {\r\n if (hasSubmenu.value) {\r\n submenuOpen.value = !submenuOpen.value\r\n }\r\n}\r\n\r\nconst paddingLeft = computed(() => {\r\n if (!props.expanded) return undefined\r\n const basePadding = 20 // px-5 = 20px\r\n const indentPerLevel = 16 // 16px per nesting level\r\n return `${basePadding + props.depth * indentPerLevel}px`\r\n})\r\n\r\n// Helper functions for flyout child items\r\nconst childLinkComponent = (child: MenuItemProps) => {\r\n if (child.children && child.children.length > 0) {\r\n return 'button'\r\n }\r\n try {\r\n const RouterLink = resolveComponent('RouterLink')\r\n if (typeof RouterLink !== 'string') {\r\n return RouterLink\r\n }\r\n } catch {\r\n // RouterLink not available\r\n }\r\n return 'a'\r\n}\r\n\r\nconst childLinkProps = (child: MenuItemProps) => {\r\n if (child.children && child.children.length > 0) {\r\n return { type: 'button' as const }\r\n }\r\n const component = childLinkComponent(child)\r\n if (component === 'a') {\r\n return { href: child.link }\r\n }\r\n return { to: child.link }\r\n}\r\n\r\nconst isChildRouteActive = (child: MenuItemProps) => {\r\n const path = props.currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\r\n if (child.link === '/') {\r\n return path === '/'\r\n }\r\n return path === child.link || path.startsWith(child.link + '/')\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n class=\"w-full\"\r\n @mouseenter=\"!expanded && hasSubmenu && openFlyout()\"\r\n @mouseleave=\"!expanded && hasSubmenu && closeFlyout()\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n ref=\"triggerRef\"\r\n v-bind=\"linkProps\"\r\n :class=\"expanded ? 'flex-row' : 'flex-col'\"\r\n :style=\"expanded ? { paddingLeft } : undefined\"\r\n class=\"group relative flex w-full items-center justify-center gap-2 pr-5 py-2\"\r\n @click=\"toggleSubmenu\"\r\n >\r\n <div class=\"relative\">\r\n <Icon\r\n :class=\"[\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\r\n expanded ? 'size-5' : 'size-8',\r\n ]\"\r\n class=\"transition-all duration-300\"\r\n :icon=\"menuItem.icon\"\r\n />\r\n\r\n <span\r\n v-if=\"menuItem.notification\"\r\n class=\"absolute top-0.25 right-0.25 size-1.5 rounded-full bg-red-600\"\r\n />\r\n </div>\r\n\r\n <Transition\r\n enter-active-class=\"transition-all duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 -translate-x-2\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition-all duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 -translate-x-2\"\r\n >\r\n <span\r\n v-if=\"expanded\"\r\n :class=\"\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500'\r\n \"\r\n class=\"flex-1 text-left text-sm font-semibold whitespace-nowrap\"\r\n >{{ menuItem.label }}</span>\r\n </Transition>\r\n\r\n <!-- Chevron for submenu -->\r\n <Icon\r\n v-if=\"hasSubmenu && expanded\"\r\n :class=\"[\r\n submenuOpen ? 'rotate-90' : '',\r\n isRouteActive || isChildActive\r\n ? 'text-white'\r\n : 'text-white/50 group-hover:text-white/80 dark:text-gray-700 dark:group-hover:text-gray-500',\r\n ]\"\r\n class=\"size-4 transition-transform duration-200\"\r\n icon=\"lucide:chevron-right\"\r\n />\r\n </component>\r\n\r\n <!-- Submenu content (expanded mode - inline) -->\r\n <Transition\r\n enter-active-class=\"transition-all duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 max-h-0\"\r\n enter-to-class=\"opacity-100 max-h-96\"\r\n leave-active-class=\"transition-all duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 max-h-96\"\r\n leave-to-class=\"opacity-0 max-h-0\"\r\n >\r\n <div\r\n v-if=\"hasSubmenu && submenuOpen && expanded\"\r\n class=\"overflow-hidden\"\r\n >\r\n <!-- Slot for custom submenu content -->\r\n <slot\r\n name=\"submenu\"\r\n :depth=\"depth + 1\"\r\n :expanded=\"expanded\"\r\n :current-path=\"currentPath\"\r\n />\r\n\r\n <!-- Default children from prop -->\r\n <MenuItem\r\n v-for=\"(child, index) in menuItem.children\"\r\n :key=\"index\"\r\n :menu-item=\"child\"\r\n :expanded=\"expanded\"\r\n :current-path=\"currentPath\"\r\n :depth=\"depth + 1\"\r\n />\r\n </div>\r\n </Transition>\r\n\r\n <!-- Flyout submenu (compacted mode - popover) -->\r\n <Teleport to=\"body\">\r\n <Transition\r\n enter-active-class=\"transition duration-150 ease-out\"\r\n enter-from-class=\"opacity-0 scale-95\"\r\n enter-to-class=\"opacity-100 scale-100\"\r\n leave-active-class=\"transition duration-100 ease-in\"\r\n leave-from-class=\"opacity-100 scale-100\"\r\n leave-to-class=\"opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"hasSubmenu && flyoutOpen && !expanded\"\r\n ref=\"flyoutRef\"\r\n :style=\"dropdownStyle\"\r\n class=\"z-9999 min-w-48 rounded-lg border border-gray-200 bg-white py-2 shadow-lg dark:border-gray-700 dark:bg-gray-800\"\r\n @mouseenter=\"openFlyout()\"\r\n @mouseleave=\"closeFlyout()\"\r\n >\r\n <!-- Label header -->\r\n <div class=\"px-4 py-2 text-xs font-semibold text-gray-500 uppercase dark:text-gray-400\">\r\n {{ menuItem.label }}\r\n </div>\r\n\r\n <!-- Slot for custom submenu content -->\r\n <slot\r\n name=\"submenu\"\r\n :depth=\"0\"\r\n :expanded=\"true\"\r\n :current-path=\"currentPath\"\r\n />\r\n\r\n <!-- Default children from prop -->\r\n <template v-if=\"menuItem.children\">\r\n <component\r\n :is=\"childLinkComponent(child)\"\r\n v-for=\"(child, index) in menuItem.children\"\r\n :key=\"index\"\r\n v-bind=\"childLinkProps(child)\"\r\n :class=\"[\r\n 'flex items-center gap-3 px-4 py-2 text-sm transition-colors',\r\n isChildRouteActive(child)\r\n ? 'bg-primary-50 text-primary-700 dark:bg-primary-900/20 dark:text-primary-400'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700',\r\n ]\"\r\n @click=\"closeFlyout()\"\r\n >\r\n <Icon\r\n :icon=\"child.icon\"\r\n class=\"size-4\"\r\n />\r\n <span>{{ child.label }}</span>\r\n </component>\r\n </template>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport { useId } from '@/composables/useId'\r\n\r\nexport interface DropdownItem {\r\n key: string\r\n label: string\r\n icon?: string\r\n disabled?: boolean\r\n danger?: boolean\r\n divider?: boolean\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Dropdown items (optional if using default slot) */\r\n items?: DropdownItem[]\r\n /** Align dropdown */\r\n align?: 'left' | 'right'\r\n /** Dropdown width */\r\n width?: 'auto' | 'full' | 'sm' | 'md' | 'lg'\r\n /** Use teleport to body to avoid overflow clipping */\r\n teleport?: boolean\r\n /** Custom ID for accessibility */\r\n id?: string\r\n }>(),\r\n {\r\n items: () => [],\r\n align: 'left',\r\n width: 'auto',\r\n teleport: true,\r\n },\r\n)\r\n\r\n// Generate unique IDs for accessibility\r\nconst { related } = useId({ prefix: 'dropdown', id: props.id })\r\nconst triggerId = computed(() => related('trigger'))\r\nconst menuId = computed(() => related('menu'))\r\n\r\nconst emit = defineEmits<{\r\n select: [item: DropdownItem]\r\n}>()\r\n\r\nconst triggerRef = ref<HTMLElement>()\r\nconst menuRef = ref<HTMLElement>()\r\n\r\nconst { isOpen, dropdownStyle, toggle, close } = useDropdown(triggerRef, menuRef, {\r\n teleport: props.teleport,\r\n align: props.align,\r\n})\r\n\r\nconst selectItem = (item: DropdownItem) => {\r\n if (item.disabled || item.divider) return\r\n emit('select', item)\r\n close()\r\n}\r\n\r\nconst widthClasses = {\r\n auto: 'w-auto min-w-40',\r\n full: 'w-full',\r\n sm: 'w-32',\r\n md: 'w-48',\r\n lg: 'w-64',\r\n}\r\n\r\nconst computedDropdownStyle = computed(() => {\r\n if (!props.teleport) return {}\r\n const { width: _, ...rest } = dropdownStyle.value\r\n return rest\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"relative inline-block\">\r\n <div\r\n ref=\"triggerRef\"\r\n @click=\"toggle\"\r\n >\r\n <slot name=\"trigger\">\r\n <button\r\n :id=\"triggerId\"\r\n type=\"button\"\r\n :aria-expanded=\"isOpen\"\r\n aria-haspopup=\"menu\"\r\n :aria-controls=\"menuId\"\r\n class=\"inline-flex items-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n >\r\n <slot name=\"trigger-label\">\r\n Options\r\n </slot>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n :class=\"['size-4 transition-transform', isOpen && 'rotate-180']\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </slot>\r\n </div>\r\n\r\n <Teleport\r\n to=\"body\"\r\n :disabled=\"!teleport\"\r\n >\r\n <Transition\r\n enter-active-class=\"transition ease-out duration-100\"\r\n enter-from-class=\"transform opacity-0 scale-95\"\r\n enter-to-class=\"transform opacity-100 scale-100\"\r\n leave-active-class=\"transition ease-in duration-75\"\r\n leave-from-class=\"transform opacity-100 scale-100\"\r\n leave-to-class=\"transform opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n :id=\"menuId\"\r\n ref=\"menuRef\"\r\n role=\"menu\"\r\n :aria-labelledby=\"triggerId\"\r\n :style=\"computedDropdownStyle\"\r\n :class=\"[\r\n 'z-9999 rounded-lg border border-gray-200 bg-white py-1 shadow-lg dark:border-gray-700 dark:bg-gray-800',\r\n widthClasses[width],\r\n !teleport && (align === 'right' ? 'absolute mt-2 right-0' : 'absolute mt-2 left-0'),\r\n ]\"\r\n >\r\n <!-- Custom content via default slot -->\r\n <slot :close=\"close\">\r\n <!-- Default items rendering -->\r\n <template\r\n v-for=\"item in items\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n v-if=\"item.divider\"\r\n role=\"separator\"\r\n class=\"my-1 border-t border-gray-200 dark:border-gray-700\"\r\n />\r\n <button\r\n v-else\r\n type=\"button\"\r\n role=\"menuitem\"\r\n :disabled=\"item.disabled\"\r\n :class=\"[\r\n 'flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors',\r\n item.disabled\r\n ? 'cursor-not-allowed opacity-50'\r\n : item.danger\r\n ? 'text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700',\r\n ]\"\r\n @click=\"selectItem(item)\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n aria-hidden=\"true\"\r\n />\r\n {{ item.label }}\r\n </button>\r\n </template>\r\n </slot>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n"],"names":["useSlots","ref","useDropdown","computed","resolveComponent","_createElementBlock","_unref","_createBlock","_resolveDynamicComponent","_mergeProps","_createElementVNode","_hoisted_1","_createVNode","Icon","_normalizeClass","_openBlock","_hoisted_2","_Transition","_toDisplayString","_hoisted_3","_renderSlot","_Fragment","_Teleport","_hoisted_4","useId","_renderList"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { _ as _sfc_main$o, u as useBreakpoints } from "./index-SNefWfX0.js";
3
3
  import { a as _sfc_main$m, _ as _sfc_main$n, b as _sfc_main$u } from "./ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js";
4
4
  import { e as _sfc_main$p, d as _sfc_main$q, c as _sfc_main$r, b as _sfc_main$s, a as _sfc_main$t } from "./BadgeType.vue_vue_type_script_setup_true_lang-tHRMWBb-.js";
5
5
  import { Icon } from "@iconify/vue";
6
- import { u as useDropdown } from "./useDropdown-iVu14E6s.js";
6
+ import { u as useDropdown } from "./useDropdown-De0cKI83.js";
7
7
  import { u as useId } from "./useId-xeHj7rkg.js";
8
8
  import { u as useDarkMode } from "./useDarkMode-Cl5QWTlC.js";
9
9
  const _hoisted_1$h = {
@@ -2300,4 +2300,4 @@ export {
2300
2300
  _sfc_main$1 as t,
2301
2301
  _sfc_main as u
2302
2302
  };
2303
- //# sourceMappingURL=FilterTabs.vue_vue_type_script_setup_true_lang-DzLwUVCW.js.map
2303
+ //# sourceMappingURL=FilterTabs.vue_vue_type_script_setup_true_lang-CcOgc2Y_.js.map