bolt-table 0.1.0 → 0.1.2

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/dist/index.mjs CHANGED
@@ -1,48 +1,90 @@
1
1
  // src/BoltTable.tsx
2
- import {
3
- closestCenter,
4
- DndContext,
5
- DragOverlay,
6
- PointerSensor,
7
- useSensor,
8
- useSensors
9
- } from "@dnd-kit/core";
10
- import {
11
- arrayMove,
12
- horizontalListSortingStrategy,
13
- SortableContext
14
- } from "@dnd-kit/sortable";
15
2
  import { useVirtualizer } from "@tanstack/react-virtual";
16
- import {
17
- ChevronDown,
18
- ChevronLeft,
19
- ChevronRight,
20
- ChevronsLeft,
21
- ChevronsRight,
22
- GripVertical as GripVertical2
23
- } from "lucide-react";
24
3
  import React4, {
25
4
  useCallback,
26
5
  useMemo as useMemo2,
27
6
  useRef as useRef4,
28
7
  useState as useState2
29
8
  } from "react";
9
+ import { createPortal as createPortal2 } from "react-dom";
30
10
 
31
11
  // src/DraggableHeader.tsx
32
- import { useSortable } from "@dnd-kit/sortable";
33
- import {
34
- ArrowDownAZ,
35
- ArrowUpAZ,
36
- EyeOff,
37
- Filter,
38
- FilterX,
39
- GripVertical,
40
- Pin,
41
- PinOff
42
- } from "lucide-react";
43
12
  import React, { useEffect, useRef, useState } from "react";
44
13
  import { createPortal } from "react-dom";
45
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+
15
+ // src/icons.tsx
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ var svgBase = {
18
+ xmlns: "http://www.w3.org/2000/svg",
19
+ width: 24,
20
+ height: 24,
21
+ viewBox: "0 0 24 24",
22
+ fill: "none",
23
+ stroke: "currentColor",
24
+ strokeWidth: 2,
25
+ strokeLinecap: "round",
26
+ strokeLinejoin: "round"
27
+ };
28
+ var GripVerticalIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
29
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "12", r: "1" }),
30
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "5", r: "1" }),
31
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "19", r: "1" }),
32
+ /* @__PURE__ */ jsx("circle", { cx: "15", cy: "12", r: "1" }),
33
+ /* @__PURE__ */ jsx("circle", { cx: "15", cy: "5", r: "1" }),
34
+ /* @__PURE__ */ jsx("circle", { cx: "15", cy: "19", r: "1" })
35
+ ] });
36
+ var ChevronDownIcon = ({ style, className }) => /* @__PURE__ */ jsx("svg", { ...svgBase, style, className, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
37
+ var ChevronLeftIcon = ({ style, className }) => /* @__PURE__ */ jsx("svg", { ...svgBase, style, className, children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
38
+ var ChevronRightIcon = ({ style, className }) => /* @__PURE__ */ jsx("svg", { ...svgBase, style, className, children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
39
+ var ChevronsLeftIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
40
+ /* @__PURE__ */ jsx("path", { d: "m11 17-5-5 5-5" }),
41
+ /* @__PURE__ */ jsx("path", { d: "m18 17-5-5 5-5" })
42
+ ] });
43
+ var ChevronsRightIcon = ({
44
+ style,
45
+ className
46
+ }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
47
+ /* @__PURE__ */ jsx("path", { d: "m6 17 5-5-5-5" }),
48
+ /* @__PURE__ */ jsx("path", { d: "m13 17 5-5-5-5" })
49
+ ] });
50
+ var ArrowUpAZIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
51
+ /* @__PURE__ */ jsx("path", { d: "m3 8 4-4 4 4" }),
52
+ /* @__PURE__ */ jsx("path", { d: "M7 4v16" }),
53
+ /* @__PURE__ */ jsx("path", { d: "M20 8h-5" }),
54
+ /* @__PURE__ */ jsx("path", { d: "M15 10V6.5a2.5 2.5 0 0 1 5 0V10" }),
55
+ /* @__PURE__ */ jsx("path", { d: "M15 14h5l-5 6h5" })
56
+ ] });
57
+ var ArrowDownAZIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
58
+ /* @__PURE__ */ jsx("path", { d: "m3 16 4 4 4-4" }),
59
+ /* @__PURE__ */ jsx("path", { d: "M7 20V4" }),
60
+ /* @__PURE__ */ jsx("path", { d: "M20 8h-5" }),
61
+ /* @__PURE__ */ jsx("path", { d: "M15 10V6.5a2.5 2.5 0 0 1 5 0V10" }),
62
+ /* @__PURE__ */ jsx("path", { d: "M15 14h5l-5 6h5" })
63
+ ] });
64
+ var FilterIcon = ({ style, className }) => /* @__PURE__ */ jsx("svg", { ...svgBase, style, className, children: /* @__PURE__ */ jsx("polygon", { points: "22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" }) });
65
+ var FilterXIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
66
+ /* @__PURE__ */ jsx("path", { d: "M13.013 3H2l8 9.46V19l4 2v-8.54l.9-1.055" }),
67
+ /* @__PURE__ */ jsx("path", { d: "m22 3-5 5" }),
68
+ /* @__PURE__ */ jsx("path", { d: "m17 3 5 5" })
69
+ ] });
70
+ var PinIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
71
+ /* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "17", y2: "22" }),
72
+ /* @__PURE__ */ jsx("path", { d: "M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24Z" })
73
+ ] });
74
+ var PinOffIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
75
+ /* @__PURE__ */ jsx("line", { x1: "2", x2: "22", y1: "2", y2: "22" }),
76
+ /* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "17", y2: "22" }),
77
+ /* @__PURE__ */ jsx("path", { d: "M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4" })
78
+ ] });
79
+ var EyeOffIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
80
+ /* @__PURE__ */ jsx("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }),
81
+ /* @__PURE__ */ jsx("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }),
82
+ /* @__PURE__ */ jsx("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }),
83
+ /* @__PURE__ */ jsx("line", { x1: "2", x2: "22", y1: "2", y2: "22" })
84
+ ] });
85
+
86
+ // src/DraggableHeader.tsx
87
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
46
88
  function isColumnSortable(col) {
47
89
  return col.sortable !== false;
48
90
  }
@@ -68,7 +110,9 @@ var DraggableHeader = React.memo(
68
110
  filterValue = "",
69
111
  onFilter,
70
112
  onClearFilter,
71
- customContextMenuItems
113
+ customContextMenuItems,
114
+ icons,
115
+ onColumnDragStart
72
116
  }) => {
73
117
  const effectivelySortable = isColumnSortable(column);
74
118
  const effectivelyFilterable = isColumnFilterable(column);
@@ -76,21 +120,6 @@ var DraggableHeader = React.memo(
76
120
  const [showFilterInput, setShowFilterInput] = useState(false);
77
121
  const filterInputRef = useRef(null);
78
122
  const menuRef = useRef(null);
79
- const {
80
- attributes,
81
- listeners,
82
- setNodeRef,
83
- transition,
84
- isDragging,
85
- // true while this header is being dragged
86
- isOver
87
- // true while another header is being dragged over this one
88
- } = useSortable({
89
- id: column.key,
90
- // Pinned columns cannot be dragged (their position is fixed by pinning)
91
- disabled: Boolean(column.pinned)
92
- });
93
- const theme = typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "light";
94
123
  useEffect(() => {
95
124
  const handleClickOutside = (e) => {
96
125
  if (menuRef.current && !menuRef.current.contains(e.target)) {
@@ -126,95 +155,121 @@ var DraggableHeader = React.memo(
126
155
  const columnWidth = column.width ?? 150;
127
156
  const widthPx = `${columnWidth}px`;
128
157
  const isPinned = Boolean(column.pinned);
129
- const zIndex = isDragging ? 5 : isPinned ? 12 : 10;
130
- const style = {
158
+ const zIndex = isPinned ? 12 : 10;
159
+ const headerStyle = {
131
160
  position: "sticky",
132
161
  top: 0,
133
162
  zIndex,
134
- // Last column stretches to fill remaining space; all others are fixed width
135
163
  width: isLastColumn ? "100%" : widthPx,
136
164
  minWidth: widthPx,
137
165
  ...isLastColumn ? {} : { maxWidth: widthPx },
138
166
  gridColumn: visualIndex + 1,
139
167
  gridRow: 1,
140
- // Fade out slightly while being dragged
141
- opacity: isDragging ? 0.3 : 1,
142
- transition,
143
- borderWidth: "1px",
144
- // Show a dashed accent-colored border when another column is dragged over this one
145
- borderStyle: isOver ? "dashed" : "solid",
146
- ...isOver ? { borderColor: accentColor || "#1788ff" } : { borderLeftColor: "transparent" },
147
- // Sticky positioning for pinned columns
148
- ...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px`, position: "sticky" } : {},
149
- ...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px`, position: "sticky" } : {},
150
- // Pinned columns get a semi-transparent background so they visually
151
- // separate from scrolling content behind them
168
+ borderTop: "none",
169
+ borderRight: "none",
170
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
171
+ borderLeft: "none",
172
+ ...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
173
+ ...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
152
174
  ...isPinned ? {
153
- backgroundColor: styles?.pinnedBg ?? theme === "dark" ? "#10182890" : "#f9fafb90",
175
+ backgroundColor: styles?.pinnedBg ?? "Canvas",
154
176
  ...styles?.pinnedHeader
155
177
  } : {},
156
- // Column-level style overrides applied last (highest specificity)
157
178
  ...column.style,
158
- ...styles?.header
179
+ ...styles?.header,
180
+ backgroundColor: styles?.pinnedBg && isPinned ? styles.pinnedBg : isPinned ? "Canvas" : "rgba(128,128,128,0.06)",
181
+ display: "flex",
182
+ height: 36,
183
+ alignItems: "center",
184
+ overflow: "hidden",
185
+ textOverflow: "ellipsis",
186
+ whiteSpace: "nowrap",
187
+ ...isPinned ? {} : { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }
159
188
  };
160
- const baseClasses = "bg-muted/40 group relative truncate flex h-9 items-center overflow-hidden backdrop-blur ";
161
- const className = `${baseClasses} ${column.className ?? ""} ${classNames?.header ?? ""} ${classNames?.pinnedHeader ?? ""} `;
162
- return /* @__PURE__ */ jsxs(Fragment, { children: [
163
- /* @__PURE__ */ jsxs(
189
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
190
+ /* @__PURE__ */ jsxs2(
164
191
  "div",
165
192
  {
166
- ref: setNodeRef,
167
193
  "data-column-key": column.key,
168
- style,
169
- className,
194
+ "data-bt-header": "",
195
+ style: headerStyle,
196
+ className: `${column.className ?? ""} ${classNames?.header ?? ""} ${isPinned ? classNames?.pinnedHeader ?? "" : ""}`,
170
197
  onContextMenu: handleContextMenu,
171
198
  children: [
172
- /* @__PURE__ */ jsxs(
199
+ /* @__PURE__ */ jsxs2(
173
200
  "div",
174
201
  {
175
- ...isPinned ? {} : attributes,
176
- ...isPinned ? {} : listeners,
177
- className: `group relative z-10 flex h-full flex-1 touch-none items-center gap-1 truncate overflow-hidden px-2 font-medium ${isPinned ? "cursor-default" : "cursor-grab active:cursor-grabbing"}`,
202
+ role: isPinned ? void 0 : "button",
203
+ tabIndex: isPinned ? void 0 : 0,
204
+ "aria-roledescription": isPinned ? void 0 : "sortable",
205
+ onPointerDown: isPinned ? void 0 : (e) => {
206
+ if (e.button !== 0) return;
207
+ e.preventDefault();
208
+ onColumnDragStart?.(column.key, e);
209
+ },
210
+ style: {
211
+ position: "relative",
212
+ zIndex: 10,
213
+ display: "flex",
214
+ height: "100%",
215
+ flex: "1 1 0%",
216
+ touchAction: "none",
217
+ alignItems: "center",
218
+ gap: 4,
219
+ overflow: "hidden",
220
+ textOverflow: "ellipsis",
221
+ whiteSpace: "nowrap",
222
+ paddingLeft: 8,
223
+ paddingRight: 8,
224
+ borderLeft: "1px solid rgba(128,128,128,0.2)",
225
+ fontWeight: 500,
226
+ cursor: isPinned ? "default" : "grab"
227
+ },
178
228
  "aria-label": isPinned ? `${column.key} column (pinned)` : `Drag ${column.key} column`,
179
229
  children: [
180
- hideGripIcon || isPinned ? null : gripIcon ?? /* @__PURE__ */ jsx(GripVertical, { className: "h-3 w-3 shrink-0 opacity-35 group-hover:opacity-80" }),
181
- /* @__PURE__ */ jsxs(
230
+ hideGripIcon || isPinned ? null : icons?.gripVertical ?? gripIcon ?? /* @__PURE__ */ jsx2("span", { "data-bt-grip": "", style: { opacity: 0.35, flexShrink: 0, display: "flex" }, children: /* @__PURE__ */ jsx2(GripVerticalIcon, { style: { width: 12, height: 12 } }) }),
231
+ /* @__PURE__ */ jsxs2(
182
232
  "div",
183
233
  {
184
- className: `flex min-w-0 items-center gap-1 truncate overflow-hidden text-left select-none`,
234
+ style: {
235
+ display: "flex",
236
+ minWidth: 0,
237
+ alignItems: "center",
238
+ gap: 4,
239
+ overflow: "hidden",
240
+ textOverflow: "ellipsis",
241
+ whiteSpace: "nowrap",
242
+ textAlign: "left",
243
+ userSelect: "none"
244
+ },
185
245
  children: [
186
246
  column.title,
187
- sortDirection === "asc" && /* @__PURE__ */ jsx(
188
- ArrowUpAZ,
189
- {
190
- className: "h-3 w-3 shrink-0",
191
- style: { color: accentColor }
192
- }
193
- ),
194
- sortDirection === "desc" && /* @__PURE__ */ jsx(
195
- ArrowDownAZ,
196
- {
197
- className: "h-3 w-3 shrink-0",
198
- style: { color: accentColor }
199
- }
200
- ),
201
- filterValue && /* @__PURE__ */ jsx(
202
- Filter,
203
- {
204
- className: "h-2.5 w-2.5 shrink-0",
205
- style: { color: accentColor }
206
- }
207
- )
247
+ sortDirection === "asc" && /* @__PURE__ */ jsx2("span", { style: { color: accentColor, flexShrink: 0, display: "flex" }, children: icons?.sortAsc ?? /* @__PURE__ */ jsx2(ArrowUpAZIcon, { style: { width: 12, height: 12 } }) }),
248
+ sortDirection === "desc" && /* @__PURE__ */ jsx2("span", { style: { color: accentColor, flexShrink: 0, display: "flex" }, children: icons?.sortDesc ?? /* @__PURE__ */ jsx2(ArrowDownAZIcon, { style: { width: 12, height: 12 } }) }),
249
+ filterValue && /* @__PURE__ */ jsx2("span", { style: { color: accentColor, flexShrink: 0, display: "flex" }, children: icons?.filter ?? /* @__PURE__ */ jsx2(FilterIcon, { style: { width: 10, height: 10 } }) })
208
250
  ]
209
251
  }
210
252
  )
211
253
  ]
212
254
  }
213
255
  ),
214
- isPinned && /* @__PURE__ */ jsx(
256
+ isPinned && /* @__PURE__ */ jsx2(
215
257
  "button",
216
258
  {
217
- className: "group/unpin relative h-full w-6 shrink-0 cursor-pointer border-0 bg-transparent p-0",
259
+ style: {
260
+ position: "relative",
261
+ height: "100%",
262
+ width: 24,
263
+ flexShrink: 0,
264
+ cursor: "pointer",
265
+ border: "none",
266
+ background: "transparent",
267
+ padding: 0,
268
+ color: accentColor || "#1788ff",
269
+ display: "flex",
270
+ alignItems: "center",
271
+ justifyContent: "center"
272
+ },
218
273
  onClick: (e) => {
219
274
  e.preventDefault();
220
275
  e.stopPropagation();
@@ -222,21 +277,37 @@ var DraggableHeader = React.memo(
222
277
  },
223
278
  "aria-label": `Unpin ${column.key} column`,
224
279
  title: "Unpin column",
225
- style: { color: accentColor || "1788ff" },
226
- children: /* @__PURE__ */ jsx(PinOff, { className: "mx-auto h-3 w-3" })
280
+ children: icons?.pinOff ?? /* @__PURE__ */ jsx2(PinOffIcon, { style: { width: 12, height: 12 } })
227
281
  }
228
282
  ),
229
- !isPinned && /* @__PURE__ */ jsx(
283
+ !isPinned && /* @__PURE__ */ jsx2(
230
284
  "button",
231
285
  {
232
- className: "group/resize relative h-full w-3 shrink-0 cursor-col-resize border-0 bg-transparent p-0",
286
+ "data-bt-resize": "",
287
+ style: {
288
+ position: "relative",
289
+ height: "100%",
290
+ width: 12,
291
+ flexShrink: 0,
292
+ cursor: "col-resize",
293
+ border: "none",
294
+ background: "transparent",
295
+ padding: 0
296
+ },
233
297
  onMouseDown: handleResizeStart,
234
298
  "aria-label": `Resize ${column.key} column`,
235
- children: /* @__PURE__ */ jsx(
299
+ children: /* @__PURE__ */ jsx2(
236
300
  "div",
237
301
  {
238
- className: "absolute top-0 right-0 h-full w-0.5 opacity-0 transition-opacity group-hover/resize:opacity-100",
302
+ "data-bt-resize-line": "",
239
303
  style: {
304
+ position: "absolute",
305
+ top: 0,
306
+ right: 0,
307
+ height: "100%",
308
+ width: 2,
309
+ opacity: 0,
310
+ transition: "opacity 0.15s",
240
311
  backgroundColor: accentColor || "#1788ff"
241
312
  }
242
313
  }
@@ -247,113 +318,212 @@ var DraggableHeader = React.memo(
247
318
  }
248
319
  ),
249
320
  contextMenu && typeof document !== "undefined" && createPortal(
250
- /* @__PURE__ */ jsxs(
321
+ /* @__PURE__ */ jsxs2(
251
322
  "div",
252
323
  {
253
324
  ref: menuRef,
254
- className: "text-xxs fixed z-[9999] min-w-40 rounded-md border py-1 shadow-lg backdrop-blur",
255
325
  style: {
326
+ fontSize: 10,
327
+ position: "fixed",
328
+ zIndex: 9999,
329
+ minWidth: 160,
330
+ borderRadius: 6,
331
+ border: "1px solid rgba(128,128,128,0.2)",
332
+ paddingTop: 4,
333
+ paddingBottom: 4,
334
+ boxShadow: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)",
335
+ backdropFilter: "blur(12px)",
336
+ backgroundColor: "rgba(128,128,128,0.1)",
256
337
  left: `${contextMenu.x}px`,
257
- top: `${contextMenu.y}px`,
258
- position: "fixed"
338
+ top: `${contextMenu.y}px`
259
339
  },
260
340
  role: "menu",
261
341
  children: [
262
- effectivelySortable && onSort && /* @__PURE__ */ jsxs(Fragment, { children: [
263
- /* @__PURE__ */ jsxs(
342
+ effectivelySortable && onSort && /* @__PURE__ */ jsxs2(Fragment, { children: [
343
+ /* @__PURE__ */ jsxs2(
264
344
  "button",
265
345
  {
266
- className: `cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left ${sortDirection === "asc" ? "font-semibold" : ""}`,
267
- style: sortDirection === "asc" ? { color: accentColor } : void 0,
346
+ "data-bt-ctx-item": "",
347
+ style: {
348
+ cursor: "pointer",
349
+ display: "flex",
350
+ width: "100%",
351
+ alignItems: "center",
352
+ gap: 8,
353
+ paddingLeft: 12,
354
+ paddingRight: 12,
355
+ paddingTop: 6,
356
+ paddingBottom: 6,
357
+ textAlign: "left",
358
+ background: "none",
359
+ border: "none",
360
+ fontSize: "inherit",
361
+ color: "inherit",
362
+ fontWeight: sortDirection === "asc" ? 600 : void 0,
363
+ ...sortDirection === "asc" ? { color: accentColor } : {}
364
+ },
268
365
  onClick: () => {
269
366
  onSort(column.key, "asc");
270
367
  setContextMenu(null);
271
368
  },
272
369
  children: [
273
- /* @__PURE__ */ jsx(ArrowUpAZ, { className: "h-3 w-3" }),
370
+ icons?.sortAsc ?? /* @__PURE__ */ jsx2(ArrowUpAZIcon, { style: { width: 12, height: 12 } }),
274
371
  "Sort Ascending"
275
372
  ]
276
373
  }
277
374
  ),
278
- /* @__PURE__ */ jsxs(
375
+ /* @__PURE__ */ jsxs2(
279
376
  "button",
280
377
  {
281
- className: `cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left ${sortDirection === "desc" ? "font-semibold" : ""}`,
282
- style: sortDirection === "desc" ? { color: accentColor } : void 0,
378
+ "data-bt-ctx-item": "",
379
+ style: {
380
+ cursor: "pointer",
381
+ display: "flex",
382
+ width: "100%",
383
+ alignItems: "center",
384
+ gap: 8,
385
+ paddingLeft: 12,
386
+ paddingRight: 12,
387
+ paddingTop: 6,
388
+ paddingBottom: 6,
389
+ textAlign: "left",
390
+ background: "none",
391
+ border: "none",
392
+ fontSize: "inherit",
393
+ color: "inherit",
394
+ fontWeight: sortDirection === "desc" ? 600 : void 0,
395
+ ...sortDirection === "desc" ? { color: accentColor } : {}
396
+ },
283
397
  onClick: () => {
284
398
  onSort(column.key, "desc");
285
399
  setContextMenu(null);
286
400
  },
287
401
  children: [
288
- /* @__PURE__ */ jsx(ArrowDownAZ, { className: "h-3 w-3" }),
402
+ icons?.sortDesc ?? /* @__PURE__ */ jsx2(ArrowDownAZIcon, { style: { width: 12, height: 12 } }),
289
403
  "Sort Descending"
290
404
  ]
291
405
  }
292
406
  ),
293
- /* @__PURE__ */ jsx("div", { className: "my-1 border-t dark:border-gray-700" })
407
+ /* @__PURE__ */ jsx2("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
294
408
  ] }),
295
- effectivelyFilterable && onFilter && /* @__PURE__ */ jsxs(Fragment, { children: [
296
- showFilterInput ? (
297
- // Inline text input — pressing Enter applies the filter,
298
- // pressing Escape cancels and returns to the button
299
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 px-2 py-1.5", children: /* @__PURE__ */ jsx(
300
- "input",
301
- {
302
- ref: filterInputRef,
303
- type: "text",
304
- autoFocus: true,
305
- defaultValue: filterValue,
306
- placeholder: "Filter...",
307
- className: "bg-background text-foreground w-full rounded border px-1.5 py-0.5 text-xs outline-none focus:border-blue-400",
308
- onKeyDown: (e) => {
309
- if (e.key === "Enter") {
310
- onFilter(
311
- column.key,
312
- e.target.value
313
- );
314
- setShowFilterInput(false);
315
- setContextMenu(null);
316
- }
317
- if (e.key === "Escape") {
318
- setShowFilterInput(false);
319
- }
409
+ effectivelyFilterable && onFilter && /* @__PURE__ */ jsxs2(Fragment, { children: [
410
+ showFilterInput ? /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 4, paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6 }, children: /* @__PURE__ */ jsx2(
411
+ "input",
412
+ {
413
+ ref: filterInputRef,
414
+ type: "text",
415
+ autoFocus: true,
416
+ defaultValue: filterValue,
417
+ placeholder: "Filter...",
418
+ style: {
419
+ width: "100%",
420
+ borderRadius: 4,
421
+ border: "1px solid rgba(128,128,128,0.2)",
422
+ paddingLeft: 6,
423
+ paddingRight: 6,
424
+ paddingTop: 2,
425
+ paddingBottom: 2,
426
+ fontSize: 12,
427
+ outline: "none",
428
+ background: "inherit",
429
+ color: "inherit"
430
+ },
431
+ onKeyDown: (e) => {
432
+ if (e.key === "Enter") {
433
+ onFilter(
434
+ column.key,
435
+ e.target.value
436
+ );
437
+ setShowFilterInput(false);
438
+ setContextMenu(null);
439
+ }
440
+ if (e.key === "Escape") {
441
+ setShowFilterInput(false);
320
442
  }
321
443
  }
322
- ) })
323
- ) : /* @__PURE__ */ jsxs(
444
+ }
445
+ ) }) : /* @__PURE__ */ jsxs2(
324
446
  "button",
325
447
  {
326
- className: "cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left",
448
+ "data-bt-ctx-item": "",
449
+ style: {
450
+ cursor: "pointer",
451
+ display: "flex",
452
+ width: "100%",
453
+ alignItems: "center",
454
+ gap: 8,
455
+ paddingLeft: 12,
456
+ paddingRight: 12,
457
+ paddingTop: 6,
458
+ paddingBottom: 6,
459
+ textAlign: "left",
460
+ background: "none",
461
+ border: "none",
462
+ fontSize: "inherit",
463
+ color: "inherit"
464
+ },
327
465
  onClick: () => {
328
466
  setShowFilterInput(true);
329
467
  },
330
468
  children: [
331
- /* @__PURE__ */ jsx(Filter, { className: "h-3 w-3" }),
469
+ icons?.filter ?? /* @__PURE__ */ jsx2(FilterIcon, { style: { width: 12, height: 12 } }),
332
470
  filterValue ? `Filtered: "${filterValue}"` : "Filter Column"
333
471
  ]
334
472
  }
335
473
  ),
336
- filterValue && /* @__PURE__ */ jsxs(
474
+ filterValue && /* @__PURE__ */ jsxs2(
337
475
  "button",
338
476
  {
339
- className: "cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left text-red-500",
477
+ "data-bt-ctx-item": "",
478
+ style: {
479
+ cursor: "pointer",
480
+ display: "flex",
481
+ width: "100%",
482
+ alignItems: "center",
483
+ gap: 8,
484
+ paddingLeft: 12,
485
+ paddingRight: 12,
486
+ paddingTop: 6,
487
+ paddingBottom: 6,
488
+ textAlign: "left",
489
+ background: "none",
490
+ border: "none",
491
+ fontSize: "inherit",
492
+ color: "#ef4444"
493
+ },
340
494
  onClick: () => {
341
495
  onClearFilter?.(column.key);
342
496
  setShowFilterInput(false);
343
497
  setContextMenu(null);
344
498
  },
345
499
  children: [
346
- /* @__PURE__ */ jsx(FilterX, { className: "h-3 w-3" }),
500
+ icons?.filterClear ?? /* @__PURE__ */ jsx2(FilterXIcon, { style: { width: 12, height: 12 } }),
347
501
  "Clear Filter"
348
502
  ]
349
503
  }
350
504
  ),
351
- /* @__PURE__ */ jsx("div", { className: "my-1 border-t dark:border-gray-700" })
505
+ /* @__PURE__ */ jsx2("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
352
506
  ] }),
353
- /* @__PURE__ */ jsxs(
507
+ /* @__PURE__ */ jsxs2(
354
508
  "button",
355
509
  {
356
- className: "cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left",
510
+ "data-bt-ctx-item": "",
511
+ style: {
512
+ cursor: "pointer",
513
+ display: "flex",
514
+ width: "100%",
515
+ alignItems: "center",
516
+ gap: 8,
517
+ paddingLeft: 12,
518
+ paddingRight: 12,
519
+ paddingTop: 6,
520
+ paddingBottom: 6,
521
+ textAlign: "left",
522
+ background: "none",
523
+ border: "none",
524
+ fontSize: "inherit",
525
+ color: "inherit"
526
+ },
357
527
  onClick: () => {
358
528
  onTogglePin?.(
359
529
  column.key,
@@ -362,15 +532,31 @@ var DraggableHeader = React.memo(
362
532
  setContextMenu(null);
363
533
  },
364
534
  children: [
365
- column.pinned === "left" ? /* @__PURE__ */ jsx(PinOff, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Pin, { className: "h-3 w-3" }),
535
+ column.pinned === "left" ? icons?.pinOff ?? /* @__PURE__ */ jsx2(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ jsx2(PinIcon, { style: { width: 12, height: 12 } }),
366
536
  column.pinned === "left" ? "Unpin Left" : "Pin Left"
367
537
  ]
368
538
  }
369
539
  ),
370
- /* @__PURE__ */ jsxs(
540
+ /* @__PURE__ */ jsxs2(
371
541
  "button",
372
542
  {
373
- className: "cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left",
543
+ "data-bt-ctx-item": "",
544
+ style: {
545
+ cursor: "pointer",
546
+ display: "flex",
547
+ width: "100%",
548
+ alignItems: "center",
549
+ gap: 8,
550
+ paddingLeft: 12,
551
+ paddingRight: 12,
552
+ paddingTop: 6,
553
+ paddingBottom: 6,
554
+ textAlign: "left",
555
+ background: "none",
556
+ border: "none",
557
+ fontSize: "inherit",
558
+ color: "inherit"
559
+ },
374
560
  onClick: () => {
375
561
  onTogglePin?.(
376
562
  column.key,
@@ -379,41 +565,74 @@ var DraggableHeader = React.memo(
379
565
  setContextMenu(null);
380
566
  },
381
567
  children: [
382
- column.pinned === "right" ? /* @__PURE__ */ jsx(PinOff, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Pin, { className: "h-3 w-3" }),
568
+ column.pinned === "right" ? icons?.pinOff ?? /* @__PURE__ */ jsx2(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ jsx2(PinIcon, { style: { width: 12, height: 12 } }),
383
569
  column.pinned === "right" ? "Unpin Right" : "Pin Right"
384
570
  ]
385
571
  }
386
572
  ),
387
- !isPinned && /* @__PURE__ */ jsxs(Fragment, { children: [
388
- /* @__PURE__ */ jsx("div", { className: "my-1 border-t dark:border-gray-700" }),
389
- /* @__PURE__ */ jsxs(
573
+ !isPinned && /* @__PURE__ */ jsxs2(Fragment, { children: [
574
+ /* @__PURE__ */ jsx2("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
575
+ /* @__PURE__ */ jsxs2(
390
576
  "button",
391
577
  {
392
- className: "cusror-pointer flex w-full items-center gap-2 px-3 py-1.5 text-left",
578
+ "data-bt-ctx-item": "",
579
+ style: {
580
+ cursor: "pointer",
581
+ display: "flex",
582
+ width: "100%",
583
+ alignItems: "center",
584
+ gap: 8,
585
+ paddingLeft: 12,
586
+ paddingRight: 12,
587
+ paddingTop: 6,
588
+ paddingBottom: 6,
589
+ textAlign: "left",
590
+ background: "none",
591
+ border: "none",
592
+ fontSize: "inherit",
593
+ color: "inherit"
594
+ },
393
595
  onClick: () => {
394
596
  onToggleHide?.(column.key);
395
597
  setContextMenu(null);
396
598
  },
397
599
  children: [
398
- /* @__PURE__ */ jsx(EyeOff, { className: "h-3 w-3" }),
600
+ icons?.eyeOff ?? /* @__PURE__ */ jsx2(EyeOffIcon, { style: { width: 12, height: 12 } }),
399
601
  "Hide Column"
400
602
  ]
401
603
  }
402
604
  )
403
605
  ] }),
404
- customContextMenuItems && customContextMenuItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
405
- /* @__PURE__ */ jsx("div", { className: "my-1 border-t dark:border-gray-700" }),
406
- customContextMenuItems.map((item) => /* @__PURE__ */ jsxs(
606
+ customContextMenuItems && customContextMenuItems.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
607
+ /* @__PURE__ */ jsx2("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
608
+ customContextMenuItems.map((item) => /* @__PURE__ */ jsxs2(
407
609
  "button",
408
610
  {
611
+ "data-bt-ctx-item": "",
409
612
  disabled: item.disabled,
410
- className: `flex w-full items-center gap-2 px-3 py-1.5 text-left ${item.disabled ? "cursor-not-allowed opacity-50" : "cusror-pointer"} ${item.danger ? "text-red-500" : ""}`,
613
+ style: {
614
+ display: "flex",
615
+ width: "100%",
616
+ alignItems: "center",
617
+ gap: 8,
618
+ paddingLeft: 12,
619
+ paddingRight: 12,
620
+ paddingTop: 6,
621
+ paddingBottom: 6,
622
+ textAlign: "left",
623
+ background: "none",
624
+ border: "none",
625
+ fontSize: "inherit",
626
+ cursor: item.disabled ? "not-allowed" : "pointer",
627
+ opacity: item.disabled ? 0.5 : 1,
628
+ color: item.danger ? "#ef4444" : "inherit"
629
+ },
411
630
  onClick: () => {
412
631
  item.onClick(column.key);
413
632
  setContextMenu(null);
414
633
  },
415
634
  children: [
416
- item.icon && /* @__PURE__ */ jsx("span", { className: "flex h-3 w-3 items-center justify-center", children: item.icon }),
635
+ item.icon && /* @__PURE__ */ jsx2("span", { style: { display: "flex", width: 12, height: 12, alignItems: "center", justifyContent: "center" }, children: item.icon }),
417
636
  item.label
418
637
  ]
419
638
  },
@@ -439,7 +658,7 @@ var DraggableHeader_default = DraggableHeader;
439
658
 
440
659
  // src/ResizeOverlay.tsx
441
660
  import { forwardRef, useImperativeHandle, useRef as useRef2 } from "react";
442
- import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
661
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
443
662
  var ResizeOverlay = forwardRef(
444
663
  ({ accentColor = "#1778ff" }, ref) => {
445
664
  const lineRef = useRef2(null);
@@ -520,8 +739,8 @@ var ResizeOverlay = forwardRef(
520
739
  const b = parseInt(hex.slice(5, 7), 16);
521
740
  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
522
741
  };
523
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
524
- /* @__PURE__ */ jsx2(
742
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
743
+ /* @__PURE__ */ jsx3(
525
744
  "div",
526
745
  {
527
746
  ref: lineRef,
@@ -541,7 +760,7 @@ var ResizeOverlay = forwardRef(
541
760
  }
542
761
  }
543
762
  ),
544
- /* @__PURE__ */ jsx2(
763
+ /* @__PURE__ */ jsx3(
545
764
  "div",
546
765
  {
547
766
  ref: labelRef,
@@ -575,7 +794,7 @@ var ResizeOverlay_default = ResizeOverlay;
575
794
 
576
795
  // src/TableBody.tsx
577
796
  import React3, { useEffect as useEffect2, useMemo, useRef as useRef3 } from "react";
578
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
797
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
579
798
  var SHIMMER_WIDTHS = [55, 70, 45, 80, 60, 50, 75, 65];
580
799
  var Cell = React3.memo(
581
800
  ({
@@ -593,26 +812,33 @@ var Cell = React3.memo(
593
812
  accentColor,
594
813
  isLoading
595
814
  }) => {
596
- const justifyClass = column.key === "__select__" || column.key === "__expand__" ? "justify-center" : "";
597
815
  const isPinned = Boolean(column.pinned);
598
816
  if (isLoading && column.key !== "__select__" && column.key !== "__expand__") {
599
- const shimmerContent = column.shimmerRender ? column.shimmerRender() : /* @__PURE__ */ jsx3(
817
+ const shimmerContent = column.shimmerRender ? column.shimmerRender() : /* @__PURE__ */ jsx4(
600
818
  "div",
601
819
  {
602
- className: "bg-muted-foreground/15 animate-pulse rounded",
603
820
  style: {
604
- // Vary widths across cells so skeletons look more natural
821
+ backgroundColor: "rgba(100, 116, 139, 0.15)",
822
+ animation: "bt-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
823
+ borderRadius: 4,
605
824
  width: `${SHIMMER_WIDTHS[(rowIndex + column.key.length) % SHIMMER_WIDTHS.length]}%`,
606
825
  height: 14
607
826
  }
608
827
  }
609
828
  );
610
- return /* @__PURE__ */ jsx3(
829
+ return /* @__PURE__ */ jsx4(
611
830
  "div",
612
831
  {
613
- className: `flex items-center overflow-hidden border-b px-2 ${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
832
+ className: `${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
614
833
  style: {
834
+ display: "flex",
835
+ alignItems: "center",
836
+ overflow: "hidden",
837
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
838
+ paddingLeft: 8,
839
+ paddingRight: 8,
615
840
  height: "100%",
841
+ boxSizing: "border-box",
616
842
  ...column.style,
617
843
  ...isPinned ? styles?.pinnedCell : void 0
618
844
  },
@@ -624,7 +850,7 @@ var Cell = React3.memo(
624
850
  const checkboxProps = rowSelection.getCheckboxProps?.(record) ?? {
625
851
  disabled: false
626
852
  };
627
- const content2 = rowSelection.type === "radio" ? /* @__PURE__ */ jsx3(
853
+ const content2 = rowSelection.type === "radio" ? /* @__PURE__ */ jsx4(
628
854
  "input",
629
855
  {
630
856
  type: "radio",
@@ -635,10 +861,9 @@ var Cell = React3.memo(
635
861
  rowSelection.onSelect?.(record, true, [record], e.nativeEvent);
636
862
  rowSelection.onChange?.([rowKey], [record], { type: "single" });
637
863
  },
638
- className: "cursor-pointer",
639
- style: { accentColor }
864
+ style: { cursor: "pointer", accentColor }
640
865
  }
641
- ) : /* @__PURE__ */ jsx3(
866
+ ) : /* @__PURE__ */ jsx4(
642
867
  "input",
643
868
  {
644
869
  type: "checkbox",
@@ -665,16 +890,23 @@ var Cell = React3.memo(
665
890
  type: "multiple"
666
891
  });
667
892
  },
668
- className: "cursor-pointer",
669
- style: { accentColor }
893
+ style: { cursor: "pointer", accentColor }
670
894
  }
671
895
  );
672
- return /* @__PURE__ */ jsx3(
896
+ return /* @__PURE__ */ jsx4(
673
897
  "div",
674
898
  {
675
- className: `flex items-center overflow-hidden border-b px-2 ${justifyClass} ${column.className ?? ""} ${classNames?.cell ?? ""} `,
899
+ className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
676
900
  style: {
901
+ display: "flex",
902
+ alignItems: "center",
903
+ overflow: "hidden",
904
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
905
+ paddingLeft: 8,
906
+ paddingRight: 8,
907
+ justifyContent: column.key === "__select__" || column.key === "__expand__" ? "center" : void 0,
677
908
  height: "100%",
909
+ boxSizing: "border-box",
678
910
  ...column.style,
679
911
  ...isPinned ? styles?.pinnedCell : void 0
680
912
  },
@@ -683,12 +915,22 @@ var Cell = React3.memo(
683
915
  );
684
916
  }
685
917
  const content = column.render ? column.render(value, record, rowIndex) : value ?? "";
686
- return /* @__PURE__ */ jsx3(
918
+ return /* @__PURE__ */ jsx4(
687
919
  "div",
688
920
  {
689
- className: `flex items-center truncate overflow-hidden border-b px-2 ${justifyClass} ${column.className ?? ""} ${classNames?.cell ?? ""} `,
921
+ className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
690
922
  style: {
923
+ display: "flex",
924
+ alignItems: "center",
925
+ overflow: "hidden",
926
+ textOverflow: "ellipsis",
927
+ whiteSpace: "nowrap",
928
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
929
+ paddingLeft: 8,
930
+ paddingRight: 8,
931
+ justifyContent: column.key === "__select__" || column.key === "__expand__" ? "center" : void 0,
691
932
  height: "100%",
933
+ boxSizing: "border-box",
692
934
  ...column.style,
693
935
  ...isPinned ? styles?.pinnedCell : void 0
694
936
  },
@@ -736,7 +978,7 @@ var MeasuredExpandedRow = React3.memo(
736
978
  observer.observe(el);
737
979
  return () => observer.disconnect();
738
980
  }, [rowKey]);
739
- return /* @__PURE__ */ jsx3("div", { ref, children });
981
+ return /* @__PURE__ */ jsx4("div", { ref, children });
740
982
  }
741
983
  );
742
984
  MeasuredExpandedRow.displayName = "MeasuredExpandedRow";
@@ -761,7 +1003,7 @@ var TableBody = ({
761
1003
  }) => {
762
1004
  const virtualItems = rowVirtualizer.getVirtualItems();
763
1005
  const totalSize = rowVirtualizer.getTotalSize();
764
- const theme = typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "light";
1006
+ const selectedKeySet = useMemo(() => new Set(normalizedSelectedKeys), [normalizedSelectedKeys]);
765
1007
  const columnStyles = useMemo(() => {
766
1008
  return orderedColumns.map((col, colIndex) => {
767
1009
  const stickyOffset = columnOffsets.get(col.key);
@@ -781,25 +1023,23 @@ var TableBody = ({
781
1023
  else if (col.pinned === "right" && stickyOffset !== void 0)
782
1024
  style.right = `${stickyOffset}px`;
783
1025
  if (isPinned) {
784
- style.backdropFilter = "blur(14px)";
785
- style.backgroundColor = styles?.pinnedBg ?? theme === "dark" ? "#10182890" : "#f9fafb90";
1026
+ style.backgroundColor = styles?.pinnedBg ?? "Canvas";
786
1027
  if (styles?.pinnedCell) Object.assign(style, styles.pinnedCell);
787
1028
  }
788
1029
  return { key: col.key, style, isPinned };
789
1030
  });
790
1031
  }, [orderedColumns, columnOffsets, totalSize, styles]);
791
- return /* @__PURE__ */ jsxs3(Fragment3, { children: [
1032
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
792
1033
  columnStyles.map((colStyle, colIndex) => {
793
1034
  const col = orderedColumns[colIndex];
794
- return /* @__PURE__ */ jsx3(
1035
+ return /* @__PURE__ */ jsx4(
795
1036
  "div",
796
1037
  {
797
- className: "truncate",
798
1038
  style: colStyle.style,
799
1039
  children: virtualItems.map((virtualRow) => {
800
1040
  const row = data[virtualRow.index];
801
1041
  const rowKey = getRowKey ? getRowKey(row, virtualRow.index) : String(virtualRow.index);
802
- const isSelected = normalizedSelectedKeys.includes(rowKey);
1042
+ const isSelected = selectedKeySet.has(rowKey);
803
1043
  const isExpanded = resolvedExpandedKeys?.has(rowKey) ?? false;
804
1044
  const cellValue = row[col.dataIndex];
805
1045
  const isRowShimmer = isLoading || rowKey.startsWith("__shimmer_");
@@ -814,7 +1054,7 @@ var TableBody = ({
814
1054
  * - Absolute positioned at virtualRow.start for virtualization
815
1055
  * - Height = virtualRow.size (includes expanded row height)
816
1056
  */
817
- /* @__PURE__ */ jsx3(
1057
+ /* @__PURE__ */ jsx4(
818
1058
  "div",
819
1059
  {
820
1060
  "data-row-key": rowKey,
@@ -826,13 +1066,14 @@ var TableBody = ({
826
1066
  right: 0,
827
1067
  height: `${virtualRow.size}px`
828
1068
  },
829
- className: "truncate",
830
- children: /* @__PURE__ */ jsx3(
1069
+ children: /* @__PURE__ */ jsx4(
831
1070
  "div",
832
1071
  {
833
- style: { height: `${rowHeight}px`, position: "relative" },
834
- className: "truncate",
835
- children: /* @__PURE__ */ jsx3(
1072
+ style: {
1073
+ height: `${rowHeight}px`,
1074
+ position: "relative"
1075
+ },
1076
+ children: /* @__PURE__ */ jsx4(
836
1077
  Cell,
837
1078
  {
838
1079
  value: cellValue,
@@ -863,7 +1104,7 @@ var TableBody = ({
863
1104
  `spacer-${colStyle.key}`
864
1105
  );
865
1106
  }),
866
- expandable && /* @__PURE__ */ jsx3(
1107
+ expandable && /* @__PURE__ */ jsx4(
867
1108
  "div",
868
1109
  {
869
1110
  style: {
@@ -880,31 +1121,27 @@ var TableBody = ({
880
1121
  const row = data[virtualRow.index];
881
1122
  const rk = getRowKey ? getRowKey(row, virtualRow.index) : String(virtualRow.index);
882
1123
  if (!(resolvedExpandedKeys?.has(rk) ?? false)) return null;
883
- const expandedContent = /* @__PURE__ */ jsx3(
1124
+ const expandedContent = /* @__PURE__ */ jsx4(
884
1125
  "div",
885
1126
  {
886
- className: `${classNames?.expandedRow ?? ""}`,
1127
+ className: classNames?.expandedRow ?? "",
887
1128
  style: {
888
- // Sticky left:0 + fixed width = viewport-locked panel
889
- // regardless of how far the user has scrolled horizontally
890
1129
  position: "sticky",
891
1130
  left: 0,
892
1131
  zIndex: 5,
893
1132
  width: scrollAreaWidth && scrollAreaWidth > 0 ? `${scrollAreaWidth}px` : "100%",
894
1133
  overflow: "auto",
895
- // Restore pointer events so the expanded content is interactive
896
1134
  pointerEvents: "auto",
897
- borderBottom: "1px solid hsl(var(--border))",
898
- backgroundColor: "hsl(var(--muted)/0.4)",
1135
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
1136
+ backgroundColor: "rgba(128,128,128,0.06)",
899
1137
  padding: 20,
900
- // Optional max height — makes the panel scrollable for tall content
901
1138
  ...maxExpandedRowHeight ? { maxHeight: `${maxExpandedRowHeight}px` } : void 0,
902
1139
  ...styles?.expandedRow
903
1140
  },
904
1141
  children: expandable.expandedRowRender(row, virtualRow.index, 0, true)
905
1142
  }
906
1143
  );
907
- return /* @__PURE__ */ jsx3(
1144
+ return /* @__PURE__ */ jsx4(
908
1145
  "div",
909
1146
  {
910
1147
  style: {
@@ -914,7 +1151,7 @@ var TableBody = ({
914
1151
  left: 0,
915
1152
  right: 0
916
1153
  },
917
- children: onExpandedRowResize ? /* @__PURE__ */ jsx3(
1154
+ children: onExpandedRowResize ? /* @__PURE__ */ jsx4(
918
1155
  MeasuredExpandedRow,
919
1156
  {
920
1157
  rowKey: rk,
@@ -934,7 +1171,13 @@ TableBody.displayName = "TableBody";
934
1171
  var TableBody_default = TableBody;
935
1172
 
936
1173
  // src/BoltTable.tsx
937
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1174
+ import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1175
+ function arrayMove(arr, from, to) {
1176
+ const result = arr.slice();
1177
+ const [item] = result.splice(from, 1);
1178
+ result.splice(to, 0, item);
1179
+ return result;
1180
+ }
938
1181
  var SHIMMER_WIDTHS2 = [55, 70, 45, 80, 60, 50, 75, 65, 40, 72];
939
1182
  function BoltTable({
940
1183
  columns: initialColumns,
@@ -948,6 +1191,7 @@ function BoltTable({
948
1191
  styles = {},
949
1192
  gripIcon,
950
1193
  hideGripIcon,
1194
+ icons,
951
1195
  pagination,
952
1196
  onPaginationChange,
953
1197
  onColumnResize,
@@ -1062,7 +1306,7 @@ function BoltTable({
1062
1306
  const canExpand = expandable.rowExpandable?.(record) ?? true;
1063
1307
  const isExpanded = resolvedExpandedKeys.has(key);
1064
1308
  if (!canExpand)
1065
- return /* @__PURE__ */ jsx4("span", { style: { display: "inline-block", width: 16 } });
1309
+ return /* @__PURE__ */ jsx5("span", { style: { display: "inline-block", width: 16 } });
1066
1310
  if (typeof expandable.expandIcon === "function") {
1067
1311
  return expandable.expandIcon({
1068
1312
  expanded: isExpanded,
@@ -1073,7 +1317,7 @@ function BoltTable({
1073
1317
  record
1074
1318
  });
1075
1319
  }
1076
- return /* @__PURE__ */ jsx4(
1320
+ return /* @__PURE__ */ jsx5(
1077
1321
  "button",
1078
1322
  {
1079
1323
  onClick: (e) => {
@@ -1091,7 +1335,7 @@ function BoltTable({
1091
1335
  borderRadius: "3px",
1092
1336
  color: accentColor
1093
1337
  },
1094
- children: isExpanded ? /* @__PURE__ */ jsx4(ChevronDown, { style: { width: 14, height: 14 } }) : /* @__PURE__ */ jsx4(ChevronRight, { style: { width: 14, height: 14 } })
1338
+ children: isExpanded ? icons?.chevronDown ?? /* @__PURE__ */ jsx5(ChevronDownIcon, { style: { width: 14, height: 14 } }) : icons?.chevronRight ?? /* @__PURE__ */ jsx5(ChevronRightIcon, { style: { width: 14, height: 14 } })
1095
1339
  }
1096
1340
  );
1097
1341
  }
@@ -1182,25 +1426,91 @@ function BoltTable({
1182
1426
  };
1183
1427
  }, []);
1184
1428
  const resizeStateRef = useRef4(null);
1185
- const sensors = useSensors(useSensor(PointerSensor));
1186
- const handleDragStart = (event) => {
1187
- if (event.active.id === "__select__" || event.active.id === "__expand__")
1188
- return;
1189
- setActiveId(event.active.id);
1190
- };
1191
- const handleDragEnd = (event) => {
1192
- const { active, over } = event;
1193
- if (over && active.id !== over.id) {
1194
- setColumnOrder((items) => {
1195
- const oldIndex = items.indexOf(active.id);
1196
- const newIndex = items.indexOf(over.id);
1197
- const newOrder = arrayMove(items, oldIndex, newIndex);
1198
- setTimeout(() => onColumnOrderChange?.(newOrder), 0);
1199
- return newOrder;
1200
- });
1201
- }
1202
- setActiveId(null);
1203
- };
1429
+ const overIdRef = useRef4(null);
1430
+ const dragActiveIdRef = useRef4(null);
1431
+ const ghostRef = useRef4(null);
1432
+ const onColumnOrderChangeRef = useRef4(onColumnOrderChange);
1433
+ onColumnOrderChangeRef.current = onColumnOrderChange;
1434
+ const handleColumnDragStart = useCallback(
1435
+ (columnKey, e) => {
1436
+ if (columnKey === "__select__" || columnKey === "__expand__") return;
1437
+ const headerEl = e.currentTarget.closest(
1438
+ "[data-column-key]"
1439
+ );
1440
+ if (!headerEl) return;
1441
+ const rect = headerEl.getBoundingClientRect();
1442
+ const offsetX = e.clientX - rect.left;
1443
+ const offsetY = e.clientY - rect.top;
1444
+ setActiveId(columnKey);
1445
+ dragActiveIdRef.current = columnKey;
1446
+ headerEl.setAttribute("data-dragging", "");
1447
+ const ghost = ghostRef.current;
1448
+ if (ghost) {
1449
+ ghost.style.display = "flex";
1450
+ ghost.style.width = `${rect.width}px`;
1451
+ ghost.style.left = `${e.clientX - offsetX}px`;
1452
+ ghost.style.top = `${rect.top}px`;
1453
+ }
1454
+ const onMove = (ev) => {
1455
+ if (ghost) {
1456
+ ghost.style.left = `${ev.clientX - offsetX}px`;
1457
+ ghost.style.top = `${ev.clientY - offsetY}px`;
1458
+ }
1459
+ const scrollEl = tableAreaRef.current;
1460
+ if (!scrollEl) return;
1461
+ const headers = scrollEl.querySelectorAll("[data-column-key]");
1462
+ let newOverId = null;
1463
+ headers.forEach((h) => {
1464
+ const key = h.dataset.columnKey;
1465
+ if (!key || key === "__select__" || key === "__expand__" || key === columnKey) {
1466
+ h.removeAttribute("data-drag-over");
1467
+ return;
1468
+ }
1469
+ const r = h.getBoundingClientRect();
1470
+ if (ev.clientX >= r.left && ev.clientX <= r.right && ev.clientY >= r.top - 20 && ev.clientY <= r.bottom + 20) {
1471
+ newOverId = key;
1472
+ h.setAttribute("data-drag-over", "");
1473
+ } else {
1474
+ h.removeAttribute("data-drag-over");
1475
+ }
1476
+ });
1477
+ overIdRef.current = newOverId;
1478
+ };
1479
+ const onUp = () => {
1480
+ document.removeEventListener("pointermove", onMove);
1481
+ document.removeEventListener("pointerup", onUp);
1482
+ const scrollEl = tableAreaRef.current;
1483
+ if (scrollEl) {
1484
+ scrollEl.querySelectorAll("[data-dragging]").forEach((h) => h.removeAttribute("data-dragging"));
1485
+ scrollEl.querySelectorAll("[data-drag-over]").forEach((h) => h.removeAttribute("data-drag-over"));
1486
+ }
1487
+ if (ghost) ghost.style.display = "none";
1488
+ const currentOverId = overIdRef.current;
1489
+ const currentActiveId = dragActiveIdRef.current;
1490
+ if (currentOverId && currentActiveId && currentOverId !== currentActiveId) {
1491
+ React4.startTransition(() => {
1492
+ setColumnOrder((items) => {
1493
+ const oldIndex = items.indexOf(currentActiveId);
1494
+ const newIndex = items.indexOf(currentOverId);
1495
+ if (oldIndex === -1 || newIndex === -1) return items;
1496
+ const newOrder = arrayMove(items, oldIndex, newIndex);
1497
+ setTimeout(
1498
+ () => onColumnOrderChangeRef.current?.(newOrder),
1499
+ 0
1500
+ );
1501
+ return newOrder;
1502
+ });
1503
+ });
1504
+ }
1505
+ setActiveId(null);
1506
+ dragActiveIdRef.current = null;
1507
+ overIdRef.current = null;
1508
+ };
1509
+ document.addEventListener("pointermove", onMove);
1510
+ document.addEventListener("pointerup", onUp);
1511
+ },
1512
+ []
1513
+ );
1204
1514
  const handleResizeStart = (columnKey, e) => {
1205
1515
  e.preventDefault();
1206
1516
  e.stopPropagation();
@@ -1254,17 +1564,19 @@ function BoltTable({
1254
1564
  if (!resizeStateRef.current) return;
1255
1565
  const { startX, startWidth, currentX, columnKey } = resizeStateRef.current;
1256
1566
  const finalWidth = Math.max(40, startWidth + (currentX - startX));
1257
- manuallyResizedRef.current.add(columnKey);
1258
- setColumnWidths((prev) => {
1259
- const next = new Map(prev);
1260
- next.set(columnKey, finalWidth);
1261
- return next;
1262
- });
1263
- onColumnResize?.(columnKey, finalWidth);
1264
1567
  resizeOverlayRef.current?.hide();
1265
1568
  resizeStateRef.current = null;
1266
1569
  document.removeEventListener("mousemove", handleResizeMove);
1267
1570
  document.removeEventListener("mouseup", handleResizeEnd);
1571
+ manuallyResizedRef.current.add(columnKey);
1572
+ React4.startTransition(() => {
1573
+ setColumnWidths((prev) => {
1574
+ const next = new Map(prev);
1575
+ next.set(columnKey, finalWidth);
1576
+ return next;
1577
+ });
1578
+ });
1579
+ onColumnResize?.(columnKey, finalWidth);
1268
1580
  }, [onColumnResize]);
1269
1581
  const { leftPinned, unpinned, rightPinned } = useMemo2(() => {
1270
1582
  const columnMap = new Map(columnsWithSelection.map((c) => [c.key, c]));
@@ -1564,27 +1876,31 @@ function BoltTable({
1564
1876
  };
1565
1877
  const HEADER_HEIGHT = 36;
1566
1878
  const MAX_AUTO_ROWS = 10;
1567
- const naturalContentHeight = rowVirtualizer.getTotalSize() + HEADER_HEIGHT;
1879
+ const virtualTotalSize = rowVirtualizer.getTotalSize();
1880
+ const naturalContentHeight = virtualTotalSize + HEADER_HEIGHT;
1568
1881
  const maxAutoHeight = MAX_AUTO_ROWS * rowHeight + HEADER_HEIGHT;
1569
1882
  const isEmpty = displayData.length === 0 && !showShimmer;
1570
1883
  const emptyMinHeight = 4 * rowHeight + HEADER_HEIGHT;
1571
1884
  const clampedAutoHeight = isEmpty ? emptyMinHeight : Math.min(naturalContentHeight, maxAutoHeight);
1572
- return /* @__PURE__ */ jsxs4(
1573
- DndContext,
1574
- {
1575
- sensors,
1576
- collisionDetection: closestCenter,
1577
- onDragStart: handleDragStart,
1578
- onDragEnd: handleDragEnd,
1579
- children: [
1580
- /* @__PURE__ */ jsxs4(
1581
- "div",
1582
- {
1583
- className: `flex ${autoHeight ? "max-h-full" : "h-full"} w-full flex-col ${className}`,
1584
- children: [
1585
- /* @__PURE__ */ jsx4("style", { children: `
1885
+ return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1886
+ /* @__PURE__ */ jsxs5(
1887
+ "div",
1888
+ {
1889
+ className,
1890
+ style: {
1891
+ display: "flex",
1892
+ width: "100%",
1893
+ flexDirection: "column",
1894
+ ...autoHeight ? { maxHeight: "100%" } : { height: "100%" }
1895
+ },
1896
+ children: [
1897
+ /* @__PURE__ */ jsx5("style", { children: `
1898
+ @keyframes bt-pulse {
1899
+ 0%, 100% { opacity: 1; }
1900
+ 50% { opacity: 0.5; }
1901
+ }
1586
1902
  [data-row-key][data-hover] > div {
1587
- background-color: ${styles.rowHover?.backgroundColor ?? `hsl(var(--muted) / 0.5)`};
1903
+ background-color: ${styles.rowHover?.backgroundColor ?? "rgba(0, 0, 0, 0.04)"};
1588
1904
  }
1589
1905
  [data-row-key][data-selected] > div {
1590
1906
  background-color: ${styles.rowSelected?.backgroundColor ?? `${accentColor}15`};
@@ -1592,447 +1908,675 @@ function BoltTable({
1592
1908
  [data-row-key][data-selected][data-hover] > div {
1593
1909
  background-color: ${styles.rowSelected?.backgroundColor ?? `${accentColor}25`};
1594
1910
  }
1911
+ [data-bt-header]:hover [data-bt-grip] {
1912
+ opacity: 0.8 !important;
1913
+ }
1914
+ [data-bt-resize]:hover [data-bt-resize-line] {
1915
+ opacity: 1 !important;
1916
+ }
1917
+ [data-bt-ctx-item]:not(:disabled):hover {
1918
+ background-color: rgba(0, 0, 0, 0.06);
1919
+ }
1920
+ [data-column-key][data-dragging] {
1921
+ opacity: 0.3 !important;
1922
+ }
1923
+ [data-column-key][data-drag-over] {
1924
+ border: 1px dashed ${accentColor} !important;
1925
+ }
1595
1926
  ` }),
1596
- /* @__PURE__ */ jsx4(
1597
- "div",
1598
- {
1599
- className: `relative ${autoHeight ? "" : "flex-1"}`,
1600
- style: autoHeight ? {
1601
- height: `${clampedAutoHeight}px`,
1602
- maxHeight: `${clampedAutoHeight}px`,
1603
- flexShrink: 1,
1604
- flexGrow: 0
1605
- } : void 0,
1606
- children: layoutLoading ? (
1607
- /*
1608
- * ── Layout loading skeleton ──────────────────────────────────
1609
- * Shown when layoutLoading=true. Renders real column headers
1610
- * (based on orderedColumns) alongside shimmer body rows.
1611
- * Used for initial page load when column widths are not yet known.
1612
- */
1613
- /* @__PURE__ */ jsx4(
1927
+ /* @__PURE__ */ jsx5(
1928
+ "div",
1929
+ {
1930
+ style: {
1931
+ position: "relative",
1932
+ ...autoHeight ? {
1933
+ height: `${clampedAutoHeight}px`,
1934
+ maxHeight: `${clampedAutoHeight}px`,
1935
+ flexShrink: 1,
1936
+ flexGrow: 0
1937
+ } : { flex: "1 1 0%" }
1938
+ },
1939
+ children: layoutLoading ? (
1940
+ /*
1941
+ * ── Layout loading skeleton ──────────────────────────────────
1942
+ * Shown when layoutLoading=true. Renders real column headers
1943
+ * (based on orderedColumns) alongside shimmer body rows.
1944
+ * Used for initial page load when column widths are not yet known.
1945
+ */
1946
+ /* @__PURE__ */ jsx5(
1947
+ "div",
1948
+ {
1949
+ style: {
1950
+ position: "absolute",
1951
+ inset: 0,
1952
+ overflow: "auto",
1953
+ contain: "layout paint"
1954
+ },
1955
+ children: /* @__PURE__ */ jsxs5(
1614
1956
  "div",
1615
1957
  {
1616
- className: "absolute inset-0 overflow-auto",
1617
- style: { contain: "layout paint" },
1618
- children: /* @__PURE__ */ jsxs4(
1619
- "div",
1620
- {
1621
- style: {
1622
- display: "grid",
1623
- gridTemplateColumns,
1624
- gridTemplateRows: "36px auto",
1625
- minWidth: `${totalTableWidth}px`,
1626
- width: "100%",
1627
- position: "relative"
1628
- },
1629
- children: [
1630
- orderedColumns.map((column) => {
1958
+ style: {
1959
+ display: "grid",
1960
+ gridTemplateColumns,
1961
+ gridTemplateRows: "36px auto",
1962
+ minWidth: `${totalTableWidth}px`,
1963
+ width: "100%",
1964
+ position: "relative"
1965
+ },
1966
+ children: [
1967
+ orderedColumns.map((column) => {
1968
+ const isPinned = !!column.pinned;
1969
+ const offset = columnOffsets.get(column.key);
1970
+ const isSystem = column.key === "__select__" || column.key === "__expand__";
1971
+ return /* @__PURE__ */ jsx5(
1972
+ "div",
1973
+ {
1974
+ className: isPinned ? classNames.pinnedHeader ?? "" : classNames.header ?? "",
1975
+ style: {
1976
+ display: "flex",
1977
+ height: 36,
1978
+ alignItems: "center",
1979
+ overflow: "hidden",
1980
+ textOverflow: "ellipsis",
1981
+ whiteSpace: "nowrap",
1982
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
1983
+ backdropFilter: "blur(8px)",
1984
+ position: "sticky",
1985
+ top: 0,
1986
+ zIndex: isPinned ? 13 : 10,
1987
+ ...isPinned ? {
1988
+ [column.pinned]: offset ?? 0,
1989
+ ...styles.pinnedHeader
1990
+ } : styles.header,
1991
+ paddingLeft: isSystem ? 0 : 8,
1992
+ paddingRight: isSystem ? 0 : 8
1993
+ }
1994
+ },
1995
+ column.key
1996
+ );
1997
+ }),
1998
+ /* @__PURE__ */ jsx5("div", { style: { gridColumn: "1 / -1" }, children: Array.from({ length: shimmerCount }).map((_, rowIndex) => /* @__PURE__ */ jsx5(
1999
+ "div",
2000
+ {
2001
+ style: {
2002
+ display: "grid",
2003
+ gridTemplateColumns,
2004
+ height: rowHeight
2005
+ },
2006
+ children: orderedColumns.map((column, colIndex) => {
1631
2007
  const isPinned = !!column.pinned;
1632
2008
  const offset = columnOffsets.get(column.key);
1633
2009
  const isSystem = column.key === "__select__" || column.key === "__expand__";
1634
- return /* @__PURE__ */ jsx4(
2010
+ const widthPercent = SHIMMER_WIDTHS2[(rowIndex * 7 + colIndex) % SHIMMER_WIDTHS2.length];
2011
+ return /* @__PURE__ */ jsx5(
1635
2012
  "div",
1636
2013
  {
1637
- className: `flex h-9 items-center truncate border-t border-b ${isPinned ? `bg-background backdrop-blur ${classNames.pinnedHeader ?? ""}` : `bg-muted/40 backdrop-blur ${classNames.header ?? ""}`}`,
2014
+ className: isPinned ? classNames.pinnedCell ?? "" : "",
1638
2015
  style: {
1639
- position: "sticky",
1640
- top: 0,
1641
- zIndex: isPinned ? 13 : 10,
2016
+ display: "flex",
2017
+ alignItems: "center",
2018
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
1642
2019
  ...isPinned ? {
2020
+ position: "sticky",
1643
2021
  [column.pinned]: offset ?? 0,
1644
- ...styles.pinnedHeader
1645
- } : styles.header,
2022
+ zIndex: 5,
2023
+ ...styles.pinnedCell
2024
+ } : {},
1646
2025
  paddingLeft: isSystem ? 0 : 8,
1647
- paddingRight: isSystem ? 0 : 8
1648
- }
1649
- },
1650
- column.key
1651
- );
1652
- }),
1653
- /* @__PURE__ */ jsx4("div", { style: { gridColumn: "1 / -1" }, children: Array.from({ length: shimmerCount }).map((_, rowIndex) => /* @__PURE__ */ jsx4(
1654
- "div",
1655
- {
1656
- style: {
1657
- display: "grid",
1658
- gridTemplateColumns,
1659
- height: rowHeight
1660
- },
1661
- children: orderedColumns.map((column, colIndex) => {
1662
- const isPinned = !!column.pinned;
1663
- const offset = columnOffsets.get(column.key);
1664
- const isSystem = column.key === "__select__" || column.key === "__expand__";
1665
- const widthPercent = SHIMMER_WIDTHS2[(rowIndex * 7 + colIndex) % SHIMMER_WIDTHS2.length];
1666
- return /* @__PURE__ */ jsx4(
2026
+ paddingRight: isSystem ? 0 : 8,
2027
+ justifyContent: isSystem ? "center" : void 0
2028
+ },
2029
+ children: /* @__PURE__ */ jsx5(
1667
2030
  "div",
1668
2031
  {
1669
- className: `flex items-center border-b ${isPinned ? `bg-background ${classNames.pinnedCell ?? ""}` : ""}`,
1670
2032
  style: {
1671
- ...isPinned ? {
1672
- position: "sticky",
1673
- [column.pinned]: offset ?? 0,
1674
- zIndex: 5,
1675
- ...styles.pinnedCell
1676
- } : {},
1677
- paddingLeft: isSystem ? 0 : 8,
1678
- paddingRight: isSystem ? 0 : 8,
1679
- justifyContent: isSystem ? "center" : void 0
1680
- },
1681
- children: /* @__PURE__ */ jsx4(
1682
- "div",
1683
- {
1684
- className: "bg-muted-foreground/15 animate-pulse rounded",
1685
- style: {
1686
- height: isSystem ? 16 : 14,
1687
- width: isSystem ? 16 : `${widthPercent}%`,
1688
- borderRadius: isSystem ? 3 : 4,
1689
- animationDelay: `${(rowIndex * 7 + colIndex) * 50}ms`
1690
- }
1691
- }
1692
- )
1693
- },
1694
- column.key
1695
- );
1696
- })
1697
- },
1698
- rowIndex
1699
- )) })
1700
- ]
1701
- }
1702
- )
2033
+ backgroundColor: "rgba(100, 116, 139, 0.15)",
2034
+ animation: "bt-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
2035
+ borderRadius: isSystem ? 3 : 4,
2036
+ height: isSystem ? 16 : 14,
2037
+ width: isSystem ? 16 : `${widthPercent}%`,
2038
+ animationDelay: `${(rowIndex * 7 + colIndex) * 50}ms`
2039
+ }
2040
+ }
2041
+ )
2042
+ },
2043
+ column.key
2044
+ );
2045
+ })
2046
+ },
2047
+ rowIndex
2048
+ )) })
2049
+ ]
1703
2050
  }
1704
2051
  )
1705
- ) : (
1706
- /*
1707
- * ── Main scroll container ────────────────────────────────────
1708
- * absolute inset-0 so it fills whatever height the wrapper resolves to.
1709
- * contain: layout paint browser optimization hint that this element
1710
- * is a layout and paint boundary (improves compositing performance).
1711
- */
1712
- /* @__PURE__ */ jsxs4(
1713
- "div",
1714
- {
1715
- ref: tableAreaCallbackRef,
1716
- className: "absolute inset-0 overflow-auto",
1717
- style: { contain: "layout paint" },
1718
- children: [
1719
- /* @__PURE__ */ jsx4(ResizeOverlay_default, { ref: resizeOverlayRef, accentColor }),
1720
- /* @__PURE__ */ jsxs4(
1721
- "div",
1722
- {
1723
- style: {
1724
- display: "grid",
1725
- gridTemplateColumns,
1726
- gridTemplateRows: "36px 1fr",
1727
- minWidth: `${totalTableWidth}px`,
1728
- height: "100%",
1729
- width: "100%",
1730
- position: "relative"
1731
- },
1732
- children: [
1733
- /* @__PURE__ */ jsx4(
1734
- SortableContext,
2052
+ }
2053
+ )
2054
+ ) : (
2055
+ /*
2056
+ * ── Main scroll container ────────────────────────────────────
2057
+ * absolute inset-0 so it fills whatever height the wrapper resolves to.
2058
+ * contain: layout paint — browser optimization hint that this element
2059
+ * is a layout and paint boundary (improves compositing performance).
2060
+ */
2061
+ /* @__PURE__ */ jsxs5(
2062
+ "div",
2063
+ {
2064
+ ref: tableAreaCallbackRef,
2065
+ style: {
2066
+ position: "absolute",
2067
+ inset: 0,
2068
+ overflow: "auto",
2069
+ contain: "layout paint"
2070
+ },
2071
+ children: [
2072
+ /* @__PURE__ */ jsx5(ResizeOverlay_default, { ref: resizeOverlayRef, accentColor }),
2073
+ /* @__PURE__ */ jsxs5(
2074
+ "div",
2075
+ {
2076
+ style: {
2077
+ display: "grid",
2078
+ gridTemplateColumns,
2079
+ gridTemplateRows: isEmpty ? "36px 1fr" : `36px ${virtualTotalSize}px`,
2080
+ minWidth: `${totalTableWidth}px`,
2081
+ width: "100%",
2082
+ position: "relative",
2083
+ ...isEmpty ? { height: "100%" } : {}
2084
+ },
2085
+ children: [
2086
+ orderedColumns.map((column, visualIndex) => {
2087
+ if (column.key === "__select__" && rowSelection) {
2088
+ return /* @__PURE__ */ jsx5(
2089
+ "div",
1735
2090
  {
1736
- items: columnOrder,
1737
- strategy: horizontalListSortingStrategy,
1738
- children: orderedColumns.map((column, visualIndex) => {
1739
- if (column.key === "__select__" && rowSelection) {
1740
- return /* @__PURE__ */ jsx4(
1741
- "div",
1742
- {
1743
- className: `bg-muted/40 sticky flex h-9 items-center justify-center truncate border-t border-b backdrop-blur ${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""} `,
1744
- style: {
1745
- position: "sticky",
1746
- left: columnOffsets.get("__select__") ?? 0,
1747
- top: 0,
1748
- zIndex: 13,
1749
- width: "48px",
1750
- ...styles.header,
1751
- ...styles.pinnedHeader
1752
- },
1753
- children: rowSelection.type !== "radio" && !rowSelection.hideSelectAll && /* @__PURE__ */ jsx4(
1754
- "input",
1755
- {
1756
- type: "checkbox",
1757
- checked: data.length > 0 && normalizedSelectedKeys.length === data.length,
1758
- ref: (input) => {
1759
- if (input) {
1760
- input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length < data.length;
1761
- }
1762
- },
1763
- onChange: (e) => {
1764
- if (e.target.checked) {
1765
- const allKeys = data.map(
1766
- (row, idx) => getRowKey(row, idx)
1767
- );
1768
- rowSelection.onSelectAll?.(
1769
- true,
1770
- data,
1771
- data
1772
- );
1773
- rowSelection.onChange?.(allKeys, data, {
1774
- type: "all"
1775
- });
1776
- } else {
1777
- rowSelection.onSelectAll?.(false, [], data);
1778
- rowSelection.onChange?.([], [], {
1779
- type: "all"
1780
- });
1781
- }
1782
- },
1783
- className: "cursor-pointer",
1784
- style: { accentColor }
1785
- }
1786
- )
1787
- },
1788
- "__select__"
1789
- );
1790
- }
1791
- if (column.key === "__expand__") {
1792
- return /* @__PURE__ */ jsx4(
1793
- "div",
1794
- {
1795
- className: `bg-muted/40 sticky flex h-9 items-center justify-center truncate border-t border-b backdrop-blur ${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
1796
- style: {
1797
- position: "sticky",
1798
- left: columnOffsets.get("__expand__") ?? 0,
1799
- top: 0,
1800
- zIndex: 13,
1801
- width: "40px",
1802
- ...styles.header,
1803
- ...styles.pinnedHeader
1804
- }
1805
- },
1806
- "__expand__"
1807
- );
1808
- }
1809
- return /* @__PURE__ */ jsx4(
1810
- DraggableHeader_default,
1811
- {
1812
- column,
1813
- accentColor,
1814
- visualIndex,
1815
- onResizeStart: handleResizeStart,
1816
- styles,
1817
- classNames,
1818
- gripIcon,
1819
- hideGripIcon,
1820
- stickyOffset: columnOffsets.get(column.key),
1821
- onTogglePin: handleTogglePin,
1822
- onToggleHide: handleToggleHide,
1823
- isLastColumn: visualIndex === orderedColumns.length - 1,
1824
- sortDirection: sortState.key === column.key ? sortState.direction : null,
1825
- onSort: handleSort,
1826
- filterValue: columnFilters[column.key] ?? "",
1827
- onFilter: handleColumnFilter,
1828
- onClearFilter: handleClearFilter,
1829
- customContextMenuItems: columnContextMenuItems
2091
+ className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2092
+ style: {
2093
+ display: "flex",
2094
+ height: 36,
2095
+ alignItems: "center",
2096
+ justifyContent: "center",
2097
+ overflow: "hidden",
2098
+ textOverflow: "ellipsis",
2099
+ whiteSpace: "nowrap",
2100
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2101
+ backgroundColor: "Canvas",
2102
+ position: "sticky",
2103
+ left: columnOffsets.get("__select__") ?? 0,
2104
+ top: 0,
2105
+ zIndex: 13,
2106
+ width: "48px",
2107
+ ...styles.header,
2108
+ ...styles.pinnedHeader
2109
+ },
2110
+ children: rowSelection.type !== "radio" && !rowSelection.hideSelectAll && /* @__PURE__ */ jsx5(
2111
+ "input",
2112
+ {
2113
+ type: "checkbox",
2114
+ checked: data.length > 0 && normalizedSelectedKeys.length === data.length,
2115
+ ref: (input) => {
2116
+ if (input) {
2117
+ input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length < data.length;
2118
+ }
2119
+ },
2120
+ onChange: (e) => {
2121
+ if (e.target.checked) {
2122
+ const allKeys = data.map(
2123
+ (row, idx) => getRowKey(row, idx)
2124
+ );
2125
+ rowSelection.onSelectAll?.(
2126
+ true,
2127
+ data,
2128
+ data
2129
+ );
2130
+ rowSelection.onChange?.(allKeys, data, {
2131
+ type: "all"
2132
+ });
2133
+ } else {
2134
+ rowSelection.onSelectAll?.(false, [], data);
2135
+ rowSelection.onChange?.([], [], {
2136
+ type: "all"
2137
+ });
2138
+ }
1830
2139
  },
1831
- column.key
1832
- );
1833
- })
1834
- }
1835
- ),
1836
- isEmpty ? (
1837
- /*
1838
- * ── Empty state ────────────────────────────────────────
1839
- * col-span-full + height:100% fills the 1fr body grid row.
1840
- *
1841
- * The inner div uses `position: sticky; left: 0` with a fixed
1842
- * width (scrollAreaWidth) to viewport-lock the empty state panel.
1843
- * Without this, the empty message would scroll horizontally
1844
- * with the grid content when there are many columns.
1845
- */
1846
- /* @__PURE__ */ jsx4(
2140
+ style: { cursor: "pointer", accentColor }
2141
+ }
2142
+ )
2143
+ },
2144
+ "__select__"
2145
+ );
2146
+ }
2147
+ if (column.key === "__expand__") {
2148
+ return /* @__PURE__ */ jsx5(
2149
+ "div",
2150
+ {
2151
+ className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2152
+ style: {
2153
+ display: "flex",
2154
+ height: 36,
2155
+ alignItems: "center",
2156
+ justifyContent: "center",
2157
+ overflow: "hidden",
2158
+ textOverflow: "ellipsis",
2159
+ whiteSpace: "nowrap",
2160
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2161
+ backgroundColor: "Canvas",
2162
+ position: "sticky",
2163
+ left: columnOffsets.get("__expand__") ?? 0,
2164
+ top: 0,
2165
+ zIndex: 13,
2166
+ width: "40px",
2167
+ ...styles.header,
2168
+ ...styles.pinnedHeader
2169
+ }
2170
+ },
2171
+ "__expand__"
2172
+ );
2173
+ }
2174
+ return /* @__PURE__ */ jsx5(
2175
+ DraggableHeader_default,
2176
+ {
2177
+ column,
2178
+ accentColor,
2179
+ visualIndex,
2180
+ onResizeStart: handleResizeStart,
2181
+ onColumnDragStart: handleColumnDragStart,
2182
+ styles,
2183
+ classNames,
2184
+ gripIcon,
2185
+ hideGripIcon,
2186
+ icons,
2187
+ stickyOffset: columnOffsets.get(column.key),
2188
+ onTogglePin: handleTogglePin,
2189
+ onToggleHide: handleToggleHide,
2190
+ isLastColumn: visualIndex === orderedColumns.length - 1,
2191
+ sortDirection: sortState.key === column.key ? sortState.direction : null,
2192
+ onSort: handleSort,
2193
+ filterValue: columnFilters[column.key] ?? "",
2194
+ onFilter: handleColumnFilter,
2195
+ onClearFilter: handleClearFilter,
2196
+ customContextMenuItems: columnContextMenuItems
2197
+ },
2198
+ column.key
2199
+ );
2200
+ }),
2201
+ isEmpty ? (
2202
+ /*
2203
+ * ── Empty state ────────────────────────────────────────
2204
+ * col-span-full + height:100% fills the 1fr body grid row.
2205
+ *
2206
+ * The inner div uses `position: sticky; left: 0` with a fixed
2207
+ * width (scrollAreaWidth) to viewport-lock the empty state panel.
2208
+ * Without this, the empty message would scroll horizontally
2209
+ * with the grid content when there are many columns.
2210
+ */
2211
+ /* @__PURE__ */ jsx5(
2212
+ "div",
2213
+ {
2214
+ style: {
2215
+ gridColumn: "1 / -1",
2216
+ height: "100%",
2217
+ position: "relative"
2218
+ },
2219
+ children: /* @__PURE__ */ jsx5(
1847
2220
  "div",
1848
2221
  {
1849
- className: "col-span-full",
1850
- style: { height: "100%", position: "relative" },
1851
- children: /* @__PURE__ */ jsx4(
2222
+ style: {
2223
+ position: "sticky",
2224
+ left: 0,
2225
+ width: scrollAreaWidth > 0 ? `${scrollAreaWidth}px` : "100%",
2226
+ height: "100%",
2227
+ display: "flex",
2228
+ alignItems: "center",
2229
+ justifyContent: "center"
2230
+ },
2231
+ children: emptyRenderer ?? /* @__PURE__ */ jsx5(
1852
2232
  "div",
1853
2233
  {
1854
2234
  style: {
1855
- position: "sticky",
1856
- left: 0,
1857
- width: scrollAreaWidth > 0 ? `${scrollAreaWidth}px` : "100%",
1858
- height: "100%",
1859
2235
  display: "flex",
2236
+ flexDirection: "column",
1860
2237
  alignItems: "center",
1861
- justifyContent: "center"
2238
+ gap: 8,
2239
+ paddingTop: 32,
2240
+ paddingBottom: 32,
2241
+ color: "#6b7280"
1862
2242
  },
1863
- children: emptyRenderer ?? /* @__PURE__ */ jsx4("div", { className: "text-muted-foreground flex flex-col items-center gap-2 py-8", children: /* @__PURE__ */ jsx4("span", { className: "text-sm", children: "No data" }) })
2243
+ children: /* @__PURE__ */ jsx5("span", { style: { fontSize: 14 }, children: "No data" })
1864
2244
  }
1865
2245
  )
1866
2246
  }
1867
2247
  )
1868
- ) : (
1869
- /* ── Virtualized table body ─────────────────────────── */
1870
- /* @__PURE__ */ jsx4(
1871
- TableBody_default,
1872
- {
1873
- data: displayData,
1874
- orderedColumns,
1875
- rowVirtualizer,
1876
- columnOffsets,
1877
- styles,
1878
- classNames,
1879
- rowSelection: !showShimmer ? rowSelection : void 0,
1880
- normalizedSelectedKeys,
1881
- getRowKey,
1882
- expandable: !showShimmer ? expandable : void 0,
1883
- resolvedExpandedKeys,
1884
- rowHeight,
1885
- totalTableWidth,
1886
- scrollAreaWidth,
1887
- accentColor,
1888
- scrollContainerRef: tableAreaRef,
1889
- isLoading: showShimmer,
1890
- onExpandedRowResize: handleExpandedRowResize,
1891
- maxExpandedRowHeight
1892
- }
1893
- )
1894
- )
1895
- ]
1896
- }
1897
- )
1898
- ]
1899
- }
1900
- )
1901
- )
1902
- }
1903
- ),
1904
- pagination !== false && /* @__PURE__ */ jsxs4(
1905
- "div",
1906
- {
1907
- className: "flex h-9 items-center justify-between border-t px-3 text-xs backdrop-blur",
1908
- style: {
1909
- backgroundColor: "hsl(var(--background)/0.4)",
1910
- gap: "12px"
1911
- },
1912
- children: [
1913
- /* @__PURE__ */ jsx4("div", { className: "flex flex-1 items-center", children: (() => {
1914
- const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
1915
- const rangeEnd = Math.min(currentPage * pageSize, total);
1916
- return pagination?.showTotal ? /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground text-xs", children: [
1917
- "Showing",
1918
- " ",
1919
- pagination.showTotal(total, [rangeStart, rangeEnd]),
1920
- " of",
1921
- " ",
1922
- total,
1923
- " items"
1924
- ] }) : /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground text-xs", children: [
1925
- rangeStart,
1926
- "\u2013",
1927
- rangeEnd,
1928
- " of ",
1929
- total
1930
- ] });
1931
- })() }),
1932
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-1 items-center justify-center gap-1", children: [
1933
- /* @__PURE__ */ jsx4(
2248
+ }
2249
+ )
2250
+ ) : (
2251
+ /* ── Virtualized table body ─────────────────────────── */
2252
+ /* @__PURE__ */ jsx5(
2253
+ TableBody_default,
2254
+ {
2255
+ data: displayData,
2256
+ orderedColumns,
2257
+ rowVirtualizer,
2258
+ columnOffsets,
2259
+ styles,
2260
+ classNames,
2261
+ rowSelection: !showShimmer ? rowSelection : void 0,
2262
+ normalizedSelectedKeys,
2263
+ getRowKey,
2264
+ expandable: !showShimmer ? expandable : void 0,
2265
+ resolvedExpandedKeys,
2266
+ rowHeight,
2267
+ totalTableWidth,
2268
+ scrollAreaWidth,
2269
+ accentColor,
2270
+ scrollContainerRef: tableAreaRef,
2271
+ isLoading: showShimmer,
2272
+ onExpandedRowResize: handleExpandedRowResize,
2273
+ maxExpandedRowHeight
2274
+ }
2275
+ )
2276
+ )
2277
+ ]
2278
+ }
2279
+ )
2280
+ ]
2281
+ }
2282
+ )
2283
+ )
2284
+ }
2285
+ ),
2286
+ pagination !== false && /* @__PURE__ */ jsxs5(
2287
+ "div",
2288
+ {
2289
+ style: {
2290
+ display: "flex",
2291
+ height: 36,
2292
+ alignItems: "center",
2293
+ justifyContent: "space-between",
2294
+ borderTop: "1px solid rgba(128,128,128,0.2)",
2295
+ paddingLeft: 12,
2296
+ paddingRight: 12,
2297
+ fontSize: 12,
2298
+ backdropFilter: "blur(8px)",
2299
+ backgroundColor: "rgba(128,128,128,0.06)",
2300
+ gap: 12
2301
+ },
2302
+ children: [
2303
+ /* @__PURE__ */ jsx5("div", { style: { display: "flex", flex: "1 1 0%", alignItems: "center" }, children: (() => {
2304
+ const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
2305
+ const rangeEnd = Math.min(currentPage * pageSize, total);
2306
+ return pagination?.showTotal ? /* @__PURE__ */ jsxs5("span", { style: { color: "#6b7280", fontSize: 12 }, children: [
2307
+ "Showing",
2308
+ " ",
2309
+ pagination.showTotal(total, [rangeStart, rangeEnd]),
2310
+ " of",
2311
+ " ",
2312
+ total,
2313
+ " items"
2314
+ ] }) : /* @__PURE__ */ jsxs5("span", { style: { color: "#6b7280", fontSize: 12 }, children: [
2315
+ rangeStart,
2316
+ "\u2013",
2317
+ rangeEnd,
2318
+ " of ",
2319
+ total
2320
+ ] });
2321
+ })() }),
2322
+ /* @__PURE__ */ jsxs5(
2323
+ "div",
2324
+ {
2325
+ style: {
2326
+ display: "flex",
2327
+ flex: "1 1 0%",
2328
+ alignItems: "center",
2329
+ justifyContent: "center",
2330
+ gap: 4
2331
+ },
2332
+ children: [
2333
+ /* @__PURE__ */ jsx5(
1934
2334
  "button",
1935
2335
  {
1936
2336
  onClick: () => handlePageChange(1),
1937
2337
  disabled: currentPage === 1,
1938
- className: "inline-flex h-6 w-6 cursor-pointer items-center justify-center text-xs transition-colors disabled:cursor-not-allowed disabled:opacity-30",
2338
+ style: {
2339
+ display: "inline-flex",
2340
+ height: 24,
2341
+ width: 24,
2342
+ cursor: currentPage === 1 ? "not-allowed" : "pointer",
2343
+ alignItems: "center",
2344
+ justifyContent: "center",
2345
+ fontSize: 12,
2346
+ opacity: currentPage === 1 ? 0.3 : 1,
2347
+ background: "none",
2348
+ border: "none",
2349
+ padding: 0,
2350
+ color: "inherit"
2351
+ },
1939
2352
  title: "First page",
1940
- children: /* @__PURE__ */ jsx4(ChevronsLeft, { className: "h-3 w-3" })
2353
+ children: icons?.chevronsLeft ?? /* @__PURE__ */ jsx5(ChevronsLeftIcon, { style: { width: 12, height: 12 } })
1941
2354
  }
1942
2355
  ),
1943
- /* @__PURE__ */ jsx4(
2356
+ /* @__PURE__ */ jsx5(
1944
2357
  "button",
1945
2358
  {
1946
2359
  onClick: () => handlePageChange(currentPage - 1),
1947
2360
  disabled: currentPage === 1,
1948
- className: "inline-flex h-6 w-6 cursor-pointer items-center justify-center text-xs transition-colors disabled:cursor-not-allowed disabled:opacity-30",
2361
+ style: {
2362
+ display: "inline-flex",
2363
+ height: 24,
2364
+ width: 24,
2365
+ cursor: currentPage === 1 ? "not-allowed" : "pointer",
2366
+ alignItems: "center",
2367
+ justifyContent: "center",
2368
+ fontSize: 12,
2369
+ opacity: currentPage === 1 ? 0.3 : 1,
2370
+ background: "none",
2371
+ border: "none",
2372
+ padding: 0,
2373
+ color: "inherit"
2374
+ },
1949
2375
  title: "Previous page",
1950
- children: /* @__PURE__ */ jsx4(ChevronLeft, { className: "h-3 w-3" })
2376
+ children: icons?.chevronLeft ?? /* @__PURE__ */ jsx5(ChevronLeftIcon, { style: { width: 12, height: 12 } })
1951
2377
  }
1952
2378
  ),
1953
2379
  getPageNumbers().map((page) => {
1954
2380
  if (page === "ellipsis-left" || page === "ellipsis-right") {
1955
- return /* @__PURE__ */ jsx4(
2381
+ return /* @__PURE__ */ jsx5(
1956
2382
  "span",
1957
2383
  {
1958
- className: "text-muted-foreground px-1 text-xs select-none",
2384
+ style: {
2385
+ color: "#6b7280",
2386
+ paddingLeft: 4,
2387
+ paddingRight: 4,
2388
+ fontSize: 12,
2389
+ userSelect: "none"
2390
+ },
1959
2391
  children: "..."
1960
2392
  },
1961
2393
  page
1962
2394
  );
1963
2395
  }
1964
- return /* @__PURE__ */ jsx4(
2396
+ return /* @__PURE__ */ jsx5(
1965
2397
  "button",
1966
2398
  {
1967
2399
  style: {
1968
- color: page === currentPage ? accentColor : void 0
2400
+ display: "inline-flex",
2401
+ height: 24,
2402
+ minWidth: 24,
2403
+ cursor: "pointer",
2404
+ alignItems: "center",
2405
+ justifyContent: "center",
2406
+ borderRadius: 4,
2407
+ paddingLeft: 6,
2408
+ paddingRight: 6,
2409
+ fontSize: 12,
2410
+ color: page === currentPage ? accentColor : void 0,
2411
+ background: "none",
2412
+ border: "none"
1969
2413
  },
1970
2414
  onClick: () => handlePageChange(page),
1971
- className: "inline-flex h-6 min-w-6 cursor-pointer items-center justify-center rounded px-1.5 text-xs transition-colors",
1972
2415
  children: page
1973
2416
  },
1974
2417
  page
1975
2418
  );
1976
2419
  }),
1977
- /* @__PURE__ */ jsx4(
2420
+ /* @__PURE__ */ jsx5(
1978
2421
  "button",
1979
2422
  {
1980
2423
  onClick: () => handlePageChange(currentPage + 1),
1981
2424
  disabled: currentPage === totalPages,
1982
- className: "inline-flex h-6 w-6 cursor-pointer items-center justify-center text-xs transition-colors disabled:cursor-not-allowed disabled:opacity-30",
2425
+ style: {
2426
+ display: "inline-flex",
2427
+ height: 24,
2428
+ width: 24,
2429
+ cursor: currentPage === totalPages ? "not-allowed" : "pointer",
2430
+ alignItems: "center",
2431
+ justifyContent: "center",
2432
+ fontSize: 12,
2433
+ opacity: currentPage === totalPages ? 0.3 : 1,
2434
+ background: "none",
2435
+ border: "none",
2436
+ padding: 0,
2437
+ color: "inherit"
2438
+ },
1983
2439
  title: "Next page",
1984
- children: /* @__PURE__ */ jsx4(ChevronRight, { className: "h-3 w-3" })
2440
+ children: icons?.chevronRight ?? /* @__PURE__ */ jsx5(ChevronRightIcon, { style: { width: 12, height: 12 } })
1985
2441
  }
1986
2442
  ),
1987
- /* @__PURE__ */ jsx4(
2443
+ /* @__PURE__ */ jsx5(
1988
2444
  "button",
1989
2445
  {
1990
2446
  onClick: () => handlePageChange(totalPages),
1991
2447
  disabled: currentPage === totalPages,
1992
- className: "inline-flex h-6 w-6 cursor-pointer items-center justify-center text-xs transition-colors disabled:cursor-not-allowed disabled:opacity-30",
2448
+ style: {
2449
+ display: "inline-flex",
2450
+ height: 24,
2451
+ width: 24,
2452
+ cursor: currentPage === totalPages ? "not-allowed" : "pointer",
2453
+ alignItems: "center",
2454
+ justifyContent: "center",
2455
+ fontSize: 12,
2456
+ opacity: currentPage === totalPages ? 0.3 : 1,
2457
+ background: "none",
2458
+ border: "none",
2459
+ padding: 0,
2460
+ color: "inherit"
2461
+ },
1993
2462
  title: "Last page",
1994
- children: /* @__PURE__ */ jsx4(ChevronsRight, { className: "h-3 w-3" })
2463
+ children: icons?.chevronsRight ?? /* @__PURE__ */ jsx5(ChevronsRightIcon, { style: { width: 12, height: 12 } })
1995
2464
  }
1996
2465
  )
1997
- ] }),
1998
- /* @__PURE__ */ jsx4("div", { className: "flex flex-1 items-center justify-end gap-2", children: /* @__PURE__ */ jsx4(
2466
+ ]
2467
+ }
2468
+ ),
2469
+ /* @__PURE__ */ jsx5(
2470
+ "div",
2471
+ {
2472
+ style: {
2473
+ display: "flex",
2474
+ flex: "1 1 0%",
2475
+ alignItems: "center",
2476
+ justifyContent: "flex-end",
2477
+ gap: 8
2478
+ },
2479
+ children: /* @__PURE__ */ jsx5(
1999
2480
  "select",
2000
2481
  {
2001
2482
  value: pageSize,
2002
2483
  onChange: (e) => handlePageSizeChange(Number(e.target.value)),
2003
- className: "bg-background text-foreground hover:border-primary cursor-pointer rounded border px-1.5 py-0.5 text-xs",
2004
- style: { height: "24px" },
2005
- children: [10, 15, 20, 25, 50, 100].map((size) => /* @__PURE__ */ jsxs4("option", { value: size, children: [
2484
+ style: {
2485
+ cursor: "pointer",
2486
+ borderRadius: 4,
2487
+ border: "1px solid rgba(128,128,128,0.2)",
2488
+ paddingLeft: 6,
2489
+ paddingRight: 6,
2490
+ paddingTop: 2,
2491
+ paddingBottom: 2,
2492
+ fontSize: 12,
2493
+ height: 24,
2494
+ background: "inherit",
2495
+ color: "inherit"
2496
+ },
2497
+ children: [10, 15, 20, 25, 50, 100].map((size) => /* @__PURE__ */ jsxs5("option", { value: size, children: [
2006
2498
  size,
2007
2499
  " / page"
2008
2500
  ] }, size))
2009
2501
  }
2010
- ) })
2011
- ]
2012
- }
2013
- )
2014
- ]
2015
- }
2016
- ),
2017
- /* @__PURE__ */ jsx4(DragOverlay, { children: activeColumn ? /* @__PURE__ */ jsx4(
2018
- "div",
2019
- {
2020
- className: `flex h-9 items-center truncate overflow-hidden border border-dashed shadow-md backdrop-blur ${classNames.header ?? ""} ${classNames.dragHeader ?? ""}`,
2021
- style: {
2022
- width: `${activeColumn.width ?? 150}px`,
2023
- cursor: "grabbing",
2024
- ...styles.header,
2025
- ...styles.dragHeader
2026
- },
2027
- children: /* @__PURE__ */ jsxs4("div", { className: "relative z-10 flex h-full flex-1 items-center gap-1 truncate overflow-hidden px-2 font-medium", children: [
2028
- /* @__PURE__ */ jsx4(GripVertical2, { className: "h-3 w-3 shrink-0" }),
2029
- /* @__PURE__ */ jsx4("div", { className: "min-w-0 truncate overflow-hidden text-left text-ellipsis whitespace-nowrap select-none", children: typeof activeColumn.title === "string" ? activeColumn.title : activeColumn.key })
2030
- ] })
2031
- }
2032
- ) : null })
2033
- ]
2034
- }
2035
- );
2502
+ )
2503
+ }
2504
+ )
2505
+ ]
2506
+ }
2507
+ )
2508
+ ]
2509
+ }
2510
+ ),
2511
+ typeof document !== "undefined" && createPortal2(
2512
+ /* @__PURE__ */ jsx5(
2513
+ "div",
2514
+ {
2515
+ ref: ghostRef,
2516
+ className: `${classNames.header ?? ""} ${classNames.dragHeader ?? ""}`,
2517
+ style: {
2518
+ display: "none",
2519
+ position: "fixed",
2520
+ zIndex: 99999,
2521
+ height: 36,
2522
+ alignItems: "center",
2523
+ overflow: "hidden",
2524
+ textOverflow: "ellipsis",
2525
+ whiteSpace: "nowrap",
2526
+ borderRadius: 6,
2527
+ border: "1px dashed rgba(128,128,128,0.3)",
2528
+ boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
2529
+ backdropFilter: "blur(16px)",
2530
+ WebkitBackdropFilter: "blur(16px)",
2531
+ backgroundColor: "rgba(128,128,128,0.12)",
2532
+ cursor: "grabbing",
2533
+ pointerEvents: "none",
2534
+ ...styles.header,
2535
+ ...styles.dragHeader
2536
+ },
2537
+ children: /* @__PURE__ */ jsxs5(
2538
+ "div",
2539
+ {
2540
+ style: {
2541
+ display: "flex",
2542
+ height: "100%",
2543
+ flex: "1 1 0%",
2544
+ alignItems: "center",
2545
+ gap: 4,
2546
+ overflow: "hidden",
2547
+ paddingLeft: 8,
2548
+ paddingRight: 8,
2549
+ fontWeight: 500
2550
+ },
2551
+ children: [
2552
+ icons?.gripVertical ?? gripIcon ?? /* @__PURE__ */ jsx5(
2553
+ GripVerticalIcon,
2554
+ {
2555
+ style: { width: 12, height: 12, flexShrink: 0 }
2556
+ }
2557
+ ),
2558
+ /* @__PURE__ */ jsx5(
2559
+ "div",
2560
+ {
2561
+ style: {
2562
+ minWidth: 0,
2563
+ overflow: "hidden",
2564
+ textOverflow: "ellipsis",
2565
+ whiteSpace: "nowrap",
2566
+ textAlign: "left",
2567
+ userSelect: "none"
2568
+ },
2569
+ children: activeColumn ? typeof activeColumn.title === "string" ? activeColumn.title : activeColumn.key : ""
2570
+ }
2571
+ )
2572
+ ]
2573
+ }
2574
+ )
2575
+ }
2576
+ ),
2577
+ document.body
2578
+ )
2579
+ ] });
2036
2580
  }
2037
2581
  export {
2038
2582
  BoltTable,