eidos-ui 2.0.0 → 2.1.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 (223) hide show
  1. package/dist/Avatar.types-BY-C09Ke.d.cts +23 -0
  2. package/dist/Avatar.types-BY-C09Ke.d.ts +23 -0
  3. package/dist/{Header.types-BZi80bWz.d.cts → Header.types-B3QtuiL-.d.cts} +7 -3
  4. package/dist/{Header.types-DJt-q01P.d.ts → Header.types-C6w0FBY8.d.ts} +7 -3
  5. package/dist/{Table.types-Cl5gR8r9.d.cts → Table.types-CPj-udMc.d.cts} +95 -0
  6. package/dist/{Table.types-jhPb7JNU.d.ts → Table.types-CZZ7QWAI.d.ts} +95 -0
  7. package/dist/Toolbar.types-DSk8z2iy.d.cts +38 -0
  8. package/dist/Toolbar.types-RN0klQzu.d.ts +38 -0
  9. package/dist/alert/index.cjs +4 -4
  10. package/dist/alert/index.d.cts +2 -1
  11. package/dist/alert/index.d.ts +2 -1
  12. package/dist/alert/index.js +3 -3
  13. package/dist/avatar/index.d.cts +3 -21
  14. package/dist/avatar/index.d.ts +3 -21
  15. package/dist/button/index.cjs +3 -3
  16. package/dist/button/index.js +2 -2
  17. package/dist/chip/index.cjs +3 -3
  18. package/dist/chip/index.js +2 -2
  19. package/dist/{chunk-KIXFSXIN.cjs → chunk-3E7TKBQI.cjs} +5 -3
  20. package/dist/chunk-3E7TKBQI.cjs.map +1 -0
  21. package/dist/{chunk-ZBKJ3EMK.cjs → chunk-442U3W6R.cjs} +3 -3
  22. package/dist/{chunk-ZBKJ3EMK.cjs.map → chunk-442U3W6R.cjs.map} +1 -1
  23. package/dist/{chunk-YQLCPKGV.js → chunk-5HUZYY54.js} +6 -4
  24. package/dist/chunk-5HUZYY54.js.map +1 -0
  25. package/dist/{chunk-G5IGADJI.cjs → chunk-5VM2256W.cjs} +7 -11
  26. package/dist/chunk-5VM2256W.cjs.map +1 -0
  27. package/dist/{chunk-Z4ZY7L7W.js → chunk-5ZL6PYU3.js} +3 -3
  28. package/dist/{chunk-A3NE2C7C.js → chunk-67RFMV6K.js} +2 -2
  29. package/dist/{chunk-2U7UJOOB.cjs → chunk-6HUHH6Y4.cjs} +17 -15
  30. package/dist/chunk-6HUHH6Y4.cjs.map +1 -0
  31. package/dist/{chunk-5WROPW7Z.js → chunk-A7WQINIG.js} +3 -3
  32. package/dist/{chunk-DKZTDYH5.cjs → chunk-AAA6TR5I.cjs} +3 -3
  33. package/dist/{chunk-DKZTDYH5.cjs.map → chunk-AAA6TR5I.cjs.map} +1 -1
  34. package/dist/{chunk-A7Z2QAFZ.cjs → chunk-APK5OQRV.cjs} +5 -5
  35. package/dist/{chunk-A7Z2QAFZ.cjs.map → chunk-APK5OQRV.cjs.map} +1 -1
  36. package/dist/{chunk-ISABZ2VX.cjs → chunk-AXBYJ2OY.cjs} +9 -9
  37. package/dist/{chunk-ISABZ2VX.cjs.map → chunk-AXBYJ2OY.cjs.map} +1 -1
  38. package/dist/{chunk-6RGJAQCU.cjs → chunk-B5G5XVFJ.cjs} +5 -5
  39. package/dist/{chunk-6RGJAQCU.cjs.map → chunk-B5G5XVFJ.cjs.map} +1 -1
  40. package/dist/{chunk-MW2S7PZ7.cjs → chunk-D5IY2HUV.cjs} +5 -5
  41. package/dist/{chunk-MW2S7PZ7.cjs.map → chunk-D5IY2HUV.cjs.map} +1 -1
  42. package/dist/{chunk-FMPXSF3H.cjs → chunk-DAXZRNNO.cjs} +4 -4
  43. package/dist/{chunk-FMPXSF3H.cjs.map → chunk-DAXZRNNO.cjs.map} +1 -1
  44. package/dist/{chunk-AJZTVCST.js → chunk-EXITZVB2.js} +24 -9
  45. package/dist/chunk-EXITZVB2.js.map +1 -0
  46. package/dist/{chunk-AYMD4D4M.cjs → chunk-EZME5CLK.cjs} +3 -3
  47. package/dist/{chunk-AYMD4D4M.cjs.map → chunk-EZME5CLK.cjs.map} +1 -1
  48. package/dist/{chunk-IV4LM3MB.js → chunk-F26VIKNF.js} +9 -11
  49. package/dist/chunk-F26VIKNF.js.map +1 -0
  50. package/dist/{chunk-WPTMMOA6.cjs → chunk-G77YR73R.cjs} +10 -13
  51. package/dist/chunk-G77YR73R.cjs.map +1 -0
  52. package/dist/chunk-GEHL4LKK.cjs +32 -0
  53. package/dist/chunk-GEHL4LKK.cjs.map +1 -0
  54. package/dist/chunk-GGSII6Y2.cjs +921 -0
  55. package/dist/chunk-GGSII6Y2.cjs.map +1 -0
  56. package/dist/{chunk-3VRMTWUS.js → chunk-GHQ6SQPI.js} +7 -10
  57. package/dist/chunk-GHQ6SQPI.js.map +1 -0
  58. package/dist/{chunk-56B6RLOE.js → chunk-GI6VJYOS.js} +4 -4
  59. package/dist/{chunk-56B6RLOE.js.map → chunk-GI6VJYOS.js.map} +1 -1
  60. package/dist/{chunk-UGMONQGH.cjs → chunk-GR2PMCVN.cjs} +10 -12
  61. package/dist/chunk-GR2PMCVN.cjs.map +1 -0
  62. package/dist/{chunk-7AHZTHXR.cjs → chunk-GT22EGJP.cjs} +5 -5
  63. package/dist/{chunk-7AHZTHXR.cjs.map → chunk-GT22EGJP.cjs.map} +1 -1
  64. package/dist/{chunk-ALGX5X4N.js → chunk-IFVT5UCY.js} +3 -3
  65. package/dist/{chunk-5CLC3FJO.js → chunk-KBG77JHC.js} +13 -2
  66. package/dist/chunk-KBG77JHC.js.map +1 -0
  67. package/dist/{chunk-HLNKIAE5.cjs → chunk-KJZUYC4X.cjs} +5 -5
  68. package/dist/{chunk-HLNKIAE5.cjs.map → chunk-KJZUYC4X.cjs.map} +1 -1
  69. package/dist/{chunk-4BQM5F76.cjs → chunk-LFWPQYWX.cjs} +3 -3
  70. package/dist/{chunk-4BQM5F76.cjs.map → chunk-LFWPQYWX.cjs.map} +1 -1
  71. package/dist/{chunk-XVSODE4K.cjs → chunk-LIFUHQH5.cjs} +35 -20
  72. package/dist/chunk-LIFUHQH5.cjs.map +1 -0
  73. package/dist/{chunk-PJC7NZUV.cjs → chunk-LUL6RZ4M.cjs} +3 -3
  74. package/dist/{chunk-PJC7NZUV.cjs.map → chunk-LUL6RZ4M.cjs.map} +1 -1
  75. package/dist/{chunk-4UJ7LG4W.cjs → chunk-N2IGZIEX.cjs} +3 -3
  76. package/dist/{chunk-4UJ7LG4W.cjs.map → chunk-N2IGZIEX.cjs.map} +1 -1
  77. package/dist/{chunk-3LHQUOGP.js → chunk-NGVOXM7P.js} +3 -3
  78. package/dist/{chunk-WTXASLBB.js → chunk-O5WEKLNF.js} +2 -2
  79. package/dist/{chunk-BOB5JJ7F.js → chunk-P7IQY5YH.js} +2 -2
  80. package/dist/{chunk-VZYLJSV5.js → chunk-R4PU2TBM.js} +2 -2
  81. package/dist/{chunk-P2GCAVUZ.js → chunk-RAZRQ57B.js} +2 -2
  82. package/dist/{chunk-K7IFNKMN.js → chunk-REVK7IGN.js} +2 -2
  83. package/dist/{chunk-6U2H26A4.cjs → chunk-RHOT7AEI.cjs} +3 -3
  84. package/dist/{chunk-6U2H26A4.cjs.map → chunk-RHOT7AEI.cjs.map} +1 -1
  85. package/dist/{chunk-MH2CD2QT.js → chunk-RKA2OJRT.js} +207 -102
  86. package/dist/chunk-RKA2OJRT.js.map +1 -0
  87. package/dist/{chunk-JC4WLVBG.js → chunk-RWOX2NJN.js} +2 -2
  88. package/dist/{chunk-4LM33LDV.js → chunk-S3CT536K.js} +2 -2
  89. package/dist/{chunk-4M3LZLOH.js → chunk-SHYSLWQG.js} +2 -2
  90. package/dist/{chunk-EQEV7GPT.cjs → chunk-SKEWTQJ7.cjs} +5 -5
  91. package/dist/{chunk-EQEV7GPT.cjs.map → chunk-SKEWTQJ7.cjs.map} +1 -1
  92. package/dist/{chunk-2ZENLZEQ.cjs → chunk-SKTDGCWJ.cjs} +232 -127
  93. package/dist/chunk-SKTDGCWJ.cjs.map +1 -0
  94. package/dist/{chunk-2BXCIWL7.js → chunk-SN6EWQDJ.js} +3 -3
  95. package/dist/{chunk-DW2YDWGN.js → chunk-TEJIPPZR.js} +2 -2
  96. package/dist/{chunk-OGKD5PLS.cjs → chunk-TRLBYA5G.cjs} +4 -4
  97. package/dist/{chunk-OGKD5PLS.cjs.map → chunk-TRLBYA5G.cjs.map} +1 -1
  98. package/dist/{chunk-WE5FTQGD.js → chunk-VHMOKXUT.js} +3 -7
  99. package/dist/chunk-VHMOKXUT.js.map +1 -0
  100. package/dist/{chunk-S77GR5YQ.cjs → chunk-VHQTDITV.cjs} +3 -3
  101. package/dist/{chunk-S77GR5YQ.cjs.map → chunk-VHQTDITV.cjs.map} +1 -1
  102. package/dist/{chunk-3HMKE2GJ.js → chunk-VSTQEHVZ.js} +6 -4
  103. package/dist/chunk-VSTQEHVZ.js.map +1 -0
  104. package/dist/{chunk-HNUTV3HR.cjs → chunk-WUBQJVB7.cjs} +3 -3
  105. package/dist/{chunk-HNUTV3HR.cjs.map → chunk-WUBQJVB7.cjs.map} +1 -1
  106. package/dist/{chunk-S7TWEVC3.js → chunk-Y53HCLGW.js} +2 -2
  107. package/dist/{chunk-WIE7HDIM.js → chunk-YJXZR7RL.js} +2 -2
  108. package/dist/{chunk-IJYYHBZC.cjs → chunk-Z4SLV6WG.cjs} +3 -3
  109. package/dist/{chunk-IJYYHBZC.cjs.map → chunk-Z4SLV6WG.cjs.map} +1 -1
  110. package/dist/chunk-ZEZK664O.js +921 -0
  111. package/dist/chunk-ZEZK664O.js.map +1 -0
  112. package/dist/{chunk-JMD3P4CY.js → chunk-ZHFPV43D.js} +2 -2
  113. package/dist/combobox/index.cjs +4 -4
  114. package/dist/combobox/index.js +3 -3
  115. package/dist/context-menu/index.cjs +4 -4
  116. package/dist/context-menu/index.js +3 -3
  117. package/dist/data-grid/index.cjs +13 -13
  118. package/dist/data-grid/index.d.cts +49 -3
  119. package/dist/data-grid/index.d.ts +49 -3
  120. package/dist/data-grid/index.js +12 -12
  121. package/dist/date-picker/index.cjs +6 -6
  122. package/dist/date-picker/index.js +5 -5
  123. package/dist/drawer/index.cjs +4 -4
  124. package/dist/drawer/index.d.cts +2 -1
  125. package/dist/drawer/index.d.ts +2 -1
  126. package/dist/drawer/index.js +3 -3
  127. package/dist/empty-state/index.d.cts +2 -2
  128. package/dist/empty-state/index.d.ts +2 -2
  129. package/dist/header/index.cjs +4 -4
  130. package/dist/header/index.d.cts +2 -2
  131. package/dist/header/index.d.ts +2 -2
  132. package/dist/header/index.js +3 -3
  133. package/dist/index.cjs +29 -29
  134. package/dist/index.css +318 -73
  135. package/dist/index.d.cts +5 -4
  136. package/dist/index.d.ts +5 -4
  137. package/dist/index.js +28 -28
  138. package/dist/inline-edit/index.cjs +4 -4
  139. package/dist/inline-edit/index.js +3 -3
  140. package/dist/input/index.cjs +3 -3
  141. package/dist/input/index.js +2 -2
  142. package/dist/menu/index.cjs +3 -3
  143. package/dist/menu/index.js +2 -2
  144. package/dist/modal/index.cjs +4 -4
  145. package/dist/modal/index.d.cts +2 -1
  146. package/dist/modal/index.d.ts +2 -1
  147. package/dist/modal/index.js +3 -3
  148. package/dist/navigation/index.cjs +4 -4
  149. package/dist/navigation/index.js +3 -3
  150. package/dist/page-layout/index.cjs +8 -8
  151. package/dist/page-layout/index.d.cts +3 -2
  152. package/dist/page-layout/index.d.ts +3 -2
  153. package/dist/page-layout/index.js +7 -7
  154. package/dist/pagination/index.cjs +6 -6
  155. package/dist/pagination/index.js +5 -5
  156. package/dist/popover/index.cjs +2 -2
  157. package/dist/popover/index.d.cts +2 -2
  158. package/dist/popover/index.d.ts +2 -2
  159. package/dist/popover/index.js +1 -1
  160. package/dist/segmented-control/index.cjs +3 -3
  161. package/dist/segmented-control/index.js +2 -2
  162. package/dist/select/index.cjs +4 -4
  163. package/dist/select/index.js +3 -3
  164. package/dist/snackbar/index.cjs +4 -4
  165. package/dist/snackbar/index.js +3 -3
  166. package/dist/split-button/index.cjs +4 -4
  167. package/dist/split-button/index.js +3 -3
  168. package/dist/table/index.cjs +11 -11
  169. package/dist/table/index.d.cts +3 -3
  170. package/dist/table/index.d.ts +3 -3
  171. package/dist/table/index.js +10 -10
  172. package/dist/tabs/index.cjs +3 -3
  173. package/dist/tabs/index.js +2 -2
  174. package/dist/tag-input/index.cjs +4 -4
  175. package/dist/tag-input/index.js +3 -3
  176. package/dist/textarea/index.cjs +3 -3
  177. package/dist/textarea/index.js +2 -2
  178. package/dist/toolbar/index.cjs +5 -5
  179. package/dist/toolbar/index.d.cts +3 -2
  180. package/dist/toolbar/index.d.ts +3 -2
  181. package/dist/toolbar/index.js +4 -4
  182. package/package.json +6 -5
  183. package/dist/Toolbar.types-BGD57Uhm.d.ts +0 -22
  184. package/dist/Toolbar.types-tQkLmPIu.d.cts +0 -22
  185. package/dist/chunk-2U7UJOOB.cjs.map +0 -1
  186. package/dist/chunk-2ZENLZEQ.cjs.map +0 -1
  187. package/dist/chunk-3HMKE2GJ.js.map +0 -1
  188. package/dist/chunk-3VRMTWUS.js.map +0 -1
  189. package/dist/chunk-5CLC3FJO.js.map +0 -1
  190. package/dist/chunk-AJZTVCST.js.map +0 -1
  191. package/dist/chunk-G5IGADJI.cjs.map +0 -1
  192. package/dist/chunk-GOR642KK.cjs +0 -21
  193. package/dist/chunk-GOR642KK.cjs.map +0 -1
  194. package/dist/chunk-IV4LM3MB.js.map +0 -1
  195. package/dist/chunk-KIXFSXIN.cjs.map +0 -1
  196. package/dist/chunk-MH2CD2QT.js.map +0 -1
  197. package/dist/chunk-QONDJ5VM.cjs +0 -744
  198. package/dist/chunk-QONDJ5VM.cjs.map +0 -1
  199. package/dist/chunk-UGMONQGH.cjs.map +0 -1
  200. package/dist/chunk-VSFKM7FE.js +0 -744
  201. package/dist/chunk-VSFKM7FE.js.map +0 -1
  202. package/dist/chunk-WE5FTQGD.js.map +0 -1
  203. package/dist/chunk-WPTMMOA6.cjs.map +0 -1
  204. package/dist/chunk-XVSODE4K.cjs.map +0 -1
  205. package/dist/chunk-YQLCPKGV.js.map +0 -1
  206. /package/dist/{chunk-Z4ZY7L7W.js.map → chunk-5ZL6PYU3.js.map} +0 -0
  207. /package/dist/{chunk-A3NE2C7C.js.map → chunk-67RFMV6K.js.map} +0 -0
  208. /package/dist/{chunk-5WROPW7Z.js.map → chunk-A7WQINIG.js.map} +0 -0
  209. /package/dist/{chunk-ALGX5X4N.js.map → chunk-IFVT5UCY.js.map} +0 -0
  210. /package/dist/{chunk-3LHQUOGP.js.map → chunk-NGVOXM7P.js.map} +0 -0
  211. /package/dist/{chunk-WTXASLBB.js.map → chunk-O5WEKLNF.js.map} +0 -0
  212. /package/dist/{chunk-BOB5JJ7F.js.map → chunk-P7IQY5YH.js.map} +0 -0
  213. /package/dist/{chunk-VZYLJSV5.js.map → chunk-R4PU2TBM.js.map} +0 -0
  214. /package/dist/{chunk-P2GCAVUZ.js.map → chunk-RAZRQ57B.js.map} +0 -0
  215. /package/dist/{chunk-K7IFNKMN.js.map → chunk-REVK7IGN.js.map} +0 -0
  216. /package/dist/{chunk-JC4WLVBG.js.map → chunk-RWOX2NJN.js.map} +0 -0
  217. /package/dist/{chunk-4LM33LDV.js.map → chunk-S3CT536K.js.map} +0 -0
  218. /package/dist/{chunk-4M3LZLOH.js.map → chunk-SHYSLWQG.js.map} +0 -0
  219. /package/dist/{chunk-2BXCIWL7.js.map → chunk-SN6EWQDJ.js.map} +0 -0
  220. /package/dist/{chunk-DW2YDWGN.js.map → chunk-TEJIPPZR.js.map} +0 -0
  221. /package/dist/{chunk-S7TWEVC3.js.map → chunk-Y53HCLGW.js.map} +0 -0
  222. /package/dist/{chunk-WIE7HDIM.js.map → chunk-YJXZR7RL.js.map} +0 -0
  223. /package/dist/{chunk-JMD3P4CY.js.map → chunk-ZHFPV43D.js.map} +0 -0
@@ -0,0 +1,921 @@
1
+ import {
2
+ CSS,
3
+ DndContext,
4
+ KeyboardSensor,
5
+ PointerSensor,
6
+ SortableContext,
7
+ TableFiltersDropdown,
8
+ arrayMove,
9
+ horizontalListSortingStrategy,
10
+ sortableKeyboardCoordinates,
11
+ useSensor,
12
+ useSensors,
13
+ useSortable
14
+ } from "./chunk-EXITZVB2.js";
15
+ import {
16
+ Spinner
17
+ } from "./chunk-6ZAT5CGB.js";
18
+ import {
19
+ SplitButton
20
+ } from "./chunk-NGVOXM7P.js";
21
+ import {
22
+ Pagination
23
+ } from "./chunk-GI6VJYOS.js";
24
+ import {
25
+ EmptyState
26
+ } from "./chunk-3TUCQAYL.js";
27
+ import {
28
+ Checkbox
29
+ } from "./chunk-H6CWTMAH.js";
30
+ import {
31
+ Dropdown
32
+ } from "./chunk-4BKTBV2I.js";
33
+ import {
34
+ Button
35
+ } from "./chunk-YJXZR7RL.js";
36
+ import {
37
+ devWarn
38
+ } from "./chunk-KBG77JHC.js";
39
+
40
+ // src/components/Table/Table.component.tsx
41
+ import { useState, useMemo, useEffect, useLayoutEffect, useRef, useCallback } from "react";
42
+ import {
43
+ ChevronsUpDown,
44
+ ArrowUp,
45
+ ArrowDown,
46
+ Check,
47
+ Download,
48
+ Columns3,
49
+ AlignJustify,
50
+ GripVertical,
51
+ FolderOpen,
52
+ SearchX
53
+ } from "lucide-react";
54
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
55
+ var MIN_DATA_COLUMN_WIDTH_PX = 100;
56
+ var ICON_COLUMN_WIDTH_PX = 48;
57
+ var CHECKBOX_COLUMN_WIDTH_PX = 40;
58
+ var COMPACT_TOOLBAR_WIDTH_PX = 560;
59
+ var DENSITY_OPTIONS = [
60
+ { value: "compact", label: "Compact" },
61
+ { value: "comfortable", label: "Comfortable" },
62
+ { value: "spacious", label: "Spacious" }
63
+ ];
64
+ function escapeCsvValue(value) {
65
+ if (value.includes(",") || value.includes("\n") || value.includes('"')) {
66
+ return `"${value.replace(/"/g, '""')}"`;
67
+ }
68
+ return value;
69
+ }
70
+ function SortableColumnHeader({
71
+ id,
72
+ column,
73
+ isSortable,
74
+ isCurrentlySorted,
75
+ sortDirection,
76
+ alignment,
77
+ columnType,
78
+ columnWidth,
79
+ pinnedClass,
80
+ stickyStyle,
81
+ onSortClick
82
+ }) {
83
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
84
+ id
85
+ });
86
+ const transformStr = CSS.Transform.toString(transform);
87
+ const thClassName = [
88
+ "eidos-table-header-cell",
89
+ `eidos-table-header-cell-${columnType}`,
90
+ isSortable ? "eidos-table-sortable" : "",
91
+ isCurrentlySorted ? "eidos-table-sorted" : "",
92
+ `eidos-table-align-${alignment}`,
93
+ pinnedClass
94
+ ].filter(Boolean).join(" ");
95
+ return /* @__PURE__ */ jsxs(
96
+ "th",
97
+ {
98
+ ref: setNodeRef,
99
+ className: thClassName,
100
+ style: {
101
+ width: columnWidth,
102
+ ...stickyStyle,
103
+ ...transformStr ? { transform: transformStr } : {},
104
+ transition: transition ?? void 0,
105
+ opacity: isDragging ? 0.5 : 1
106
+ },
107
+ "data-col-key": id,
108
+ onClick: () => isSortable && onSortClick(),
109
+ ...attributes,
110
+ children: [
111
+ /* @__PURE__ */ jsx(
112
+ "span",
113
+ {
114
+ className: "eidos-table-drag-handle",
115
+ ...listeners,
116
+ onClick: (e) => e.stopPropagation(),
117
+ title: "Drag to reorder",
118
+ children: /* @__PURE__ */ jsx(GripVertical, { size: 12 })
119
+ }
120
+ ),
121
+ /* @__PURE__ */ jsxs("div", { className: `eidos-table-header-content eidos-table-align-${alignment}`, children: [
122
+ /* @__PURE__ */ jsx("span", { className: "eidos-table-header-label", children: column.label }),
123
+ isSortable && /* @__PURE__ */ jsxs("div", { className: "eidos-table-sort-indicator", children: [
124
+ sortDirection === "asc" && /* @__PURE__ */ jsx(ArrowUp, { size: 14 }),
125
+ sortDirection === "desc" && /* @__PURE__ */ jsx(ArrowDown, { size: 14 }),
126
+ !sortDirection && /* @__PURE__ */ jsx(ChevronsUpDown, { size: 14 })
127
+ ] })
128
+ ] })
129
+ ]
130
+ }
131
+ );
132
+ }
133
+ var Table = ({
134
+ data,
135
+ columns,
136
+ loading = false,
137
+ emptyMessage = "No data available",
138
+ onRowClick,
139
+ className,
140
+ showFooter = false,
141
+ totalItems,
142
+ showPagination = false,
143
+ pageSize = 25,
144
+ pageSizeOptions = [10, 25, 50, 100],
145
+ onSortChange,
146
+ currentSort,
147
+ filters = {},
148
+ onFiltersChange,
149
+ defaultFilters,
150
+ showFilters = false,
151
+ // Selection
152
+ selectable = false,
153
+ rowKey,
154
+ selectedRows: controlledSelected,
155
+ defaultSelectedRows = [],
156
+ onSelectionChange,
157
+ selectAllScope = "all",
158
+ onSelectAllMatching,
159
+ bulkActions = [],
160
+ // New features
161
+ density = "comfortable",
162
+ showDensity = false,
163
+ showColumnVisibility = false,
164
+ showExport = false,
165
+ draggableColumns = false,
166
+ onColumnReorder,
167
+ // Card view
168
+ hasCardView = true,
169
+ cardViewBreakpoint = 640,
170
+ cardMinWidth = 280
171
+ }) => {
172
+ const [columnOrder, setColumnOrder] = useState(() => columns.map((c) => String(c.key)));
173
+ const columnKeysSignature = columns.map((c) => String(c.key)).join("\0");
174
+ const prevKeysRef = useRef(columnKeysSignature);
175
+ if (prevKeysRef.current !== columnKeysSignature) {
176
+ prevKeysRef.current = columnKeysSignature;
177
+ setColumnOrder(columns.map((c) => String(c.key)));
178
+ }
179
+ const orderedColumns = useMemo(() => {
180
+ const orderMap = new Map(columnOrder.map((key, idx) => [key, idx]));
181
+ return [...columns].sort((a, b) => {
182
+ const ai = orderMap.get(String(a.key)) ?? Infinity;
183
+ const bi = orderMap.get(String(b.key)) ?? Infinity;
184
+ return ai - bi;
185
+ });
186
+ }, [columns, columnOrder]);
187
+ const [internalDensity, setInternalDensity] = useState(density);
188
+ const effectiveDensity = showDensity ? internalDensity : density;
189
+ const [hiddenColumnKeys, setHiddenColumnKeys] = useState(() => /* @__PURE__ */ new Set());
190
+ const visibleColumns = useMemo(
191
+ () => orderedColumns.filter((c) => !hiddenColumnKeys.has(String(c.key))),
192
+ [orderedColumns, hiddenColumnKeys]
193
+ );
194
+ const [containerWidth, setContainerWidth] = useState(null);
195
+ const resizeObserverRef = useRef(null);
196
+ const setContainerRef = useCallback((el) => {
197
+ resizeObserverRef.current?.disconnect();
198
+ resizeObserverRef.current = null;
199
+ if (!el) return;
200
+ const observer = new ResizeObserver((entries) => {
201
+ const width = entries[0]?.contentRect.width;
202
+ if (width != null) setContainerWidth(width);
203
+ });
204
+ observer.observe(el);
205
+ resizeObserverRef.current = observer;
206
+ }, []);
207
+ const minTableWidth = useMemo(
208
+ () => visibleColumns.reduce(
209
+ (total, column) => total + (column.type === "icon" || column.type === "action" ? ICON_COLUMN_WIDTH_PX : MIN_DATA_COLUMN_WIDTH_PX),
210
+ selectable ? CHECKBOX_COLUMN_WIDTH_PX : 0
211
+ ),
212
+ [visibleColumns, selectable]
213
+ );
214
+ const isCardView = hasCardView && containerWidth !== null && (containerWidth < cardViewBreakpoint || containerWidth < minTableWidth);
215
+ const isCompactToolbar = containerWidth !== null && containerWidth < COMPACT_TOOLBAR_WIDTH_PX;
216
+ const cardHeaderColumn = useMemo(
217
+ () => visibleColumns.find((c) => c.cardHeader),
218
+ [visibleColumns]
219
+ );
220
+ const cardSubheaderColumn = useMemo(
221
+ () => visibleColumns.find((c) => c.cardSubheader),
222
+ [visibleColumns]
223
+ );
224
+ const cardActionsColumn = useMemo(
225
+ () => visibleColumns.find((c) => c.type === "action"),
226
+ [visibleColumns]
227
+ );
228
+ const cardFieldColumns = useMemo(
229
+ () => visibleColumns.filter(
230
+ (c) => c !== cardHeaderColumn && c !== cardSubheaderColumn && c !== cardActionsColumn
231
+ ),
232
+ [visibleColumns, cardHeaderColumn, cardSubheaderColumn, cardActionsColumn]
233
+ );
234
+ const theadRef = useRef(null);
235
+ const [pinnedOffsets, setPinnedOffsets] = useState(/* @__PURE__ */ new Map());
236
+ useLayoutEffect(() => {
237
+ const hasPinned = visibleColumns.some((c) => c.pin);
238
+ if (!hasPinned || !theadRef.current) {
239
+ setPinnedOffsets(/* @__PURE__ */ new Map());
240
+ return;
241
+ }
242
+ const headerRow = theadRef.current.querySelector("tr");
243
+ if (!headerRow) return;
244
+ const cells = Array.from(headerRow.querySelectorAll("th[data-col-key]"));
245
+ const newOffsets = /* @__PURE__ */ new Map();
246
+ let leftAccum = 0;
247
+ for (const cell of cells) {
248
+ const key = cell.dataset.colKey;
249
+ if (key === "__checkbox__") {
250
+ newOffsets.set(key, { side: "left", offset: leftAccum });
251
+ leftAccum += cell.offsetWidth;
252
+ } else {
253
+ const col = visibleColumns.find((c) => String(c.key) === key);
254
+ if (col?.pin === "left") {
255
+ newOffsets.set(key, { side: "left", offset: leftAccum });
256
+ leftAccum += cell.offsetWidth;
257
+ }
258
+ }
259
+ }
260
+ let rightAccum = 0;
261
+ for (let i = cells.length - 1; i >= 0; i--) {
262
+ const cell = cells[i];
263
+ const key = cell.dataset.colKey;
264
+ const col = visibleColumns.find((c) => String(c.key) === key);
265
+ if (col?.pin === "right") {
266
+ newOffsets.set(key, { side: "right", offset: rightAccum });
267
+ rightAccum += cell.offsetWidth;
268
+ }
269
+ }
270
+ setPinnedOffsets(newOffsets);
271
+ }, [visibleColumns, selectable]);
272
+ const isControlledSelection = controlledSelected !== void 0;
273
+ const [internalSelected, setInternalSelected] = useState(defaultSelectedRows);
274
+ const selectedSet = useMemo(
275
+ () => new Set(isControlledSelection ? controlledSelected : internalSelected),
276
+ [isControlledSelection, controlledSelected, internalSelected]
277
+ );
278
+ const getRowKey = (item, index) => {
279
+ if (rowKey) return String(item[rowKey]);
280
+ if ("id" in item) return String(item.id);
281
+ return String(index);
282
+ };
283
+ const rowsByKey = useMemo(() => {
284
+ const map = /* @__PURE__ */ new Map();
285
+ data.forEach((item, idx) => map.set(getRowKey(item, idx), item));
286
+ return map;
287
+ }, [data, rowKey]);
288
+ const selectedRowCacheRef = useRef(/* @__PURE__ */ new Map());
289
+ const rowsForKeys = (keys) => {
290
+ const cache = selectedRowCacheRef.current;
291
+ return keys.map((key) => rowsByKey.get(key) ?? cache.get(key)).filter((row) => row !== void 0);
292
+ };
293
+ useEffect(() => {
294
+ const cache = selectedRowCacheRef.current;
295
+ const next = /* @__PURE__ */ new Map();
296
+ selectedSet.forEach((key) => {
297
+ const row = rowsByKey.get(key) ?? cache.get(key);
298
+ if (row) next.set(key, row);
299
+ });
300
+ selectedRowCacheRef.current = next;
301
+ }, [rowsByKey, selectedSet]);
302
+ const commitSelection = (keys) => {
303
+ if (!isControlledSelection) setInternalSelected(keys);
304
+ onSelectionChange?.(keys, rowsForKeys(keys));
305
+ };
306
+ const toggleRow = (key) => {
307
+ const next = selectedSet.has(key) ? [...selectedSet].filter((k) => k !== key) : [...selectedSet, key];
308
+ commitSelection(next);
309
+ };
310
+ const [currentPage, setCurrentPage] = useState(1);
311
+ const [currentPageSize, setCurrentPageSize] = useState(pageSize);
312
+ const displayData = useMemo(() => {
313
+ if (!showPagination) return data;
314
+ const startIndex = (currentPage - 1) * currentPageSize;
315
+ return data.slice(startIndex, startIndex + currentPageSize);
316
+ }, [data, showPagination, currentPage, currentPageSize]);
317
+ const totalPages = Math.ceil(data.length / currentPageSize);
318
+ const selectAllKeys = useMemo(() => {
319
+ if (selectAllScope === "page") {
320
+ const offset = showPagination ? (currentPage - 1) * currentPageSize : 0;
321
+ return displayData.map((item, idx) => getRowKey(item, offset + idx));
322
+ }
323
+ return data.map((item, idx) => getRowKey(item, idx));
324
+ }, [selectAllScope, displayData, data, showPagination, currentPage, currentPageSize, rowKey]);
325
+ const allSelected = selectAllKeys.length > 0 && selectAllKeys.every((key) => selectedSet.has(key));
326
+ const someSelected = !allSelected && selectAllKeys.some((key) => selectedSet.has(key));
327
+ const toggleAll = () => {
328
+ const inScope = new Set(selectAllKeys);
329
+ commitSelection(
330
+ allSelected ? [...selectedSet].filter((key) => !inScope.has(key)) : [.../* @__PURE__ */ new Set([...selectedSet, ...selectAllKeys])]
331
+ );
332
+ };
333
+ const clearSelection = () => commitSelection([]);
334
+ const [isSelectingAllMatching, setIsSelectingAllMatching] = useState(false);
335
+ const totalItemCount = totalItems ?? data.length;
336
+ const holdsEveryRow = totalItemCount <= data.length;
337
+ const hasSelectedAllMatching = !holdsEveryRow && selectedSet.size >= totalItemCount;
338
+ const canSelectAllMatching = !!onSelectAllMatching && selectable && !holdsEveryRow && allSelected && !hasSelectedAllMatching;
339
+ const selectAllMatching = async () => {
340
+ if (!onSelectAllMatching) return;
341
+ setIsSelectingAllMatching(true);
342
+ try {
343
+ commitSelection(await onSelectAllMatching());
344
+ } catch (error) {
345
+ devWarn(
346
+ "table-select-all-matching-failed",
347
+ `Table: onSelectAllMatching() rejected, so the selection was left untouched. ${String(error)}`
348
+ );
349
+ } finally {
350
+ setIsSelectingAllMatching(false);
351
+ }
352
+ };
353
+ useEffect(() => {
354
+ if (!selectable || selectAllScope !== "all") return;
355
+ if (totalItems === void 0 || totalItems <= data.length) return;
356
+ devWarn(
357
+ `table-select-all-scope:${data.length}/${totalItems}`,
358
+ `Table: selectAllScope="all" can only select the ${data.length} row(s) in \`data\`, but \`totalItems\` is ${totalItems}. The keys of rows the table has never received cannot be known here - pass the full dataset, or use selectAllScope="page" to make the scope explicit.`
359
+ );
360
+ }, [selectable, selectAllScope, totalItems, data.length]);
361
+ const handleSort = (key) => {
362
+ const newDirection = currentSort?.key === key && currentSort?.direction === "asc" ? "desc" : "asc";
363
+ onSortChange?.(key, newDirection);
364
+ };
365
+ const handlePageChange = (page) => setCurrentPage(page);
366
+ const handlePageSizeChange = (newPageSize) => {
367
+ setCurrentPageSize(newPageSize);
368
+ setCurrentPage(1);
369
+ };
370
+ const hasSelection = selectedSet.size > 0;
371
+ const showToolbar = showFilters && !!onFiltersChange || showColumnVisibility || showExport || showDensity || selectable && (hasSelection || isCardView);
372
+ const selectedItems = useMemo(
373
+ () => rowsForKeys([...selectedSet]),
374
+ // eslint-disable-next-line react-hooks/exhaustive-deps
375
+ [rowsByKey, selectedSet]
376
+ );
377
+ const getCellValue = (item, column) => typeof column.key === "string" && column.key.includes(".") ? column.key.split(".").reduce(
378
+ (obj, k) => obj?.[k],
379
+ item
380
+ ) : item[column.key];
381
+ const renderCellContent = (item, column) => {
382
+ const value = getCellValue(item, column);
383
+ return column.render ? column.render(value, item) : String(value ?? "");
384
+ };
385
+ const getRawValue = (item, column) => String(getCellValue(item, column) ?? "");
386
+ const handleExportCsv = () => {
387
+ const headers = visibleColumns.map((c) => escapeCsvValue(c.label)).join(",");
388
+ const rows = data.map(
389
+ (item) => visibleColumns.map((col) => escapeCsvValue(getRawValue(item, col))).join(",")
390
+ );
391
+ const csv = [headers, ...rows].join("\n");
392
+ const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
393
+ const url = URL.createObjectURL(blob);
394
+ const link = document.createElement("a");
395
+ link.href = url;
396
+ link.download = "export.csv";
397
+ document.body.appendChild(link);
398
+ link.click();
399
+ document.body.removeChild(link);
400
+ URL.revokeObjectURL(url);
401
+ };
402
+ const sensors = useSensors(
403
+ useSensor(PointerSensor),
404
+ useSensor(KeyboardSensor, {
405
+ coordinateGetter: sortableKeyboardCoordinates
406
+ })
407
+ );
408
+ const handleDragEnd = (event) => {
409
+ const { active, over } = event;
410
+ if (!over || active.id === over.id) return;
411
+ const activeId = String(active.id);
412
+ const overId = String(over.id);
413
+ const oldIndex = columnOrder.indexOf(activeId);
414
+ const newIndex = columnOrder.indexOf(overId);
415
+ if (oldIndex === -1 || newIndex === -1) return;
416
+ const newOrder = arrayMove(columnOrder, oldIndex, newIndex);
417
+ setColumnOrder(newOrder);
418
+ if (onColumnReorder) {
419
+ const orderMap = new Map(newOrder.map((key, idx) => [key, idx]));
420
+ const reordered = [...columns].sort((a, b) => {
421
+ const ai = orderMap.get(String(a.key)) ?? Infinity;
422
+ const bi = orderMap.get(String(b.key)) ?? Infinity;
423
+ return ai - bi;
424
+ });
425
+ onColumnReorder(reordered);
426
+ }
427
+ };
428
+ const getCellPinnedProps = (colKey) => {
429
+ const pinInfo = pinnedOffsets.get(colKey);
430
+ if (!pinInfo) return { style: {}, className: "" };
431
+ return {
432
+ style: {
433
+ position: "sticky",
434
+ [pinInfo.side]: pinInfo.offset,
435
+ zIndex: 1
436
+ },
437
+ className: pinInfo.side === "left" ? "eidos-table-cell--pinned-left" : "eidos-table-cell--pinned-right"
438
+ };
439
+ };
440
+ const getHeaderPinnedProps = (colKey) => {
441
+ const pinInfo = pinnedOffsets.get(colKey);
442
+ if (!pinInfo) return { style: {}, className: "" };
443
+ return {
444
+ style: {
445
+ position: "sticky",
446
+ [pinInfo.side]: pinInfo.offset,
447
+ zIndex: 3
448
+ },
449
+ className: pinInfo.side === "left" ? "eidos-table-header-cell--pinned-left" : "eidos-table-header-cell--pinned-right"
450
+ };
451
+ };
452
+ const densityClass = effectiveDensity !== "comfortable" ? `eidos-table--${effectiveDensity}` : "";
453
+ const effectivePageSizeOptions = useMemo(
454
+ () => pageSizeOptions.includes(currentPageSize) ? pageSizeOptions : [...pageSizeOptions, currentPageSize].sort((a, b) => a - b),
455
+ [pageSizeOptions, currentPageSize]
456
+ );
457
+ if (loading) {
458
+ return /* @__PURE__ */ jsx("div", { ref: setContainerRef, className: `eidos-table-container ${className || ""}`, children: /* @__PURE__ */ jsxs("div", { className: "eidos-table-loading", children: [
459
+ /* @__PURE__ */ jsx(Spinner, { size: "md" }),
460
+ /* @__PURE__ */ jsx("p", { children: "Loading..." })
461
+ ] }) });
462
+ }
463
+ const densityPanel = /* @__PURE__ */ jsx("div", { className: "eidos-table-menu-panel", children: DENSITY_OPTIONS.map((option) => /* @__PURE__ */ jsxs(
464
+ "button",
465
+ {
466
+ className: [
467
+ "eidos-table-menu-item",
468
+ effectiveDensity === option.value ? "eidos-table-menu-item--active" : ""
469
+ ].filter(Boolean).join(" "),
470
+ onClick: () => setInternalDensity(option.value),
471
+ children: [
472
+ /* @__PURE__ */ jsx("span", { className: "eidos-table-menu-item-check", children: effectiveDensity === option.value && /* @__PURE__ */ jsx(Check, { size: 14 }) }),
473
+ /* @__PURE__ */ jsx("span", { children: option.label })
474
+ ]
475
+ },
476
+ option.value
477
+ )) });
478
+ const columnVisibilityPanel = /* @__PURE__ */ jsx("div", { className: "eidos-table-menu-panel", children: orderedColumns.map((col) => {
479
+ const key = String(col.key);
480
+ const isVisible = !hiddenColumnKeys.has(key);
481
+ const isLastVisible = visibleColumns.length === 1 && isVisible;
482
+ return /* @__PURE__ */ jsxs(
483
+ "button",
484
+ {
485
+ className: ["eidos-table-menu-item", isVisible ? "eidos-table-menu-item--active" : ""].filter(Boolean).join(" "),
486
+ disabled: isLastVisible,
487
+ onClick: () => {
488
+ setHiddenColumnKeys((prev) => {
489
+ const next = new Set(prev);
490
+ if (next.has(key)) next.delete(key);
491
+ else next.add(key);
492
+ return next;
493
+ });
494
+ },
495
+ children: [
496
+ /* @__PURE__ */ jsx(
497
+ Checkbox,
498
+ {
499
+ checked: isVisible,
500
+ disabled: isLastVisible,
501
+ size: "sm",
502
+ onChange: () => {
503
+ }
504
+ }
505
+ ),
506
+ /* @__PURE__ */ jsx("span", { children: col.label })
507
+ ]
508
+ },
509
+ key
510
+ );
511
+ }) });
512
+ const sortableItems = visibleColumns.map((c) => String(c.key));
513
+ const emptyStateNode = Object.keys(filters).length > 0 ? /* @__PURE__ */ jsx(
514
+ EmptyState,
515
+ {
516
+ icon: /* @__PURE__ */ jsx(SearchX, {}),
517
+ title: "No results found",
518
+ description: "Try adjusting your filters or search terms.",
519
+ action: onFiltersChange ? /* @__PURE__ */ jsx(
520
+ Button,
521
+ {
522
+ size: "sm",
523
+ variant: "outlined",
524
+ color: "primary",
525
+ onClick: () => onFiltersChange({}),
526
+ children: "Clear filters"
527
+ }
528
+ ) : void 0,
529
+ size: "sm"
530
+ }
531
+ ) : /* @__PURE__ */ jsx(
532
+ EmptyState,
533
+ {
534
+ icon: /* @__PURE__ */ jsx(FolderOpen, {}),
535
+ title: emptyMessage,
536
+ description: "There are no records to display.",
537
+ size: "sm"
538
+ }
539
+ );
540
+ const hasCardToolbar = selectable || !!cardHeaderColumn || !!cardSubheaderColumn || !!cardActionsColumn;
541
+ const cardsContent = /* @__PURE__ */ jsx(
542
+ "div",
543
+ {
544
+ className: "eidos-table-cards",
545
+ style: { "--eidos-table-card-min-width": `${cardMinWidth}px` },
546
+ children: displayData.length > 0 ? displayData.map((item, rowIndex) => {
547
+ const globalIndex = showPagination ? (currentPage - 1) * currentPageSize + rowIndex : rowIndex;
548
+ const key = getRowKey(item, globalIndex);
549
+ const isSelected = selectedSet.has(key);
550
+ return /* @__PURE__ */ jsxs(
551
+ "div",
552
+ {
553
+ className: [
554
+ "eidos-table-card",
555
+ onRowClick ? "eidos-table-card--clickable" : "",
556
+ isSelected ? "eidos-table-card--selected" : ""
557
+ ].filter(Boolean).join(" "),
558
+ onClick: () => onRowClick?.(item),
559
+ children: [
560
+ hasCardToolbar && /* @__PURE__ */ jsxs("div", { className: "eidos-table-card-toolbar", onClick: (e) => e.stopPropagation(), children: [
561
+ /* @__PURE__ */ jsx("div", { className: "eidos-table-card-toolbar-left", children: selectable && /* @__PURE__ */ jsx(
562
+ Checkbox,
563
+ {
564
+ size: "sm",
565
+ checked: isSelected,
566
+ onChange: () => toggleRow(key),
567
+ "aria-label": `Select row ${globalIndex + 1}`
568
+ }
569
+ ) }),
570
+ /* @__PURE__ */ jsxs("div", { className: "eidos-table-card-heading", children: [
571
+ cardHeaderColumn && /* @__PURE__ */ jsx("span", { className: "eidos-table-card-heading-title", children: renderCellContent(item, cardHeaderColumn) }),
572
+ cardSubheaderColumn && /* @__PURE__ */ jsx("span", { className: "eidos-table-card-heading-subtitle", children: renderCellContent(item, cardSubheaderColumn) })
573
+ ] }),
574
+ /* @__PURE__ */ jsx("div", { className: "eidos-table-card-toolbar-right", children: cardActionsColumn && renderCellContent(item, cardActionsColumn) })
575
+ ] }),
576
+ /* @__PURE__ */ jsx("div", { className: "eidos-table-card-fields", children: cardFieldColumns.map((column) => /* @__PURE__ */ jsxs("div", { className: "eidos-table-card-field", children: [
577
+ column.label && /* @__PURE__ */ jsx("span", { className: "eidos-table-card-field-label", children: column.label }),
578
+ /* @__PURE__ */ jsx("span", { className: "eidos-table-card-field-value", children: renderCellContent(item, column) })
579
+ ] }, String(column.key))) })
580
+ ]
581
+ },
582
+ key
583
+ );
584
+ }) : /* @__PURE__ */ jsx("div", { className: "eidos-table-card-empty", children: emptyStateNode })
585
+ }
586
+ );
587
+ const tableContent = /* @__PURE__ */ jsxs(
588
+ "div",
589
+ {
590
+ ref: setContainerRef,
591
+ className: ["eidos-table-container", densityClass, className].filter(Boolean).join(" "),
592
+ children: [
593
+ showToolbar && /* @__PURE__ */ jsxs("div", { className: "eidos-table-toolbar", children: [
594
+ /* @__PURE__ */ jsxs("div", { className: "eidos-table-toolbar-left", children: [
595
+ selectable && isCardView && /* @__PURE__ */ jsx(
596
+ Checkbox,
597
+ {
598
+ size: "sm",
599
+ checked: allSelected,
600
+ indeterminate: someSelected,
601
+ onChange: toggleAll,
602
+ label: "Select all",
603
+ "aria-label": "Select all rows"
604
+ }
605
+ ),
606
+ selectable && hasSelection && /* @__PURE__ */ jsxs(Fragment, { children: [
607
+ /* @__PURE__ */ jsxs("span", { className: "eidos-table-selection-count", children: [
608
+ selectedSet.size,
609
+ " selected"
610
+ ] }),
611
+ canSelectAllMatching && /* @__PURE__ */ jsx(
612
+ Button,
613
+ {
614
+ variant: "text",
615
+ size: "sm",
616
+ loading: isSelectingAllMatching,
617
+ onClick: () => void selectAllMatching(),
618
+ children: `Select all ${totalItemCount}`
619
+ }
620
+ ),
621
+ hasSelectedAllMatching && /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", color: "secondary", onClick: clearSelection, children: "Clear selection" }),
622
+ bulkActions.length > 0 && /* @__PURE__ */ jsx("div", { className: "eidos-table-bulk-actions", children: bulkActions.map((action) => {
623
+ const isDisabled = typeof action.disabled === "function" ? action.disabled(selectedItems) : action.disabled ?? false;
624
+ if (action.type === "split-button") {
625
+ return /* @__PURE__ */ jsx(
626
+ SplitButton,
627
+ {
628
+ size: "sm",
629
+ variant: action.variant ?? "outlined",
630
+ color: action.color ?? "secondary",
631
+ preIcon: action.icon,
632
+ disabled: isDisabled,
633
+ label: action.label,
634
+ onClick: () => action.onClick(selectedItems),
635
+ options: action.options.map((option) => ({
636
+ id: option.id,
637
+ label: option.label,
638
+ icon: option.icon,
639
+ disabled: option.disabled,
640
+ onClick: () => option.onClick(selectedItems)
641
+ }))
642
+ },
643
+ action.id
644
+ );
645
+ }
646
+ return action.label ? /* @__PURE__ */ jsx(
647
+ Button,
648
+ {
649
+ size: "sm",
650
+ variant: action.variant ?? "outlined",
651
+ color: action.color ?? "secondary",
652
+ preIcon: action.icon,
653
+ posIcon: action.posIcon,
654
+ disabled: isDisabled,
655
+ onClick: () => action.onClick(selectedItems),
656
+ children: action.label
657
+ },
658
+ action.id
659
+ ) : action.icon ? /* @__PURE__ */ jsx(
660
+ Button,
661
+ {
662
+ size: "sm",
663
+ variant: action.variant ?? "outlined",
664
+ color: action.color ?? "secondary",
665
+ icon: action.icon,
666
+ disabled: isDisabled,
667
+ onClick: () => action.onClick(selectedItems)
668
+ },
669
+ action.id
670
+ ) : null;
671
+ }) })
672
+ ] })
673
+ ] }),
674
+ /* @__PURE__ */ jsxs("div", { className: "eidos-table-toolbar-right", children: [
675
+ showDensity && /* @__PURE__ */ jsx(
676
+ Dropdown,
677
+ {
678
+ placement: "bottom",
679
+ align: "end",
680
+ autoWidth: false,
681
+ trigger: isCompactToolbar ? /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", icon: AlignJustify, tooltip: "Density" }) : /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", preIcon: AlignJustify, children: "Density" }),
682
+ content: densityPanel
683
+ }
684
+ ),
685
+ showColumnVisibility && /* @__PURE__ */ jsx(
686
+ Dropdown,
687
+ {
688
+ placement: "bottom",
689
+ align: "end",
690
+ autoWidth: false,
691
+ trigger: isCompactToolbar ? /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", icon: Columns3, tooltip: "Columns" }) : /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", preIcon: Columns3, children: "Columns" }),
692
+ content: columnVisibilityPanel
693
+ }
694
+ ),
695
+ showExport && /* @__PURE__ */ jsx(
696
+ Button,
697
+ {
698
+ variant: "text",
699
+ size: "sm",
700
+ icon: Download,
701
+ onClick: handleExportCsv,
702
+ tooltip: "Export CSV"
703
+ }
704
+ ),
705
+ showFilters && onFiltersChange && /* @__PURE__ */ jsx(
706
+ TableFiltersDropdown,
707
+ {
708
+ columns,
709
+ filters,
710
+ onFiltersChange,
711
+ defaultFilters
712
+ }
713
+ )
714
+ ] })
715
+ ] }),
716
+ isCardView ? cardsContent : (
717
+ /* Table wrapped for horizontal scroll */
718
+ /* @__PURE__ */ jsx("div", { className: "eidos-table-scroll", children: /* @__PURE__ */ jsxs(
719
+ "table",
720
+ {
721
+ className: [
722
+ "eidos-table",
723
+ densityClass,
724
+ draggableColumns ? "eidos-table--draggable-columns" : ""
725
+ ].filter(Boolean).join(" "),
726
+ children: [
727
+ /* @__PURE__ */ jsx("thead", { ref: theadRef, children: /* @__PURE__ */ jsxs("tr", { children: [
728
+ selectable && /* @__PURE__ */ jsx(
729
+ "th",
730
+ {
731
+ className: [
732
+ "eidos-table-header-cell",
733
+ "eidos-table-checkbox-cell",
734
+ getHeaderPinnedProps("__checkbox__").className
735
+ ].filter(Boolean).join(" "),
736
+ style: getHeaderPinnedProps("__checkbox__").style,
737
+ "data-col-key": "__checkbox__",
738
+ children: /* @__PURE__ */ jsx(
739
+ Checkbox,
740
+ {
741
+ size: "sm",
742
+ checked: allSelected,
743
+ indeterminate: someSelected,
744
+ onChange: toggleAll,
745
+ "aria-label": "Select all rows"
746
+ }
747
+ )
748
+ }
749
+ ),
750
+ draggableColumns ? visibleColumns.map((column) => {
751
+ const colKey = String(column.key);
752
+ const columnType = column.type || "data";
753
+ const columnWidth = column.width;
754
+ const isSortable = !!column.sortable;
755
+ const isCurrentlySorted = currentSort?.key === colKey;
756
+ const sortDirection = isCurrentlySorted ? currentSort.direction : null;
757
+ const alignment = column.align || "left";
758
+ const { style: pinnedStyle, className: pinnedClass } = getHeaderPinnedProps(colKey);
759
+ return /* @__PURE__ */ jsx(
760
+ SortableColumnHeader,
761
+ {
762
+ id: colKey,
763
+ column,
764
+ isSortable,
765
+ isCurrentlySorted: !!isCurrentlySorted,
766
+ sortDirection,
767
+ alignment,
768
+ columnType,
769
+ columnWidth,
770
+ pinnedClass,
771
+ stickyStyle: pinnedStyle,
772
+ onSortClick: () => handleSort(colKey)
773
+ },
774
+ colKey
775
+ );
776
+ }) : visibleColumns.map((column, index) => {
777
+ const colKey = String(column.key);
778
+ const columnType = column.type || "data";
779
+ const columnWidth = column.width;
780
+ const isSortable = column.sortable;
781
+ const isCurrentlySorted = currentSort?.key === colKey;
782
+ const sortDirection = isCurrentlySorted ? currentSort.direction : null;
783
+ const alignment = column.align || "left";
784
+ const alignmentClass = `eidos-table-align-${alignment}`;
785
+ const { style: pinnedStyle, className: pinnedClass } = getHeaderPinnedProps(colKey);
786
+ return /* @__PURE__ */ jsx(
787
+ "th",
788
+ {
789
+ className: [
790
+ "eidos-table-header-cell",
791
+ `eidos-table-header-cell-${columnType}`,
792
+ isSortable ? "eidos-table-sortable" : "",
793
+ isCurrentlySorted ? "eidos-table-sorted" : "",
794
+ alignmentClass,
795
+ pinnedClass
796
+ ].filter(Boolean).join(" "),
797
+ style: { width: columnWidth, ...pinnedStyle },
798
+ "data-col-key": colKey,
799
+ onClick: () => isSortable && handleSort(colKey),
800
+ children: /* @__PURE__ */ jsxs("div", { className: `eidos-table-header-content ${alignmentClass}`, children: [
801
+ /* @__PURE__ */ jsx("span", { children: column.label }),
802
+ isSortable && /* @__PURE__ */ jsxs("div", { className: "eidos-table-sort-indicator", children: [
803
+ sortDirection === "asc" && /* @__PURE__ */ jsx(ArrowUp, { size: 14 }),
804
+ sortDirection === "desc" && /* @__PURE__ */ jsx(ArrowDown, { size: 14 }),
805
+ !sortDirection && /* @__PURE__ */ jsx(ChevronsUpDown, { size: 14 })
806
+ ] })
807
+ ] })
808
+ },
809
+ index
810
+ );
811
+ })
812
+ ] }) }),
813
+ /* @__PURE__ */ jsx("tbody", { children: displayData.length > 0 ? displayData.map((item, rowIndex) => {
814
+ const globalIndex = showPagination ? (currentPage - 1) * currentPageSize + rowIndex : rowIndex;
815
+ const key = getRowKey(item, globalIndex);
816
+ const isSelected = selectedSet.has(key);
817
+ return /* @__PURE__ */ jsxs(
818
+ "tr",
819
+ {
820
+ className: [
821
+ "eidos-table-row",
822
+ onRowClick ? "eidos-table-clickable" : "",
823
+ isSelected ? "eidos-table-row--selected" : ""
824
+ ].filter(Boolean).join(" "),
825
+ onClick: () => onRowClick?.(item),
826
+ children: [
827
+ selectable && /* @__PURE__ */ jsx(
828
+ "td",
829
+ {
830
+ className: [
831
+ "eidos-table-cell",
832
+ "eidos-table-checkbox-cell",
833
+ getCellPinnedProps("__checkbox__").className
834
+ ].filter(Boolean).join(" "),
835
+ style: getCellPinnedProps("__checkbox__").style,
836
+ onClick: (e) => {
837
+ e.stopPropagation();
838
+ toggleRow(key);
839
+ },
840
+ children: /* @__PURE__ */ jsx("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx(
841
+ Checkbox,
842
+ {
843
+ size: "sm",
844
+ checked: isSelected,
845
+ onChange: () => toggleRow(key),
846
+ "aria-label": `Select row ${globalIndex + 1}`
847
+ }
848
+ ) })
849
+ }
850
+ ),
851
+ visibleColumns.map((column, colIndex) => {
852
+ const colKey = String(column.key);
853
+ const columnType = column.type || "data";
854
+ const columnWidth = column.width;
855
+ const alignment = column.align || "left";
856
+ const alignmentClass = `eidos-table-align-${alignment}`;
857
+ const { style: pinnedStyle, className: pinnedClass } = getCellPinnedProps(colKey);
858
+ return /* @__PURE__ */ jsx(
859
+ "td",
860
+ {
861
+ className: [
862
+ "eidos-table-cell",
863
+ `eidos-table-cell-${columnType}`,
864
+ alignmentClass,
865
+ pinnedClass
866
+ ].filter(Boolean).join(" "),
867
+ style: { width: columnWidth, ...pinnedStyle },
868
+ onClick: columnType === "action" ? (e) => e.stopPropagation() : void 0,
869
+ children: renderCellContent(item, column)
870
+ },
871
+ colIndex
872
+ );
873
+ })
874
+ ]
875
+ },
876
+ key
877
+ );
878
+ }) : /* @__PURE__ */ jsx("tr", { className: "eidos-table-empty-row", children: /* @__PURE__ */ jsx(
879
+ "td",
880
+ {
881
+ colSpan: selectable ? visibleColumns.length + 1 : visibleColumns.length,
882
+ className: "eidos-table-cell eidos-table-empty-cell",
883
+ children: emptyStateNode
884
+ }
885
+ ) }) })
886
+ ]
887
+ }
888
+ ) })
889
+ ),
890
+ showFooter && /* @__PURE__ */ jsx("div", { className: "eidos-table-footer", children: /* @__PURE__ */ jsx("div", { className: "eidos-table-footer-content", children: showPagination && data.length > 0 ? /* @__PURE__ */ jsx(
891
+ Pagination,
892
+ {
893
+ page: currentPage,
894
+ totalPages,
895
+ onChange: handlePageChange,
896
+ totalItems: totalItems ?? data.length,
897
+ pageSize: currentPageSize,
898
+ onPageSizeChange: handlePageSizeChange,
899
+ pageSizeOptions: effectivePageSizeOptions,
900
+ size: "sm"
901
+ }
902
+ ) : /* @__PURE__ */ jsxs("span", { className: "eidos-table-results-info", children: [
903
+ "Showing ",
904
+ data.length,
905
+ " of ",
906
+ totalItems ?? data.length,
907
+ " results"
908
+ ] }) }) })
909
+ ]
910
+ }
911
+ );
912
+ if (draggableColumns) {
913
+ return /* @__PURE__ */ jsx(DndContext, { sensors, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(SortableContext, { items: sortableItems, strategy: horizontalListSortingStrategy, children: tableContent }) });
914
+ }
915
+ return tableContent;
916
+ };
917
+
918
+ export {
919
+ Table
920
+ };
921
+ //# sourceMappingURL=chunk-ZEZK664O.js.map