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,870 @@
1
+ import { readonly, ref, computed, onMounted, onUnmounted, watch, shallowRef } from "vue";
2
+ var IDX = 256, HEX = [], SIZE = 256, BUFFER;
3
+ while (IDX--) HEX[IDX] = (IDX + 256).toString(16).substring(1);
4
+ function uid(len) {
5
+ var i = 0, tmp = 11;
6
+ if (!BUFFER || IDX + tmp > SIZE * 2) {
7
+ for (BUFFER = "", IDX = 0; i < SIZE; i++) {
8
+ BUFFER += HEX[Math.random() * 256 | 0];
9
+ }
10
+ }
11
+ return BUFFER.substring(IDX, IDX++ + tmp);
12
+ }
13
+ const notifications = ref([]);
14
+ function useNotifications() {
15
+ const notify = (type, message, options = {}) => {
16
+ const id = uid();
17
+ const notification = {
18
+ id,
19
+ type,
20
+ message,
21
+ title: options.title ?? null,
22
+ duration: options.duration ?? 5e3
23
+ };
24
+ notifications.value.push(notification);
25
+ if (notification.duration && notification.duration > 0) {
26
+ setTimeout(() => remove(id), notification.duration);
27
+ }
28
+ return id;
29
+ };
30
+ const success = (message, options) => notify("success", message, options);
31
+ const warning = (message, options) => notify("warning", message, options);
32
+ const error = (message, options) => notify("error", message, options);
33
+ const info = (message, options) => notify("info", message, options);
34
+ const remove = (id) => {
35
+ notifications.value = notifications.value.filter((n) => n.id !== id);
36
+ };
37
+ const clear = () => {
38
+ notifications.value = [];
39
+ };
40
+ return {
41
+ notifications: readonly(notifications),
42
+ notify,
43
+ success,
44
+ warning,
45
+ error,
46
+ info,
47
+ remove,
48
+ clear
49
+ };
50
+ }
51
+ function useExportCSV() {
52
+ const escapeCSV = (value) => {
53
+ if (value === null || value === void 0) return "";
54
+ const str = String(value);
55
+ if (str.includes(",") || str.includes('"') || str.includes("\n")) {
56
+ return `"${str.replace(/"/g, '""')}"`;
57
+ }
58
+ return str;
59
+ };
60
+ const exportToCSV = (data, columns, filename = "export.csv") => {
61
+ if (!data || data.length === 0) {
62
+ console.warn("No data to export");
63
+ return;
64
+ }
65
+ const headers = columns.map((col) => escapeCSV(col.label)).join(",");
66
+ const rows = data.map(
67
+ (item) => columns.map((col) => escapeCSV(item[col.key])).join(",")
68
+ );
69
+ const csv = [headers, ...rows].join("\n");
70
+ const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
71
+ const url = URL.createObjectURL(blob);
72
+ const link = document.createElement("a");
73
+ link.setAttribute("href", url);
74
+ link.setAttribute("download", filename);
75
+ link.style.visibility = "hidden";
76
+ document.body.appendChild(link);
77
+ link.click();
78
+ document.body.removeChild(link);
79
+ URL.revokeObjectURL(url);
80
+ };
81
+ return {
82
+ exportToCSV,
83
+ escapeCSV
84
+ };
85
+ }
86
+ function useModal(options) {
87
+ const {
88
+ initialOpen = false,
89
+ initialData = null,
90
+ onOpen,
91
+ onClose
92
+ } = options ?? {};
93
+ const isOpen = ref(initialOpen);
94
+ const data = ref(initialData);
95
+ const open = (newData) => {
96
+ data.value = newData ?? null;
97
+ isOpen.value = true;
98
+ onOpen == null ? void 0 : onOpen(data.value);
99
+ };
100
+ const close = () => {
101
+ isOpen.value = false;
102
+ data.value = null;
103
+ onClose == null ? void 0 : onClose();
104
+ };
105
+ const toggle = () => {
106
+ if (isOpen.value) {
107
+ close();
108
+ } else {
109
+ open();
110
+ }
111
+ };
112
+ return {
113
+ isOpen,
114
+ data,
115
+ open,
116
+ close,
117
+ toggle
118
+ };
119
+ }
120
+ function useModals(modals) {
121
+ return modals;
122
+ }
123
+ const toasts = ref([]);
124
+ let toastId = 0;
125
+ function useToast() {
126
+ const add = (options) => {
127
+ const id = `toast-${++toastId}`;
128
+ const toast = {
129
+ id,
130
+ message: options.message,
131
+ type: options.type || "info",
132
+ title: options.title,
133
+ duration: options.duration ?? 5e3
134
+ };
135
+ toasts.value.push(toast);
136
+ return id;
137
+ };
138
+ const remove = (id) => {
139
+ const index = toasts.value.findIndex((t) => t.id === id);
140
+ if (index > -1) {
141
+ toasts.value.splice(index, 1);
142
+ }
143
+ };
144
+ const clear = () => {
145
+ toasts.value = [];
146
+ };
147
+ const success = (message, title) => {
148
+ return add({ message, title, type: "success" });
149
+ };
150
+ const error = (message, title) => {
151
+ return add({ message, title, type: "error" });
152
+ };
153
+ const warning = (message, title) => {
154
+ return add({ message, title, type: "warning" });
155
+ };
156
+ const info = (message, title) => {
157
+ return add({ message, title, type: "info" });
158
+ };
159
+ return {
160
+ toasts,
161
+ add,
162
+ remove,
163
+ clear,
164
+ success,
165
+ error,
166
+ warning,
167
+ info
168
+ };
169
+ }
170
+ function useTableKeyboardNavigation(options) {
171
+ const {
172
+ tableRef,
173
+ rowCount,
174
+ colCount,
175
+ cellNavigation = false,
176
+ onRowActivate,
177
+ onCellActivate,
178
+ onFocusChange,
179
+ skipHeader = true,
180
+ wrap = true
181
+ } = options;
182
+ const focusedRow = ref(skipHeader ? 1 : 0);
183
+ const focusedCol = ref(0);
184
+ const isActive = ref(false);
185
+ const totalRows = computed(() => typeof rowCount === "number" ? rowCount : rowCount.value);
186
+ const totalCols = computed(() => typeof colCount === "number" ? colCount : colCount.value);
187
+ const startRow = computed(() => skipHeader ? 1 : 0);
188
+ const clampRow = (row) => {
189
+ if (wrap) {
190
+ if (row < startRow.value) return totalRows.value - 1;
191
+ if (row >= totalRows.value) return startRow.value;
192
+ return row;
193
+ }
194
+ return Math.max(startRow.value, Math.min(totalRows.value - 1, row));
195
+ };
196
+ const clampCol = (col) => {
197
+ if (wrap) {
198
+ if (col < 0) return totalCols.value - 1;
199
+ if (col >= totalCols.value) return 0;
200
+ return col;
201
+ }
202
+ return Math.max(0, Math.min(totalCols.value - 1, col));
203
+ };
204
+ const setFocusedRow = (index) => {
205
+ focusedRow.value = clampRow(index);
206
+ onFocusChange == null ? void 0 : onFocusChange(focusedRow.value, focusedCol.value);
207
+ };
208
+ const setFocusedCell = (row, col) => {
209
+ focusedRow.value = clampRow(row);
210
+ focusedCol.value = clampCol(col);
211
+ onFocusChange == null ? void 0 : onFocusChange(focusedRow.value, focusedCol.value);
212
+ };
213
+ const activate = () => {
214
+ isActive.value = true;
215
+ focusCurrentElement();
216
+ };
217
+ const deactivate = () => {
218
+ isActive.value = false;
219
+ };
220
+ const focusCurrentElement = () => {
221
+ if (!tableRef.value) return;
222
+ const selector = cellNavigation ? `tr:nth-child(${focusedRow.value + 1}) td:nth-child(${focusedCol.value + 1}), tr:nth-child(${focusedRow.value + 1}) th:nth-child(${focusedCol.value + 1})` : `tr:nth-child(${focusedRow.value + 1})`;
223
+ const element = tableRef.value.querySelector(selector);
224
+ element == null ? void 0 : element.focus();
225
+ };
226
+ const handleKeyDown = (event) => {
227
+ if (!isActive.value) return;
228
+ const { key, shiftKey, ctrlKey, metaKey } = event;
229
+ if (ctrlKey || metaKey) return;
230
+ let handled = false;
231
+ switch (key) {
232
+ case "ArrowDown":
233
+ setFocusedRow(focusedRow.value + 1);
234
+ handled = true;
235
+ break;
236
+ case "ArrowUp":
237
+ setFocusedRow(focusedRow.value - 1);
238
+ handled = true;
239
+ break;
240
+ case "ArrowRight":
241
+ if (cellNavigation) {
242
+ setFocusedCell(focusedRow.value, focusedCol.value + 1);
243
+ handled = true;
244
+ }
245
+ break;
246
+ case "ArrowLeft":
247
+ if (cellNavigation) {
248
+ setFocusedCell(focusedRow.value, focusedCol.value - 1);
249
+ handled = true;
250
+ }
251
+ break;
252
+ case "Home":
253
+ if (cellNavigation) {
254
+ setFocusedCell(shiftKey ? startRow.value : focusedRow.value, 0);
255
+ } else {
256
+ setFocusedRow(startRow.value);
257
+ }
258
+ handled = true;
259
+ break;
260
+ case "End":
261
+ if (cellNavigation) {
262
+ setFocusedCell(
263
+ shiftKey ? totalRows.value - 1 : focusedRow.value,
264
+ totalCols.value - 1
265
+ );
266
+ } else {
267
+ setFocusedRow(totalRows.value - 1);
268
+ }
269
+ handled = true;
270
+ break;
271
+ case "PageDown":
272
+ setFocusedRow(focusedRow.value + 10);
273
+ handled = true;
274
+ break;
275
+ case "PageUp":
276
+ setFocusedRow(focusedRow.value - 10);
277
+ handled = true;
278
+ break;
279
+ case "Enter":
280
+ case " ":
281
+ if (cellNavigation) {
282
+ onCellActivate == null ? void 0 : onCellActivate(focusedRow.value, focusedCol.value);
283
+ } else {
284
+ onRowActivate == null ? void 0 : onRowActivate(focusedRow.value);
285
+ }
286
+ handled = true;
287
+ break;
288
+ case "Escape":
289
+ deactivate();
290
+ handled = true;
291
+ break;
292
+ case "Tab":
293
+ deactivate();
294
+ return;
295
+ }
296
+ if (handled) {
297
+ event.preventDefault();
298
+ event.stopPropagation();
299
+ focusCurrentElement();
300
+ }
301
+ };
302
+ const getRowProps = (rowIndex) => ({
303
+ tabIndex: focusedRow.value === rowIndex && isActive.value ? 0 : -1,
304
+ "aria-selected": focusedRow.value === rowIndex ? true : void 0,
305
+ onFocus: () => {
306
+ if (!isActive.value) {
307
+ isActive.value = true;
308
+ }
309
+ focusedRow.value = rowIndex;
310
+ }
311
+ });
312
+ const getCellProps = (rowIndex, colIndex) => ({
313
+ tabIndex: focusedRow.value === rowIndex && focusedCol.value === colIndex && isActive.value ? 0 : -1,
314
+ "aria-selected": focusedRow.value === rowIndex && focusedCol.value === colIndex ? true : void 0,
315
+ onFocus: () => {
316
+ if (!isActive.value) {
317
+ isActive.value = true;
318
+ }
319
+ focusedRow.value = rowIndex;
320
+ focusedCol.value = colIndex;
321
+ }
322
+ });
323
+ const handleTableFocus = () => {
324
+ if (!isActive.value) {
325
+ activate();
326
+ }
327
+ };
328
+ onMounted(() => {
329
+ var _a;
330
+ (_a = tableRef.value) == null ? void 0 : _a.addEventListener("focus", handleTableFocus, true);
331
+ });
332
+ onUnmounted(() => {
333
+ var _a;
334
+ (_a = tableRef.value) == null ? void 0 : _a.removeEventListener("focus", handleTableFocus, true);
335
+ });
336
+ return {
337
+ focusedRow,
338
+ focusedCol,
339
+ isActive,
340
+ setFocusedRow,
341
+ setFocusedCell,
342
+ activate,
343
+ deactivate,
344
+ getRowProps,
345
+ getCellProps,
346
+ handleKeyDown
347
+ };
348
+ }
349
+ function useColumnVisibility(options) {
350
+ const {
351
+ columns: columnsOption,
352
+ initialHidden = [],
353
+ persist = false,
354
+ storageKey = "table-column-visibility",
355
+ minVisible = 1
356
+ } = options;
357
+ const loadInitialState = () => {
358
+ if (persist && typeof window !== "undefined") {
359
+ try {
360
+ const stored = localStorage.getItem(storageKey);
361
+ if (stored) {
362
+ return new Set(JSON.parse(stored));
363
+ }
364
+ } catch {
365
+ }
366
+ }
367
+ return new Set(initialHidden);
368
+ };
369
+ const hiddenColumns = ref(loadInitialState());
370
+ const saveState = () => {
371
+ if (persist && typeof window !== "undefined") {
372
+ try {
373
+ localStorage.setItem(storageKey, JSON.stringify([...hiddenColumns.value]));
374
+ } catch {
375
+ }
376
+ }
377
+ };
378
+ const rawColumns = computed(() => {
379
+ const cols = "value" in columnsOption ? columnsOption.value : columnsOption;
380
+ return cols;
381
+ });
382
+ const columns = computed(() => {
383
+ return rawColumns.value.map((col) => ({
384
+ ...col,
385
+ hidden: hiddenColumns.value.has(col.name)
386
+ }));
387
+ });
388
+ const visibleColumns = computed(() => {
389
+ return columns.value.filter((col) => !col.hidden);
390
+ });
391
+ const isVisible = (columnName) => {
392
+ return !hiddenColumns.value.has(columnName);
393
+ };
394
+ const show = (columnName) => {
395
+ hiddenColumns.value.delete(columnName);
396
+ hiddenColumns.value = new Set(hiddenColumns.value);
397
+ saveState();
398
+ };
399
+ const hide = (columnName) => {
400
+ if (visibleColumns.value.length <= minVisible) {
401
+ return;
402
+ }
403
+ hiddenColumns.value.add(columnName);
404
+ hiddenColumns.value = new Set(hiddenColumns.value);
405
+ saveState();
406
+ };
407
+ const toggle = (columnName) => {
408
+ if (isVisible(columnName)) {
409
+ hide(columnName);
410
+ } else {
411
+ show(columnName);
412
+ }
413
+ };
414
+ const showAll = () => {
415
+ hiddenColumns.value = /* @__PURE__ */ new Set();
416
+ saveState();
417
+ };
418
+ const hideAll = () => {
419
+ const columnsToKeep = rawColumns.value.slice(0, minVisible).map((c) => c.name);
420
+ const newHidden = new Set(
421
+ rawColumns.value.filter((c) => !columnsToKeep.includes(c.name)).map((c) => c.name)
422
+ );
423
+ hiddenColumns.value = newHidden;
424
+ saveState();
425
+ };
426
+ const reset = () => {
427
+ hiddenColumns.value = new Set(initialHidden);
428
+ saveState();
429
+ };
430
+ const setVisibility = (visibility) => {
431
+ const newHidden = /* @__PURE__ */ new Set();
432
+ let visibleCount = 0;
433
+ for (const col of rawColumns.value) {
434
+ const shouldBeVisible = visibility[col.name] ?? true;
435
+ if (shouldBeVisible) {
436
+ visibleCount++;
437
+ } else {
438
+ newHidden.add(col.name);
439
+ }
440
+ }
441
+ if (visibleCount < minVisible) {
442
+ let added = 0;
443
+ for (const col of rawColumns.value) {
444
+ if (newHidden.has(col.name)) {
445
+ newHidden.delete(col.name);
446
+ added++;
447
+ if (visibleCount + added >= minVisible) break;
448
+ }
449
+ }
450
+ }
451
+ hiddenColumns.value = newHidden;
452
+ saveState();
453
+ };
454
+ return {
455
+ columns,
456
+ visibleColumns,
457
+ hiddenColumns,
458
+ isVisible,
459
+ show,
460
+ hide,
461
+ toggle,
462
+ showAll,
463
+ hideAll,
464
+ reset,
465
+ setVisibility
466
+ };
467
+ }
468
+ function useColumnResize(options) {
469
+ const {
470
+ columns: columnsOption,
471
+ defaultMinWidth = 50,
472
+ defaultMaxWidth = 1e3,
473
+ storageKey,
474
+ persist = false
475
+ } = options;
476
+ const allColumns = computed(() => {
477
+ return "value" in columnsOption ? columnsOption.value : columnsOption;
478
+ });
479
+ const getInitialWidths = () => {
480
+ const map = /* @__PURE__ */ new Map();
481
+ allColumns.value.forEach((col) => {
482
+ map.set(col.name, col.width);
483
+ });
484
+ return map;
485
+ };
486
+ const loadFromStorage = () => {
487
+ if (!persist || !storageKey) return null;
488
+ try {
489
+ const stored = localStorage.getItem(storageKey);
490
+ if (stored) {
491
+ const parsed = JSON.parse(stored);
492
+ return new Map(Object.entries(parsed));
493
+ }
494
+ } catch {
495
+ }
496
+ return null;
497
+ };
498
+ const saveToStorage = () => {
499
+ if (!persist || !storageKey) return;
500
+ try {
501
+ const obj = Object.fromEntries(widths.value);
502
+ localStorage.setItem(storageKey, JSON.stringify(obj));
503
+ } catch {
504
+ }
505
+ };
506
+ const widths = ref(loadFromStorage() ?? getInitialWidths());
507
+ watch(
508
+ allColumns,
509
+ (newColumns) => {
510
+ const stored = loadFromStorage();
511
+ newColumns.forEach((col) => {
512
+ if (!widths.value.has(col.name)) {
513
+ widths.value.set(col.name, (stored == null ? void 0 : stored.get(col.name)) ?? col.width);
514
+ }
515
+ });
516
+ },
517
+ { deep: true }
518
+ );
519
+ const resizingColumn = ref(null);
520
+ const startX = ref(0);
521
+ const startWidth = ref(0);
522
+ const isResizing = computed(() => resizingColumn.value !== null);
523
+ const columnWidths = computed(() => {
524
+ const result = {};
525
+ widths.value.forEach((width, name) => {
526
+ result[name] = width;
527
+ });
528
+ return result;
529
+ });
530
+ const getWidth = (name) => {
531
+ var _a;
532
+ return widths.value.get(name) ?? ((_a = allColumns.value.find((c) => c.name === name)) == null ? void 0 : _a.width) ?? 100;
533
+ };
534
+ const getColumnConfig = (name) => {
535
+ return allColumns.value.find((c) => c.name === name);
536
+ };
537
+ const setWidth = (name, width) => {
538
+ const config = getColumnConfig(name);
539
+ const minWidth = (config == null ? void 0 : config.minWidth) ?? defaultMinWidth;
540
+ const maxWidth = (config == null ? void 0 : config.maxWidth) ?? defaultMaxWidth;
541
+ const clampedWidth = Math.max(minWidth, Math.min(maxWidth, width));
542
+ const newWidths = new Map(widths.value);
543
+ newWidths.set(name, clampedWidth);
544
+ widths.value = newWidths;
545
+ saveToStorage();
546
+ };
547
+ const handleMouseMove = (event) => {
548
+ if (!resizingColumn.value) return;
549
+ const clientX = "touches" in event ? event.touches[0].clientX : event.clientX;
550
+ const deltaX = clientX - startX.value;
551
+ const newWidth = startWidth.value + deltaX;
552
+ setWidth(resizingColumn.value, newWidth);
553
+ };
554
+ const handleMouseUp = () => {
555
+ resizingColumn.value = null;
556
+ document.removeEventListener("mousemove", handleMouseMove);
557
+ document.removeEventListener("mouseup", handleMouseUp);
558
+ document.removeEventListener("touchmove", handleMouseMove);
559
+ document.removeEventListener("touchend", handleMouseUp);
560
+ document.body.style.cursor = "";
561
+ document.body.style.userSelect = "";
562
+ };
563
+ const startResize = (name, event) => {
564
+ event.preventDefault();
565
+ resizingColumn.value = name;
566
+ startX.value = "touches" in event ? event.touches[0].clientX : event.clientX;
567
+ startWidth.value = getWidth(name);
568
+ document.addEventListener("mousemove", handleMouseMove);
569
+ document.addEventListener("mouseup", handleMouseUp);
570
+ document.addEventListener("touchmove", handleMouseMove);
571
+ document.addEventListener("touchend", handleMouseUp);
572
+ document.body.style.cursor = "col-resize";
573
+ document.body.style.userSelect = "none";
574
+ };
575
+ const reset = () => {
576
+ widths.value = getInitialWidths();
577
+ saveToStorage();
578
+ };
579
+ const resetColumn = (name) => {
580
+ const config = getColumnConfig(name);
581
+ if (config) {
582
+ setWidth(name, config.width);
583
+ }
584
+ };
585
+ return {
586
+ columnWidths,
587
+ getWidth,
588
+ setWidth,
589
+ startResize,
590
+ isResizing,
591
+ resizingColumn,
592
+ reset,
593
+ resetColumn
594
+ };
595
+ }
596
+ function usePinnedRows(options = {}) {
597
+ const {
598
+ keyField = "id",
599
+ initialPinned = [],
600
+ maxPinnedTop = Infinity,
601
+ maxPinnedBottom = Infinity
602
+ } = options;
603
+ const getItemKey = (item) => {
604
+ const key = item[keyField];
605
+ return String(key ?? Math.random());
606
+ };
607
+ const pinnedMap = shallowRef(
608
+ new Map(initialPinned.map((p) => [getItemKey(p.item), p]))
609
+ );
610
+ const pinnedTop = computed(() => {
611
+ const items = [];
612
+ pinnedMap.value.forEach(({ item, position }) => {
613
+ if (position === "top") {
614
+ items.push(item);
615
+ }
616
+ });
617
+ return items;
618
+ });
619
+ const pinnedBottom = computed(() => {
620
+ const items = [];
621
+ pinnedMap.value.forEach(({ item, position }) => {
622
+ if (position === "bottom") {
623
+ items.push(item);
624
+ }
625
+ });
626
+ return items;
627
+ });
628
+ const pinnedKeys = computed(() => {
629
+ return new Set(pinnedMap.value.keys());
630
+ });
631
+ const isPinned = (item) => {
632
+ return pinnedMap.value.has(getItemKey(item));
633
+ };
634
+ const getPinPosition = (item) => {
635
+ const pinned = pinnedMap.value.get(getItemKey(item));
636
+ return (pinned == null ? void 0 : pinned.position) ?? null;
637
+ };
638
+ const pin = (item, position) => {
639
+ const currentCount = position === "top" ? pinnedTop.value.length : pinnedBottom.value.length;
640
+ const maxCount = position === "top" ? maxPinnedTop : maxPinnedBottom;
641
+ if (currentCount >= maxCount && getPinPosition(item) !== position) {
642
+ return;
643
+ }
644
+ const key = getItemKey(item);
645
+ const newMap = new Map(pinnedMap.value);
646
+ newMap.set(key, { item, position });
647
+ pinnedMap.value = newMap;
648
+ };
649
+ const unpin = (item) => {
650
+ const key = getItemKey(item);
651
+ if (pinnedMap.value.has(key)) {
652
+ const newMap = new Map(pinnedMap.value);
653
+ newMap.delete(key);
654
+ pinnedMap.value = newMap;
655
+ }
656
+ };
657
+ const togglePin = (item, position = "top") => {
658
+ if (isPinned(item)) {
659
+ unpin(item);
660
+ } else {
661
+ pin(item, position);
662
+ }
663
+ };
664
+ const movePin = (item, newPosition) => {
665
+ if (isPinned(item)) {
666
+ pin(item, newPosition);
667
+ }
668
+ };
669
+ const clearAll = () => {
670
+ pinnedMap.value = /* @__PURE__ */ new Map();
671
+ };
672
+ const clear = (position) => {
673
+ const newMap = /* @__PURE__ */ new Map();
674
+ pinnedMap.value.forEach((pinned, key) => {
675
+ if (pinned.position !== position) {
676
+ newMap.set(key, pinned);
677
+ }
678
+ });
679
+ pinnedMap.value = newMap;
680
+ };
681
+ return {
682
+ pinnedTop,
683
+ pinnedBottom,
684
+ pinnedKeys,
685
+ isPinned,
686
+ getPinPosition,
687
+ pin,
688
+ unpin,
689
+ togglePin,
690
+ movePin,
691
+ clearAll,
692
+ clear
693
+ };
694
+ }
695
+ function useEditableCell(options = {}) {
696
+ const {
697
+ keyField = "id",
698
+ onSave,
699
+ onCancel,
700
+ validate
701
+ } = options;
702
+ const editingCell = ref(null);
703
+ const editValue = ref(null);
704
+ const error = ref(null);
705
+ const saving = ref(false);
706
+ const currentItem = ref(null);
707
+ const originalValue = ref(null);
708
+ const getItemKey = (item) => {
709
+ const key = item[keyField];
710
+ return String(key ?? Math.random());
711
+ };
712
+ const isEditing = (rowKey, field) => {
713
+ var _a, _b;
714
+ return ((_a = editingCell.value) == null ? void 0 : _a.rowKey) === rowKey && ((_b = editingCell.value) == null ? void 0 : _b.field) === field;
715
+ };
716
+ const startEdit = (item, field, currentValue) => {
717
+ if (editingCell.value) {
718
+ cancelEdit();
719
+ }
720
+ currentItem.value = item;
721
+ originalValue.value = currentValue;
722
+ editValue.value = currentValue;
723
+ error.value = null;
724
+ editingCell.value = {
725
+ rowKey: getItemKey(item),
726
+ field
727
+ };
728
+ };
729
+ const confirmEdit = async () => {
730
+ if (!editingCell.value || !currentItem.value) return;
731
+ const event = {
732
+ item: currentItem.value,
733
+ field: editingCell.value.field,
734
+ originalValue: originalValue.value,
735
+ newValue: editValue.value
736
+ };
737
+ if (validate) {
738
+ const validationError = validate(event);
739
+ if (validationError) {
740
+ error.value = validationError;
741
+ return;
742
+ }
743
+ }
744
+ saving.value = true;
745
+ error.value = null;
746
+ try {
747
+ if (onSave) {
748
+ await onSave(event);
749
+ }
750
+ editingCell.value = null;
751
+ editValue.value = null;
752
+ currentItem.value = null;
753
+ originalValue.value = null;
754
+ } catch (e) {
755
+ error.value = e instanceof Error ? e.message : "Failed to save";
756
+ } finally {
757
+ saving.value = false;
758
+ }
759
+ };
760
+ const cancelEdit = () => {
761
+ if (editingCell.value && currentItem.value && onCancel) {
762
+ onCancel({
763
+ item: currentItem.value,
764
+ field: editingCell.value.field,
765
+ originalValue: originalValue.value
766
+ });
767
+ }
768
+ editingCell.value = null;
769
+ editValue.value = null;
770
+ error.value = null;
771
+ currentItem.value = null;
772
+ originalValue.value = null;
773
+ };
774
+ const updateValue = (value) => {
775
+ editValue.value = value;
776
+ error.value = null;
777
+ };
778
+ const editingItem = computed(() => currentItem.value);
779
+ return {
780
+ editingCell,
781
+ editValue,
782
+ error,
783
+ saving,
784
+ isEditing,
785
+ startEdit,
786
+ confirmEdit,
787
+ cancelEdit,
788
+ updateValue,
789
+ editingItem
790
+ };
791
+ }
792
+ function useVirtualScroll(options) {
793
+ const {
794
+ items: itemsOption,
795
+ rowHeight,
796
+ containerHeight,
797
+ overscan = 3
798
+ } = options;
799
+ const scrollTop = ref(0);
800
+ const containerRef = ref(null);
801
+ const allItems = computed(() => {
802
+ return "value" in itemsOption ? itemsOption.value : itemsOption;
803
+ });
804
+ const totalHeight = computed(() => {
805
+ return allItems.value.length * rowHeight;
806
+ });
807
+ const visibleCount = computed(() => {
808
+ return Math.ceil(containerHeight / rowHeight);
809
+ });
810
+ const startIndex = computed(() => {
811
+ const rawStart = Math.floor(scrollTop.value / rowHeight);
812
+ return Math.max(0, rawStart - overscan);
813
+ });
814
+ const endIndex = computed(() => {
815
+ const rawEnd = startIndex.value + visibleCount.value + overscan * 2;
816
+ return Math.min(allItems.value.length, rawEnd);
817
+ });
818
+ const visibleItems = computed(() => {
819
+ return allItems.value.slice(startIndex.value, endIndex.value);
820
+ });
821
+ const offsetY = computed(() => {
822
+ return startIndex.value * rowHeight;
823
+ });
824
+ const onScroll = (event) => {
825
+ const target = event.target;
826
+ scrollTop.value = target.scrollTop;
827
+ };
828
+ const scrollToIndex = (index) => {
829
+ const targetScroll = index * rowHeight;
830
+ if (containerRef.value) {
831
+ containerRef.value.scrollTop = targetScroll;
832
+ }
833
+ scrollTop.value = targetScroll;
834
+ };
835
+ onMounted(() => {
836
+ if (containerRef.value) {
837
+ containerRef.value.addEventListener("scroll", onScroll, { passive: true });
838
+ }
839
+ });
840
+ onUnmounted(() => {
841
+ if (containerRef.value) {
842
+ containerRef.value.removeEventListener("scroll", onScroll);
843
+ }
844
+ });
845
+ return {
846
+ visibleItems,
847
+ totalHeight,
848
+ offsetY,
849
+ startIndex,
850
+ endIndex,
851
+ scrollTop,
852
+ onScroll,
853
+ scrollToIndex,
854
+ containerRef
855
+ };
856
+ }
857
+ export {
858
+ useExportCSV as a,
859
+ useModal as b,
860
+ useModals as c,
861
+ useToast as d,
862
+ useTableKeyboardNavigation as e,
863
+ useColumnVisibility as f,
864
+ useColumnResize as g,
865
+ usePinnedRows as h,
866
+ useEditableCell as i,
867
+ useVirtualScroll as j,
868
+ useNotifications as u
869
+ };
870
+ //# sourceMappingURL=useVirtualScroll-YeZru2Eo.js.map