cisse-vue-ui 0.5.22 → 0.5.23

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 (105) hide show
  1. package/dist/{Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js → Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js} +13 -4
  2. package/dist/Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js.map +1 -0
  3. package/dist/{Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs → Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs} +13 -4
  4. package/dist/Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs.map +1 -0
  5. package/dist/{Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs → Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs} +233 -101
  6. package/dist/Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs.map +1 -0
  7. package/dist/{Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js → Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js} +234 -102
  8. package/dist/Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js.map +1 -0
  9. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs} +76 -29
  10. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs.map +1 -0
  11. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js} +77 -30
  12. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js.map +1 -0
  13. package/dist/{DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs → DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs} +76 -44
  14. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs.map +1 -0
  15. package/dist/{DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js → DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js} +76 -44
  16. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js.map +1 -0
  17. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs → Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs} +32 -15
  18. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs.map +1 -0
  19. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js → Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js} +32 -15
  20. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js.map +1 -0
  21. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs → PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs} +2 -2
  22. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs.map → PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs.map} +1 -1
  23. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js → PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js} +2 -2
  24. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js.map → PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js.map} +1 -1
  25. package/dist/components/core/AccordionItem.vue.d.ts +2 -0
  26. package/dist/components/core/Dropdown.vue.d.ts +2 -0
  27. package/dist/components/core/Popover.vue.d.ts +2 -0
  28. package/dist/components/core/Tooltip.vue.d.ts +2 -0
  29. package/dist/components/core/index.cjs +3 -3
  30. package/dist/components/core/index.js +3 -3
  31. package/dist/components/core/index.test.d.ts +1 -0
  32. package/dist/components/feedback/LoadingSpinner.vue.d.ts +6 -1
  33. package/dist/components/feedback/Modal.vue.d.ts +8 -2
  34. package/dist/components/feedback/index.cjs +2 -2
  35. package/dist/components/feedback/index.js +2 -2
  36. package/dist/components/feedback/index.test.d.ts +1 -0
  37. package/dist/components/form/Checkbox.vue.d.ts +2 -0
  38. package/dist/components/form/DatePicker.vue.d.ts +2 -0
  39. package/dist/components/form/FormHelp.vue.d.ts +2 -0
  40. package/dist/components/form/Switch.vue.d.ts +2 -0
  41. package/dist/components/form/index.cjs +2 -2
  42. package/dist/components/form/index.js +2 -2
  43. package/dist/components/form/index.test.d.ts +1 -0
  44. package/dist/components/index.cjs +7 -7
  45. package/dist/components/index.js +7 -7
  46. package/dist/components/index.test.d.ts +1 -0
  47. package/dist/components/layout/index.cjs +1 -1
  48. package/dist/components/layout/index.js +1 -1
  49. package/dist/components/layout/index.test.d.ts +1 -0
  50. package/dist/components/type/index.test.d.ts +1 -0
  51. package/dist/composables/index.cjs +6 -0
  52. package/dist/composables/index.cjs.map +1 -1
  53. package/dist/composables/index.d.ts +2 -0
  54. package/dist/composables/index.js +6 -0
  55. package/dist/composables/index.js.map +1 -1
  56. package/dist/composables/index.test.d.ts +1 -0
  57. package/dist/composables/useDarkMode.test.d.ts +1 -0
  58. package/dist/composables/useDropdown.test.d.ts +1 -0
  59. package/dist/composables/useExportCSV.test.d.ts +1 -0
  60. package/dist/composables/useFocusTrap.d.ts +41 -0
  61. package/dist/composables/useFocusTrap.test.d.ts +1 -0
  62. package/dist/composables/useId.d.ts +42 -0
  63. package/dist/composables/useId.test.d.ts +1 -0
  64. package/dist/composables/useModal.d.ts +1 -1
  65. package/dist/composables/useModal.test.d.ts +1 -0
  66. package/dist/{index-DZYqrXV0.js → index-BMoLBt6A.js} +8 -8
  67. package/dist/index-BMoLBt6A.js.map +1 -0
  68. package/dist/{index-Dghdw1yo.js → index-CJwlO351.js} +18 -9
  69. package/dist/index-CJwlO351.js.map +1 -0
  70. package/dist/{index-D7HVSFi2.cjs → index-CUNU12xk.cjs} +17 -8
  71. package/dist/index-CUNU12xk.cjs.map +1 -0
  72. package/dist/{index-DjEv91o4.cjs → index-DwFvFW-3.cjs} +8 -8
  73. package/dist/index-DwFvFW-3.cjs.map +1 -0
  74. package/dist/index.cjs +14 -8
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.js +14 -8
  77. package/dist/index.js.map +1 -1
  78. package/dist/index.test.d.ts +1 -0
  79. package/dist/types/form.d.ts +4 -0
  80. package/dist/types/index.test.d.ts +1 -0
  81. package/dist/useFocusTrap-AnlJsihM.js +120 -0
  82. package/dist/useFocusTrap-AnlJsihM.js.map +1 -0
  83. package/dist/useFocusTrap-kcxO8AeU.cjs +119 -0
  84. package/dist/useFocusTrap-kcxO8AeU.cjs.map +1 -0
  85. package/dist/useId-nxrBaIC9.cjs +25 -0
  86. package/dist/useId-nxrBaIC9.cjs.map +1 -0
  87. package/dist/useId-xeHj7rkg.js +26 -0
  88. package/dist/useId-xeHj7rkg.js.map +1 -0
  89. package/dist/useToast-Bk60GArg.cjs.map +1 -1
  90. package/dist/useToast-ina5g3mj.js.map +1 -1
  91. package/package.json +9 -8
  92. package/dist/Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js.map +0 -1
  93. package/dist/Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs.map +0 -1
  94. package/dist/Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js.map +0 -1
  95. package/dist/Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs.map +0 -1
  96. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js.map +0 -1
  97. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs.map +0 -1
  98. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js.map +0 -1
  99. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs.map +0 -1
  100. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js.map +0 -1
  101. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs.map +0 -1
  102. package/dist/index-D7HVSFi2.cjs.map +0 -1
  103. package/dist/index-DZYqrXV0.js.map +0 -1
  104. package/dist/index-Dghdw1yo.js.map +0 -1
  105. package/dist/index-DjEv91o4.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs","sources":["../src/components/layout/BaseLayout.vue","../src/components/layout/PageLayout.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { ref, computed, resolveComponent } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport MenuItem from '@/components/core/MenuItem.vue'\r\nimport Dropdown from '@/components/core/Dropdown.vue'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nexport interface UserMenuItem {\r\n label: string\r\n icon?: string\r\n link?: string\r\n action?: () => void\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Menu items for the sidebar */\r\n menuItems?: MenuItemProps[]\r\n /** App/brand name displayed in sidebar */\r\n appName?: string\r\n /** App icon (iconify icon name) */\r\n appIcon?: string\r\n /** Whether sidebar is open (v-model:sidebarOpen) */\r\n sidebarOpen?: boolean\r\n /** Whether dark mode is enabled (v-model:dark) */\r\n dark?: boolean\r\n /** Show dark mode toggle in header */\r\n showDarkToggle?: boolean\r\n /** Primary color class for sidebar background */\r\n sidebarClass?: string\r\n /** Current route path for menu active state (pass useRoute().path) */\r\n currentPath?: string\r\n /** User display name */\r\n userName?: string\r\n /** User avatar (initials or image URL) */\r\n userAvatar?: string\r\n /** User menu items (dropdown) */\r\n userMenuItems?: UserMenuItem[]\r\n }>(),\r\n {\r\n menuItems: () => [],\r\n appName: 'App',\r\n appIcon: 'lucide:box',\r\n sidebarOpen: true,\r\n dark: false,\r\n showDarkToggle: true,\r\n sidebarClass: 'bg-[#172b4c] dark:bg-slate-950',\r\n currentPath: undefined,\r\n userName: undefined,\r\n userAvatar: undefined,\r\n userMenuItems: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:sidebarOpen': [value: boolean]\r\n 'update:dark': [value: boolean]\r\n}>()\r\n\r\nconst internalSidebarOpen = ref(props.sidebarOpen)\r\nconst internalDark = ref(props.dark)\r\n\r\nconst sidebarOpenModel = computed({\r\n get: () => props.sidebarOpen ?? internalSidebarOpen.value,\r\n set: (value: boolean) => {\r\n internalSidebarOpen.value = value\r\n emit('update:sidebarOpen', value)\r\n },\r\n})\r\n\r\nconst darkModel = computed({\r\n get: () => props.dark ?? internalDark.value,\r\n set: (value: boolean) => {\r\n internalDark.value = value\r\n emit('update:dark', value)\r\n },\r\n})\r\n\r\nconst toggleSidebar = () => {\r\n sidebarOpenModel.value = !sidebarOpenModel.value\r\n}\r\n\r\nconst toggleDark = () => {\r\n darkModel.value = !darkModel.value\r\n}\r\n\r\n// Try to resolve RouterView\r\nconst routerViewComponent = computed(() => {\r\n try {\r\n const RouterView = resolveComponent('RouterView')\r\n if (typeof RouterView !== 'string') {\r\n return RouterView\r\n }\r\n } catch {\r\n // RouterView not available\r\n }\r\n return null\r\n})\r\n\r\n// Try to resolve RouterLink\r\nconst routerLinkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (routerLinkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n\r\nconst handleUserMenuClick = (item: UserMenuItem) => {\r\n if (item.action) {\r\n item.action()\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"font-inter relative flex h-dvh overflow-hidden bg-gray-100 dark:bg-slate-900\">\r\n <!-- Backdrop for mobile -->\r\n <div\r\n v-if=\"sidebarOpenModel\"\r\n class=\"absolute z-40 h-full w-full bg-slate-950/20 lg:hidden dark:bg-white/20\"\r\n @click=\"sidebarOpenModel = false\"\r\n />\r\n\r\n <!-- Sidebar -->\r\n <aside\r\n :class=\"[\r\n sidebarOpenModel ? 'lg:w-60' : '-translate-x-76 lg:w-16 lg:translate-x-0',\r\n sidebarClass,\r\n ]\"\r\n class=\"@container absolute z-50 flex h-full w-76 flex-col justify-between gap-10 transition-all duration-1000 ease-in-out lg:relative\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div class=\"flex h-16 items-center px-3\">\r\n <div class=\"flex flex-1 items-center justify-center gap-3\">\r\n <slot name=\"logo\">\r\n <div\r\n class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-lg bg-white/20\"\r\n >\r\n <Icon\r\n class=\"size-5 text-white\"\r\n :icon=\"appIcon\"\r\n />\r\n </div>\r\n <span\r\n :class=\"sidebarOpenModel ? 'block' : 'hidden'\"\r\n class=\"font-outfit flex-1 text-lg font-semibold text-white\"\r\n >\r\n {{ appName }}\r\n </span>\r\n </slot>\r\n </div>\r\n\r\n <button\r\n class=\"rounded-lg bg-white/10 p-1 transition hover:bg-white/20 lg:hidden\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-white\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Menu Items -->\r\n <div\r\n :class=\"sidebarOpenModel ? 'items-start' : 'items-center'\"\r\n class=\"flex flex-1 flex-col gap-8 px-2 lg:justify-center\"\r\n >\r\n <slot\r\n name=\"menu\"\r\n :current-path=\"currentPath\"\r\n >\r\n <MenuItem\r\n v-for=\"(item, index) in menuItems\"\r\n :key=\"index\"\r\n :menu-item=\"item\"\r\n :expanded=\"sidebarOpenModel\"\r\n :current-path=\"currentPath\"\r\n />\r\n </slot>\r\n </div>\r\n\r\n <!-- Sidebar Footer -->\r\n <div class=\"flex flex-col gap-3 px-3 pb-3\">\r\n <slot name=\"sidebar-footer\" />\r\n </div>\r\n </aside>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"flex flex-1 flex-col min-w-0\">\r\n <!-- Header -->\r\n <header\r\n class=\"flex h-16 items-center justify-between border-b border-slate-200 bg-white px-4 dark:border-slate-800 dark:bg-slate-950\"\r\n >\r\n <div>\r\n <button\r\n class=\"rounded-lg bg-gray-100 p-1 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-gray-900 hover:text-gray-800 dark:text-gray-100\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <div class=\"flex-1\">\r\n <slot name=\"header-center\" />\r\n </div>\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <slot name=\"header-actions\" />\r\n\r\n <button\r\n v-if=\"showDarkToggle\"\r\n class=\"flex items-center justify-center rounded-lg bg-gray-100 p-2 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleDark\"\r\n >\r\n <Icon\r\n :icon=\"darkModel ? 'lucide:sun' : 'lucide:moon'\"\r\n class=\"size-5 text-gray-900 dark:text-gray-100\"\r\n />\r\n </button>\r\n\r\n <!-- User Menu -->\r\n <Dropdown\r\n v-if=\"userName || userAvatar\"\r\n align=\"right\"\r\n >\r\n <template #trigger>\r\n <button\r\n class=\"flex items-center gap-2 rounded-lg p-1.5 transition hover:bg-gray-100 dark:hover:bg-gray-800\"\r\n >\r\n <div\r\n class=\"flex size-8 items-center justify-center rounded-full bg-primary text-sm font-medium text-white\"\r\n >\r\n {{ userAvatar || '?' }}\r\n </div>\r\n <span class=\"hidden text-sm font-medium text-gray-700 dark:text-gray-300 md:block\">\r\n {{ userName }}\r\n </span>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n class=\"size-4 text-gray-500\"\r\n />\r\n </button>\r\n </template>\r\n\r\n <template #default=\"{ close }\">\r\n <div class=\"min-w-48 py-1\">\r\n <component\r\n :is=\"item.link ? routerLinkComponent : 'button'\"\r\n v-for=\"item in userMenuItems\"\r\n :key=\"item.label\"\r\n v-bind=\"item.link ? getLinkProps(item.link) : {}\"\r\n class=\"flex w-full items-center gap-2 px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800\"\r\n @click=\"handleUserMenuClick(item); close()\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n />\r\n {{ item.label }}\r\n </component>\r\n </div>\r\n </template>\r\n </Dropdown>\r\n </div>\r\n </header>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex flex-1 flex-col overflow-y-auto overflow-x-hidden\">\r\n <main class=\"container mx-auto flex flex-1 flex-col gap-5 p-5 max-w-full\">\r\n <slot>\r\n <component\r\n :is=\"routerViewComponent\"\r\n v-if=\"routerViewComponent\"\r\n />\r\n </slot>\r\n </main>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent } from 'vue'\r\n\r\nexport interface PageBreadcrumb {\r\n label: string\r\n link: string\r\n}\r\n\r\ndefineProps<{\r\n /** Page title */\r\n title?: string\r\n /** Page description */\r\n description?: string\r\n /** Breadcrumb navigation items */\r\n breadcrumbs?: PageBreadcrumb[]\r\n}>()\r\n\r\n// Try to resolve RouterLink\r\nconst linkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (linkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Breadcrumbs -->\r\n <nav\r\n v-if=\"breadcrumbs && breadcrumbs.length > 0\"\r\n aria-label=\"Breadcrumb\"\r\n >\r\n <ol class=\"flex items-center\">\r\n <li\r\n v-for=\"(breadcrumb, index) in breadcrumbs\"\r\n :key=\"index\"\r\n class=\"flex items-center\"\r\n >\r\n <span\r\n v-if=\"index > 0\"\r\n class=\"mx-3 text-sm font-semibold text-gray-400 dark:text-gray-600\"\r\n >\r\n /\r\n </span>\r\n\r\n <slot\r\n name=\"breadcrumb\"\r\n :breadcrumb=\"breadcrumb\"\r\n :index=\"index\"\r\n :is-last=\"index === breadcrumbs.length - 1\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n v-bind=\"getLinkProps(breadcrumb.link)\"\r\n :class=\"[\r\n 'text-sm transition-colors',\r\n index < breadcrumbs.length - 1\r\n ? 'font-semibold text-gray-900 hover:text-primary/90 hover:underline dark:text-gray-100'\r\n : 'text-gray-400 dark:text-gray-600',\r\n ]\"\r\n >\r\n {{ breadcrumb.label }}\r\n </component>\r\n </slot>\r\n </li>\r\n </ol>\r\n </nav>\r\n\r\n <!-- Page Header -->\r\n <div class=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\r\n <div class=\"flex flex-col gap-1 min-w-0 flex-1\">\r\n <h1\r\n v-if=\"title\"\r\n class=\"text-2xl font-bold text-gray-900 dark:text-gray-100 truncate\"\r\n >\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </h1>\r\n\r\n <p\r\n v-if=\"description\"\r\n class=\"text-sm text-gray-600 dark:text-gray-400\"\r\n >\r\n <slot name=\"description\">\r\n {{ description }}\r\n </slot>\r\n </p>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 flex-wrap flex-shrink-0\">\r\n <slot name=\"actions\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex-1\">\r\n <slot />\r\n </div>\r\n </div>\r\n</template>\r\n"],"names":["ref","computed","resolveComponent","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_renderSlot","_hoisted_4","_createVNode","_unref","Icon","_Fragment","_renderList","_createBlock","MenuItem","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","Dropdown","_hoisted_10","_toDisplayString","_withCtx","_resolveDynamicComponent","_mergeProps","_createTextVNode"],"mappings":"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"}
1
+ {"version":3,"file":"PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs","sources":["../src/components/layout/BaseLayout.vue","../src/components/layout/PageLayout.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { ref, computed, resolveComponent } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport MenuItem from '@/components/core/MenuItem.vue'\r\nimport Dropdown from '@/components/core/Dropdown.vue'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nexport interface UserMenuItem {\r\n label: string\r\n icon?: string\r\n link?: string\r\n action?: () => void\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Menu items for the sidebar */\r\n menuItems?: MenuItemProps[]\r\n /** App/brand name displayed in sidebar */\r\n appName?: string\r\n /** App icon (iconify icon name) */\r\n appIcon?: string\r\n /** Whether sidebar is open (v-model:sidebarOpen) */\r\n sidebarOpen?: boolean\r\n /** Whether dark mode is enabled (v-model:dark) */\r\n dark?: boolean\r\n /** Show dark mode toggle in header */\r\n showDarkToggle?: boolean\r\n /** Primary color class for sidebar background */\r\n sidebarClass?: string\r\n /** Current route path for menu active state (pass useRoute().path) */\r\n currentPath?: string\r\n /** User display name */\r\n userName?: string\r\n /** User avatar (initials or image URL) */\r\n userAvatar?: string\r\n /** User menu items (dropdown) */\r\n userMenuItems?: UserMenuItem[]\r\n }>(),\r\n {\r\n menuItems: () => [],\r\n appName: 'App',\r\n appIcon: 'lucide:box',\r\n sidebarOpen: true,\r\n dark: false,\r\n showDarkToggle: true,\r\n sidebarClass: 'bg-[#172b4c] dark:bg-slate-950',\r\n currentPath: undefined,\r\n userName: undefined,\r\n userAvatar: undefined,\r\n userMenuItems: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:sidebarOpen': [value: boolean]\r\n 'update:dark': [value: boolean]\r\n}>()\r\n\r\nconst internalSidebarOpen = ref(props.sidebarOpen)\r\nconst internalDark = ref(props.dark)\r\n\r\nconst sidebarOpenModel = computed({\r\n get: () => props.sidebarOpen ?? internalSidebarOpen.value,\r\n set: (value: boolean) => {\r\n internalSidebarOpen.value = value\r\n emit('update:sidebarOpen', value)\r\n },\r\n})\r\n\r\nconst darkModel = computed({\r\n get: () => props.dark ?? internalDark.value,\r\n set: (value: boolean) => {\r\n internalDark.value = value\r\n emit('update:dark', value)\r\n },\r\n})\r\n\r\nconst toggleSidebar = () => {\r\n sidebarOpenModel.value = !sidebarOpenModel.value\r\n}\r\n\r\nconst toggleDark = () => {\r\n darkModel.value = !darkModel.value\r\n}\r\n\r\n// Try to resolve RouterView\r\nconst routerViewComponent = computed(() => {\r\n try {\r\n const RouterView = resolveComponent('RouterView')\r\n if (typeof RouterView !== 'string') {\r\n return RouterView\r\n }\r\n } catch {\r\n // RouterView not available\r\n }\r\n return null\r\n})\r\n\r\n// Try to resolve RouterLink\r\nconst routerLinkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (routerLinkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n\r\nconst handleUserMenuClick = (item: UserMenuItem) => {\r\n if (item.action) {\r\n item.action()\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"font-inter relative flex h-dvh overflow-hidden bg-gray-100 dark:bg-slate-900\">\r\n <!-- Backdrop for mobile -->\r\n <div\r\n v-if=\"sidebarOpenModel\"\r\n class=\"absolute z-40 h-full w-full bg-slate-950/20 lg:hidden dark:bg-white/20\"\r\n @click=\"sidebarOpenModel = false\"\r\n />\r\n\r\n <!-- Sidebar -->\r\n <aside\r\n :class=\"[\r\n sidebarOpenModel ? 'lg:w-60' : '-translate-x-76 lg:w-16 lg:translate-x-0',\r\n sidebarClass,\r\n ]\"\r\n class=\"@container absolute z-50 flex h-full w-76 flex-col justify-between gap-10 transition-all duration-1000 ease-in-out lg:relative\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div class=\"flex h-16 items-center px-3\">\r\n <div class=\"flex flex-1 items-center justify-center gap-3\">\r\n <slot name=\"logo\">\r\n <div\r\n class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-lg bg-white/20\"\r\n >\r\n <Icon\r\n class=\"size-5 text-white\"\r\n :icon=\"appIcon\"\r\n />\r\n </div>\r\n <span\r\n :class=\"sidebarOpenModel ? 'block' : 'hidden'\"\r\n class=\"font-outfit flex-1 text-lg font-semibold text-white\"\r\n >\r\n {{ appName }}\r\n </span>\r\n </slot>\r\n </div>\r\n\r\n <button\r\n class=\"rounded-lg bg-white/10 p-1 transition hover:bg-white/20 lg:hidden\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-white\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Menu Items -->\r\n <div\r\n :class=\"sidebarOpenModel ? 'items-start' : 'items-center'\"\r\n class=\"flex flex-1 flex-col gap-8 px-2 lg:justify-center\"\r\n >\r\n <slot\r\n name=\"menu\"\r\n :current-path=\"currentPath\"\r\n >\r\n <MenuItem\r\n v-for=\"(item, index) in menuItems\"\r\n :key=\"index\"\r\n :menu-item=\"item\"\r\n :expanded=\"sidebarOpenModel\"\r\n :current-path=\"currentPath\"\r\n />\r\n </slot>\r\n </div>\r\n\r\n <!-- Sidebar Footer -->\r\n <div class=\"flex flex-col gap-3 px-3 pb-3\">\r\n <slot name=\"sidebar-footer\" />\r\n </div>\r\n </aside>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"flex flex-1 flex-col min-w-0\">\r\n <!-- Header -->\r\n <header\r\n class=\"flex h-16 items-center justify-between border-b border-slate-200 bg-white px-4 dark:border-slate-800 dark:bg-slate-950\"\r\n >\r\n <div>\r\n <button\r\n class=\"rounded-lg bg-gray-100 p-1 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-gray-900 hover:text-gray-800 dark:text-gray-100\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <div class=\"flex-1\">\r\n <slot name=\"header-center\" />\r\n </div>\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <slot name=\"header-actions\" />\r\n\r\n <button\r\n v-if=\"showDarkToggle\"\r\n class=\"flex items-center justify-center rounded-lg bg-gray-100 p-2 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleDark\"\r\n >\r\n <Icon\r\n :icon=\"darkModel ? 'lucide:sun' : 'lucide:moon'\"\r\n class=\"size-5 text-gray-900 dark:text-gray-100\"\r\n />\r\n </button>\r\n\r\n <!-- User Menu -->\r\n <Dropdown\r\n v-if=\"userName || userAvatar\"\r\n align=\"right\"\r\n >\r\n <template #trigger>\r\n <button\r\n class=\"flex items-center gap-2 rounded-lg p-1.5 transition hover:bg-gray-100 dark:hover:bg-gray-800\"\r\n >\r\n <div\r\n class=\"flex size-8 items-center justify-center rounded-full bg-primary text-sm font-medium text-white\"\r\n >\r\n {{ userAvatar || '?' }}\r\n </div>\r\n <span class=\"hidden text-sm font-medium text-gray-700 dark:text-gray-300 md:block\">\r\n {{ userName }}\r\n </span>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n class=\"size-4 text-gray-500\"\r\n />\r\n </button>\r\n </template>\r\n\r\n <template #default=\"{ close }\">\r\n <div class=\"min-w-48 py-1\">\r\n <component\r\n :is=\"item.link ? routerLinkComponent : 'button'\"\r\n v-for=\"item in userMenuItems\"\r\n :key=\"item.label\"\r\n v-bind=\"item.link ? getLinkProps(item.link) : {}\"\r\n class=\"flex w-full items-center gap-2 px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800\"\r\n @click=\"handleUserMenuClick(item); close()\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n />\r\n {{ item.label }}\r\n </component>\r\n </div>\r\n </template>\r\n </Dropdown>\r\n </div>\r\n </header>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex flex-1 flex-col overflow-y-auto overflow-x-hidden\">\r\n <main class=\"container mx-auto flex flex-1 flex-col gap-5 p-5 max-w-full\">\r\n <slot>\r\n <component\r\n :is=\"routerViewComponent\"\r\n v-if=\"routerViewComponent\"\r\n />\r\n </slot>\r\n </main>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent } from 'vue'\r\n\r\nexport interface PageBreadcrumb {\r\n label: string\r\n link: string\r\n}\r\n\r\ndefineProps<{\r\n /** Page title */\r\n title?: string\r\n /** Page description */\r\n description?: string\r\n /** Breadcrumb navigation items */\r\n breadcrumbs?: PageBreadcrumb[]\r\n}>()\r\n\r\n// Try to resolve RouterLink\r\nconst linkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (linkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Breadcrumbs -->\r\n <nav\r\n v-if=\"breadcrumbs && breadcrumbs.length > 0\"\r\n aria-label=\"Breadcrumb\"\r\n >\r\n <ol class=\"flex items-center\">\r\n <li\r\n v-for=\"(breadcrumb, index) in breadcrumbs\"\r\n :key=\"index\"\r\n class=\"flex items-center\"\r\n >\r\n <span\r\n v-if=\"index > 0\"\r\n class=\"mx-3 text-sm font-semibold text-gray-400 dark:text-gray-600\"\r\n >\r\n /\r\n </span>\r\n\r\n <slot\r\n name=\"breadcrumb\"\r\n :breadcrumb=\"breadcrumb\"\r\n :index=\"index\"\r\n :is-last=\"index === breadcrumbs.length - 1\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n v-bind=\"getLinkProps(breadcrumb.link)\"\r\n :class=\"[\r\n 'text-sm transition-colors',\r\n index < breadcrumbs.length - 1\r\n ? 'font-semibold text-gray-900 hover:text-primary/90 hover:underline dark:text-gray-100'\r\n : 'text-gray-400 dark:text-gray-600',\r\n ]\"\r\n >\r\n {{ breadcrumb.label }}\r\n </component>\r\n </slot>\r\n </li>\r\n </ol>\r\n </nav>\r\n\r\n <!-- Page Header -->\r\n <div class=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\r\n <div class=\"flex flex-col gap-1 min-w-0 flex-1\">\r\n <h1\r\n v-if=\"title\"\r\n class=\"text-2xl font-bold text-gray-900 dark:text-gray-100 truncate\"\r\n >\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </h1>\r\n\r\n <p\r\n v-if=\"description\"\r\n class=\"text-sm text-gray-600 dark:text-gray-400\"\r\n >\r\n <slot name=\"description\">\r\n {{ description }}\r\n </slot>\r\n </p>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 flex-wrap flex-shrink-0\">\r\n <slot name=\"actions\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex-1\">\r\n <slot />\r\n </div>\r\n </div>\r\n</template>\r\n"],"names":["ref","computed","resolveComponent","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_renderSlot","_hoisted_4","_createVNode","_unref","Icon","_Fragment","_renderList","_createBlock","MenuItem","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","Dropdown","_hoisted_10","_toDisplayString","_withCtx","_resolveDynamicComponent","_mergeProps","_createTextVNode"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, ref, computed, resolveComponent, createElementBlock, openBlock, createCommentVNode, createElementVNode, normalizeClass, renderSlot, createVNode, unref, toDisplayString, Fragment, renderList, createBlock, withCtx, resolveDynamicComponent, mergeProps, createTextVNode } from "vue";
2
2
  import { Icon } from "@iconify/vue";
3
- import { _ as _sfc_main$2, a as _sfc_main$3 } from "./Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js";
3
+ import { _ as _sfc_main$2, a as _sfc_main$3 } from "./Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js";
4
4
  const _hoisted_1$1 = { class: "font-inter relative flex h-dvh overflow-hidden bg-gray-100 dark:bg-slate-900" };
5
5
  const _hoisted_2$1 = { class: "flex h-16 items-center px-3" };
6
6
  const _hoisted_3$1 = { class: "flex flex-1 items-center justify-center gap-3" };
@@ -331,4 +331,4 @@ export {
331
331
  _sfc_main$1 as _,
332
332
  _sfc_main as a
333
333
  };
334
- //# sourceMappingURL=PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js.map
334
+ //# sourceMappingURL=PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js","sources":["../src/components/layout/BaseLayout.vue","../src/components/layout/PageLayout.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { ref, computed, resolveComponent } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport MenuItem from '@/components/core/MenuItem.vue'\r\nimport Dropdown from '@/components/core/Dropdown.vue'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nexport interface UserMenuItem {\r\n label: string\r\n icon?: string\r\n link?: string\r\n action?: () => void\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Menu items for the sidebar */\r\n menuItems?: MenuItemProps[]\r\n /** App/brand name displayed in sidebar */\r\n appName?: string\r\n /** App icon (iconify icon name) */\r\n appIcon?: string\r\n /** Whether sidebar is open (v-model:sidebarOpen) */\r\n sidebarOpen?: boolean\r\n /** Whether dark mode is enabled (v-model:dark) */\r\n dark?: boolean\r\n /** Show dark mode toggle in header */\r\n showDarkToggle?: boolean\r\n /** Primary color class for sidebar background */\r\n sidebarClass?: string\r\n /** Current route path for menu active state (pass useRoute().path) */\r\n currentPath?: string\r\n /** User display name */\r\n userName?: string\r\n /** User avatar (initials or image URL) */\r\n userAvatar?: string\r\n /** User menu items (dropdown) */\r\n userMenuItems?: UserMenuItem[]\r\n }>(),\r\n {\r\n menuItems: () => [],\r\n appName: 'App',\r\n appIcon: 'lucide:box',\r\n sidebarOpen: true,\r\n dark: false,\r\n showDarkToggle: true,\r\n sidebarClass: 'bg-[#172b4c] dark:bg-slate-950',\r\n currentPath: undefined,\r\n userName: undefined,\r\n userAvatar: undefined,\r\n userMenuItems: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:sidebarOpen': [value: boolean]\r\n 'update:dark': [value: boolean]\r\n}>()\r\n\r\nconst internalSidebarOpen = ref(props.sidebarOpen)\r\nconst internalDark = ref(props.dark)\r\n\r\nconst sidebarOpenModel = computed({\r\n get: () => props.sidebarOpen ?? internalSidebarOpen.value,\r\n set: (value: boolean) => {\r\n internalSidebarOpen.value = value\r\n emit('update:sidebarOpen', value)\r\n },\r\n})\r\n\r\nconst darkModel = computed({\r\n get: () => props.dark ?? internalDark.value,\r\n set: (value: boolean) => {\r\n internalDark.value = value\r\n emit('update:dark', value)\r\n },\r\n})\r\n\r\nconst toggleSidebar = () => {\r\n sidebarOpenModel.value = !sidebarOpenModel.value\r\n}\r\n\r\nconst toggleDark = () => {\r\n darkModel.value = !darkModel.value\r\n}\r\n\r\n// Try to resolve RouterView\r\nconst routerViewComponent = computed(() => {\r\n try {\r\n const RouterView = resolveComponent('RouterView')\r\n if (typeof RouterView !== 'string') {\r\n return RouterView\r\n }\r\n } catch {\r\n // RouterView not available\r\n }\r\n return null\r\n})\r\n\r\n// Try to resolve RouterLink\r\nconst routerLinkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (routerLinkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n\r\nconst handleUserMenuClick = (item: UserMenuItem) => {\r\n if (item.action) {\r\n item.action()\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"font-inter relative flex h-dvh overflow-hidden bg-gray-100 dark:bg-slate-900\">\r\n <!-- Backdrop for mobile -->\r\n <div\r\n v-if=\"sidebarOpenModel\"\r\n class=\"absolute z-40 h-full w-full bg-slate-950/20 lg:hidden dark:bg-white/20\"\r\n @click=\"sidebarOpenModel = false\"\r\n />\r\n\r\n <!-- Sidebar -->\r\n <aside\r\n :class=\"[\r\n sidebarOpenModel ? 'lg:w-60' : '-translate-x-76 lg:w-16 lg:translate-x-0',\r\n sidebarClass,\r\n ]\"\r\n class=\"@container absolute z-50 flex h-full w-76 flex-col justify-between gap-10 transition-all duration-1000 ease-in-out lg:relative\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div class=\"flex h-16 items-center px-3\">\r\n <div class=\"flex flex-1 items-center justify-center gap-3\">\r\n <slot name=\"logo\">\r\n <div\r\n class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-lg bg-white/20\"\r\n >\r\n <Icon\r\n class=\"size-5 text-white\"\r\n :icon=\"appIcon\"\r\n />\r\n </div>\r\n <span\r\n :class=\"sidebarOpenModel ? 'block' : 'hidden'\"\r\n class=\"font-outfit flex-1 text-lg font-semibold text-white\"\r\n >\r\n {{ appName }}\r\n </span>\r\n </slot>\r\n </div>\r\n\r\n <button\r\n class=\"rounded-lg bg-white/10 p-1 transition hover:bg-white/20 lg:hidden\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-white\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Menu Items -->\r\n <div\r\n :class=\"sidebarOpenModel ? 'items-start' : 'items-center'\"\r\n class=\"flex flex-1 flex-col gap-8 px-2 lg:justify-center\"\r\n >\r\n <slot\r\n name=\"menu\"\r\n :current-path=\"currentPath\"\r\n >\r\n <MenuItem\r\n v-for=\"(item, index) in menuItems\"\r\n :key=\"index\"\r\n :menu-item=\"item\"\r\n :expanded=\"sidebarOpenModel\"\r\n :current-path=\"currentPath\"\r\n />\r\n </slot>\r\n </div>\r\n\r\n <!-- Sidebar Footer -->\r\n <div class=\"flex flex-col gap-3 px-3 pb-3\">\r\n <slot name=\"sidebar-footer\" />\r\n </div>\r\n </aside>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"flex flex-1 flex-col min-w-0\">\r\n <!-- Header -->\r\n <header\r\n class=\"flex h-16 items-center justify-between border-b border-slate-200 bg-white px-4 dark:border-slate-800 dark:bg-slate-950\"\r\n >\r\n <div>\r\n <button\r\n class=\"rounded-lg bg-gray-100 p-1 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-gray-900 hover:text-gray-800 dark:text-gray-100\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <div class=\"flex-1\">\r\n <slot name=\"header-center\" />\r\n </div>\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <slot name=\"header-actions\" />\r\n\r\n <button\r\n v-if=\"showDarkToggle\"\r\n class=\"flex items-center justify-center rounded-lg bg-gray-100 p-2 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleDark\"\r\n >\r\n <Icon\r\n :icon=\"darkModel ? 'lucide:sun' : 'lucide:moon'\"\r\n class=\"size-5 text-gray-900 dark:text-gray-100\"\r\n />\r\n </button>\r\n\r\n <!-- User Menu -->\r\n <Dropdown\r\n v-if=\"userName || userAvatar\"\r\n align=\"right\"\r\n >\r\n <template #trigger>\r\n <button\r\n class=\"flex items-center gap-2 rounded-lg p-1.5 transition hover:bg-gray-100 dark:hover:bg-gray-800\"\r\n >\r\n <div\r\n class=\"flex size-8 items-center justify-center rounded-full bg-primary text-sm font-medium text-white\"\r\n >\r\n {{ userAvatar || '?' }}\r\n </div>\r\n <span class=\"hidden text-sm font-medium text-gray-700 dark:text-gray-300 md:block\">\r\n {{ userName }}\r\n </span>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n class=\"size-4 text-gray-500\"\r\n />\r\n </button>\r\n </template>\r\n\r\n <template #default=\"{ close }\">\r\n <div class=\"min-w-48 py-1\">\r\n <component\r\n :is=\"item.link ? routerLinkComponent : 'button'\"\r\n v-for=\"item in userMenuItems\"\r\n :key=\"item.label\"\r\n v-bind=\"item.link ? getLinkProps(item.link) : {}\"\r\n class=\"flex w-full items-center gap-2 px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800\"\r\n @click=\"handleUserMenuClick(item); close()\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n />\r\n {{ item.label }}\r\n </component>\r\n </div>\r\n </template>\r\n </Dropdown>\r\n </div>\r\n </header>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex flex-1 flex-col overflow-y-auto overflow-x-hidden\">\r\n <main class=\"container mx-auto flex flex-1 flex-col gap-5 p-5 max-w-full\">\r\n <slot>\r\n <component\r\n :is=\"routerViewComponent\"\r\n v-if=\"routerViewComponent\"\r\n />\r\n </slot>\r\n </main>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent } from 'vue'\r\n\r\nexport interface PageBreadcrumb {\r\n label: string\r\n link: string\r\n}\r\n\r\ndefineProps<{\r\n /** Page title */\r\n title?: string\r\n /** Page description */\r\n description?: string\r\n /** Breadcrumb navigation items */\r\n breadcrumbs?: PageBreadcrumb[]\r\n}>()\r\n\r\n// Try to resolve RouterLink\r\nconst linkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (linkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Breadcrumbs -->\r\n <nav\r\n v-if=\"breadcrumbs && breadcrumbs.length > 0\"\r\n aria-label=\"Breadcrumb\"\r\n >\r\n <ol class=\"flex items-center\">\r\n <li\r\n v-for=\"(breadcrumb, index) in breadcrumbs\"\r\n :key=\"index\"\r\n class=\"flex items-center\"\r\n >\r\n <span\r\n v-if=\"index > 0\"\r\n class=\"mx-3 text-sm font-semibold text-gray-400 dark:text-gray-600\"\r\n >\r\n /\r\n </span>\r\n\r\n <slot\r\n name=\"breadcrumb\"\r\n :breadcrumb=\"breadcrumb\"\r\n :index=\"index\"\r\n :is-last=\"index === breadcrumbs.length - 1\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n v-bind=\"getLinkProps(breadcrumb.link)\"\r\n :class=\"[\r\n 'text-sm transition-colors',\r\n index < breadcrumbs.length - 1\r\n ? 'font-semibold text-gray-900 hover:text-primary/90 hover:underline dark:text-gray-100'\r\n : 'text-gray-400 dark:text-gray-600',\r\n ]\"\r\n >\r\n {{ breadcrumb.label }}\r\n </component>\r\n </slot>\r\n </li>\r\n </ol>\r\n </nav>\r\n\r\n <!-- Page Header -->\r\n <div class=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\r\n <div class=\"flex flex-col gap-1 min-w-0 flex-1\">\r\n <h1\r\n v-if=\"title\"\r\n class=\"text-2xl font-bold text-gray-900 dark:text-gray-100 truncate\"\r\n >\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </h1>\r\n\r\n <p\r\n v-if=\"description\"\r\n class=\"text-sm text-gray-600 dark:text-gray-400\"\r\n >\r\n <slot name=\"description\">\r\n {{ description }}\r\n </slot>\r\n </p>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 flex-wrap flex-shrink-0\">\r\n <slot name=\"actions\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex-1\">\r\n <slot />\r\n </div>\r\n </div>\r\n</template>\r\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_renderSlot","_hoisted_4","_createVNode","_unref","_Fragment","_renderList","_createBlock","MenuItem","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","Dropdown","_hoisted_10","_toDisplayString","_withCtx","_resolveDynamicComponent","_mergeProps","_createTextVNode"],"mappings":"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"}
1
+ {"version":3,"file":"PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js","sources":["../src/components/layout/BaseLayout.vue","../src/components/layout/PageLayout.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nimport { ref, computed, resolveComponent } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport MenuItem from '@/components/core/MenuItem.vue'\r\nimport Dropdown from '@/components/core/Dropdown.vue'\r\nimport type { MenuItemProps } from '@/types'\r\n\r\nexport interface UserMenuItem {\r\n label: string\r\n icon?: string\r\n link?: string\r\n action?: () => void\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Menu items for the sidebar */\r\n menuItems?: MenuItemProps[]\r\n /** App/brand name displayed in sidebar */\r\n appName?: string\r\n /** App icon (iconify icon name) */\r\n appIcon?: string\r\n /** Whether sidebar is open (v-model:sidebarOpen) */\r\n sidebarOpen?: boolean\r\n /** Whether dark mode is enabled (v-model:dark) */\r\n dark?: boolean\r\n /** Show dark mode toggle in header */\r\n showDarkToggle?: boolean\r\n /** Primary color class for sidebar background */\r\n sidebarClass?: string\r\n /** Current route path for menu active state (pass useRoute().path) */\r\n currentPath?: string\r\n /** User display name */\r\n userName?: string\r\n /** User avatar (initials or image URL) */\r\n userAvatar?: string\r\n /** User menu items (dropdown) */\r\n userMenuItems?: UserMenuItem[]\r\n }>(),\r\n {\r\n menuItems: () => [],\r\n appName: 'App',\r\n appIcon: 'lucide:box',\r\n sidebarOpen: true,\r\n dark: false,\r\n showDarkToggle: true,\r\n sidebarClass: 'bg-[#172b4c] dark:bg-slate-950',\r\n currentPath: undefined,\r\n userName: undefined,\r\n userAvatar: undefined,\r\n userMenuItems: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:sidebarOpen': [value: boolean]\r\n 'update:dark': [value: boolean]\r\n}>()\r\n\r\nconst internalSidebarOpen = ref(props.sidebarOpen)\r\nconst internalDark = ref(props.dark)\r\n\r\nconst sidebarOpenModel = computed({\r\n get: () => props.sidebarOpen ?? internalSidebarOpen.value,\r\n set: (value: boolean) => {\r\n internalSidebarOpen.value = value\r\n emit('update:sidebarOpen', value)\r\n },\r\n})\r\n\r\nconst darkModel = computed({\r\n get: () => props.dark ?? internalDark.value,\r\n set: (value: boolean) => {\r\n internalDark.value = value\r\n emit('update:dark', value)\r\n },\r\n})\r\n\r\nconst toggleSidebar = () => {\r\n sidebarOpenModel.value = !sidebarOpenModel.value\r\n}\r\n\r\nconst toggleDark = () => {\r\n darkModel.value = !darkModel.value\r\n}\r\n\r\n// Try to resolve RouterView\r\nconst routerViewComponent = computed(() => {\r\n try {\r\n const RouterView = resolveComponent('RouterView')\r\n if (typeof RouterView !== 'string') {\r\n return RouterView\r\n }\r\n } catch {\r\n // RouterView not available\r\n }\r\n return null\r\n})\r\n\r\n// Try to resolve RouterLink\r\nconst routerLinkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (routerLinkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n\r\nconst handleUserMenuClick = (item: UserMenuItem) => {\r\n if (item.action) {\r\n item.action()\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"font-inter relative flex h-dvh overflow-hidden bg-gray-100 dark:bg-slate-900\">\r\n <!-- Backdrop for mobile -->\r\n <div\r\n v-if=\"sidebarOpenModel\"\r\n class=\"absolute z-40 h-full w-full bg-slate-950/20 lg:hidden dark:bg-white/20\"\r\n @click=\"sidebarOpenModel = false\"\r\n />\r\n\r\n <!-- Sidebar -->\r\n <aside\r\n :class=\"[\r\n sidebarOpenModel ? 'lg:w-60' : '-translate-x-76 lg:w-16 lg:translate-x-0',\r\n sidebarClass,\r\n ]\"\r\n class=\"@container absolute z-50 flex h-full w-76 flex-col justify-between gap-10 transition-all duration-1000 ease-in-out lg:relative\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div class=\"flex h-16 items-center px-3\">\r\n <div class=\"flex flex-1 items-center justify-center gap-3\">\r\n <slot name=\"logo\">\r\n <div\r\n class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-lg bg-white/20\"\r\n >\r\n <Icon\r\n class=\"size-5 text-white\"\r\n :icon=\"appIcon\"\r\n />\r\n </div>\r\n <span\r\n :class=\"sidebarOpenModel ? 'block' : 'hidden'\"\r\n class=\"font-outfit flex-1 text-lg font-semibold text-white\"\r\n >\r\n {{ appName }}\r\n </span>\r\n </slot>\r\n </div>\r\n\r\n <button\r\n class=\"rounded-lg bg-white/10 p-1 transition hover:bg-white/20 lg:hidden\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-white\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Menu Items -->\r\n <div\r\n :class=\"sidebarOpenModel ? 'items-start' : 'items-center'\"\r\n class=\"flex flex-1 flex-col gap-8 px-2 lg:justify-center\"\r\n >\r\n <slot\r\n name=\"menu\"\r\n :current-path=\"currentPath\"\r\n >\r\n <MenuItem\r\n v-for=\"(item, index) in menuItems\"\r\n :key=\"index\"\r\n :menu-item=\"item\"\r\n :expanded=\"sidebarOpenModel\"\r\n :current-path=\"currentPath\"\r\n />\r\n </slot>\r\n </div>\r\n\r\n <!-- Sidebar Footer -->\r\n <div class=\"flex flex-col gap-3 px-3 pb-3\">\r\n <slot name=\"sidebar-footer\" />\r\n </div>\r\n </aside>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"flex flex-1 flex-col min-w-0\">\r\n <!-- Header -->\r\n <header\r\n class=\"flex h-16 items-center justify-between border-b border-slate-200 bg-white px-4 dark:border-slate-800 dark:bg-slate-950\"\r\n >\r\n <div>\r\n <button\r\n class=\"rounded-lg bg-gray-100 p-1 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleSidebar\"\r\n >\r\n <Icon\r\n class=\"size-6 text-gray-900 hover:text-gray-800 dark:text-gray-100\"\r\n icon=\"lucide:menu\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <div class=\"flex-1\">\r\n <slot name=\"header-center\" />\r\n </div>\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <slot name=\"header-actions\" />\r\n\r\n <button\r\n v-if=\"showDarkToggle\"\r\n class=\"flex items-center justify-center rounded-lg bg-gray-100 p-2 transition hover:bg-gray-200 dark:bg-gray-900 dark:hover:bg-gray-800\"\r\n @click=\"toggleDark\"\r\n >\r\n <Icon\r\n :icon=\"darkModel ? 'lucide:sun' : 'lucide:moon'\"\r\n class=\"size-5 text-gray-900 dark:text-gray-100\"\r\n />\r\n </button>\r\n\r\n <!-- User Menu -->\r\n <Dropdown\r\n v-if=\"userName || userAvatar\"\r\n align=\"right\"\r\n >\r\n <template #trigger>\r\n <button\r\n class=\"flex items-center gap-2 rounded-lg p-1.5 transition hover:bg-gray-100 dark:hover:bg-gray-800\"\r\n >\r\n <div\r\n class=\"flex size-8 items-center justify-center rounded-full bg-primary text-sm font-medium text-white\"\r\n >\r\n {{ userAvatar || '?' }}\r\n </div>\r\n <span class=\"hidden text-sm font-medium text-gray-700 dark:text-gray-300 md:block\">\r\n {{ userName }}\r\n </span>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n class=\"size-4 text-gray-500\"\r\n />\r\n </button>\r\n </template>\r\n\r\n <template #default=\"{ close }\">\r\n <div class=\"min-w-48 py-1\">\r\n <component\r\n :is=\"item.link ? routerLinkComponent : 'button'\"\r\n v-for=\"item in userMenuItems\"\r\n :key=\"item.label\"\r\n v-bind=\"item.link ? getLinkProps(item.link) : {}\"\r\n class=\"flex w-full items-center gap-2 px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800\"\r\n @click=\"handleUserMenuClick(item); close()\"\r\n >\r\n <Icon\r\n v-if=\"item.icon\"\r\n :icon=\"item.icon\"\r\n class=\"size-4\"\r\n />\r\n {{ item.label }}\r\n </component>\r\n </div>\r\n </template>\r\n </Dropdown>\r\n </div>\r\n </header>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex flex-1 flex-col overflow-y-auto overflow-x-hidden\">\r\n <main class=\"container mx-auto flex flex-1 flex-col gap-5 p-5 max-w-full\">\r\n <slot>\r\n <component\r\n :is=\"routerViewComponent\"\r\n v-if=\"routerViewComponent\"\r\n />\r\n </slot>\r\n </main>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed, resolveComponent } from 'vue'\r\n\r\nexport interface PageBreadcrumb {\r\n label: string\r\n link: string\r\n}\r\n\r\ndefineProps<{\r\n /** Page title */\r\n title?: string\r\n /** Page description */\r\n description?: string\r\n /** Breadcrumb navigation items */\r\n breadcrumbs?: PageBreadcrumb[]\r\n}>()\r\n\r\n// Try to resolve RouterLink\r\nconst linkComponent = computed(() => {\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 getLinkProps = (link: string) => {\r\n if (linkComponent.value === 'a') {\r\n return { href: link }\r\n }\r\n return { to: link }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Breadcrumbs -->\r\n <nav\r\n v-if=\"breadcrumbs && breadcrumbs.length > 0\"\r\n aria-label=\"Breadcrumb\"\r\n >\r\n <ol class=\"flex items-center\">\r\n <li\r\n v-for=\"(breadcrumb, index) in breadcrumbs\"\r\n :key=\"index\"\r\n class=\"flex items-center\"\r\n >\r\n <span\r\n v-if=\"index > 0\"\r\n class=\"mx-3 text-sm font-semibold text-gray-400 dark:text-gray-600\"\r\n >\r\n /\r\n </span>\r\n\r\n <slot\r\n name=\"breadcrumb\"\r\n :breadcrumb=\"breadcrumb\"\r\n :index=\"index\"\r\n :is-last=\"index === breadcrumbs.length - 1\"\r\n >\r\n <component\r\n :is=\"linkComponent\"\r\n v-bind=\"getLinkProps(breadcrumb.link)\"\r\n :class=\"[\r\n 'text-sm transition-colors',\r\n index < breadcrumbs.length - 1\r\n ? 'font-semibold text-gray-900 hover:text-primary/90 hover:underline dark:text-gray-100'\r\n : 'text-gray-400 dark:text-gray-600',\r\n ]\"\r\n >\r\n {{ breadcrumb.label }}\r\n </component>\r\n </slot>\r\n </li>\r\n </ol>\r\n </nav>\r\n\r\n <!-- Page Header -->\r\n <div class=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\r\n <div class=\"flex flex-col gap-1 min-w-0 flex-1\">\r\n <h1\r\n v-if=\"title\"\r\n class=\"text-2xl font-bold text-gray-900 dark:text-gray-100 truncate\"\r\n >\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </h1>\r\n\r\n <p\r\n v-if=\"description\"\r\n class=\"text-sm text-gray-600 dark:text-gray-400\"\r\n >\r\n <slot name=\"description\">\r\n {{ description }}\r\n </slot>\r\n </p>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 flex-wrap flex-shrink-0\">\r\n <slot name=\"actions\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Page Content -->\r\n <div class=\"flex-1\">\r\n <slot />\r\n </div>\r\n </div>\r\n</template>\r\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_renderSlot","_hoisted_4","_createVNode","_unref","_Fragment","_renderList","_createBlock","MenuItem","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","Dropdown","_hoisted_10","_toDisplayString","_withCtx","_resolveDynamicComponent","_mergeProps","_createTextVNode"],"mappings":"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"}
@@ -7,6 +7,8 @@ type __VLS_Props = {
7
7
  icon?: string;
8
8
  /** Disable this item */
9
9
  disabled?: boolean;
10
+ /** Custom ID for accessibility */
11
+ id?: string;
10
12
  };
11
13
  declare function __VLS_template(): {
12
14
  attrs: Partial<{}>;
@@ -15,6 +15,8 @@ type __VLS_Props = {
15
15
  width?: 'auto' | 'full' | 'sm' | 'md' | 'lg';
16
16
  /** Use teleport to body to avoid overflow clipping */
17
17
  teleport?: boolean;
18
+ /** Custom ID for accessibility */
19
+ id?: string;
18
20
  };
19
21
  declare function __VLS_template(): {
20
22
  attrs: Partial<{}>;
@@ -8,6 +8,8 @@ type __VLS_Props = {
8
8
  teleport?: boolean;
9
9
  /** Width of the popover */
10
10
  width?: 'auto' | 'sm' | 'md' | 'lg';
11
+ /** Custom ID for accessibility */
12
+ id?: string;
11
13
  };
12
14
  declare function __VLS_template(): {
13
15
  attrs: Partial<{}>;
@@ -8,6 +8,8 @@ type __VLS_Props = {
8
8
  delay?: number;
9
9
  /** Disable the tooltip */
10
10
  disabled?: boolean;
11
+ /** Custom ID for accessibility */
12
+ id?: string;
11
13
  };
12
14
  declare function __VLS_template(): {
13
15
  attrs: Partial<{}>;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const DarkModeToggle_vue_vue_type_script_setup_true_lang = require("../../DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs");
4
- const Dropdown_vue_vue_type_script_setup_true_lang = require("../../Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs");
3
+ const DarkModeToggle_vue_vue_type_script_setup_true_lang = require("../../DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs");
4
+ const Dropdown_vue_vue_type_script_setup_true_lang = require("../../Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs");
5
5
  const BadgeType_vue_vue_type_script_setup_true_lang = require("../../BadgeType.vue_vue_type_script_setup_true_lang-CJb63H1I.cjs");
6
- const Button_vue_vue_type_script_setup_true_lang = require("../../Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs");
6
+ const Button_vue_vue_type_script_setup_true_lang = require("../../Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs");
7
7
  exports.Accordion = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$15;
8
8
  exports.AccordionItem = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$16;
9
9
  exports.AutocompleteComponent = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$4;
@@ -1,7 +1,7 @@
1
- import { o, p, d, f, n, _, j, r, m, b, l, c, i, h, e, a, g, q, k } from "../../DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js";
2
- import { a as a2, _ as _2 } from "../../Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js";
1
+ import { o, p, d, f, n, _, j, r, m, b, l, c, i, h, e, a, g, q, k } from "../../DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js";
2
+ import { a as a2, _ as _2 } from "../../Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js";
3
3
  import { _ as _3 } from "../../BadgeType.vue_vue_type_script_setup_true_lang-CnB5eNEM.js";
4
- import { _ as _4 } from "../../Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js";
4
+ import { _ as _4 } from "../../Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js";
5
5
  export {
6
6
  o as Accordion,
7
7
  p as AccordionItem,
@@ -0,0 +1 @@
1
+ export {};
@@ -2,6 +2,11 @@ import { SpinnerSize } from '../../types';
2
2
  type __VLS_Props = {
3
3
  text?: string;
4
4
  size?: SpinnerSize;
5
+ /** Accessible label for screen readers (defaults to 'Loading' or text prop) */
6
+ ariaLabel?: string;
5
7
  };
6
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
8
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
9
+ size: SpinnerSize;
10
+ ariaLabel: string;
11
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
7
12
  export default _default;
@@ -7,6 +7,8 @@ type __VLS_Props = {
7
7
  closeButtonLabel?: string;
8
8
  /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */
9
9
  teleport?: string | false;
10
+ /** Custom ID for the modal (auto-generated if not provided) */
11
+ id?: string;
10
12
  };
11
13
  declare function __VLS_template(): {
12
14
  attrs: Partial<{}>;
@@ -16,7 +18,9 @@ declare function __VLS_template(): {
16
18
  default?(_: {}): any;
17
19
  footer?(_: {}): any;
18
20
  };
19
- refs: {};
21
+ refs: {
22
+ dialogRef: HTMLDivElement;
23
+ };
20
24
  rootEl: any;
21
25
  };
22
26
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
@@ -31,7 +35,9 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
31
35
  closeOnEscape: boolean;
32
36
  closeOnBackdrop: boolean;
33
37
  closeButtonLabel: string;
34
- }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
38
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
39
+ dialogRef: HTMLDivElement;
40
+ }, any>;
35
41
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
36
42
  export default _default;
37
43
  type __VLS_WithTemplateSlots<T, S> = T & {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const ConfirmDialog_vue_vue_type_script_setup_true_lang = require("../../ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs");
4
- const Button_vue_vue_type_script_setup_true_lang = require("../../Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs");
3
+ const ConfirmDialog_vue_vue_type_script_setup_true_lang = require("../../ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs");
4
+ const Button_vue_vue_type_script_setup_true_lang = require("../../Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs");
5
5
  exports.Alert = ConfirmDialog_vue_vue_type_script_setup_true_lang._sfc_main$5;
6
6
  exports.ConfirmDialog = ConfirmDialog_vue_vue_type_script_setup_true_lang._sfc_main$10;
7
7
  exports.EmptyState = ConfirmDialog_vue_vue_type_script_setup_true_lang._sfc_main$6;
@@ -1,5 +1,5 @@
1
- import { e, j, f, _, a, c, d, b, P, i, g, h } from "../../ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js";
2
- import { b as b2, c as c2, a as a2 } from "../../Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js";
1
+ import { e, j, f, _, a, c, d, b, P, i, g, h } from "../../ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js";
2
+ import { b as b2, c as c2, a as a2 } from "../../Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js";
3
3
  export {
4
4
  e as Alert,
5
5
  b2 as CardSkeleton,
@@ -0,0 +1 @@
1
+ export {};
@@ -9,6 +9,8 @@ type __VLS_Props = {
9
9
  disabled?: boolean;
10
10
  /** Indeterminate state */
11
11
  indeterminate?: boolean;
12
+ /** Custom ID for the checkbox */
13
+ id?: string;
12
14
  };
13
15
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
14
16
  "update:modelValue": (value: boolean) => any;
@@ -13,6 +13,8 @@ type __VLS_Props = {
13
13
  maxDate?: Date;
14
14
  /** Use teleport */
15
15
  teleport?: boolean;
16
+ /** Custom ID for accessibility */
17
+ id?: string;
16
18
  };
17
19
  type __VLS_PublicProps = {
18
20
  modelValue?: Date | null;
@@ -1,4 +1,6 @@
1
1
  type __VLS_Props = {
2
+ /** ID for aria-describedby linking */
3
+ id?: string;
2
4
  error?: boolean;
3
5
  text?: string;
4
6
  };
@@ -9,6 +9,8 @@ type __VLS_Props = {
9
9
  disabled?: boolean;
10
10
  /** Size variant */
11
11
  size?: 'sm' | 'md' | 'lg';
12
+ /** Custom ID for the switch */
13
+ id?: string;
12
14
  };
13
15
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
14
16
  "update:modelValue": (value: boolean) => any;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Combobox_vue_vue_type_script_setup_true_lang = require("../../Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs");
4
- const index = require("../../index-D7HVSFi2.cjs");
3
+ const Combobox_vue_vue_type_script_setup_true_lang = require("../../Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs");
4
+ const index = require("../../index-CUNU12xk.cjs");
5
5
  exports.ColorPicker = Combobox_vue_vue_type_script_setup_true_lang._sfc_main$10;
6
6
  exports.Combobox = Combobox_vue_vue_type_script_setup_true_lang._sfc_main$12;
7
7
  exports.DatePicker = Combobox_vue_vue_type_script_setup_true_lang._sfc_main$7;
@@ -1,5 +1,5 @@
1
- import { j, l, g, h, d, a, b, _, c, k, i, e, S, f } from "../../Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js";
2
- import { _ as _2 } from "../../index-Dghdw1yo.js";
1
+ import { j, l, g, h, d, a, b, _, c, k, i, e, S, f } from "../../Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js";
2
+ import { _ as _2 } from "../../index-CJwlO351.js";
3
3
  export {
4
4
  _2 as Checkbox,
5
5
  j as ColorPicker,
@@ -0,0 +1 @@
1
+ export {};
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const DarkModeToggle_vue_vue_type_script_setup_true_lang = require("../DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs");
4
- const Dropdown_vue_vue_type_script_setup_true_lang = require("../Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs");
3
+ const DarkModeToggle_vue_vue_type_script_setup_true_lang = require("../DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs");
4
+ const Dropdown_vue_vue_type_script_setup_true_lang = require("../Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs");
5
5
  const BadgeType_vue_vue_type_script_setup_true_lang = require("../BadgeType.vue_vue_type_script_setup_true_lang-CJb63H1I.cjs");
6
- const Button_vue_vue_type_script_setup_true_lang = require("../Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs");
7
- const Combobox_vue_vue_type_script_setup_true_lang = require("../Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs");
8
- const index = require("../index-D7HVSFi2.cjs");
9
- const ConfirmDialog_vue_vue_type_script_setup_true_lang = require("../ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs");
10
- const PageLayout_vue_vue_type_script_setup_true_lang = require("../PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs");
6
+ const Button_vue_vue_type_script_setup_true_lang = require("../Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs");
7
+ const Combobox_vue_vue_type_script_setup_true_lang = require("../Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs");
8
+ const index = require("../index-CUNU12xk.cjs");
9
+ const ConfirmDialog_vue_vue_type_script_setup_true_lang = require("../ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs");
10
+ const PageLayout_vue_vue_type_script_setup_true_lang = require("../PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs");
11
11
  exports.Accordion = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$15;
12
12
  exports.AccordionItem = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$16;
13
13
  exports.AutocompleteComponent = DarkModeToggle_vue_vue_type_script_setup_true_lang._sfc_main$4;
@@ -1,11 +1,11 @@
1
- import { o, p, d, f, n, _, j, r, m, b, l, c, i, h, e, a, g, q, k } from "../DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js";
2
- import { a as a2, _ as _2 } from "../Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js";
1
+ import { o, p, d, f, n, _, j, r, m, b, l, c, i, h, e, a, g, q, k } from "../DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js";
2
+ import { a as a2, _ as _2 } from "../Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js";
3
3
  import { e as e2, d as d2, c as c2, b as b2, _ as _3, a as a3 } from "../BadgeType.vue_vue_type_script_setup_true_lang-CnB5eNEM.js";
4
- import { _ as _4, b as b3, c as c3, a as a4 } from "../Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js";
5
- import { j as j2, l as l2, g as g2, h as h2, d as d3, a as a5, b as b4, _ as _5, c as c4, k as k2, i as i2, e as e3, S, f as f2 } from "../Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js";
6
- import { _ as _6 } from "../index-Dghdw1yo.js";
7
- import { e as e4, j as j3, f as f3, _ as _7, a as a6, c as c5, d as d4, b as b5, P, i as i3, g as g3, h as h3 } from "../ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js";
8
- import { _ as _8, a as a7 } from "../PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js";
4
+ import { _ as _4, b as b3, c as c3, a as a4 } from "../Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js";
5
+ import { j as j2, l as l2, g as g2, h as h2, d as d3, a as a5, b as b4, _ as _5, c as c4, k as k2, i as i2, e as e3, S, f as f2 } from "../Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js";
6
+ import { _ as _6 } from "../index-CJwlO351.js";
7
+ import { e as e4, j as j3, f as f3, _ as _7, a as a6, c as c5, d as d4, b as b5, P, i as i3, g as g3, h as h3 } from "../ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js";
8
+ import { _ as _8, a as a7 } from "../PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js";
9
9
  export {
10
10
  o as Accordion,
11
11
  p as AccordionItem,
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const PageLayout_vue_vue_type_script_setup_true_lang = require("../../PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs");
3
+ const PageLayout_vue_vue_type_script_setup_true_lang = require("../../PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs");
4
4
  exports.BaseLayout = PageLayout_vue_vue_type_script_setup_true_lang._sfc_main;
5
5
  exports.PageLayout = PageLayout_vue_vue_type_script_setup_true_lang._sfc_main$1;
6
6
  //# sourceMappingURL=index.cjs.map
@@ -1,4 +1,4 @@
1
- import { _, a } from "../../PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js";
1
+ import { _, a } from "../../PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js";
2
2
  export {
3
3
  _ as BaseLayout,
4
4
  a as PageLayout
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -3,6 +3,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const useToast = require("../useToast-Bk60GArg.cjs");
4
4
  const useDarkMode = require("../useDarkMode-DLZcJEUQ.cjs");
5
5
  const useDropdown = require("../useDropdown-DHFnd259.cjs");
6
+ const useId = require("../useId-nxrBaIC9.cjs");
7
+ const useFocusTrap = require("../useFocusTrap-kcxO8AeU.cjs");
6
8
  exports.useExportCSV = useToast.useExportCSV;
7
9
  exports.useModal = useToast.useModal;
8
10
  exports.useModals = useToast.useModals;
@@ -10,4 +12,8 @@ exports.useNotifications = useToast.useNotifications;
10
12
  exports.useToast = useToast.useToast;
11
13
  exports.useDarkMode = useDarkMode.useDarkMode;
12
14
  exports.useDropdown = useDropdown.useDropdown;
15
+ exports.generateId = useId.generateId;
16
+ exports.resetIdCounter = useId.resetIdCounter;
17
+ exports.useId = useId.useId;
18
+ exports.useFocusTrap = useFocusTrap.useFocusTrap;
13
19
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
@@ -4,3 +4,5 @@ export { useExportCSV } from './useExportCSV';
4
4
  export { useDropdown, type UseDropdownOptions, type UseDropdownReturn, type KeyboardNavigationOptions } from './useDropdown';
5
5
  export { useModal, useModals, type UseModalReturn } from './useModal';
6
6
  export { useToast, type ToastOptions } from './useToast';
7
+ export { useId, generateId, resetIdCounter, type UseIdOptions, type UseIdReturn } from './useId';
8
+ export { useFocusTrap, type UseFocusTrapOptions, type UseFocusTrapReturn } from './useFocusTrap';
@@ -1,10 +1,16 @@
1
1
  import { a, b, c, u, d } from "../useToast-ina5g3mj.js";
2
2
  import { u as u2 } from "../useDarkMode-Cl5QWTlC.js";
3
3
  import { u as u3 } from "../useDropdown-iVu14E6s.js";
4
+ import { g, r, u as u4 } from "../useId-xeHj7rkg.js";
5
+ import { u as u5 } from "../useFocusTrap-AnlJsihM.js";
4
6
  export {
7
+ g as generateId,
8
+ r as resetIdCounter,
5
9
  u2 as useDarkMode,
6
10
  u3 as useDropdown,
7
11
  a as useExportCSV,
12
+ u5 as useFocusTrap,
13
+ u4 as useId,
8
14
  b as useModal,
9
15
  c as useModals,
10
16
  u as useNotifications,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ import { Ref } from 'vue';
2
+ export interface UseFocusTrapOptions {
3
+ /** Whether the focus trap is active */
4
+ active?: Ref<boolean> | boolean;
5
+ /** Focus the first focusable element when trap activates */
6
+ focusFirst?: boolean;
7
+ /** Restore focus to the previously focused element when trap deactivates */
8
+ restoreFocus?: boolean;
9
+ /** Initial element to focus (selector or element) */
10
+ initialFocus?: string | HTMLElement | null;
11
+ }
12
+ export interface UseFocusTrapReturn {
13
+ /** Ref to attach to the container element */
14
+ containerRef: Ref<HTMLElement | null>;
15
+ /** Activate the focus trap manually */
16
+ activate: () => void;
17
+ /** Deactivate the focus trap manually */
18
+ deactivate: () => void;
19
+ /** Whether the focus trap is currently active */
20
+ isActive: Ref<boolean>;
21
+ }
22
+ /**
23
+ * Composable for trapping focus within a container element (for modals, dialogs, etc.)
24
+ *
25
+ * @example
26
+ * ```vue
27
+ * <script setup>
28
+ * const isOpen = ref(false)
29
+ * const { containerRef } = useFocusTrap({ active: isOpen })
30
+ * </script>
31
+ *
32
+ * <template>
33
+ * <div v-if="isOpen" ref="containerRef" role="dialog">
34
+ * <button>First focusable</button>
35
+ * <input type="text" />
36
+ * <button @click="isOpen = false">Close</button>
37
+ * </div>
38
+ * </template>
39
+ * ```
40
+ */
41
+ export declare function useFocusTrap(options?: UseFocusTrapOptions): UseFocusTrapReturn;