cisse-vue-ui 0.8.4 → 0.10.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.
- package/README.md +666 -4
- package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-B190Yija.js → CheckboxGroup.vue_vue_type_script_setup_true_lang-ZP02bMgY.js} +2 -2
- 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
- package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js} +37 -184
- package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js.map +1 -0
- 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
- package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CLfy0-Wb.cjs.map +1 -0
- package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js → FilterTabs.vue_vue_type_script_setup_true_lang-CJnvcF8Z.js} +1568 -384
- package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-CJnvcF8Z.js.map +1 -0
- package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs → FilterTabs.vue_vue_type_script_setup_true_lang-l8lJzwoY.cjs} +1564 -380
- package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-l8lJzwoY.cjs.map +1 -0
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js +298 -0
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js.map +1 -0
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs +297 -0
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs.map +1 -0
- package/dist/components/core/Breadcrumb.stories.d.ts +5 -0
- package/dist/components/core/CardWrapper.stories.d.ts +32 -0
- package/dist/components/core/CardWrapper.vue.d.ts +129 -0
- package/dist/components/core/CollapsibleCard.vue.d.ts +1 -1
- package/dist/components/core/DataTable.stories.d.ts +38 -0
- package/dist/components/core/Dropdown.vue.d.ts +1 -1
- package/dist/components/core/Popover.vue.d.ts +2 -2
- package/dist/components/core/StatItem.stories.d.ts +25 -0
- package/dist/components/core/StatItem.test.d.ts +1 -0
- package/dist/components/core/StatItem.vue.d.ts +81 -0
- package/dist/components/core/Stats.stories.d.ts +24 -0
- package/dist/components/core/Stats.test.d.ts +1 -0
- package/dist/components/core/Stats.vue.d.ts +41 -0
- package/dist/components/core/Tooltip.stories.d.ts +3 -0
- package/dist/components/core/index.cjs +41 -22
- package/dist/components/core/index.cjs.map +1 -1
- package/dist/components/core/index.d.ts +10 -4
- package/dist/components/core/index.js +41 -22
- package/dist/components/core/table/DataTable.test.d.ts +1 -0
- package/dist/components/core/{TableComponent.vue.d.ts → table/DataTable.vue.d.ts} +60 -7
- package/dist/components/core/table/Table.stories.d.ts +27 -0
- package/dist/components/core/table/atoms/Caption.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Caption.vue.d.ts +26 -0
- package/dist/components/core/table/atoms/Col.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Col.vue.d.ts +8 -0
- package/dist/components/core/table/atoms/Colgroup.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Colgroup.vue.d.ts +17 -0
- package/dist/components/core/table/atoms/Table.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Table.vue.d.ts +46 -0
- package/dist/components/core/table/atoms/Tbody.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Tbody.vue.d.ts +17 -0
- package/dist/components/core/table/atoms/Td.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Td.vue.d.ts +43 -0
- package/dist/components/core/table/atoms/Tfoot.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Tfoot.vue.d.ts +17 -0
- package/dist/components/core/table/atoms/Th.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Th.vue.d.ts +64 -0
- package/dist/components/core/table/atoms/Thead.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Thead.vue.d.ts +17 -0
- package/dist/components/core/table/atoms/Tr.test.d.ts +1 -0
- package/dist/components/core/table/atoms/Tr.vue.d.ts +35 -0
- package/dist/components/core/table/atoms/index.d.ts +10 -0
- package/dist/components/core/table/index.d.ts +3 -0
- package/dist/components/core/table/molecules/ExpandableRow.test.d.ts +1 -0
- package/dist/components/core/table/molecules/ExpandableRow.vue.d.ts +47 -0
- package/dist/components/core/table/molecules/TableFooter.test.d.ts +1 -0
- package/dist/components/core/table/molecules/TableFooter.vue.d.ts +21 -0
- package/dist/components/core/table/molecules/TableHeader.test.d.ts +1 -0
- package/dist/components/core/table/molecules/TableHeader.vue.d.ts +49 -0
- package/dist/components/core/table/molecules/TableRow.test.d.ts +1 -0
- package/dist/components/core/table/molecules/TableRow.vue.d.ts +59 -0
- package/dist/components/core/table/molecules/index.d.ts +4 -0
- package/dist/components/feedback/Progress.vue.d.ts +1 -1
- package/dist/components/feedback/TableSkeleton.vue.d.ts +1 -1
- package/dist/components/feedback/index.cjs +14 -14
- package/dist/components/feedback/index.js +14 -14
- package/dist/components/form/Combobox.vue.d.ts +1 -1
- package/dist/components/form/DatePicker.vue.d.ts +1 -1
- package/dist/components/form/FormSection.vue.d.ts +1 -1
- package/dist/components/form/IconPicker.stories.d.ts +19 -0
- package/dist/components/form/IconPicker.test.d.ts +1 -0
- package/dist/components/form/InputWrapper.stories.d.ts +0 -5
- package/dist/components/form/Rating.vue.d.ts +1 -1
- package/dist/components/form/SearchInput.vue.d.ts +1 -1
- package/dist/components/form/index.js +2 -2
- package/dist/components/index.cjs +55 -36
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +67 -48
- package/dist/composables/index.cjs +15 -8
- package/dist/composables/index.cjs.map +1 -1
- package/dist/composables/index.d.ts +7 -0
- package/dist/composables/index.js +12 -5
- package/dist/composables/useColumnResize.d.ts +38 -0
- package/dist/composables/useColumnResize.test.d.ts +1 -0
- package/dist/composables/useColumnVisibility.d.ts +44 -0
- package/dist/composables/useColumnVisibility.test.d.ts +1 -0
- package/dist/composables/useEditableCell.d.ts +51 -0
- package/dist/composables/useEditableCell.test.d.ts +1 -0
- package/dist/composables/usePagination.d.ts +44 -0
- package/dist/composables/usePagination.test.d.ts +1 -0
- package/dist/composables/usePinnedRows.d.ts +41 -0
- package/dist/composables/usePinnedRows.test.d.ts +1 -0
- package/dist/composables/useTableKeyboardNavigation.d.ts +52 -0
- package/dist/composables/useTableKeyboardNavigation.test.d.ts +1 -0
- package/dist/composables/useVirtualScroll.d.ts +32 -0
- package/dist/composables/useVirtualScroll.test.d.ts +1 -0
- package/dist/{index-SNefWfX0.js → index-BaWpldIJ.js} +3 -3
- package/dist/{index-SNefWfX0.js.map → index-BaWpldIJ.js.map} +1 -1
- package/dist/{index-LFQFhClN.cjs → index-CYXOfUOG.cjs} +56 -37
- package/dist/{index-LFQFhClN.cjs.map → index-CYXOfUOG.cjs.map} +1 -1
- package/dist/index-C_N7WRnM.js +116 -0
- package/dist/index-C_N7WRnM.js.map +1 -0
- package/dist/index.cjs +71 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -55
- package/dist/style.css +1 -1
- package/dist/types/components.d.ts +1 -1
- package/dist/types/property.d.ts +8 -0
- package/dist/usePagination-BGwbICFC.js +135 -0
- package/dist/usePagination-BGwbICFC.js.map +1 -0
- package/dist/usePagination-gvvh1zqA.cjs +134 -0
- package/dist/usePagination-gvvh1zqA.cjs.map +1 -0
- package/dist/useVirtualScroll-BivP86fA.cjs +869 -0
- package/dist/useVirtualScroll-BivP86fA.cjs.map +1 -0
- package/dist/useVirtualScroll-YeZru2Eo.js +870 -0
- package/dist/useVirtualScroll-YeZru2Eo.js.map +1 -0
- package/package.json +1 -1
- package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs.map +0 -1
- package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js.map +0 -1
- package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js.map +0 -1
- package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs.map +0 -1
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js +0 -150
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js.map +0 -1
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs +0 -149
- package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs.map +0 -1
- package/dist/components/core/StatsCard.stories.d.ts +0 -15
- package/dist/components/core/StatsCard.vue.d.ts +0 -44
- package/dist/components/core/StatsGrid.stories.d.ts +0 -12
- package/dist/components/core/StatsGrid.vue.d.ts +0 -16
- package/dist/components/core/TableComponent.stories.d.ts +0 -16
- package/dist/index-CyL_6V7D.js +0 -97
- package/dist/index-CyL_6V7D.js.map +0 -1
- package/dist/useDarkMode-Cl5QWTlC.js +0 -53
- package/dist/useDarkMode-Cl5QWTlC.js.map +0 -1
- package/dist/useDarkMode-DLZcJEUQ.cjs +0 -52
- package/dist/useDarkMode-DLZcJEUQ.cjs.map +0 -1
- package/dist/useToast-Bk60GArg.cjs +0 -176
- package/dist/useToast-Bk60GArg.cjs.map +0 -1
- package/dist/useToast-ina5g3mj.js +0 -177
- package/dist/useToast-ina5g3mj.js.map +0 -1
- /package/dist/components/core/{StatsCard.test.d.ts → AccordionItem.test.d.ts} +0 -0
- /package/dist/components/core/{StatsGrid.test.d.ts → CardWrapper.test.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVirtualScroll-BivP86fA.cjs","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":["ref","readonly","computed","onMounted","onUnmounted","watch","shallowRef"],"mappings":"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","x_google_ignoreList":[0]}
|