cisse-vue-ui 0.8.4 → 0.9.0

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 (137) hide show
  1. package/README.md +666 -4
  2. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-B190Yija.js → CheckboxGroup.vue_vue_type_script_setup_true_lang-ZP02bMgY.js} +2 -2
  3. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-B190Yija.js.map → CheckboxGroup.vue_vue_type_script_setup_true_lang-ZP02bMgY.js.map} +1 -1
  4. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js} +37 -184
  5. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js.map +1 -0
  6. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-CLfy0-Wb.cjs} +33 -180
  7. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CLfy0-Wb.cjs.map +1 -0
  8. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs → FilterTabs.vue_vue_type_script_setup_true_lang-COkZbeGG.cjs} +1259 -208
  9. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-COkZbeGG.cjs.map +1 -0
  10. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js → FilterTabs.vue_vue_type_script_setup_true_lang-CzpYHtc5.js} +1268 -217
  11. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-CzpYHtc5.js.map +1 -0
  12. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js +298 -0
  13. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js.map +1 -0
  14. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs +297 -0
  15. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs.map +1 -0
  16. package/dist/components/core/AccordionItem.test.d.ts +1 -0
  17. package/dist/components/core/Breadcrumb.stories.d.ts +5 -0
  18. package/dist/components/core/CardWrapper.stories.d.ts +32 -0
  19. package/dist/components/core/CardWrapper.test.d.ts +1 -0
  20. package/dist/components/core/CardWrapper.vue.d.ts +129 -0
  21. package/dist/components/core/CollapsibleCard.vue.d.ts +1 -1
  22. package/dist/components/core/DataTable.stories.d.ts +38 -0
  23. package/dist/components/core/Dropdown.vue.d.ts +1 -1
  24. package/dist/components/core/Popover.vue.d.ts +2 -2
  25. package/dist/components/core/Tooltip.stories.d.ts +3 -0
  26. package/dist/components/core/index.cjs +39 -22
  27. package/dist/components/core/index.cjs.map +1 -1
  28. package/dist/components/core/index.d.ts +4 -1
  29. package/dist/components/core/index.js +39 -22
  30. package/dist/components/core/table/DataTable.test.d.ts +1 -0
  31. package/dist/components/core/{TableComponent.vue.d.ts → table/DataTable.vue.d.ts} +60 -7
  32. package/dist/components/core/table/Table.stories.d.ts +27 -0
  33. package/dist/components/core/table/atoms/Caption.test.d.ts +1 -0
  34. package/dist/components/core/table/atoms/Caption.vue.d.ts +26 -0
  35. package/dist/components/core/table/atoms/Col.test.d.ts +1 -0
  36. package/dist/components/core/table/atoms/Col.vue.d.ts +8 -0
  37. package/dist/components/core/table/atoms/Colgroup.test.d.ts +1 -0
  38. package/dist/components/core/table/atoms/Colgroup.vue.d.ts +17 -0
  39. package/dist/components/core/table/atoms/Table.test.d.ts +1 -0
  40. package/dist/components/core/table/atoms/Table.vue.d.ts +46 -0
  41. package/dist/components/core/table/atoms/Tbody.test.d.ts +1 -0
  42. package/dist/components/core/table/atoms/Tbody.vue.d.ts +17 -0
  43. package/dist/components/core/table/atoms/Td.test.d.ts +1 -0
  44. package/dist/components/core/table/atoms/Td.vue.d.ts +43 -0
  45. package/dist/components/core/table/atoms/Tfoot.test.d.ts +1 -0
  46. package/dist/components/core/table/atoms/Tfoot.vue.d.ts +17 -0
  47. package/dist/components/core/table/atoms/Th.test.d.ts +1 -0
  48. package/dist/components/core/table/atoms/Th.vue.d.ts +64 -0
  49. package/dist/components/core/table/atoms/Thead.test.d.ts +1 -0
  50. package/dist/components/core/table/atoms/Thead.vue.d.ts +17 -0
  51. package/dist/components/core/table/atoms/Tr.test.d.ts +1 -0
  52. package/dist/components/core/table/atoms/Tr.vue.d.ts +35 -0
  53. package/dist/components/core/table/atoms/index.d.ts +10 -0
  54. package/dist/components/core/table/index.d.ts +3 -0
  55. package/dist/components/core/table/molecules/ExpandableRow.test.d.ts +1 -0
  56. package/dist/components/core/table/molecules/ExpandableRow.vue.d.ts +47 -0
  57. package/dist/components/core/table/molecules/TableFooter.test.d.ts +1 -0
  58. package/dist/components/core/table/molecules/TableFooter.vue.d.ts +21 -0
  59. package/dist/components/core/table/molecules/TableHeader.test.d.ts +1 -0
  60. package/dist/components/core/table/molecules/TableHeader.vue.d.ts +49 -0
  61. package/dist/components/core/table/molecules/TableRow.test.d.ts +1 -0
  62. package/dist/components/core/table/molecules/TableRow.vue.d.ts +59 -0
  63. package/dist/components/core/table/molecules/index.d.ts +4 -0
  64. package/dist/components/feedback/Progress.vue.d.ts +1 -1
  65. package/dist/components/feedback/TableSkeleton.vue.d.ts +1 -1
  66. package/dist/components/feedback/index.cjs +14 -14
  67. package/dist/components/feedback/index.js +14 -14
  68. package/dist/components/form/Combobox.vue.d.ts +1 -1
  69. package/dist/components/form/DatePicker.vue.d.ts +1 -1
  70. package/dist/components/form/FormSection.vue.d.ts +1 -1
  71. package/dist/components/form/IconPicker.stories.d.ts +19 -0
  72. package/dist/components/form/IconPicker.test.d.ts +1 -0
  73. package/dist/components/form/InputWrapper.stories.d.ts +0 -5
  74. package/dist/components/form/Rating.vue.d.ts +1 -1
  75. package/dist/components/form/SearchInput.vue.d.ts +1 -1
  76. package/dist/components/form/index.js +2 -2
  77. package/dist/components/index.cjs +53 -36
  78. package/dist/components/index.cjs.map +1 -1
  79. package/dist/components/index.js +65 -48
  80. package/dist/composables/index.cjs +15 -8
  81. package/dist/composables/index.cjs.map +1 -1
  82. package/dist/composables/index.d.ts +7 -0
  83. package/dist/composables/index.js +12 -5
  84. package/dist/composables/useColumnResize.d.ts +38 -0
  85. package/dist/composables/useColumnResize.test.d.ts +1 -0
  86. package/dist/composables/useColumnVisibility.d.ts +44 -0
  87. package/dist/composables/useColumnVisibility.test.d.ts +1 -0
  88. package/dist/composables/useEditableCell.d.ts +51 -0
  89. package/dist/composables/useEditableCell.test.d.ts +1 -0
  90. package/dist/composables/usePagination.d.ts +44 -0
  91. package/dist/composables/usePagination.test.d.ts +1 -0
  92. package/dist/composables/usePinnedRows.d.ts +41 -0
  93. package/dist/composables/usePinnedRows.test.d.ts +1 -0
  94. package/dist/composables/useTableKeyboardNavigation.d.ts +52 -0
  95. package/dist/composables/useTableKeyboardNavigation.test.d.ts +1 -0
  96. package/dist/composables/useVirtualScroll.d.ts +32 -0
  97. package/dist/composables/useVirtualScroll.test.d.ts +1 -0
  98. package/dist/index-0kwQORZJ.js +114 -0
  99. package/dist/index-0kwQORZJ.js.map +1 -0
  100. package/dist/{index-LFQFhClN.cjs → index-BMSH4AOz.cjs} +54 -37
  101. package/dist/{index-LFQFhClN.cjs.map → index-BMSH4AOz.cjs.map} +1 -1
  102. package/dist/{index-SNefWfX0.js → index-BaWpldIJ.js} +3 -3
  103. package/dist/{index-SNefWfX0.js.map → index-BaWpldIJ.js.map} +1 -1
  104. package/dist/index.cjs +69 -45
  105. package/dist/index.cjs.map +1 -1
  106. package/dist/index.js +79 -55
  107. package/dist/style.css +1 -1
  108. package/dist/types/components.d.ts +1 -1
  109. package/dist/types/property.d.ts +8 -0
  110. package/dist/usePagination-BGwbICFC.js +135 -0
  111. package/dist/usePagination-BGwbICFC.js.map +1 -0
  112. package/dist/usePagination-gvvh1zqA.cjs +134 -0
  113. package/dist/usePagination-gvvh1zqA.cjs.map +1 -0
  114. package/dist/useVirtualScroll-BivP86fA.cjs +869 -0
  115. package/dist/useVirtualScroll-BivP86fA.cjs.map +1 -0
  116. package/dist/useVirtualScroll-YeZru2Eo.js +870 -0
  117. package/dist/useVirtualScroll-YeZru2Eo.js.map +1 -0
  118. package/package.json +1 -1
  119. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs.map +0 -1
  120. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js.map +0 -1
  121. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js.map +0 -1
  122. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs.map +0 -1
  123. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js +0 -150
  124. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js.map +0 -1
  125. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs +0 -149
  126. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs.map +0 -1
  127. package/dist/components/core/TableComponent.stories.d.ts +0 -16
  128. package/dist/index-CyL_6V7D.js +0 -97
  129. package/dist/index-CyL_6V7D.js.map +0 -1
  130. package/dist/useDarkMode-Cl5QWTlC.js +0 -53
  131. package/dist/useDarkMode-Cl5QWTlC.js.map +0 -1
  132. package/dist/useDarkMode-DLZcJEUQ.cjs +0 -52
  133. package/dist/useDarkMode-DLZcJEUQ.cjs.map +0 -1
  134. package/dist/useToast-Bk60GArg.cjs +0 -176
  135. package/dist/useToast-Bk60GArg.cjs.map +0 -1
  136. package/dist/useToast-ina5g3mj.js +0 -177
  137. package/dist/useToast-ina5g3mj.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVirtualScroll-YeZru2Eo.js","sources":["../node_modules/uid/dist/index.mjs","../src/composables/useNotifications.ts","../src/composables/useExportCSV.ts","../src/composables/useModal.ts","../src/composables/useToast.ts","../src/composables/useTableKeyboardNavigation.ts","../src/composables/useColumnVisibility.ts","../src/composables/useColumnResize.ts","../src/composables/usePinnedRows.ts","../src/composables/useEditableCell.ts","../src/composables/useVirtualScroll.ts"],"sourcesContent":["var IDX=256, HEX=[], SIZE=256, BUFFER;\nwhile (IDX--) HEX[IDX] = (IDX + 256).toString(16).substring(1);\n\nexport function uid(len) {\n\tvar i=0, tmp=(len || 11);\n\tif (!BUFFER || ((IDX + tmp) > SIZE*2)) {\n\t\tfor (BUFFER='',IDX=0; i < SIZE; i++) {\n\t\t\tBUFFER += HEX[Math.random() * 256 | 0];\n\t\t}\n\t}\n\n\treturn BUFFER.substring(IDX, IDX++ + tmp);\n}\n","import { ref, readonly } from 'vue'\r\nimport { uid } from 'uid'\r\nimport type { Notification, NotificationType, NotificationOptions } from '@/types'\r\n\r\n// Global state (singleton pattern) - shared across all useNotifications() calls\r\nconst notifications = ref<Notification[]>([])\r\n\r\n/**\r\n * Composable for managing notifications/toasts\r\n * Uses singleton pattern - all components share the same notifications state\r\n */\r\nexport function useNotifications() {\r\n\r\n const notify = (\r\n type: NotificationType,\r\n message: string,\r\n options: NotificationOptions = {},\r\n ): string => {\r\n const id = uid()\r\n const notification: Notification = {\r\n id,\r\n type,\r\n message,\r\n title: options.title ?? null,\r\n duration: options.duration ?? 5000,\r\n }\r\n\r\n notifications.value.push(notification)\r\n\r\n if (notification.duration && notification.duration > 0) {\r\n setTimeout(() => remove(id), notification.duration)\r\n }\r\n\r\n return id\r\n }\r\n\r\n const success = (message: string, options?: NotificationOptions) =>\r\n notify('success', message, options)\r\n\r\n const warning = (message: string, options?: NotificationOptions) =>\r\n notify('warning', message, options)\r\n\r\n const error = (message: string, options?: NotificationOptions) =>\r\n notify('error', message, options)\r\n\r\n const info = (message: string, options?: NotificationOptions) =>\r\n notify('info', message, options)\r\n\r\n const remove = (id: string) => {\r\n notifications.value = notifications.value.filter((n) => n.id !== id)\r\n }\r\n\r\n const clear = () => {\r\n notifications.value = []\r\n }\r\n\r\n return {\r\n notifications: readonly(notifications),\r\n notify,\r\n success,\r\n warning,\r\n error,\r\n info,\r\n remove,\r\n clear,\r\n }\r\n}\r\n","/**\n * Composable for exporting data to CSV format\n */\nexport function useExportCSV() {\n const escapeCSV = (value: unknown): string => {\n if (value === null || value === undefined) return ''\n const str = String(value)\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`\n }\n return str\n }\n\n const exportToCSV = <T extends Record<string, unknown>>(\n data: T[],\n columns: { key: keyof T; label: string }[],\n filename: string = 'export.csv',\n ) => {\n if (!data || data.length === 0) {\n console.warn('No data to export')\n return\n }\n\n // Create header row\n const headers = columns.map((col) => escapeCSV(col.label)).join(',')\n\n // Create data rows\n const rows = data.map((item) =>\n columns.map((col) => escapeCSV(item[col.key])).join(','),\n )\n\n // Combine header and rows\n const csv = [headers, ...rows].join('\\n')\n\n // Create and trigger download\n const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.setAttribute('href', url)\n link.setAttribute('download', filename)\n link.style.visibility = 'hidden'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n URL.revokeObjectURL(url)\n }\n\n return {\n exportToCSV,\n escapeCSV,\n }\n}\n","import { ref, type Ref } from 'vue'\r\n\r\nexport interface UseModalReturn<T = unknown> {\r\n /** Whether the modal is currently open */\r\n isOpen: Ref<boolean>\r\n /** Data associated with the modal (e.g., item being edited) */\r\n data: Ref<T | null>\r\n /** Open the modal, optionally with data */\r\n open: (newData?: T) => void\r\n /** Close the modal and clear data */\r\n close: () => void\r\n /** Toggle the modal state */\r\n toggle: () => void\r\n}\r\n\r\n/**\r\n * Composable for managing modal state\r\n *\r\n * @example\r\n * ```ts\r\n * // Simple modal\r\n * const createModal = useModal()\r\n * createModal.open()\r\n * createModal.close()\r\n *\r\n * // Modal with data (e.g., for editing)\r\n * const editModal = useModal<User>()\r\n * editModal.open(selectedUser)\r\n * // Access editModal.data.value in modal\r\n *\r\n * // With onClose callback\r\n * const deleteModal = useModal<Item>({ onClose: () => refetch() })\r\n * ```\r\n */\r\nexport function useModal<T = unknown>(options?: {\r\n /** Initial open state */\r\n initialOpen?: boolean\r\n /** Initial data */\r\n initialData?: T | null\r\n /** Callback when modal opens */\r\n onOpen?: (data: T | null) => void\r\n /** Callback when modal closes */\r\n onClose?: () => void\r\n}): UseModalReturn<T> {\r\n const {\r\n initialOpen = false,\r\n initialData = null,\r\n onOpen,\r\n onClose,\r\n } = options ?? {}\r\n\r\n const isOpen = ref(initialOpen)\r\n const data = ref<T | null>(initialData) as Ref<T | null>\r\n\r\n const open = (newData?: T) => {\r\n data.value = newData ?? null\r\n isOpen.value = true\r\n onOpen?.(data.value)\r\n }\r\n\r\n const close = () => {\r\n isOpen.value = false\r\n data.value = null\r\n onClose?.()\r\n }\r\n\r\n const toggle = () => {\r\n if (isOpen.value) {\r\n close()\r\n } else {\r\n open()\r\n }\r\n }\r\n\r\n return {\r\n isOpen,\r\n data,\r\n open,\r\n close,\r\n toggle,\r\n }\r\n}\r\n\r\n/**\r\n * Create multiple related modals at once\r\n * Useful when a page has several modals (create, edit, delete, etc.)\r\n *\r\n * @example\r\n * ```ts\r\n * const modals = useModals({\r\n * create: useModal(),\r\n * edit: useModal<User>(),\r\n * delete: useModal<User>(),\r\n * })\r\n *\r\n * modals.create.open()\r\n * modals.edit.open(user)\r\n * modals.delete.close()\r\n * ```\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport function useModals<T extends Record<string, UseModalReturn<any>>>(\r\n modals: T\r\n): T {\r\n return modals\r\n}\r\n","import { ref } from 'vue'\r\nimport type { ToastType } from '@/components/feedback/Toast.vue'\r\nimport type { ToastItem } from '@/components/feedback/ToastContainer.vue'\r\n\r\nexport interface ToastOptions {\r\n message: string\r\n type?: ToastType\r\n title?: string\r\n duration?: number\r\n}\r\n\r\nconst toasts = ref<ToastItem[]>([])\r\n\r\nlet toastId = 0\r\n\r\nexport function useToast() {\r\n const add = (options: ToastOptions): string => {\r\n const id = `toast-${++toastId}`\r\n const toast: ToastItem = {\r\n id,\r\n message: options.message,\r\n type: options.type || 'info',\r\n title: options.title,\r\n duration: options.duration ?? 5000,\r\n }\r\n toasts.value.push(toast)\r\n return id\r\n }\r\n\r\n const remove = (id: string) => {\r\n const index = toasts.value.findIndex((t) => t.id === id)\r\n if (index > -1) {\r\n toasts.value.splice(index, 1)\r\n }\r\n }\r\n\r\n const clear = () => {\r\n toasts.value = []\r\n }\r\n\r\n const success = (message: string, title?: string) => {\r\n return add({ message, title, type: 'success' })\r\n }\r\n\r\n const error = (message: string, title?: string) => {\r\n return add({ message, title, type: 'error' })\r\n }\r\n\r\n const warning = (message: string, title?: string) => {\r\n return add({ message, title, type: 'warning' })\r\n }\r\n\r\n const info = (message: string, title?: string) => {\r\n return add({ message, title, type: 'info' })\r\n }\r\n\r\n return {\r\n toasts,\r\n add,\r\n remove,\r\n clear,\r\n success,\r\n error,\r\n warning,\r\n info,\r\n }\r\n}\r\n","import { ref, computed, type Ref, onMounted, onUnmounted } from 'vue'\r\n\r\nexport interface UseTableKeyboardNavigationOptions {\r\n /** The table element ref */\r\n tableRef: Ref<HTMLElement | null>\r\n /** Number of rows in the table */\r\n rowCount: Ref<number> | number\r\n /** Number of columns in the table */\r\n colCount: Ref<number> | number\r\n /** Enable cell-level navigation (default: false, uses row-level) */\r\n cellNavigation?: boolean\r\n /** Callback when a row is activated (Enter/Space) */\r\n onRowActivate?: (rowIndex: number) => void\r\n /** Callback when a cell is activated (Enter/Space) */\r\n onCellActivate?: (rowIndex: number, colIndex: number) => void\r\n /** Callback when focus changes */\r\n onFocusChange?: (rowIndex: number, colIndex: number) => void\r\n /** Skip header row in navigation */\r\n skipHeader?: boolean\r\n /** Enable wrap-around navigation */\r\n wrap?: boolean\r\n}\r\n\r\nexport interface UseTableKeyboardNavigationReturn {\r\n /** Currently focused row index */\r\n focusedRow: Ref<number>\r\n /** Currently focused column index (for cell navigation) */\r\n focusedCol: Ref<number>\r\n /** Whether keyboard navigation is active */\r\n isActive: Ref<boolean>\r\n /** Set focus to a specific row */\r\n setFocusedRow: (index: number) => void\r\n /** Set focus to a specific cell */\r\n setFocusedCell: (row: number, col: number) => void\r\n /** Start keyboard navigation */\r\n activate: () => void\r\n /** Stop keyboard navigation */\r\n deactivate: () => void\r\n /** Get props to apply to a row for navigation */\r\n getRowProps: (rowIndex: number) => {\r\n tabIndex: number\r\n 'aria-selected'?: boolean\r\n onFocus: () => void\r\n }\r\n /** Get props to apply to a cell for navigation */\r\n getCellProps: (rowIndex: number, colIndex: number) => {\r\n tabIndex: number\r\n 'aria-selected'?: boolean\r\n onFocus: () => void\r\n }\r\n /** Handle keyboard events (attach to table) */\r\n handleKeyDown: (event: KeyboardEvent) => void\r\n}\r\n\r\nexport function useTableKeyboardNavigation(\r\n options: UseTableKeyboardNavigationOptions\r\n): UseTableKeyboardNavigationReturn {\r\n const {\r\n tableRef,\r\n rowCount,\r\n colCount,\r\n cellNavigation = false,\r\n onRowActivate,\r\n onCellActivate,\r\n onFocusChange,\r\n skipHeader = true,\r\n wrap = true,\r\n } = options\r\n\r\n const focusedRow = ref(skipHeader ? 1 : 0)\r\n const focusedCol = ref(0)\r\n const isActive = ref(false)\r\n\r\n const totalRows = computed(() => (typeof rowCount === 'number' ? rowCount : rowCount.value))\r\n const totalCols = computed(() => (typeof colCount === 'number' ? colCount : colCount.value))\r\n const startRow = computed(() => (skipHeader ? 1 : 0))\r\n\r\n const clampRow = (row: number): number => {\r\n if (wrap) {\r\n if (row < startRow.value) return totalRows.value - 1\r\n if (row >= totalRows.value) return startRow.value\r\n return row\r\n }\r\n return Math.max(startRow.value, Math.min(totalRows.value - 1, row))\r\n }\r\n\r\n const clampCol = (col: number): number => {\r\n if (wrap) {\r\n if (col < 0) return totalCols.value - 1\r\n if (col >= totalCols.value) return 0\r\n return col\r\n }\r\n return Math.max(0, Math.min(totalCols.value - 1, col))\r\n }\r\n\r\n const setFocusedRow = (index: number) => {\r\n focusedRow.value = clampRow(index)\r\n onFocusChange?.(focusedRow.value, focusedCol.value)\r\n }\r\n\r\n const setFocusedCell = (row: number, col: number) => {\r\n focusedRow.value = clampRow(row)\r\n focusedCol.value = clampCol(col)\r\n onFocusChange?.(focusedRow.value, focusedCol.value)\r\n }\r\n\r\n const activate = () => {\r\n isActive.value = true\r\n focusCurrentElement()\r\n }\r\n\r\n const deactivate = () => {\r\n isActive.value = false\r\n }\r\n\r\n const focusCurrentElement = () => {\r\n if (!tableRef.value) return\r\n\r\n const selector = cellNavigation\r\n ? `tr:nth-child(${focusedRow.value + 1}) td:nth-child(${focusedCol.value + 1}), tr:nth-child(${focusedRow.value + 1}) th:nth-child(${focusedCol.value + 1})`\r\n : `tr:nth-child(${focusedRow.value + 1})`\r\n\r\n const element = tableRef.value.querySelector(selector) as HTMLElement\r\n element?.focus()\r\n }\r\n\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (!isActive.value) return\r\n\r\n const { key, shiftKey, ctrlKey, metaKey } = event\r\n\r\n // Don't interfere with modifier combinations (except Shift for selection)\r\n if (ctrlKey || metaKey) return\r\n\r\n let handled = false\r\n\r\n switch (key) {\r\n case 'ArrowDown':\r\n setFocusedRow(focusedRow.value + 1)\r\n handled = true\r\n break\r\n\r\n case 'ArrowUp':\r\n setFocusedRow(focusedRow.value - 1)\r\n handled = true\r\n break\r\n\r\n case 'ArrowRight':\r\n if (cellNavigation) {\r\n setFocusedCell(focusedRow.value, focusedCol.value + 1)\r\n handled = true\r\n }\r\n break\r\n\r\n case 'ArrowLeft':\r\n if (cellNavigation) {\r\n setFocusedCell(focusedRow.value, focusedCol.value - 1)\r\n handled = true\r\n }\r\n break\r\n\r\n case 'Home':\r\n if (cellNavigation) {\r\n setFocusedCell(shiftKey ? startRow.value : focusedRow.value, 0)\r\n } else {\r\n setFocusedRow(startRow.value)\r\n }\r\n handled = true\r\n break\r\n\r\n case 'End':\r\n if (cellNavigation) {\r\n setFocusedCell(\r\n shiftKey ? totalRows.value - 1 : focusedRow.value,\r\n totalCols.value - 1\r\n )\r\n } else {\r\n setFocusedRow(totalRows.value - 1)\r\n }\r\n handled = true\r\n break\r\n\r\n case 'PageDown':\r\n setFocusedRow(focusedRow.value + 10)\r\n handled = true\r\n break\r\n\r\n case 'PageUp':\r\n setFocusedRow(focusedRow.value - 10)\r\n handled = true\r\n break\r\n\r\n case 'Enter':\r\n case ' ':\r\n if (cellNavigation) {\r\n onCellActivate?.(focusedRow.value, focusedCol.value)\r\n } else {\r\n onRowActivate?.(focusedRow.value)\r\n }\r\n handled = true\r\n break\r\n\r\n case 'Escape':\r\n deactivate()\r\n handled = true\r\n break\r\n\r\n case 'Tab':\r\n // Allow normal tab behavior to exit the table\r\n deactivate()\r\n return\r\n }\r\n\r\n if (handled) {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n focusCurrentElement()\r\n }\r\n }\r\n\r\n const getRowProps = (rowIndex: number) => ({\r\n tabIndex: focusedRow.value === rowIndex && isActive.value ? 0 : -1,\r\n 'aria-selected': focusedRow.value === rowIndex ? true : undefined,\r\n onFocus: () => {\r\n if (!isActive.value) {\r\n isActive.value = true\r\n }\r\n focusedRow.value = rowIndex\r\n },\r\n })\r\n\r\n const getCellProps = (rowIndex: number, colIndex: number) => ({\r\n tabIndex:\r\n focusedRow.value === rowIndex && focusedCol.value === colIndex && isActive.value\r\n ? 0\r\n : -1,\r\n 'aria-selected':\r\n focusedRow.value === rowIndex && focusedCol.value === colIndex ? true : undefined,\r\n onFocus: () => {\r\n if (!isActive.value) {\r\n isActive.value = true\r\n }\r\n focusedRow.value = rowIndex\r\n focusedCol.value = colIndex\r\n },\r\n })\r\n\r\n // Handle focus entering the table\r\n const handleTableFocus = () => {\r\n if (!isActive.value) {\r\n activate()\r\n }\r\n }\r\n\r\n onMounted(() => {\r\n tableRef.value?.addEventListener('focus', handleTableFocus, true)\r\n })\r\n\r\n onUnmounted(() => {\r\n tableRef.value?.removeEventListener('focus', handleTableFocus, true)\r\n })\r\n\r\n return {\r\n focusedRow,\r\n focusedCol,\r\n isActive,\r\n setFocusedRow,\r\n setFocusedCell,\r\n activate,\r\n deactivate,\r\n getRowProps,\r\n getCellProps,\r\n handleKeyDown,\r\n }\r\n}\r\n","import { ref, computed, type Ref, type ComputedRef } from 'vue'\r\n\r\nexport interface Column {\r\n name: string\r\n label?: string\r\n hidden?: boolean\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface UseColumnVisibilityOptions<T extends Column> {\r\n /** Initial columns configuration */\r\n columns: T[] | Ref<T[]>\r\n /** Initial hidden column names */\r\n initialHidden?: string[]\r\n /** Persist visibility to localStorage */\r\n persist?: boolean\r\n /** Storage key for persistence */\r\n storageKey?: string\r\n /** Minimum visible columns required */\r\n minVisible?: number\r\n}\r\n\r\nexport interface UseColumnVisibilityReturn<T extends Column> {\r\n /** All columns with current visibility state */\r\n columns: ComputedRef<T[]>\r\n /** Only visible columns */\r\n visibleColumns: ComputedRef<T[]>\r\n /** Set of hidden column names */\r\n hiddenColumns: Ref<Set<string>>\r\n /** Check if a column is visible */\r\n isVisible: (columnName: string) => boolean\r\n /** Show a column */\r\n show: (columnName: string) => void\r\n /** Hide a column */\r\n hide: (columnName: string) => void\r\n /** Toggle a column's visibility */\r\n toggle: (columnName: string) => void\r\n /** Show all columns */\r\n showAll: () => void\r\n /** Hide all columns (respects minVisible) */\r\n hideAll: () => void\r\n /** Reset to initial state */\r\n reset: () => void\r\n /** Set multiple columns visibility at once */\r\n setVisibility: (visibility: Record<string, boolean>) => void\r\n}\r\n\r\nexport function useColumnVisibility<T extends Column>(\r\n options: UseColumnVisibilityOptions<T>\r\n): UseColumnVisibilityReturn<T> {\r\n const {\r\n columns: columnsOption,\r\n initialHidden = [],\r\n persist = false,\r\n storageKey = 'table-column-visibility',\r\n minVisible = 1,\r\n } = options\r\n\r\n // Load persisted state or use initial\r\n const loadInitialState = (): Set<string> => {\r\n if (persist && typeof window !== 'undefined') {\r\n try {\r\n const stored = localStorage.getItem(storageKey)\r\n if (stored) {\r\n return new Set(JSON.parse(stored))\r\n }\r\n } catch {\r\n // Ignore storage errors\r\n }\r\n }\r\n return new Set(initialHidden)\r\n }\r\n\r\n const hiddenColumns = ref<Set<string>>(loadInitialState())\r\n\r\n // Save to storage when changed\r\n const saveState = () => {\r\n if (persist && typeof window !== 'undefined') {\r\n try {\r\n localStorage.setItem(storageKey, JSON.stringify([...hiddenColumns.value]))\r\n } catch {\r\n // Ignore storage errors\r\n }\r\n }\r\n }\r\n\r\n const rawColumns = computed(() => {\r\n const cols = 'value' in columnsOption ? columnsOption.value : columnsOption\r\n return cols\r\n })\r\n\r\n const columns = computed(() => {\r\n return rawColumns.value.map((col) => ({\r\n ...col,\r\n hidden: hiddenColumns.value.has(col.name),\r\n }))\r\n })\r\n\r\n const visibleColumns = computed(() => {\r\n return columns.value.filter((col) => !col.hidden)\r\n })\r\n\r\n const isVisible = (columnName: string): boolean => {\r\n return !hiddenColumns.value.has(columnName)\r\n }\r\n\r\n const show = (columnName: string) => {\r\n hiddenColumns.value.delete(columnName)\r\n hiddenColumns.value = new Set(hiddenColumns.value) // Trigger reactivity\r\n saveState()\r\n }\r\n\r\n const hide = (columnName: string) => {\r\n // Check if we can hide (respect minVisible)\r\n if (visibleColumns.value.length <= minVisible) {\r\n return\r\n }\r\n hiddenColumns.value.add(columnName)\r\n hiddenColumns.value = new Set(hiddenColumns.value) // Trigger reactivity\r\n saveState()\r\n }\r\n\r\n const toggle = (columnName: string) => {\r\n if (isVisible(columnName)) {\r\n hide(columnName)\r\n } else {\r\n show(columnName)\r\n }\r\n }\r\n\r\n const showAll = () => {\r\n hiddenColumns.value = new Set()\r\n saveState()\r\n }\r\n\r\n const hideAll = () => {\r\n // Keep at least minVisible columns visible\r\n const columnsToKeep = rawColumns.value.slice(0, minVisible).map((c) => c.name)\r\n const newHidden = new Set(\r\n rawColumns.value\r\n .filter((c) => !columnsToKeep.includes(c.name))\r\n .map((c) => c.name)\r\n )\r\n hiddenColumns.value = newHidden\r\n saveState()\r\n }\r\n\r\n const reset = () => {\r\n hiddenColumns.value = new Set(initialHidden)\r\n saveState()\r\n }\r\n\r\n const setVisibility = (visibility: Record<string, boolean>) => {\r\n const newHidden = new Set<string>()\r\n let visibleCount = 0\r\n\r\n for (const col of rawColumns.value) {\r\n const shouldBeVisible = visibility[col.name] ?? true\r\n if (shouldBeVisible) {\r\n visibleCount++\r\n } else {\r\n newHidden.add(col.name)\r\n }\r\n }\r\n\r\n // Ensure minimum visible\r\n if (visibleCount < minVisible) {\r\n // Remove some from hidden to meet minimum\r\n let added = 0\r\n for (const col of rawColumns.value) {\r\n if (newHidden.has(col.name)) {\r\n newHidden.delete(col.name)\r\n added++\r\n if (visibleCount + added >= minVisible) break\r\n }\r\n }\r\n }\r\n\r\n hiddenColumns.value = newHidden\r\n saveState()\r\n }\r\n\r\n return {\r\n columns,\r\n visibleColumns,\r\n hiddenColumns,\r\n isVisible,\r\n show,\r\n hide,\r\n toggle,\r\n showAll,\r\n hideAll,\r\n reset,\r\n setVisibility,\r\n }\r\n}\r\n","import { ref, computed, watch, type Ref, type ComputedRef } from 'vue'\r\n\r\nexport interface ColumnWidth {\r\n name: string\r\n width: number\r\n minWidth?: number\r\n maxWidth?: number\r\n}\r\n\r\nexport interface UseColumnResizeOptions {\r\n /** Initial column widths */\r\n columns: ColumnWidth[] | Ref<ColumnWidth[]>\r\n /** Default minimum width for columns without explicit minWidth */\r\n defaultMinWidth?: number\r\n /** Default maximum width for columns without explicit maxWidth */\r\n defaultMaxWidth?: number\r\n /** LocalStorage key for persistence (optional) */\r\n storageKey?: string\r\n /** Enable persistence to localStorage */\r\n persist?: boolean\r\n}\r\n\r\nexport interface UseColumnResizeReturn {\r\n /** Current column widths */\r\n columnWidths: ComputedRef<Record<string, number>>\r\n /** Get width for a specific column */\r\n getWidth: (name: string) => number\r\n /** Set width for a specific column */\r\n setWidth: (name: string, width: number) => void\r\n /** Start resizing a column */\r\n startResize: (name: string, event: MouseEvent | TouchEvent) => void\r\n /** Check if a column is currently being resized */\r\n isResizing: ComputedRef<boolean>\r\n /** The column currently being resized */\r\n resizingColumn: Ref<string | null>\r\n /** Reset all widths to initial values */\r\n reset: () => void\r\n /** Reset a specific column width */\r\n resetColumn: (name: string) => void\r\n}\r\n\r\nexport function useColumnResize(options: UseColumnResizeOptions): UseColumnResizeReturn {\r\n const {\r\n columns: columnsOption,\r\n defaultMinWidth = 50,\r\n defaultMaxWidth = 1000,\r\n storageKey,\r\n persist = false,\r\n } = options\r\n\r\n const allColumns = computed(() => {\r\n return 'value' in columnsOption ? columnsOption.value : columnsOption\r\n })\r\n\r\n // Create initial widths map\r\n const getInitialWidths = (): Map<string, number> => {\r\n const map = new Map<string, number>()\r\n allColumns.value.forEach((col) => {\r\n map.set(col.name, col.width)\r\n })\r\n return map\r\n }\r\n\r\n // Load from localStorage if persistence is enabled\r\n const loadFromStorage = (): Map<string, number> | null => {\r\n if (!persist || !storageKey) return null\r\n try {\r\n const stored = localStorage.getItem(storageKey)\r\n if (stored) {\r\n const parsed = JSON.parse(stored) as Record<string, number>\r\n return new Map(Object.entries(parsed))\r\n }\r\n } catch {\r\n // Ignore errors\r\n }\r\n return null\r\n }\r\n\r\n // Save to localStorage\r\n const saveToStorage = () => {\r\n if (!persist || !storageKey) return\r\n try {\r\n const obj = Object.fromEntries(widths.value)\r\n localStorage.setItem(storageKey, JSON.stringify(obj))\r\n } catch {\r\n // Ignore errors\r\n }\r\n }\r\n\r\n // Initialize widths from storage or defaults\r\n const widths = ref<Map<string, number>>(loadFromStorage() ?? getInitialWidths())\r\n\r\n // Update widths when columns change\r\n watch(\r\n allColumns,\r\n (newColumns) => {\r\n const stored = loadFromStorage()\r\n newColumns.forEach((col) => {\r\n if (!widths.value.has(col.name)) {\r\n widths.value.set(col.name, stored?.get(col.name) ?? col.width)\r\n }\r\n })\r\n },\r\n { deep: true }\r\n )\r\n\r\n // Resizing state\r\n const resizingColumn = ref<string | null>(null)\r\n const startX = ref(0)\r\n const startWidth = ref(0)\r\n\r\n const isResizing = computed(() => resizingColumn.value !== null)\r\n\r\n const columnWidths = computed(() => {\r\n const result: Record<string, number> = {}\r\n widths.value.forEach((width, name) => {\r\n result[name] = width\r\n })\r\n return result\r\n })\r\n\r\n const getWidth = (name: string): number => {\r\n return widths.value.get(name) ?? allColumns.value.find((c) => c.name === name)?.width ?? 100\r\n }\r\n\r\n const getColumnConfig = (name: string): ColumnWidth | undefined => {\r\n return allColumns.value.find((c) => c.name === name)\r\n }\r\n\r\n const setWidth = (name: string, width: number) => {\r\n const config = getColumnConfig(name)\r\n const minWidth = config?.minWidth ?? defaultMinWidth\r\n const maxWidth = config?.maxWidth ?? defaultMaxWidth\r\n const clampedWidth = Math.max(minWidth, Math.min(maxWidth, width))\r\n\r\n const newWidths = new Map(widths.value)\r\n newWidths.set(name, clampedWidth)\r\n widths.value = newWidths\r\n saveToStorage()\r\n }\r\n\r\n const handleMouseMove = (event: MouseEvent | TouchEvent) => {\r\n if (!resizingColumn.value) return\r\n\r\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX\r\n const deltaX = clientX - startX.value\r\n const newWidth = startWidth.value + deltaX\r\n\r\n setWidth(resizingColumn.value, newWidth)\r\n }\r\n\r\n const handleMouseUp = () => {\r\n resizingColumn.value = null\r\n document.removeEventListener('mousemove', handleMouseMove)\r\n document.removeEventListener('mouseup', handleMouseUp)\r\n document.removeEventListener('touchmove', handleMouseMove)\r\n document.removeEventListener('touchend', handleMouseUp)\r\n document.body.style.cursor = ''\r\n document.body.style.userSelect = ''\r\n }\r\n\r\n const startResize = (name: string, event: MouseEvent | TouchEvent) => {\r\n event.preventDefault()\r\n resizingColumn.value = name\r\n startX.value = 'touches' in event ? event.touches[0].clientX : event.clientX\r\n startWidth.value = getWidth(name)\r\n\r\n document.addEventListener('mousemove', handleMouseMove)\r\n document.addEventListener('mouseup', handleMouseUp)\r\n document.addEventListener('touchmove', handleMouseMove)\r\n document.addEventListener('touchend', handleMouseUp)\r\n document.body.style.cursor = 'col-resize'\r\n document.body.style.userSelect = 'none'\r\n }\r\n\r\n const reset = () => {\r\n widths.value = getInitialWidths()\r\n saveToStorage()\r\n }\r\n\r\n const resetColumn = (name: string) => {\r\n const config = getColumnConfig(name)\r\n if (config) {\r\n setWidth(name, config.width)\r\n }\r\n }\r\n\r\n return {\r\n columnWidths,\r\n getWidth,\r\n setWidth,\r\n startResize,\r\n isResizing,\r\n resizingColumn,\r\n reset,\r\n resetColumn,\r\n }\r\n}\r\n","import { shallowRef, computed, type ComputedRef, type ShallowRef } from 'vue'\r\n\r\nexport type PinPosition = 'top' | 'bottom'\r\n\r\nexport interface PinnedItem<T = unknown> {\r\n item: T\r\n position: PinPosition\r\n}\r\n\r\nexport interface UsePinnedRowsOptions<T> {\r\n /** Key field for unique identification */\r\n keyField?: string\r\n /** Initially pinned items */\r\n initialPinned?: PinnedItem<T>[]\r\n /** Maximum number of pinned rows at top */\r\n maxPinnedTop?: number\r\n /** Maximum number of pinned rows at bottom */\r\n maxPinnedBottom?: number\r\n}\r\n\r\nexport interface UsePinnedRowsReturn<T> {\r\n /** Items pinned to the top */\r\n pinnedTop: ComputedRef<T[]>\r\n /** Items pinned to the bottom */\r\n pinnedBottom: ComputedRef<T[]>\r\n /** All pinned item keys */\r\n pinnedKeys: ComputedRef<Set<string>>\r\n /** Check if an item is pinned */\r\n isPinned: (item: T) => boolean\r\n /** Get pin position for an item (null if not pinned) */\r\n getPinPosition: (item: T) => PinPosition | null\r\n /** Pin an item to a position */\r\n pin: (item: T, position: PinPosition) => void\r\n /** Unpin an item */\r\n unpin: (item: T) => void\r\n /** Toggle pin state */\r\n togglePin: (item: T, position?: PinPosition) => void\r\n /** Move a pinned item to a different position */\r\n movePin: (item: T, newPosition: PinPosition) => void\r\n /** Clear all pinned rows */\r\n clearAll: () => void\r\n /** Clear pinned rows at a specific position */\r\n clear: (position: PinPosition) => void\r\n}\r\n\r\nexport function usePinnedRows<T>(\r\n options: UsePinnedRowsOptions<T> = {}\r\n): UsePinnedRowsReturn<T> {\r\n const {\r\n keyField = 'id',\r\n initialPinned = [],\r\n maxPinnedTop = Infinity,\r\n maxPinnedBottom = Infinity,\r\n } = options\r\n\r\n const getItemKey = (item: T): string => {\r\n const key = (item as Record<string, unknown>)[keyField]\r\n return String(key ?? Math.random())\r\n }\r\n\r\n // Map of item key -> { item, position }\r\n const pinnedMap: ShallowRef<Map<string, PinnedItem<T>>> = shallowRef(\r\n new Map(initialPinned.map((p) => [getItemKey(p.item), p]))\r\n )\r\n\r\n const pinnedTop = computed((): T[] => {\r\n const items: T[] = []\r\n pinnedMap.value.forEach(({ item, position }) => {\r\n if (position === 'top') {\r\n items.push(item as T)\r\n }\r\n })\r\n return items\r\n })\r\n\r\n const pinnedBottom = computed((): T[] => {\r\n const items: T[] = []\r\n pinnedMap.value.forEach(({ item, position }) => {\r\n if (position === 'bottom') {\r\n items.push(item as T)\r\n }\r\n })\r\n return items\r\n })\r\n\r\n const pinnedKeys = computed(() => {\r\n return new Set(pinnedMap.value.keys())\r\n })\r\n\r\n const isPinned = (item: T): boolean => {\r\n return pinnedMap.value.has(getItemKey(item))\r\n }\r\n\r\n const getPinPosition = (item: T): PinPosition | null => {\r\n const pinned = pinnedMap.value.get(getItemKey(item))\r\n return pinned?.position ?? null\r\n }\r\n\r\n const pin = (item: T, position: PinPosition) => {\r\n // Check max limits\r\n const currentCount = position === 'top' ? pinnedTop.value.length : pinnedBottom.value.length\r\n const maxCount = position === 'top' ? maxPinnedTop : maxPinnedBottom\r\n\r\n // If already at max and not already pinned at this position, don't add\r\n if (currentCount >= maxCount && getPinPosition(item) !== position) {\r\n return\r\n }\r\n\r\n const key = getItemKey(item)\r\n const newMap = new Map(pinnedMap.value)\r\n newMap.set(key, { item, position })\r\n pinnedMap.value = newMap\r\n }\r\n\r\n const unpin = (item: T) => {\r\n const key = getItemKey(item)\r\n if (pinnedMap.value.has(key)) {\r\n const newMap = new Map(pinnedMap.value)\r\n newMap.delete(key)\r\n pinnedMap.value = newMap\r\n }\r\n }\r\n\r\n const togglePin = (item: T, position: PinPosition = 'top') => {\r\n if (isPinned(item)) {\r\n unpin(item)\r\n } else {\r\n pin(item, position)\r\n }\r\n }\r\n\r\n const movePin = (item: T, newPosition: PinPosition) => {\r\n if (isPinned(item)) {\r\n pin(item, newPosition)\r\n }\r\n }\r\n\r\n const clearAll = () => {\r\n pinnedMap.value = new Map()\r\n }\r\n\r\n const clear = (position: PinPosition) => {\r\n const newMap = new Map<string, PinnedItem<T>>()\r\n pinnedMap.value.forEach((pinned, key) => {\r\n if (pinned.position !== position) {\r\n newMap.set(key, pinned)\r\n }\r\n })\r\n pinnedMap.value = newMap\r\n }\r\n\r\n return {\r\n pinnedTop,\r\n pinnedBottom,\r\n pinnedKeys,\r\n isPinned,\r\n getPinPosition,\r\n pin,\r\n unpin,\r\n togglePin,\r\n movePin,\r\n clearAll,\r\n clear,\r\n }\r\n}\r\n","import { ref, computed, type Ref, type ComputedRef } from 'vue'\r\n\r\nexport type CellType = 'text' | 'number' | 'date' | 'boolean' | 'select'\r\n\r\nexport interface CellEditEvent<T = unknown> {\r\n /** Row item being edited */\r\n item: T\r\n /** Column/field name */\r\n field: string\r\n /** Original value before edit */\r\n originalValue: unknown\r\n /** New value after edit */\r\n newValue: unknown\r\n}\r\n\r\nexport interface EditingCell {\r\n /** Row key */\r\n rowKey: string\r\n /** Column/field name */\r\n field: string\r\n}\r\n\r\nexport interface UseEditableCellOptions<T = unknown> {\r\n /** Key field for row identification */\r\n keyField?: string\r\n /** Callback when edit is confirmed */\r\n onSave?: (event: CellEditEvent<T>) => void | Promise<void>\r\n /** Callback when edit is cancelled */\r\n onCancel?: (event: Omit<CellEditEvent<T>, 'newValue'>) => void\r\n /** Validate value before saving (return error message or null) */\r\n validate?: (event: CellEditEvent<T>) => string | null\r\n}\r\n\r\nexport interface UseEditableCellReturn<T> {\r\n /** Currently editing cell (null if none) */\r\n editingCell: Ref<EditingCell | null>\r\n /** Current edit value */\r\n editValue: Ref<unknown>\r\n /** Validation error message */\r\n error: Ref<string | null>\r\n /** Whether currently saving */\r\n saving: Ref<boolean>\r\n /** Check if a specific cell is being edited */\r\n isEditing: (rowKey: string, field: string) => boolean\r\n /** Start editing a cell */\r\n startEdit: (item: T, field: string, currentValue: unknown) => void\r\n /** Confirm the edit and save */\r\n confirmEdit: () => Promise<void>\r\n /** Cancel the edit */\r\n cancelEdit: () => void\r\n /** Update the edit value */\r\n updateValue: (value: unknown) => void\r\n /** Get item being edited */\r\n editingItem: ComputedRef<T | null>\r\n}\r\n\r\nexport function useEditableCell<T>(\r\n options: UseEditableCellOptions<T> = {}\r\n): UseEditableCellReturn<T> {\r\n const {\r\n keyField = 'id',\r\n onSave,\r\n onCancel,\r\n validate,\r\n } = options\r\n\r\n const editingCell = ref<EditingCell | null>(null)\r\n const editValue = ref<unknown>(null)\r\n const error = ref<string | null>(null)\r\n const saving = ref(false)\r\n const currentItem = ref<T | null>(null)\r\n const originalValue = ref<unknown>(null)\r\n\r\n const getItemKey = (item: T): string => {\r\n const key = (item as Record<string, unknown>)[keyField]\r\n return String(key ?? Math.random())\r\n }\r\n\r\n const isEditing = (rowKey: string, field: string): boolean => {\r\n return editingCell.value?.rowKey === rowKey && editingCell.value?.field === field\r\n }\r\n\r\n const startEdit = (item: T, field: string, currentValue: unknown) => {\r\n // Cancel any existing edit\r\n if (editingCell.value) {\r\n cancelEdit()\r\n }\r\n\r\n currentItem.value = item as T\r\n originalValue.value = currentValue\r\n editValue.value = currentValue\r\n error.value = null\r\n editingCell.value = {\r\n rowKey: getItemKey(item),\r\n field,\r\n }\r\n }\r\n\r\n const confirmEdit = async () => {\r\n if (!editingCell.value || !currentItem.value) return\r\n\r\n const event: CellEditEvent<T> = {\r\n item: currentItem.value,\r\n field: editingCell.value.field,\r\n originalValue: originalValue.value,\r\n newValue: editValue.value,\r\n }\r\n\r\n // Validate if validator provided\r\n if (validate) {\r\n const validationError = validate(event)\r\n if (validationError) {\r\n error.value = validationError\r\n return\r\n }\r\n }\r\n\r\n // Save\r\n saving.value = true\r\n error.value = null\r\n\r\n try {\r\n if (onSave) {\r\n await onSave(event)\r\n }\r\n // Clear editing state on success\r\n editingCell.value = null\r\n editValue.value = null\r\n currentItem.value = null\r\n originalValue.value = null\r\n } catch (e) {\r\n error.value = e instanceof Error ? e.message : 'Failed to save'\r\n } finally {\r\n saving.value = false\r\n }\r\n }\r\n\r\n const cancelEdit = () => {\r\n if (editingCell.value && currentItem.value && onCancel) {\r\n onCancel({\r\n item: currentItem.value,\r\n field: editingCell.value.field,\r\n originalValue: originalValue.value,\r\n })\r\n }\r\n\r\n editingCell.value = null\r\n editValue.value = null\r\n error.value = null\r\n currentItem.value = null\r\n originalValue.value = null\r\n }\r\n\r\n const updateValue = (value: unknown) => {\r\n editValue.value = value\r\n error.value = null // Clear error on value change\r\n }\r\n\r\n const editingItem = computed(() => currentItem.value)\r\n\r\n return {\r\n editingCell,\r\n editValue,\r\n error,\r\n saving,\r\n isEditing,\r\n startEdit,\r\n confirmEdit,\r\n cancelEdit,\r\n updateValue,\r\n editingItem,\r\n }\r\n}\r\n","import { ref, computed, onMounted, onUnmounted, type Ref, type ComputedRef } from 'vue'\r\n\r\nexport interface UseVirtualScrollOptions<T> {\r\n /** Array of items to virtualize */\r\n items: T[] | Ref<T[]>\r\n /** Height of each row in pixels */\r\n rowHeight: number\r\n /** Visible container height in pixels */\r\n containerHeight: number\r\n /** Number of rows to render outside visible area (buffer) */\r\n overscan?: number\r\n}\r\n\r\nexport interface UseVirtualScrollReturn<T> {\r\n /** Items to actually render */\r\n visibleItems: ComputedRef<T[]>\r\n /** Total height of all items (for scroll container) */\r\n totalHeight: ComputedRef<number>\r\n /** Top offset for the visible items container */\r\n offsetY: ComputedRef<number>\r\n /** Start index of visible items */\r\n startIndex: ComputedRef<number>\r\n /** End index of visible items */\r\n endIndex: ComputedRef<number>\r\n /** Scroll position */\r\n scrollTop: Ref<number>\r\n /** Handle scroll event */\r\n onScroll: (event: Event) => void\r\n /** Scroll to a specific index */\r\n scrollToIndex: (index: number) => void\r\n /** Container ref to attach to scrollable element */\r\n containerRef: Ref<HTMLElement | null>\r\n}\r\n\r\nexport function useVirtualScroll<T>(\r\n options: UseVirtualScrollOptions<T>\r\n): UseVirtualScrollReturn<T> {\r\n const {\r\n items: itemsOption,\r\n rowHeight,\r\n containerHeight,\r\n overscan = 3,\r\n } = options\r\n\r\n const scrollTop = ref(0)\r\n const containerRef = ref<HTMLElement | null>(null)\r\n\r\n const allItems = computed(() => {\r\n return 'value' in itemsOption ? itemsOption.value : itemsOption\r\n })\r\n\r\n const totalHeight = computed(() => {\r\n return allItems.value.length * rowHeight\r\n })\r\n\r\n // Calculate how many items fit in the visible area\r\n const visibleCount = computed(() => {\r\n return Math.ceil(containerHeight / rowHeight)\r\n })\r\n\r\n // Start index accounting for overscan\r\n const startIndex = computed(() => {\r\n const rawStart = Math.floor(scrollTop.value / rowHeight)\r\n return Math.max(0, rawStart - overscan)\r\n })\r\n\r\n // End index accounting for overscan\r\n const endIndex = computed(() => {\r\n const rawEnd = startIndex.value + visibleCount.value + overscan * 2\r\n return Math.min(allItems.value.length, rawEnd)\r\n })\r\n\r\n // Items to render\r\n const visibleItems = computed(() => {\r\n return allItems.value.slice(startIndex.value, endIndex.value)\r\n })\r\n\r\n // Offset to position the visible items correctly\r\n const offsetY = computed(() => {\r\n return startIndex.value * rowHeight\r\n })\r\n\r\n const onScroll = (event: Event) => {\r\n const target = event.target as HTMLElement\r\n scrollTop.value = target.scrollTop\r\n }\r\n\r\n const scrollToIndex = (index: number) => {\r\n const targetScroll = index * rowHeight\r\n if (containerRef.value) {\r\n containerRef.value.scrollTop = targetScroll\r\n }\r\n scrollTop.value = targetScroll\r\n }\r\n\r\n // Attach scroll listener if containerRef is set\r\n onMounted(() => {\r\n if (containerRef.value) {\r\n containerRef.value.addEventListener('scroll', onScroll, { passive: true })\r\n }\r\n })\r\n\r\n onUnmounted(() => {\r\n if (containerRef.value) {\r\n containerRef.value.removeEventListener('scroll', onScroll)\r\n }\r\n })\r\n\r\n return {\r\n visibleItems,\r\n totalHeight,\r\n offsetY,\r\n startIndex,\r\n endIndex,\r\n scrollTop,\r\n onScroll,\r\n scrollToIndex,\r\n containerRef,\r\n }\r\n}\r\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cisse-vue-ui",
3
- "version": "0.8.4",
3
+ "version": "0.9.0",
4
4
  "description": "Vue 3 + TypeScript + Tailwind CSS v4 component library",
5
5
  "author": "Cisse",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs","sources":["../src/components/feedback/LoadingSpinner.vue","../src/components/feedback/Modal.vue","../src/components/feedback/PaginationControls.vue","../src/components/feedback/NotificationComponent.vue","../src/components/feedback/NotificationList.vue","../src/components/feedback/Alert.vue","../src/components/feedback/EmptyState.vue","../src/components/feedback/Toast.vue","../src/components/feedback/ToastContainer.vue","../src/components/feedback/Progress.vue","../src/components/feedback/Skeleton.vue","../src/components/feedback/ConfirmDialog.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed } from 'vue'\nimport type { SpinnerSize } from '@/types'\n\nconst props = withDefaults(\n defineProps<{\n text?: string\n size?: SpinnerSize\n /** Accessible label for screen readers (defaults to 'Loading' or text prop) */\n ariaLabel?: string\n }>(),\n {\n size: 'md',\n ariaLabel: 'Loading',\n },\n)\n\nconst sizeClasses: Record<SpinnerSize, string> = {\n sm: 'size-8',\n md: 'size-12',\n lg: 'size-16',\n}\n\nconst accessibleLabel = computed(() => props.text || props.ariaLabel)\n</script>\n\n<template>\n <div\n class=\"flex items-center justify-center py-12\"\n role=\"status\"\n aria-live=\"polite\"\n :aria-label=\"accessibleLabel\"\n >\n <div class=\"text-center\">\n <div\n :class=\"sizeClasses[size]\"\n class=\"border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent\"\n aria-hidden=\"true\"\n />\n <p\n v-if=\"text\"\n class=\"mt-4 text-gray-600 dark:text-gray-400\"\n >\n {{ text }}\n </p>\n <span v-else class=\"sr-only\">{{ accessibleLabel }}</span>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport { onMounted, onUnmounted, computed, ref } from 'vue'\r\nimport type { ModalSize } from '@/types'\r\nimport { useId } from '@/composables/useId'\r\nimport { useFocusTrap } from '@/composables/useFocusTrap'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n title?: string\r\n size?: ModalSize\r\n closeOnBackdrop?: boolean\r\n closeOnEscape?: boolean\r\n closeButtonLabel?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n /** Custom ID for the modal (auto-generated if not provided) */\r\n id?: string\r\n }>(),\r\n {\r\n title: '',\r\n size: 'default',\r\n closeOnBackdrop: true,\r\n closeOnEscape: true,\r\n closeButtonLabel: 'Close',\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst {\r\n title,\r\n size,\r\n closeOnBackdrop,\r\n closeOnEscape,\r\n closeButtonLabel,\r\n} = props\r\n\r\nconst teleportDisabled = computed(() => props.teleport === false)\r\nconst teleportTarget = computed(() => props.teleport === false ? 'body' : props.teleport)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\n// Generate unique IDs for ARIA relationships\r\nconst { id: modalId, related } = useId({ prefix: 'modal', id: props.id })\r\nconst titleId = computed(() => related('title'))\r\n\r\n// Focus trap\r\nconst isActive = ref(true)\r\nconst { containerRef: dialogRef } = useFocusTrap({\r\n active: isActive,\r\n focusFirst: true,\r\n restoreFocus: true,\r\n})\r\n\r\n// Check if modal has a title (for aria-labelledby)\r\nconst hasTitle = computed(() => Boolean(props.title))\r\n\r\nconst sizeClasses: Record<ModalSize, string> = {\r\n sm: 'max-w-md',\r\n default: 'max-w-3xl',\r\n lg: 'max-w-5xl',\r\n xl: 'max-w-7xl',\r\n full: 'max-w-full mx-4',\r\n}\r\n\r\nconst handleBackdropClick = () => {\r\n if (closeOnBackdrop) {\r\n emit('close')\r\n }\r\n}\r\n\r\nconst handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && closeOnEscape) {\r\n emit('close')\r\n }\r\n}\r\n\r\nonMounted(() => {\r\n document.addEventListener('keydown', handleEscape)\r\n document.body.style.overflow = 'hidden'\r\n})\r\n\r\nonUnmounted(() => {\r\n document.removeEventListener('keydown', handleEscape)\r\n document.body.style.overflow = ''\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportDisabled\">\r\n <div\r\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\r\n @click.self=\"handleBackdropClick\"\r\n >\r\n <div\r\n ref=\"dialogRef\"\r\n :id=\"modalId\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n :aria-labelledby=\"hasTitle ? titleId : undefined\"\r\n :class=\"sizeClasses[size]\"\r\n class=\"flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900\"\r\n >\r\n <!-- Header -->\r\n <div\r\n v-if=\"title || $slots.header || $slots.title\"\r\n class=\"flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <h3\r\n :id=\"titleId\"\r\n class=\"text-xl font-semibold text-gray-900 dark:text-gray-100\"\r\n >\r\n <slot name=\"header\">\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </slot>\r\n </h3>\r\n <button\r\n class=\"rounded-lg p-1.5 text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100\"\r\n type=\"button\"\r\n aria-label=\"Close dialog\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n class=\"size-5\"\r\n icon=\"lucide:x\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"sr-only\">{{ closeButtonLabel }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Body -->\r\n <div class=\"flex-1 overflow-y-auto px-6 py-4\">\r\n <slot />\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div\r\n v-if=\"$slots.footer\"\r\n class=\"flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <slot name=\"footer\" />\r\n </div>\r\n </div>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\n\r\nconst {\r\n currentPage,\r\n totalPages,\r\n loading = false,\r\n pageSize = 10,\r\n pageSizeOptions = [10, 20, 50, 100],\r\n showPageSize = true,\r\n showPageNumbers = true,\r\n maxVisiblePages = 7,\r\n pageLabel = 'Page',\r\n ofLabel = 'of',\r\n itemsPerPageLabel = 'Items per page:',\r\n previousLabel = 'Previous',\r\n nextLabel = 'Next',\r\n} = defineProps<{\r\n currentPage: number\r\n totalPages: number\r\n loading?: boolean\r\n pageSize?: number\r\n pageSizeOptions?: number[]\r\n showPageSize?: boolean\r\n showPageNumbers?: boolean\r\n maxVisiblePages?: number\r\n pageLabel?: string\r\n ofLabel?: string\r\n itemsPerPageLabel?: string\r\n previousLabel?: string\r\n nextLabel?: string\r\n}>()\r\n\r\ntype PageItem = number | 'ellipsis-start' | 'ellipsis-end'\r\n\r\nconst visiblePages = computed<PageItem[]>(() => {\r\n if (totalPages <= maxVisiblePages) {\r\n return Array.from({ length: totalPages }, (_, i) => i + 1)\r\n }\r\n\r\n const pages: PageItem[] = []\r\n const sidePages = Math.floor((maxVisiblePages - 3) / 2)\r\n\r\n // Always show first page\r\n pages.push(1)\r\n\r\n // Calculate range around current page\r\n let rangeStart = Math.max(2, currentPage - sidePages)\r\n let rangeEnd = Math.min(totalPages - 1, currentPage + sidePages)\r\n\r\n // Adjust range to show more pages on one side if near edges\r\n if (currentPage <= sidePages + 2) {\r\n rangeEnd = Math.min(totalPages - 1, maxVisiblePages - 2)\r\n } else if (currentPage >= totalPages - sidePages - 1) {\r\n rangeStart = Math.max(2, totalPages - maxVisiblePages + 3)\r\n }\r\n\r\n // Add ellipsis or pages after first page\r\n if (rangeStart > 2) {\r\n pages.push('ellipsis-start')\r\n }\r\n\r\n // Add range pages\r\n for (let i = rangeStart; i <= rangeEnd; i++) {\r\n pages.push(i)\r\n }\r\n\r\n // Add ellipsis or pages before last page\r\n if (rangeEnd < totalPages - 1) {\r\n pages.push('ellipsis-end')\r\n }\r\n\r\n // Always show last page\r\n if (totalPages > 1) {\r\n pages.push(totalPages)\r\n }\r\n\r\n return pages\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:page': [page: number]\r\n 'update:pageSize': [size: number]\r\n}>()\r\n\r\nconst changePage = (page: number) => {\r\n if (page >= 1 && page <= totalPages && !loading) {\r\n emit('update:page', page)\r\n }\r\n}\r\n\r\nconst changePageSize = (event: Event) => {\r\n const target = event.target as HTMLSelectElement\r\n emit('update:pageSize', Number(target.value))\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"totalPages > 1\"\r\n class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 border-t border-gray-200 px-4 sm:px-6 py-4 dark:border-gray-700\"\r\n >\r\n <!-- Info and page size -->\r\n <div class=\"flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4\">\r\n <div class=\"text-sm text-gray-700 dark:text-gray-300 text-center sm:text-left\">\r\n {{ pageLabel }} {{ currentPage }} {{ ofLabel }} {{ totalPages }}\r\n </div>\r\n <div\r\n v-if=\"showPageSize\"\r\n class=\"flex items-center justify-center sm:justify-start gap-2\"\r\n >\r\n <label\r\n class=\"text-sm text-gray-600 dark:text-gray-400 hidden sm:inline\"\r\n for=\"page-size\"\r\n >\r\n {{ itemsPerPageLabel }}\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n :value=\"pageSize\"\r\n class=\"focus:border-primary focus:ring-primary rounded border border-gray-300 bg-white px-2 py-1 text-sm text-gray-900 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\r\n @change=\"changePageSize\"\r\n >\r\n <option\r\n v-for=\"size in pageSizeOptions\"\r\n :key=\"size\"\r\n :value=\"size\"\r\n >\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Navigation buttons -->\r\n <div class=\"flex justify-center sm:justify-end items-center gap-1\">\r\n <!-- Previous button -->\r\n <button\r\n :disabled=\"currentPage === 1 || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage - 1)\"\r\n >\r\n <Icon\r\n class=\"size-4\"\r\n icon=\"lucide:chevron-left\"\r\n />\r\n <span class=\"hidden sm:inline\">{{ previousLabel }}</span>\r\n </button>\r\n\r\n <!-- Page numbers -->\r\n <template v-if=\"showPageNumbers\">\r\n <template\r\n v-for=\"page in visiblePages\"\r\n :key=\"page\"\r\n >\r\n <!-- Ellipsis -->\r\n <span\r\n v-if=\"page === 'ellipsis-start' || page === 'ellipsis-end'\"\r\n class=\"px-2 py-2 text-sm text-gray-500 dark:text-gray-400\"\r\n >\r\n …\r\n </span>\r\n <!-- Page number button -->\r\n <button\r\n v-else\r\n :disabled=\"loading\"\r\n :class=\"[\r\n 'min-w-[40px] px-3 py-2 text-sm font-medium rounded-lg border transition-colors',\r\n page === currentPage\r\n ? 'bg-primary-600 text-white border-primary-600 dark:bg-primary-500 dark:border-primary-500'\r\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-700',\r\n loading ? 'cursor-not-allowed opacity-50' : ''\r\n ]\"\r\n @click=\"changePage(page)\"\r\n >\r\n {{ page }}\r\n </button>\r\n </template>\r\n </template>\r\n\r\n <!-- Next button -->\r\n <button\r\n :disabled=\"currentPage === totalPages || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage + 1)\"\r\n >\r\n <span class=\"hidden sm:inline\">{{ nextLabel }}</span>\r\n <Icon\r\n class=\"size-4\"\r\n icon=\"lucide:chevron-right\"\r\n />\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport { computed, onMounted } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nconst props = defineProps<{\n notification: Notification\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n\nconst iconName = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'lucide:check-circle'\n case 'info':\n return 'lucide:info'\n case 'warning':\n return 'lucide:alert-triangle'\n case 'error':\n return 'lucide:x-circle'\n default:\n return 'lucide:bell'\n }\n})\n\nconst iconColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'text-green-600 dark:text-green-400'\n case 'info':\n return 'text-blue-600 dark:text-blue-400'\n case 'warning':\n return 'text-yellow-600 dark:text-yellow-400'\n case 'error':\n return 'text-red-600 dark:text-red-400'\n default:\n return 'text-gray-600 dark:text-gray-400'\n }\n})\n\nconst bgColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'bg-green-50 dark:bg-green-950'\n case 'info':\n return 'bg-blue-50 dark:bg-blue-950'\n case 'warning':\n return 'bg-yellow-50 dark:bg-yellow-950'\n case 'error':\n return 'bg-red-50 dark:bg-red-950'\n default:\n return 'bg-gray-50 dark:bg-gray-950'\n }\n})\n\nconst handleDismiss = () => {\n if (props.notification.id) {\n emit('dismiss', props.notification.id)\n }\n}\n\nonMounted(() => {\n const duration = props.notification.duration ?? props.duration ?? 5000\n if (props.autoDismiss !== false && duration > 0) {\n setTimeout(() => {\n handleDismiss()\n }, duration)\n }\n})\n</script>\n\n<template>\n <div\n class=\"flex max-w-md items-start space-x-3 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-800 dark:bg-black\"\n >\n <div :class=\"[bgColor, 'flex items-center justify-center rounded-full p-2']\">\n <Icon\n :class=\"iconColor\"\n :icon=\"iconName\"\n class=\"size-5\"\n />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <h4\n v-if=\"notification.title\"\n class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\"\n >\n {{ notification.title }}\n </h4>\n <p\n v-if=\"notification.message\"\n class=\"mt-1 text-sm text-gray-600 dark:text-gray-400\"\n >\n {{ notification.message }}\n </p>\n </div>\n\n <button\n class=\"shrink-0 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-600 dark:hover:text-gray-400\"\n @click=\"handleDismiss\"\n >\n <Icon\n class=\"size-4\"\n icon=\"lucide:x\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport type { Notification } from '@/types'\r\nimport NotificationComponent from './NotificationComponent.vue'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n notifications: Notification[]\r\n autoDismiss?: boolean\r\n duration?: number\r\n /** Position of the container */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\r\n /** Custom top offset (e.g., '80px', '5rem') to account for fixed headers */\r\n topOffset?: string\r\n }>(),\r\n {\r\n position: 'top-right',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n dismiss: [id: string]\r\n}>()\r\n\r\nconst positionClasses: Record<string, string> = {\r\n 'top-right': 'top-5 right-5',\r\n 'top-left': 'top-5 left-5',\r\n 'bottom-right': 'bottom-5 right-5',\r\n 'bottom-left': 'bottom-5 left-5',\r\n}\r\n\r\nconst isTopPosition = computed(() => props.position?.startsWith('top'))\r\n\r\nconst topStyle = computed(() => {\r\n if (!isTopPosition.value || !props.topOffset) return {}\r\n return { top: props.topOffset }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport to=\"body\">\r\n <div\r\n :class=\"['fixed z-50 flex flex-col gap-3 w-full max-w-sm', positionClasses[position]]\"\r\n :style=\"topStyle\"\r\n >\r\n <TransitionGroup\r\n enter-active-class=\"transition duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 translate-x-4\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 translate-x-4\"\r\n >\r\n <NotificationComponent\r\n v-for=\"notification in notifications\"\r\n :key=\"notification.id\"\r\n :notification=\"notification\"\r\n :auto-dismiss=\"autoDismiss\"\r\n :duration=\"duration\"\r\n @dismiss=\"emit('dismiss', $event)\"\r\n />\r\n </TransitionGroup>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'error'\n\nconst props = withDefaults(\n defineProps<{\n /** Alert variant */\n variant?: AlertVariant\n /** Title text */\n title?: string\n /** Show close button */\n dismissible?: boolean\n /** Custom icon */\n icon?: string\n }>(),\n {\n variant: 'info',\n },\n)\n\nconst emit = defineEmits<{\n dismiss: []\n}>()\n\nconst variantStyles: Record<AlertVariant, { bg: string; border: string; icon: string; iconColor: string }> = {\n info: {\n bg: 'bg-blue-50 dark:bg-blue-900/20',\n border: 'border-blue-200 dark:border-blue-800',\n icon: 'lucide:info',\n iconColor: 'text-blue-500',\n },\n success: {\n bg: 'bg-green-50 dark:bg-green-900/20',\n border: 'border-green-200 dark:border-green-800',\n icon: 'lucide:check-circle',\n iconColor: 'text-green-500',\n },\n warning: {\n bg: 'bg-yellow-50 dark:bg-yellow-900/20',\n border: 'border-yellow-200 dark:border-yellow-800',\n icon: 'lucide:alert-triangle',\n iconColor: 'text-yellow-500',\n },\n error: {\n bg: 'bg-red-50 dark:bg-red-900/20',\n border: 'border-red-200 dark:border-red-800',\n icon: 'lucide:alert-circle',\n iconColor: 'text-red-500',\n },\n}\n\nconst styles = variantStyles[props.variant]\n</script>\n\n<template>\n <div\n :class=\"[\n 'flex gap-3 rounded-lg border p-4',\n styles.bg,\n styles.border,\n ]\"\n role=\"alert\"\n >\n <Icon\n :icon=\"icon || styles.icon\"\n :class=\"['size-5 shrink-0', styles.iconColor]\"\n aria-hidden=\"true\"\n />\n <div class=\"flex-1\">\n <h4\n v-if=\"title\"\n class=\"mb-1 font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h4>\n <div class=\"text-sm text-gray-700 dark:text-gray-300\">\n <slot />\n </div>\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\n aria-label=\"Dismiss alert\"\n @click=\"emit('dismiss')\"\n >\n <Icon\n icon=\"lucide:x\"\n class=\"size-4\"\n aria-hidden=\"true\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nwithDefaults(\n defineProps<{\n /** Message to display */\n message?: string\n /** Icon name (iconify format) */\n icon?: string\n /** Title text */\n title?: string\n }>(),\n {\n message: 'No results found',\n icon: 'lucide:inbox',\n },\n)\n</script>\n\n<template>\n <div class=\"py-12 text-center\">\n <Icon\n v-if=\"icon\"\n :icon=\"icon\"\n class=\"mx-auto mb-4 size-12 text-gray-400 dark:text-gray-500\"\n />\n <h3\n v-if=\"title\"\n class=\"mb-2 text-lg font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h3>\n <p class=\"text-gray-500 dark:text-gray-400\">\n <slot>{{ message }}</slot>\n </p>\n <div\n v-if=\"$slots.action\"\n class=\"mt-4\"\n >\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\n\r\nexport type ToastType = 'success' | 'error' | 'warning' | 'info'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Toast message */\r\n message: string\r\n /** Toast type */\r\n type?: ToastType\r\n /** Title (optional) */\r\n title?: string\r\n /** Show close button */\r\n closable?: boolean\r\n /** Duration in ms (0 = no auto-close) */\r\n duration?: number\r\n }>(),\r\n {\r\n type: 'info',\r\n closable: true,\r\n duration: 5000,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\nconst typeConfig: Record<ToastType, { icon: string; bg: string; iconColor: string }> = {\r\n success: {\r\n icon: 'lucide:check-circle',\r\n bg: 'bg-green-50 border-green-200 dark:bg-green-950 dark:border-green-800',\r\n iconColor: 'text-green-500',\r\n },\r\n error: {\r\n icon: 'lucide:x-circle',\r\n bg: 'bg-red-50 border-red-200 dark:bg-red-950 dark:border-red-800',\r\n iconColor: 'text-red-500',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n bg: 'bg-yellow-50 border-yellow-200 dark:bg-yellow-950 dark:border-yellow-800',\r\n iconColor: 'text-yellow-500',\r\n },\r\n info: {\r\n icon: 'lucide:info',\r\n bg: 'bg-blue-50 border-blue-200 dark:bg-blue-950 dark:border-blue-800',\r\n iconColor: 'text-blue-500',\r\n },\r\n}\r\n\r\nconst config = typeConfig[props.type]\r\n\r\n// Auto-close\r\nif (props.duration > 0) {\r\n setTimeout(() => {\r\n emit('close')\r\n }, props.duration)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n :class=\"[\r\n 'flex items-start gap-3 rounded-lg border p-4 shadow-lg',\r\n config.bg,\r\n ]\"\r\n role=\"alert\"\r\n >\r\n <Icon\r\n :icon=\"config.icon\"\r\n :class=\"['size-5 shrink-0', config.iconColor]\"\r\n aria-hidden=\"true\"\r\n />\r\n <div class=\"flex-1 min-w-0\">\r\n <p\r\n v-if=\"title\"\r\n class=\"font-medium text-gray-900 dark:text-white\"\r\n >\r\n {{ title }}\r\n </p>\r\n <p class=\"text-sm text-gray-700 dark:text-gray-300\">\r\n {{ message }}\r\n </p>\r\n </div>\r\n <button\r\n v-if=\"closable\"\r\n type=\"button\"\r\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\r\n aria-label=\"Dismiss notification\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n icon=\"lucide:x\"\r\n class=\"size-4\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport Toast from './Toast.vue'\r\nimport type { ToastType } from './Toast.vue'\r\n\r\nexport interface ToastItem {\r\n id: string\r\n message: string\r\n type?: ToastType\r\n title?: string\r\n duration?: number\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Array of toast items */\r\n toasts: ToastItem[]\r\n /** Position of the container */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'\r\n /** Custom top offset (e.g., '80px', '5rem') to account for fixed headers */\r\n topOffset?: string\r\n }>(),\r\n {\r\n position: 'top-right',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: [id: string]\r\n}>()\r\n\r\nconst positionClasses: Record<string, string> = {\r\n 'top-right': 'right-4',\r\n 'top-left': 'left-4',\r\n 'bottom-right': 'bottom-4 right-4',\r\n 'bottom-left': 'bottom-4 left-4',\r\n 'top-center': 'left-1/2 -translate-x-1/2',\r\n 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2',\r\n}\r\n\r\nconst isTopPosition = computed(() => props.position?.startsWith('top'))\r\n\r\nconst topStyle = computed(() => {\r\n if (!isTopPosition.value) return {}\r\n return { top: props.topOffset || '1rem' }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport to=\"body\">\r\n <div\r\n :class=\"['fixed z-9999 flex flex-col gap-2 w-full max-w-sm', positionClasses[position]]\"\r\n :style=\"topStyle\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"false\"\r\n >\r\n <TransitionGroup\r\n enter-active-class=\"transition duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 translate-x-4\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 translate-x-4\"\r\n >\r\n <Toast\r\n v-for=\"toast in toasts\"\r\n :key=\"toast.id\"\r\n :message=\"toast.message\"\r\n :type=\"toast.type\"\r\n :title=\"toast.title\"\r\n :duration=\"toast.duration\"\r\n @close=\"emit('close', toast.id)\"\r\n />\r\n </TransitionGroup>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\n\r\nexport type ProgressSize = 'sm' | 'md' | 'lg'\r\nexport type ProgressVariant = 'default' | 'success' | 'warning' | 'error'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current value (0-100) */\r\n value: number\r\n /** Maximum value */\r\n max?: number\r\n /** Size variant */\r\n size?: ProgressSize\r\n /** Color variant */\r\n variant?: ProgressVariant\r\n /** Show percentage label */\r\n showLabel?: boolean\r\n /** Striped animation */\r\n striped?: boolean\r\n /** Animated stripes */\r\n animated?: boolean\r\n /** Indeterminate state (loading) */\r\n indeterminate?: boolean\r\n }>(),\r\n {\r\n max: 100,\r\n size: 'md',\r\n variant: 'default',\r\n showLabel: false,\r\n striped: false,\r\n animated: false,\r\n indeterminate: false,\r\n },\r\n)\r\n\r\nconst percentage = computed(() => {\r\n if (props.indeterminate) return 100\r\n return Math.min(Math.max((props.value / props.max) * 100, 0), 100)\r\n})\r\n\r\nconst sizeClasses: Record<ProgressSize, string> = {\r\n sm: 'h-1',\r\n md: 'h-2',\r\n lg: 'h-4',\r\n}\r\n\r\nconst variantClasses: Record<ProgressVariant, string> = {\r\n default: 'bg-primary',\r\n success: 'bg-green-500',\r\n warning: 'bg-yellow-500',\r\n error: 'bg-red-500',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <div\n v-if=\"showLabel && !indeterminate\"\n class=\"mb-1 flex justify-between text-sm\"\n >\r\n <span class=\"text-gray-600 dark:text-gray-400\">Progress</span>\r\n <span class=\"font-medium text-gray-900 dark:text-white\">{{ Math.round(percentage) }}%</span>\r\n </div>\r\n <div\r\n :class=\"[\r\n 'w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700',\r\n sizeClasses[size],\r\n ]\"\r\n role=\"progressbar\"\r\n :aria-valuenow=\"indeterminate ? undefined : value\"\r\n :aria-valuemin=\"0\"\r\n :aria-valuemax=\"max\"\r\n >\r\n <div\r\n :class=\"[\r\n 'h-full rounded-full transition-all duration-300',\r\n variantClasses[variant],\r\n striped && 'bg-stripes',\r\n animated && 'animate-stripes',\r\n indeterminate && 'animate-indeterminate',\r\n ]\"\r\n :style=\"{ width: indeterminate ? '30%' : `${percentage}%` }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.bg-stripes {\r\n background-image: linear-gradient(\r\n 45deg,\r\n rgba(255, 255, 255, 0.15) 25%,\r\n transparent 25%,\r\n transparent 50%,\r\n rgba(255, 255, 255, 0.15) 50%,\r\n rgba(255, 255, 255, 0.15) 75%,\r\n transparent 75%,\r\n transparent\r\n );\r\n background-size: 1rem 1rem;\r\n}\r\n\r\n.animate-stripes {\r\n animation: stripes 1s linear infinite;\r\n}\r\n\r\n@keyframes stripes {\r\n from {\r\n background-position: 1rem 0;\r\n }\r\n to {\r\n background-position: 0 0;\r\n }\r\n}\r\n\r\n.animate-indeterminate {\r\n animation: indeterminate 1.5s ease-in-out infinite;\r\n}\r\n\r\n@keyframes indeterminate {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nexport type SkeletonVariant = 'text' | 'circular' | 'rectangular' | 'rounded'\r\n\r\nwithDefaults(\r\n defineProps<{\r\n /** Variant style */\r\n variant?: SkeletonVariant\r\n /** Width (CSS value) */\r\n width?: string\r\n /** Height (CSS value) */\r\n height?: string\r\n /** Number of lines (for text variant) */\r\n lines?: number\r\n /** Animate the skeleton */\r\n animate?: boolean\r\n }>(),\r\n {\r\n variant: 'text',\r\n animate: true,\r\n lines: 1,\r\n },\r\n)\r\n\r\nconst variantClasses: Record<SkeletonVariant, string> = {\r\n text: 'h-4 rounded',\r\n circular: 'rounded-full',\r\n rectangular: '',\r\n rounded: 'rounded-lg',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"variant === 'text' && lines > 1\"\r\n class=\"space-y-2\"\r\n aria-hidden=\"true\"\r\n >\r\n <div\r\n v-for=\"i in lines\"\r\n :key=\"i\"\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: i === lines ? '75%' : width || '100%',\r\n height: height,\r\n }\"\r\n />\r\n </div>\r\n <div\r\n v-else\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: width || (variant === 'circular' ? '3rem' : '100%'),\r\n height: height || (variant === 'circular' ? '3rem' : variant === 'text' ? '1rem' : '6rem'),\r\n }\"\r\n aria-hidden=\"true\"\r\n />\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport Modal from './Modal.vue'\r\nimport Button from '@/components/core/Button.vue'\r\n\r\nexport type ConfirmDialogVariant = 'info' | 'warning' | 'danger' | 'success'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Whether the dialog is open */\r\n open?: boolean\r\n /** Dialog title */\r\n title?: string\r\n /** Dialog message */\r\n message?: string\r\n /** Confirm button text */\r\n confirmText?: string\r\n /** Cancel button text */\r\n cancelText?: string\r\n /** Dialog variant (affects icon and confirm button color) */\r\n variant?: ConfirmDialogVariant\r\n /** Show loading state on confirm button */\r\n loading?: boolean\r\n /** Icon to display */\r\n icon?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n }>(),\r\n {\r\n open: false,\r\n title: 'Confirm',\r\n message: 'Are you sure you want to proceed?',\r\n confirmText: 'Confirm',\r\n cancelText: 'Cancel',\r\n variant: 'info',\r\n loading: false,\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n cancel: []\r\n}>()\r\n\r\nconst variantConfig: Record<ConfirmDialogVariant, { icon: string; iconClass: string; buttonVariant: 'primary' | 'danger' | 'success' }> = {\r\n info: {\r\n icon: 'lucide:info',\r\n iconClass: 'text-blue-500',\r\n buttonVariant: 'primary',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n iconClass: 'text-yellow-500',\r\n buttonVariant: 'primary',\r\n },\r\n danger: {\r\n icon: 'lucide:alert-circle',\r\n iconClass: 'text-red-500',\r\n buttonVariant: 'danger',\r\n },\r\n success: {\r\n icon: 'lucide:check-circle',\r\n iconClass: 'text-green-500',\r\n buttonVariant: 'success',\r\n },\r\n}\r\n\r\nconst config = variantConfig[props.variant]\r\n</script>\r\n\r\n<template>\r\n <Modal\r\n v-if=\"open\"\r\n size=\"sm\"\r\n :close-on-backdrop=\"!loading\"\r\n :close-on-escape=\"!loading\"\r\n :teleport=\"teleport\"\r\n @close=\"emit('cancel')\"\r\n >\r\n <div class=\"text-center\">\r\n <!-- Icon -->\r\n <div class=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800\">\r\n <Icon\r\n :icon=\"icon || config.icon\"\r\n :class=\"[config.iconClass, 'size-8']\"\r\n />\r\n </div>\r\n\r\n <!-- Title -->\r\n <h3 class=\"mb-2 text-lg font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ title }}\r\n </h3>\r\n\r\n <!-- Message -->\r\n <p class=\"mb-6 text-gray-600 dark:text-gray-400\">\r\n <slot>{{ message }}</slot>\r\n </p>\r\n\r\n <!-- Actions -->\r\n <div class=\"flex justify-center gap-3\">\r\n <Button\r\n variant=\"outline\"\r\n :disabled=\"loading\"\r\n @click=\"emit('cancel')\"\r\n >\r\n {{ cancelText }}\r\n </Button>\r\n <Button\r\n :variant=\"config.buttonVariant\"\r\n :loading=\"loading\"\r\n @click=\"emit('confirm')\"\r\n >\r\n {{ confirmText }}\r\n </Button>\r\n </div>\r\n </div>\r\n </Modal>\r\n</template>\r\n"],"names":["computed","_createElementBlock","_createElementVNode","_hoisted_2","_normalizeClass","_hoisted_3","_toDisplayString","_hoisted_4","useId","ref","useFocusTrap","onMounted","onUnmounted","_createBlock","_Teleport","_unref","$slots","_openBlock","_renderSlot","_createVNode","Icon","_hoisted_5","_hoisted_6","_hoisted_1","_Fragment","_renderList","_TransitionGroup","NotificationComponent","Toast","_normalizeStyle","Modal","Button"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js","sources":["../src/components/feedback/LoadingSpinner.vue","../src/components/feedback/Modal.vue","../src/components/feedback/PaginationControls.vue","../src/components/feedback/NotificationComponent.vue","../src/components/feedback/NotificationList.vue","../src/components/feedback/Alert.vue","../src/components/feedback/EmptyState.vue","../src/components/feedback/Toast.vue","../src/components/feedback/ToastContainer.vue","../src/components/feedback/Progress.vue","../src/components/feedback/Skeleton.vue","../src/components/feedback/ConfirmDialog.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed } from 'vue'\nimport type { SpinnerSize } from '@/types'\n\nconst props = withDefaults(\n defineProps<{\n text?: string\n size?: SpinnerSize\n /** Accessible label for screen readers (defaults to 'Loading' or text prop) */\n ariaLabel?: string\n }>(),\n {\n size: 'md',\n ariaLabel: 'Loading',\n },\n)\n\nconst sizeClasses: Record<SpinnerSize, string> = {\n sm: 'size-8',\n md: 'size-12',\n lg: 'size-16',\n}\n\nconst accessibleLabel = computed(() => props.text || props.ariaLabel)\n</script>\n\n<template>\n <div\n class=\"flex items-center justify-center py-12\"\n role=\"status\"\n aria-live=\"polite\"\n :aria-label=\"accessibleLabel\"\n >\n <div class=\"text-center\">\n <div\n :class=\"sizeClasses[size]\"\n class=\"border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent\"\n aria-hidden=\"true\"\n />\n <p\n v-if=\"text\"\n class=\"mt-4 text-gray-600 dark:text-gray-400\"\n >\n {{ text }}\n </p>\n <span v-else class=\"sr-only\">{{ accessibleLabel }}</span>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport { onMounted, onUnmounted, computed, ref } from 'vue'\r\nimport type { ModalSize } from '@/types'\r\nimport { useId } from '@/composables/useId'\r\nimport { useFocusTrap } from '@/composables/useFocusTrap'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n title?: string\r\n size?: ModalSize\r\n closeOnBackdrop?: boolean\r\n closeOnEscape?: boolean\r\n closeButtonLabel?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n /** Custom ID for the modal (auto-generated if not provided) */\r\n id?: string\r\n }>(),\r\n {\r\n title: '',\r\n size: 'default',\r\n closeOnBackdrop: true,\r\n closeOnEscape: true,\r\n closeButtonLabel: 'Close',\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst {\r\n title,\r\n size,\r\n closeOnBackdrop,\r\n closeOnEscape,\r\n closeButtonLabel,\r\n} = props\r\n\r\nconst teleportDisabled = computed(() => props.teleport === false)\r\nconst teleportTarget = computed(() => props.teleport === false ? 'body' : props.teleport)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\n// Generate unique IDs for ARIA relationships\r\nconst { id: modalId, related } = useId({ prefix: 'modal', id: props.id })\r\nconst titleId = computed(() => related('title'))\r\n\r\n// Focus trap\r\nconst isActive = ref(true)\r\nconst { containerRef: dialogRef } = useFocusTrap({\r\n active: isActive,\r\n focusFirst: true,\r\n restoreFocus: true,\r\n})\r\n\r\n// Check if modal has a title (for aria-labelledby)\r\nconst hasTitle = computed(() => Boolean(props.title))\r\n\r\nconst sizeClasses: Record<ModalSize, string> = {\r\n sm: 'max-w-md',\r\n default: 'max-w-3xl',\r\n lg: 'max-w-5xl',\r\n xl: 'max-w-7xl',\r\n full: 'max-w-full mx-4',\r\n}\r\n\r\nconst handleBackdropClick = () => {\r\n if (closeOnBackdrop) {\r\n emit('close')\r\n }\r\n}\r\n\r\nconst handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && closeOnEscape) {\r\n emit('close')\r\n }\r\n}\r\n\r\nonMounted(() => {\r\n document.addEventListener('keydown', handleEscape)\r\n document.body.style.overflow = 'hidden'\r\n})\r\n\r\nonUnmounted(() => {\r\n document.removeEventListener('keydown', handleEscape)\r\n document.body.style.overflow = ''\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportDisabled\">\r\n <div\r\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\r\n @click.self=\"handleBackdropClick\"\r\n >\r\n <div\r\n ref=\"dialogRef\"\r\n :id=\"modalId\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n :aria-labelledby=\"hasTitle ? titleId : undefined\"\r\n :class=\"sizeClasses[size]\"\r\n class=\"flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900\"\r\n >\r\n <!-- Header -->\r\n <div\r\n v-if=\"title || $slots.header || $slots.title\"\r\n class=\"flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <h3\r\n :id=\"titleId\"\r\n class=\"text-xl font-semibold text-gray-900 dark:text-gray-100\"\r\n >\r\n <slot name=\"header\">\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </slot>\r\n </h3>\r\n <button\r\n class=\"rounded-lg p-1.5 text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100\"\r\n type=\"button\"\r\n aria-label=\"Close dialog\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n class=\"size-5\"\r\n icon=\"lucide:x\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"sr-only\">{{ closeButtonLabel }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Body -->\r\n <div class=\"flex-1 overflow-y-auto px-6 py-4\">\r\n <slot />\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div\r\n v-if=\"$slots.footer\"\r\n class=\"flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <slot name=\"footer\" />\r\n </div>\r\n </div>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\n\r\nconst {\r\n currentPage,\r\n totalPages,\r\n loading = false,\r\n pageSize = 10,\r\n pageSizeOptions = [10, 20, 50, 100],\r\n showPageSize = true,\r\n showPageNumbers = true,\r\n maxVisiblePages = 7,\r\n pageLabel = 'Page',\r\n ofLabel = 'of',\r\n itemsPerPageLabel = 'Items per page:',\r\n previousLabel = 'Previous',\r\n nextLabel = 'Next',\r\n} = defineProps<{\r\n currentPage: number\r\n totalPages: number\r\n loading?: boolean\r\n pageSize?: number\r\n pageSizeOptions?: number[]\r\n showPageSize?: boolean\r\n showPageNumbers?: boolean\r\n maxVisiblePages?: number\r\n pageLabel?: string\r\n ofLabel?: string\r\n itemsPerPageLabel?: string\r\n previousLabel?: string\r\n nextLabel?: string\r\n}>()\r\n\r\ntype PageItem = number | 'ellipsis-start' | 'ellipsis-end'\r\n\r\nconst visiblePages = computed<PageItem[]>(() => {\r\n if (totalPages <= maxVisiblePages) {\r\n return Array.from({ length: totalPages }, (_, i) => i + 1)\r\n }\r\n\r\n const pages: PageItem[] = []\r\n const sidePages = Math.floor((maxVisiblePages - 3) / 2)\r\n\r\n // Always show first page\r\n pages.push(1)\r\n\r\n // Calculate range around current page\r\n let rangeStart = Math.max(2, currentPage - sidePages)\r\n let rangeEnd = Math.min(totalPages - 1, currentPage + sidePages)\r\n\r\n // Adjust range to show more pages on one side if near edges\r\n if (currentPage <= sidePages + 2) {\r\n rangeEnd = Math.min(totalPages - 1, maxVisiblePages - 2)\r\n } else if (currentPage >= totalPages - sidePages - 1) {\r\n rangeStart = Math.max(2, totalPages - maxVisiblePages + 3)\r\n }\r\n\r\n // Add ellipsis or pages after first page\r\n if (rangeStart > 2) {\r\n pages.push('ellipsis-start')\r\n }\r\n\r\n // Add range pages\r\n for (let i = rangeStart; i <= rangeEnd; i++) {\r\n pages.push(i)\r\n }\r\n\r\n // Add ellipsis or pages before last page\r\n if (rangeEnd < totalPages - 1) {\r\n pages.push('ellipsis-end')\r\n }\r\n\r\n // Always show last page\r\n if (totalPages > 1) {\r\n pages.push(totalPages)\r\n }\r\n\r\n return pages\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:page': [page: number]\r\n 'update:pageSize': [size: number]\r\n}>()\r\n\r\nconst changePage = (page: number) => {\r\n if (page >= 1 && page <= totalPages && !loading) {\r\n emit('update:page', page)\r\n }\r\n}\r\n\r\nconst changePageSize = (event: Event) => {\r\n const target = event.target as HTMLSelectElement\r\n emit('update:pageSize', Number(target.value))\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"totalPages > 1\"\r\n class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 border-t border-gray-200 px-4 sm:px-6 py-4 dark:border-gray-700\"\r\n >\r\n <!-- Info and page size -->\r\n <div class=\"flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4\">\r\n <div class=\"text-sm text-gray-700 dark:text-gray-300 text-center sm:text-left\">\r\n {{ pageLabel }} {{ currentPage }} {{ ofLabel }} {{ totalPages }}\r\n </div>\r\n <div\r\n v-if=\"showPageSize\"\r\n class=\"flex items-center justify-center sm:justify-start gap-2\"\r\n >\r\n <label\r\n class=\"text-sm text-gray-600 dark:text-gray-400 hidden sm:inline\"\r\n for=\"page-size\"\r\n >\r\n {{ itemsPerPageLabel }}\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n :value=\"pageSize\"\r\n class=\"focus:border-primary focus:ring-primary rounded border border-gray-300 bg-white px-2 py-1 text-sm text-gray-900 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\r\n @change=\"changePageSize\"\r\n >\r\n <option\r\n v-for=\"size in pageSizeOptions\"\r\n :key=\"size\"\r\n :value=\"size\"\r\n >\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Navigation buttons -->\r\n <div class=\"flex justify-center sm:justify-end items-center gap-1\">\r\n <!-- Previous button -->\r\n <button\r\n :disabled=\"currentPage === 1 || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage - 1)\"\r\n >\r\n <Icon\r\n class=\"size-4\"\r\n icon=\"lucide:chevron-left\"\r\n />\r\n <span class=\"hidden sm:inline\">{{ previousLabel }}</span>\r\n </button>\r\n\r\n <!-- Page numbers -->\r\n <template v-if=\"showPageNumbers\">\r\n <template\r\n v-for=\"page in visiblePages\"\r\n :key=\"page\"\r\n >\r\n <!-- Ellipsis -->\r\n <span\r\n v-if=\"page === 'ellipsis-start' || page === 'ellipsis-end'\"\r\n class=\"px-2 py-2 text-sm text-gray-500 dark:text-gray-400\"\r\n >\r\n …\r\n </span>\r\n <!-- Page number button -->\r\n <button\r\n v-else\r\n :disabled=\"loading\"\r\n :class=\"[\r\n 'min-w-[40px] px-3 py-2 text-sm font-medium rounded-lg border transition-colors',\r\n page === currentPage\r\n ? 'bg-primary-600 text-white border-primary-600 dark:bg-primary-500 dark:border-primary-500'\r\n : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-700',\r\n loading ? 'cursor-not-allowed opacity-50' : ''\r\n ]\"\r\n @click=\"changePage(page)\"\r\n >\r\n {{ page }}\r\n </button>\r\n </template>\r\n </template>\r\n\r\n <!-- Next button -->\r\n <button\r\n :disabled=\"currentPage === totalPages || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage + 1)\"\r\n >\r\n <span class=\"hidden sm:inline\">{{ nextLabel }}</span>\r\n <Icon\r\n class=\"size-4\"\r\n icon=\"lucide:chevron-right\"\r\n />\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport { computed, onMounted } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nconst props = defineProps<{\n notification: Notification\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n\nconst iconName = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'lucide:check-circle'\n case 'info':\n return 'lucide:info'\n case 'warning':\n return 'lucide:alert-triangle'\n case 'error':\n return 'lucide:x-circle'\n default:\n return 'lucide:bell'\n }\n})\n\nconst iconColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'text-green-600 dark:text-green-400'\n case 'info':\n return 'text-blue-600 dark:text-blue-400'\n case 'warning':\n return 'text-yellow-600 dark:text-yellow-400'\n case 'error':\n return 'text-red-600 dark:text-red-400'\n default:\n return 'text-gray-600 dark:text-gray-400'\n }\n})\n\nconst bgColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'bg-green-50 dark:bg-green-950'\n case 'info':\n return 'bg-blue-50 dark:bg-blue-950'\n case 'warning':\n return 'bg-yellow-50 dark:bg-yellow-950'\n case 'error':\n return 'bg-red-50 dark:bg-red-950'\n default:\n return 'bg-gray-50 dark:bg-gray-950'\n }\n})\n\nconst handleDismiss = () => {\n if (props.notification.id) {\n emit('dismiss', props.notification.id)\n }\n}\n\nonMounted(() => {\n const duration = props.notification.duration ?? props.duration ?? 5000\n if (props.autoDismiss !== false && duration > 0) {\n setTimeout(() => {\n handleDismiss()\n }, duration)\n }\n})\n</script>\n\n<template>\n <div\n class=\"flex max-w-md items-start space-x-3 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-800 dark:bg-black\"\n >\n <div :class=\"[bgColor, 'flex items-center justify-center rounded-full p-2']\">\n <Icon\n :class=\"iconColor\"\n :icon=\"iconName\"\n class=\"size-5\"\n />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <h4\n v-if=\"notification.title\"\n class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\"\n >\n {{ notification.title }}\n </h4>\n <p\n v-if=\"notification.message\"\n class=\"mt-1 text-sm text-gray-600 dark:text-gray-400\"\n >\n {{ notification.message }}\n </p>\n </div>\n\n <button\n class=\"shrink-0 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-600 dark:hover:text-gray-400\"\n @click=\"handleDismiss\"\n >\n <Icon\n class=\"size-4\"\n icon=\"lucide:x\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport type { Notification } from '@/types'\r\nimport NotificationComponent from './NotificationComponent.vue'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n notifications: Notification[]\r\n autoDismiss?: boolean\r\n duration?: number\r\n /** Position of the container */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\r\n /** Custom top offset (e.g., '80px', '5rem') to account for fixed headers */\r\n topOffset?: string\r\n }>(),\r\n {\r\n position: 'top-right',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n dismiss: [id: string]\r\n}>()\r\n\r\nconst positionClasses: Record<string, string> = {\r\n 'top-right': 'top-5 right-5',\r\n 'top-left': 'top-5 left-5',\r\n 'bottom-right': 'bottom-5 right-5',\r\n 'bottom-left': 'bottom-5 left-5',\r\n}\r\n\r\nconst isTopPosition = computed(() => props.position?.startsWith('top'))\r\n\r\nconst topStyle = computed(() => {\r\n if (!isTopPosition.value || !props.topOffset) return {}\r\n return { top: props.topOffset }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport to=\"body\">\r\n <div\r\n :class=\"['fixed z-50 flex flex-col gap-3 w-full max-w-sm', positionClasses[position]]\"\r\n :style=\"topStyle\"\r\n >\r\n <TransitionGroup\r\n enter-active-class=\"transition duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 translate-x-4\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 translate-x-4\"\r\n >\r\n <NotificationComponent\r\n v-for=\"notification in notifications\"\r\n :key=\"notification.id\"\r\n :notification=\"notification\"\r\n :auto-dismiss=\"autoDismiss\"\r\n :duration=\"duration\"\r\n @dismiss=\"emit('dismiss', $event)\"\r\n />\r\n </TransitionGroup>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'error'\n\nconst props = withDefaults(\n defineProps<{\n /** Alert variant */\n variant?: AlertVariant\n /** Title text */\n title?: string\n /** Show close button */\n dismissible?: boolean\n /** Custom icon */\n icon?: string\n }>(),\n {\n variant: 'info',\n },\n)\n\nconst emit = defineEmits<{\n dismiss: []\n}>()\n\nconst variantStyles: Record<AlertVariant, { bg: string; border: string; icon: string; iconColor: string }> = {\n info: {\n bg: 'bg-blue-50 dark:bg-blue-900/20',\n border: 'border-blue-200 dark:border-blue-800',\n icon: 'lucide:info',\n iconColor: 'text-blue-500',\n },\n success: {\n bg: 'bg-green-50 dark:bg-green-900/20',\n border: 'border-green-200 dark:border-green-800',\n icon: 'lucide:check-circle',\n iconColor: 'text-green-500',\n },\n warning: {\n bg: 'bg-yellow-50 dark:bg-yellow-900/20',\n border: 'border-yellow-200 dark:border-yellow-800',\n icon: 'lucide:alert-triangle',\n iconColor: 'text-yellow-500',\n },\n error: {\n bg: 'bg-red-50 dark:bg-red-900/20',\n border: 'border-red-200 dark:border-red-800',\n icon: 'lucide:alert-circle',\n iconColor: 'text-red-500',\n },\n}\n\nconst styles = variantStyles[props.variant]\n</script>\n\n<template>\n <div\n :class=\"[\n 'flex gap-3 rounded-lg border p-4',\n styles.bg,\n styles.border,\n ]\"\n role=\"alert\"\n >\n <Icon\n :icon=\"icon || styles.icon\"\n :class=\"['size-5 shrink-0', styles.iconColor]\"\n aria-hidden=\"true\"\n />\n <div class=\"flex-1\">\n <h4\n v-if=\"title\"\n class=\"mb-1 font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h4>\n <div class=\"text-sm text-gray-700 dark:text-gray-300\">\n <slot />\n </div>\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\n aria-label=\"Dismiss alert\"\n @click=\"emit('dismiss')\"\n >\n <Icon\n icon=\"lucide:x\"\n class=\"size-4\"\n aria-hidden=\"true\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nwithDefaults(\n defineProps<{\n /** Message to display */\n message?: string\n /** Icon name (iconify format) */\n icon?: string\n /** Title text */\n title?: string\n }>(),\n {\n message: 'No results found',\n icon: 'lucide:inbox',\n },\n)\n</script>\n\n<template>\n <div class=\"py-12 text-center\">\n <Icon\n v-if=\"icon\"\n :icon=\"icon\"\n class=\"mx-auto mb-4 size-12 text-gray-400 dark:text-gray-500\"\n />\n <h3\n v-if=\"title\"\n class=\"mb-2 text-lg font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h3>\n <p class=\"text-gray-500 dark:text-gray-400\">\n <slot>{{ message }}</slot>\n </p>\n <div\n v-if=\"$slots.action\"\n class=\"mt-4\"\n >\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\n\r\nexport type ToastType = 'success' | 'error' | 'warning' | 'info'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Toast message */\r\n message: string\r\n /** Toast type */\r\n type?: ToastType\r\n /** Title (optional) */\r\n title?: string\r\n /** Show close button */\r\n closable?: boolean\r\n /** Duration in ms (0 = no auto-close) */\r\n duration?: number\r\n }>(),\r\n {\r\n type: 'info',\r\n closable: true,\r\n duration: 5000,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\nconst typeConfig: Record<ToastType, { icon: string; bg: string; iconColor: string }> = {\r\n success: {\r\n icon: 'lucide:check-circle',\r\n bg: 'bg-green-50 border-green-200 dark:bg-green-950 dark:border-green-800',\r\n iconColor: 'text-green-500',\r\n },\r\n error: {\r\n icon: 'lucide:x-circle',\r\n bg: 'bg-red-50 border-red-200 dark:bg-red-950 dark:border-red-800',\r\n iconColor: 'text-red-500',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n bg: 'bg-yellow-50 border-yellow-200 dark:bg-yellow-950 dark:border-yellow-800',\r\n iconColor: 'text-yellow-500',\r\n },\r\n info: {\r\n icon: 'lucide:info',\r\n bg: 'bg-blue-50 border-blue-200 dark:bg-blue-950 dark:border-blue-800',\r\n iconColor: 'text-blue-500',\r\n },\r\n}\r\n\r\nconst config = typeConfig[props.type]\r\n\r\n// Auto-close\r\nif (props.duration > 0) {\r\n setTimeout(() => {\r\n emit('close')\r\n }, props.duration)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n :class=\"[\r\n 'flex items-start gap-3 rounded-lg border p-4 shadow-lg',\r\n config.bg,\r\n ]\"\r\n role=\"alert\"\r\n >\r\n <Icon\r\n :icon=\"config.icon\"\r\n :class=\"['size-5 shrink-0', config.iconColor]\"\r\n aria-hidden=\"true\"\r\n />\r\n <div class=\"flex-1 min-w-0\">\r\n <p\r\n v-if=\"title\"\r\n class=\"font-medium text-gray-900 dark:text-white\"\r\n >\r\n {{ title }}\r\n </p>\r\n <p class=\"text-sm text-gray-700 dark:text-gray-300\">\r\n {{ message }}\r\n </p>\r\n </div>\r\n <button\r\n v-if=\"closable\"\r\n type=\"button\"\r\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\r\n aria-label=\"Dismiss notification\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n icon=\"lucide:x\"\r\n class=\"size-4\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport Toast from './Toast.vue'\r\nimport type { ToastType } from './Toast.vue'\r\n\r\nexport interface ToastItem {\r\n id: string\r\n message: string\r\n type?: ToastType\r\n title?: string\r\n duration?: number\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Array of toast items */\r\n toasts: ToastItem[]\r\n /** Position of the container */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'\r\n /** Custom top offset (e.g., '80px', '5rem') to account for fixed headers */\r\n topOffset?: string\r\n }>(),\r\n {\r\n position: 'top-right',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: [id: string]\r\n}>()\r\n\r\nconst positionClasses: Record<string, string> = {\r\n 'top-right': 'right-4',\r\n 'top-left': 'left-4',\r\n 'bottom-right': 'bottom-4 right-4',\r\n 'bottom-left': 'bottom-4 left-4',\r\n 'top-center': 'left-1/2 -translate-x-1/2',\r\n 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2',\r\n}\r\n\r\nconst isTopPosition = computed(() => props.position?.startsWith('top'))\r\n\r\nconst topStyle = computed(() => {\r\n if (!isTopPosition.value) return {}\r\n return { top: props.topOffset || '1rem' }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport to=\"body\">\r\n <div\r\n :class=\"['fixed z-9999 flex flex-col gap-2 w-full max-w-sm', positionClasses[position]]\"\r\n :style=\"topStyle\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"false\"\r\n >\r\n <TransitionGroup\r\n enter-active-class=\"transition duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 translate-x-4\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 translate-x-4\"\r\n >\r\n <Toast\r\n v-for=\"toast in toasts\"\r\n :key=\"toast.id\"\r\n :message=\"toast.message\"\r\n :type=\"toast.type\"\r\n :title=\"toast.title\"\r\n :duration=\"toast.duration\"\r\n @close=\"emit('close', toast.id)\"\r\n />\r\n </TransitionGroup>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\n\r\nexport type ProgressSize = 'sm' | 'md' | 'lg'\r\nexport type ProgressVariant = 'default' | 'success' | 'warning' | 'error'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current value (0-100) */\r\n value: number\r\n /** Maximum value */\r\n max?: number\r\n /** Size variant */\r\n size?: ProgressSize\r\n /** Color variant */\r\n variant?: ProgressVariant\r\n /** Show percentage label */\r\n showLabel?: boolean\r\n /** Striped animation */\r\n striped?: boolean\r\n /** Animated stripes */\r\n animated?: boolean\r\n /** Indeterminate state (loading) */\r\n indeterminate?: boolean\r\n }>(),\r\n {\r\n max: 100,\r\n size: 'md',\r\n variant: 'default',\r\n showLabel: false,\r\n striped: false,\r\n animated: false,\r\n indeterminate: false,\r\n },\r\n)\r\n\r\nconst percentage = computed(() => {\r\n if (props.indeterminate) return 100\r\n return Math.min(Math.max((props.value / props.max) * 100, 0), 100)\r\n})\r\n\r\nconst sizeClasses: Record<ProgressSize, string> = {\r\n sm: 'h-1',\r\n md: 'h-2',\r\n lg: 'h-4',\r\n}\r\n\r\nconst variantClasses: Record<ProgressVariant, string> = {\r\n default: 'bg-primary',\r\n success: 'bg-green-500',\r\n warning: 'bg-yellow-500',\r\n error: 'bg-red-500',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <div\n v-if=\"showLabel && !indeterminate\"\n class=\"mb-1 flex justify-between text-sm\"\n >\r\n <span class=\"text-gray-600 dark:text-gray-400\">Progress</span>\r\n <span class=\"font-medium text-gray-900 dark:text-white\">{{ Math.round(percentage) }}%</span>\r\n </div>\r\n <div\r\n :class=\"[\r\n 'w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700',\r\n sizeClasses[size],\r\n ]\"\r\n role=\"progressbar\"\r\n :aria-valuenow=\"indeterminate ? undefined : value\"\r\n :aria-valuemin=\"0\"\r\n :aria-valuemax=\"max\"\r\n >\r\n <div\r\n :class=\"[\r\n 'h-full rounded-full transition-all duration-300',\r\n variantClasses[variant],\r\n striped && 'bg-stripes',\r\n animated && 'animate-stripes',\r\n indeterminate && 'animate-indeterminate',\r\n ]\"\r\n :style=\"{ width: indeterminate ? '30%' : `${percentage}%` }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.bg-stripes {\r\n background-image: linear-gradient(\r\n 45deg,\r\n rgba(255, 255, 255, 0.15) 25%,\r\n transparent 25%,\r\n transparent 50%,\r\n rgba(255, 255, 255, 0.15) 50%,\r\n rgba(255, 255, 255, 0.15) 75%,\r\n transparent 75%,\r\n transparent\r\n );\r\n background-size: 1rem 1rem;\r\n}\r\n\r\n.animate-stripes {\r\n animation: stripes 1s linear infinite;\r\n}\r\n\r\n@keyframes stripes {\r\n from {\r\n background-position: 1rem 0;\r\n }\r\n to {\r\n background-position: 0 0;\r\n }\r\n}\r\n\r\n.animate-indeterminate {\r\n animation: indeterminate 1.5s ease-in-out infinite;\r\n}\r\n\r\n@keyframes indeterminate {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nexport type SkeletonVariant = 'text' | 'circular' | 'rectangular' | 'rounded'\r\n\r\nwithDefaults(\r\n defineProps<{\r\n /** Variant style */\r\n variant?: SkeletonVariant\r\n /** Width (CSS value) */\r\n width?: string\r\n /** Height (CSS value) */\r\n height?: string\r\n /** Number of lines (for text variant) */\r\n lines?: number\r\n /** Animate the skeleton */\r\n animate?: boolean\r\n }>(),\r\n {\r\n variant: 'text',\r\n animate: true,\r\n lines: 1,\r\n },\r\n)\r\n\r\nconst variantClasses: Record<SkeletonVariant, string> = {\r\n text: 'h-4 rounded',\r\n circular: 'rounded-full',\r\n rectangular: '',\r\n rounded: 'rounded-lg',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"variant === 'text' && lines > 1\"\r\n class=\"space-y-2\"\r\n aria-hidden=\"true\"\r\n >\r\n <div\r\n v-for=\"i in lines\"\r\n :key=\"i\"\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: i === lines ? '75%' : width || '100%',\r\n height: height,\r\n }\"\r\n />\r\n </div>\r\n <div\r\n v-else\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: width || (variant === 'circular' ? '3rem' : '100%'),\r\n height: height || (variant === 'circular' ? '3rem' : variant === 'text' ? '1rem' : '6rem'),\r\n }\"\r\n aria-hidden=\"true\"\r\n />\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport Modal from './Modal.vue'\r\nimport Button from '@/components/core/Button.vue'\r\n\r\nexport type ConfirmDialogVariant = 'info' | 'warning' | 'danger' | 'success'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Whether the dialog is open */\r\n open?: boolean\r\n /** Dialog title */\r\n title?: string\r\n /** Dialog message */\r\n message?: string\r\n /** Confirm button text */\r\n confirmText?: string\r\n /** Cancel button text */\r\n cancelText?: string\r\n /** Dialog variant (affects icon and confirm button color) */\r\n variant?: ConfirmDialogVariant\r\n /** Show loading state on confirm button */\r\n loading?: boolean\r\n /** Icon to display */\r\n icon?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n }>(),\r\n {\r\n open: false,\r\n title: 'Confirm',\r\n message: 'Are you sure you want to proceed?',\r\n confirmText: 'Confirm',\r\n cancelText: 'Cancel',\r\n variant: 'info',\r\n loading: false,\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n cancel: []\r\n}>()\r\n\r\nconst variantConfig: Record<ConfirmDialogVariant, { icon: string; iconClass: string; buttonVariant: 'primary' | 'danger' | 'success' }> = {\r\n info: {\r\n icon: 'lucide:info',\r\n iconClass: 'text-blue-500',\r\n buttonVariant: 'primary',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n iconClass: 'text-yellow-500',\r\n buttonVariant: 'primary',\r\n },\r\n danger: {\r\n icon: 'lucide:alert-circle',\r\n iconClass: 'text-red-500',\r\n buttonVariant: 'danger',\r\n },\r\n success: {\r\n icon: 'lucide:check-circle',\r\n iconClass: 'text-green-500',\r\n buttonVariant: 'success',\r\n },\r\n}\r\n\r\nconst config = variantConfig[props.variant]\r\n</script>\r\n\r\n<template>\r\n <Modal\r\n v-if=\"open\"\r\n size=\"sm\"\r\n :close-on-backdrop=\"!loading\"\r\n :close-on-escape=\"!loading\"\r\n :teleport=\"teleport\"\r\n @close=\"emit('cancel')\"\r\n >\r\n <div class=\"text-center\">\r\n <!-- Icon -->\r\n <div class=\"mx-auto mb-4 flex size-14 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800\">\r\n <Icon\r\n :icon=\"icon || config.icon\"\r\n :class=\"[config.iconClass, 'size-8']\"\r\n />\r\n </div>\r\n\r\n <!-- Title -->\r\n <h3 class=\"mb-2 text-lg font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ title }}\r\n </h3>\r\n\r\n <!-- Message -->\r\n <p class=\"mb-6 text-gray-600 dark:text-gray-400\">\r\n <slot>{{ message }}</slot>\r\n </p>\r\n\r\n <!-- Actions -->\r\n <div class=\"flex justify-center gap-3\">\r\n <Button\r\n variant=\"outline\"\r\n :disabled=\"loading\"\r\n @click=\"emit('cancel')\"\r\n >\r\n {{ cancelText }}\r\n </Button>\r\n <Button\r\n :variant=\"config.buttonVariant\"\r\n :loading=\"loading\"\r\n @click=\"emit('confirm')\"\r\n >\r\n {{ confirmText }}\r\n </Button>\r\n </div>\r\n </div>\r\n </Modal>\r\n</template>\r\n"],"names":["_createElementBlock","_createElementVNode","_hoisted_2","_normalizeClass","_hoisted_3","_toDisplayString","_hoisted_4","_createBlock","_Teleport","_unref","$slots","_openBlock","_renderSlot","_createVNode","_hoisted_5","_hoisted_6","_hoisted_1","_Fragment","_renderList","_TransitionGroup","NotificationComponent","Toast","_normalizeStyle","Modal","Button"],"mappings":"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"}