@forgedevstack/grid-table 1.0.1 → 1.0.3
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/CHANGELOG.md +37 -0
- package/README.md +33 -5
- package/dist/grid-table.css +1 -0
- package/dist/index.d.mts +134 -103
- package/dist/index.d.ts +134 -103
- package/dist/index.js +881 -415
- package/dist/index.mjs +882 -414
- package/package.json +14 -6
- package/src/grid-table.scss +26 -0
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import "@forgedevstack/bear/styles.css";
|
|
3
|
+
|
|
1
4
|
// src/components/GridTable/GridTable.tsx
|
|
2
|
-
import { useMemo as
|
|
5
|
+
import { useMemo as useMemo11, useCallback as useCallback13, useState as useState8, useEffect as useEffect6 } from "react";
|
|
3
6
|
|
|
4
7
|
// src/context/TableContext.tsx
|
|
5
8
|
import {
|
|
@@ -175,6 +178,10 @@ function reducer(state, action) {
|
|
|
175
178
|
return { ...state, selectedIds: action.payload };
|
|
176
179
|
case "SET_EXPANDED_IDS":
|
|
177
180
|
return { ...state, expandedIds: action.payload };
|
|
181
|
+
case "SET_EXPANDED_CELL_IDS":
|
|
182
|
+
return { ...state, expandedCellIds: action.payload };
|
|
183
|
+
case "SET_AUTO_SIZED_COLUMN_IDS":
|
|
184
|
+
return { ...state, autoSizedColumnIds: action.payload };
|
|
178
185
|
case "SET_COLUMN_STATES":
|
|
179
186
|
return { ...state, columnStates: action.payload };
|
|
180
187
|
case "SET_DRAGGING_COLUMN":
|
|
@@ -212,9 +219,24 @@ function TableProvider({
|
|
|
212
219
|
sortConfig: _sortConfig,
|
|
213
220
|
enableMultiSort = false,
|
|
214
221
|
getRowId,
|
|
215
|
-
onStateChange
|
|
222
|
+
onStateChange,
|
|
223
|
+
showOverflowTooltip = true,
|
|
224
|
+
enableCellAutoSizeOnDoubleClick = false,
|
|
225
|
+
subCellExpandTrigger = "both",
|
|
226
|
+
expandRowOnDoubleClick = false,
|
|
227
|
+
globalFilterColumns = void 0
|
|
216
228
|
}) {
|
|
217
229
|
var _a, _b;
|
|
230
|
+
const tableOptions = useMemo(
|
|
231
|
+
() => ({
|
|
232
|
+
showOverflowTooltip,
|
|
233
|
+
enableCellAutoSizeOnDoubleClick,
|
|
234
|
+
subCellExpandTrigger,
|
|
235
|
+
expandRowOnDoubleClick,
|
|
236
|
+
globalFilterColumns
|
|
237
|
+
}),
|
|
238
|
+
[showOverflowTooltip, enableCellAutoSizeOnDoubleClick, subCellExpandTrigger, expandRowOnDoubleClick, globalFilterColumns]
|
|
239
|
+
);
|
|
218
240
|
const initialColumnStates = columns.map((col, index) => ({
|
|
219
241
|
id: col.id,
|
|
220
242
|
visible: !col.hidden,
|
|
@@ -243,6 +265,8 @@ function TableProvider({
|
|
|
243
265
|
totalItems: data.length,
|
|
244
266
|
selectedIds: /* @__PURE__ */ new Set(),
|
|
245
267
|
expandedIds: /* @__PURE__ */ new Set(),
|
|
268
|
+
expandedCellIds: /* @__PURE__ */ new Set(),
|
|
269
|
+
autoSizedColumnIds: /* @__PURE__ */ new Set(),
|
|
246
270
|
loading,
|
|
247
271
|
error,
|
|
248
272
|
theme: mergedTheme,
|
|
@@ -369,6 +393,25 @@ function TableProvider({
|
|
|
369
393
|
actions.expandRow(id);
|
|
370
394
|
}
|
|
371
395
|
},
|
|
396
|
+
toggleCellExpansion: (rowId, columnId) => {
|
|
397
|
+
const key = `${String(rowId)}-${columnId}`;
|
|
398
|
+
const next = new Set(state.expandedCellIds);
|
|
399
|
+
if (next.has(key)) {
|
|
400
|
+
next.delete(key);
|
|
401
|
+
} else {
|
|
402
|
+
next.add(key);
|
|
403
|
+
}
|
|
404
|
+
dispatch({ type: "SET_EXPANDED_CELL_IDS", payload: next });
|
|
405
|
+
},
|
|
406
|
+
toggleColumnAutoSize: (columnId) => {
|
|
407
|
+
const next = new Set(state.autoSizedColumnIds);
|
|
408
|
+
if (next.has(columnId)) {
|
|
409
|
+
next.delete(columnId);
|
|
410
|
+
} else {
|
|
411
|
+
next.add(columnId);
|
|
412
|
+
}
|
|
413
|
+
dispatch({ type: "SET_AUTO_SIZED_COLUMN_IDS", payload: next });
|
|
414
|
+
},
|
|
372
415
|
reorderColumn: (sourceId, targetId) => {
|
|
373
416
|
const newStates = [...state.columnStates];
|
|
374
417
|
const sourceIndex = newStates.findIndex((c) => c.id === sourceId);
|
|
@@ -407,6 +450,8 @@ function TableProvider({
|
|
|
407
450
|
page: ONE,
|
|
408
451
|
selectedIds: /* @__PURE__ */ new Set(),
|
|
409
452
|
expandedIds: /* @__PURE__ */ new Set(),
|
|
453
|
+
expandedCellIds: /* @__PURE__ */ new Set(),
|
|
454
|
+
autoSizedColumnIds: /* @__PURE__ */ new Set(),
|
|
410
455
|
columnStates: initialColumnStates
|
|
411
456
|
}
|
|
412
457
|
})
|
|
@@ -417,11 +462,15 @@ function TableProvider({
|
|
|
417
462
|
let filteredData = [...state.data];
|
|
418
463
|
if (state.globalFilter) {
|
|
419
464
|
const searchLower = state.globalFilter.toLowerCase();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
)
|
|
424
|
-
|
|
465
|
+
const columnIds = tableOptions.globalFilterColumns;
|
|
466
|
+
filteredData = filteredData.filter((row) => {
|
|
467
|
+
const colsToSearch = columnIds && columnIds.length > 0 ? state.columns.filter((c) => columnIds.includes(c.id)) : state.columns;
|
|
468
|
+
return colsToSearch.some((col) => {
|
|
469
|
+
const accessor = col.accessor;
|
|
470
|
+
const value = typeof accessor === "function" ? accessor(row) : row[accessor];
|
|
471
|
+
return String(value != null ? value : "").toLowerCase().includes(searchLower);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
425
474
|
}
|
|
426
475
|
state.filters.forEach((filter) => {
|
|
427
476
|
const column = columns.find((c) => c.id === filter.columnId);
|
|
@@ -507,10 +556,11 @@ function TableProvider({
|
|
|
507
556
|
isTablet,
|
|
508
557
|
isDesktop
|
|
509
558
|
};
|
|
510
|
-
}, [state, columns]);
|
|
559
|
+
}, [state, columns, tableOptions]);
|
|
511
560
|
const contextValue = {
|
|
512
561
|
state,
|
|
513
562
|
actions,
|
|
563
|
+
tableOptions,
|
|
514
564
|
computed
|
|
515
565
|
};
|
|
516
566
|
return /* @__PURE__ */ jsx(TableContext.Provider, { value: contextValue, children });
|
|
@@ -999,6 +1049,7 @@ function useTable() {
|
|
|
999
1049
|
|
|
1000
1050
|
// src/components/GridHeader/GridHeader.tsx
|
|
1001
1051
|
import { useMemo as useMemo8, useCallback as useCallback7, useState as useState4, useRef as useRef3 } from "react";
|
|
1052
|
+
import { Checkbox } from "@forgedevstack/bear";
|
|
1002
1053
|
|
|
1003
1054
|
// src/components/FilterPopup/FilterPopup.tsx
|
|
1004
1055
|
import { useState as useState3, useCallback as useCallback6, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
@@ -1082,7 +1133,7 @@ function FilterPopup({
|
|
|
1082
1133
|
"div",
|
|
1083
1134
|
{
|
|
1084
1135
|
ref: popupRef,
|
|
1085
|
-
className: `filter-popup
|
|
1136
|
+
className: `filter-popup ${className}`,
|
|
1086
1137
|
style: {
|
|
1087
1138
|
top: (_a = position == null ? void 0 : position.top) != null ? _a : "100%",
|
|
1088
1139
|
left: (_b = position == null ? void 0 : position.left) != null ? _b : 0,
|
|
@@ -1090,44 +1141,44 @@ function FilterPopup({
|
|
|
1090
1141
|
...style
|
|
1091
1142
|
},
|
|
1092
1143
|
children: [
|
|
1093
|
-
/* @__PURE__ */ jsx2("div", { className: "filter-popup-header
|
|
1094
|
-
/* @__PURE__ */ jsx2("span", { className: "
|
|
1144
|
+
/* @__PURE__ */ jsx2("div", { className: "filter-popup-header", children: /* @__PURE__ */ jsxs("div", { className: "header-content", children: [
|
|
1145
|
+
/* @__PURE__ */ jsx2("span", { className: "header-title", children: columnHeader }),
|
|
1095
1146
|
/* @__PURE__ */ jsx2(
|
|
1096
1147
|
"button",
|
|
1097
1148
|
{
|
|
1098
1149
|
onClick: onClose,
|
|
1099
|
-
className: "
|
|
1150
|
+
className: "header-close",
|
|
1100
1151
|
"aria-label": "Close",
|
|
1101
|
-
children: /* @__PURE__ */ jsx2("svg", { className: "
|
|
1152
|
+
children: /* @__PURE__ */ jsx2("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1102
1153
|
}
|
|
1103
1154
|
)
|
|
1104
1155
|
] }) }),
|
|
1105
|
-
/* @__PURE__ */ jsx2("div", { className: "filter-popup-body
|
|
1156
|
+
/* @__PURE__ */ jsx2("div", { className: "filter-popup-body", children: filterType === "select" && filterOptions ? /* @__PURE__ */ jsxs(
|
|
1106
1157
|
"select",
|
|
1107
1158
|
{
|
|
1108
1159
|
value: String(value),
|
|
1109
1160
|
onChange: (e) => setValue(e.target.value),
|
|
1110
|
-
className: "w-full px-3 py-2 text-sm rounded
|
|
1161
|
+
className: "w-full px-3 py-2 text-sm rounded",
|
|
1111
1162
|
children: [
|
|
1112
1163
|
/* @__PURE__ */ jsx2("option", { value: "", children: "Select..." }),
|
|
1113
1164
|
filterOptions.map((opt) => /* @__PURE__ */ jsx2("option", { value: String(opt.value), children: opt.label }, String(opt.value)))
|
|
1114
1165
|
]
|
|
1115
1166
|
}
|
|
1116
1167
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1117
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1118
|
-
/* @__PURE__ */ jsx2("label", {
|
|
1168
|
+
/* @__PURE__ */ jsxs("div", { className: "filter-field", children: [
|
|
1169
|
+
/* @__PURE__ */ jsx2("label", { children: "Operator" }),
|
|
1119
1170
|
/* @__PURE__ */ jsx2(
|
|
1120
1171
|
"select",
|
|
1121
1172
|
{
|
|
1122
1173
|
value: operator,
|
|
1123
1174
|
onChange: (e) => setOperator(e.target.value),
|
|
1124
|
-
className: "w-full px-3 py-2 text-sm rounded
|
|
1175
|
+
className: "w-full px-3 py-2 text-sm rounded",
|
|
1125
1176
|
children: operators.map((op) => /* @__PURE__ */ jsx2("option", { value: op, children: OPERATOR_LABELS[op] }, op))
|
|
1126
1177
|
}
|
|
1127
1178
|
)
|
|
1128
1179
|
] }),
|
|
1129
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1130
|
-
/* @__PURE__ */ jsx2("label", {
|
|
1180
|
+
/* @__PURE__ */ jsxs("div", { className: "filter-field", children: [
|
|
1181
|
+
/* @__PURE__ */ jsx2("label", { children: "Value" }),
|
|
1131
1182
|
/* @__PURE__ */ jsx2(
|
|
1132
1183
|
"input",
|
|
1133
1184
|
{
|
|
@@ -1136,18 +1187,18 @@ function FilterPopup({
|
|
|
1136
1187
|
onChange: (e) => setValue(e.target.value),
|
|
1137
1188
|
onKeyDown: handleKeyDown,
|
|
1138
1189
|
placeholder: `Filter ${columnHeader}...`,
|
|
1139
|
-
className: "w-full px-3 py-2 text-sm rounded
|
|
1190
|
+
className: "w-full px-3 py-2 text-sm rounded",
|
|
1140
1191
|
autoFocus: true
|
|
1141
1192
|
}
|
|
1142
1193
|
)
|
|
1143
1194
|
] })
|
|
1144
1195
|
] }) }),
|
|
1145
|
-
/* @__PURE__ */ jsxs("div", { className: "filter-popup-footer
|
|
1196
|
+
/* @__PURE__ */ jsxs("div", { className: "filter-popup-footer", children: [
|
|
1146
1197
|
/* @__PURE__ */ jsx2(
|
|
1147
1198
|
"button",
|
|
1148
1199
|
{
|
|
1149
1200
|
onClick: handleClear,
|
|
1150
|
-
className: "
|
|
1201
|
+
className: "filter-clear",
|
|
1151
1202
|
children: translations.clearFilter
|
|
1152
1203
|
}
|
|
1153
1204
|
),
|
|
@@ -1155,7 +1206,7 @@ function FilterPopup({
|
|
|
1155
1206
|
"button",
|
|
1156
1207
|
{
|
|
1157
1208
|
onClick: handleApply,
|
|
1158
|
-
className: "
|
|
1209
|
+
className: "filter-apply",
|
|
1159
1210
|
children: translations.apply
|
|
1160
1211
|
}
|
|
1161
1212
|
)
|
|
@@ -1170,7 +1221,7 @@ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
|
1170
1221
|
var FilterIcon = ({ active = false }) => /* @__PURE__ */ jsx3(
|
|
1171
1222
|
"svg",
|
|
1172
1223
|
{
|
|
1173
|
-
className: `
|
|
1224
|
+
className: `icon-sm ${active ? "text-accent-primary" : "text-theme-muted"}`,
|
|
1174
1225
|
fill: "none",
|
|
1175
1226
|
viewBox: "0 0 24 24",
|
|
1176
1227
|
stroke: "currentColor",
|
|
@@ -1188,7 +1239,7 @@ var FilterIcon = ({ active = false }) => /* @__PURE__ */ jsx3(
|
|
|
1188
1239
|
var SortIcon = ({ direction }) => /* @__PURE__ */ jsx3(
|
|
1189
1240
|
"svg",
|
|
1190
1241
|
{
|
|
1191
|
-
className: `
|
|
1242
|
+
className: `icon-sm ${direction ? "text-accent-primary" : "text-theme-muted"}`,
|
|
1192
1243
|
fill: "none",
|
|
1193
1244
|
viewBox: "0 0 24 24",
|
|
1194
1245
|
stroke: "currentColor",
|
|
@@ -1214,6 +1265,7 @@ function HeaderCell({
|
|
|
1214
1265
|
hasFilter = false,
|
|
1215
1266
|
isDragging = false,
|
|
1216
1267
|
isDragOver = false,
|
|
1268
|
+
isColumnAutoSized = false,
|
|
1217
1269
|
onSort,
|
|
1218
1270
|
onFilterOpen,
|
|
1219
1271
|
onResizeStart,
|
|
@@ -1245,56 +1297,53 @@ function HeaderCell({
|
|
|
1245
1297
|
const cellClasses = useMemo8(() => {
|
|
1246
1298
|
const classes = [
|
|
1247
1299
|
"grid-header-cell",
|
|
1248
|
-
"relative",
|
|
1249
|
-
"flex",
|
|
1250
|
-
"items-center",
|
|
1251
|
-
"gap-2",
|
|
1252
|
-
"px-4",
|
|
1253
|
-
"py-3",
|
|
1254
|
-
"font-medium",
|
|
1255
|
-
"text-sm",
|
|
1256
|
-
"text-theme-secondary",
|
|
1257
|
-
"select-none",
|
|
1258
|
-
"border-b",
|
|
1259
|
-
"border-theme-border",
|
|
1260
|
-
"transition-colors",
|
|
1261
1300
|
ALIGN_CLASSES[column.align || "left"]
|
|
1262
1301
|
];
|
|
1263
1302
|
if (isSortable) {
|
|
1264
|
-
classes.push("cursor-pointer"
|
|
1303
|
+
classes.push("cursor-pointer");
|
|
1265
1304
|
}
|
|
1266
1305
|
if (isDragging) {
|
|
1267
1306
|
classes.push("opacity-50");
|
|
1268
1307
|
}
|
|
1269
1308
|
if (isDragOver) {
|
|
1270
|
-
classes.push("bg-accent-primary/10"
|
|
1309
|
+
classes.push("bg-accent-primary/10");
|
|
1271
1310
|
}
|
|
1272
1311
|
return classes.join(" ");
|
|
1273
1312
|
}, [column.align, isSortable, isDragging, isDragOver]);
|
|
1313
|
+
const cellStyle = useMemo8(() => {
|
|
1314
|
+
const base = {
|
|
1315
|
+
flexShrink: 0,
|
|
1316
|
+
...column.sticky && {
|
|
1317
|
+
position: "sticky",
|
|
1318
|
+
[column.sticky]: 0,
|
|
1319
|
+
zIndex: 2,
|
|
1320
|
+
backgroundColor: "var(--gt-bg-secondary, #2b2b2b)"
|
|
1321
|
+
},
|
|
1322
|
+
...column.headerStyle
|
|
1323
|
+
};
|
|
1324
|
+
if (isColumnAutoSized) {
|
|
1325
|
+
base.width = "auto";
|
|
1326
|
+
base.minWidth = "max-content";
|
|
1327
|
+
base.maxWidth = "none";
|
|
1328
|
+
} else {
|
|
1329
|
+
base.width = typeof columnState.width === "number" ? `${columnState.width}px` : columnState.width;
|
|
1330
|
+
base.minWidth = column.minWidth || MIN_COLUMN_WIDTH;
|
|
1331
|
+
base.maxWidth = column.maxWidth || MAX_COLUMN_WIDTH;
|
|
1332
|
+
}
|
|
1333
|
+
return base;
|
|
1334
|
+
}, [column, columnState.width, isColumnAutoSized]);
|
|
1274
1335
|
return /* @__PURE__ */ jsxs2(
|
|
1275
1336
|
"div",
|
|
1276
1337
|
{
|
|
1277
|
-
className: `${cellClasses} ${column.headerClassName || ""} ${column.sticky ?
|
|
1278
|
-
style:
|
|
1279
|
-
width: columnState.width,
|
|
1280
|
-
minWidth: column.minWidth || MIN_COLUMN_WIDTH,
|
|
1281
|
-
maxWidth: column.maxWidth || MAX_COLUMN_WIDTH,
|
|
1282
|
-
flexShrink: 0,
|
|
1283
|
-
...column.sticky && {
|
|
1284
|
-
position: "sticky",
|
|
1285
|
-
[column.sticky]: 0,
|
|
1286
|
-
zIndex: 2,
|
|
1287
|
-
backgroundColor: "var(--bg-secondary, #2b2b2b)"
|
|
1288
|
-
},
|
|
1289
|
-
...column.headerStyle
|
|
1290
|
-
},
|
|
1338
|
+
className: `${cellClasses} ${column.headerClassName || ""} ${column.sticky ? `sticky-${column.sticky}` : ""}`,
|
|
1339
|
+
style: cellStyle,
|
|
1291
1340
|
role: "columnheader",
|
|
1292
1341
|
"aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : "none",
|
|
1293
1342
|
onClick: handleClick,
|
|
1294
1343
|
...isDraggable ? { ...dragHandleProps, ...dropTargetProps } : {},
|
|
1295
1344
|
children: [
|
|
1296
|
-
/* @__PURE__ */ jsx3("span", { className: "grid-header-content
|
|
1297
|
-
isSortable && /* @__PURE__ */ jsxs2("span", { className: "grid-header-sort
|
|
1345
|
+
/* @__PURE__ */ jsx3("span", { className: "grid-header-content", children: headerContent }),
|
|
1346
|
+
isSortable && /* @__PURE__ */ jsxs2("span", { className: "grid-header-sort", children: [
|
|
1298
1347
|
/* @__PURE__ */ jsx3(SortIcon, { direction: sortDirection != null ? sortDirection : null }),
|
|
1299
1348
|
isMultiSort && sortIndex !== void 0 && sortIndex >= 0 && sortDirection && /* @__PURE__ */ jsx3("span", { className: "text-xs text-theme-muted", children: sortIndex + 1 })
|
|
1300
1349
|
] }),
|
|
@@ -1302,7 +1351,7 @@ function HeaderCell({
|
|
|
1302
1351
|
"button",
|
|
1303
1352
|
{
|
|
1304
1353
|
onClick: handleFilterClick,
|
|
1305
|
-
className: "grid-header-filter
|
|
1354
|
+
className: "grid-header-filter",
|
|
1306
1355
|
"aria-label": "Filter column",
|
|
1307
1356
|
children: /* @__PURE__ */ jsx3(FilterIcon, { active: hasFilter })
|
|
1308
1357
|
}
|
|
@@ -1310,7 +1359,7 @@ function HeaderCell({
|
|
|
1310
1359
|
isResizable && /* @__PURE__ */ jsx3(
|
|
1311
1360
|
"div",
|
|
1312
1361
|
{
|
|
1313
|
-
className: "grid-header-resize
|
|
1362
|
+
className: "grid-header-resize",
|
|
1314
1363
|
onMouseDown: onResizeStart,
|
|
1315
1364
|
onClick: (e) => e.stopPropagation()
|
|
1316
1365
|
}
|
|
@@ -1330,6 +1379,7 @@ function GridHeader({
|
|
|
1330
1379
|
enableDragDrop = true,
|
|
1331
1380
|
enableResize = true,
|
|
1332
1381
|
enableSelection = false,
|
|
1382
|
+
enableExpansion = false,
|
|
1333
1383
|
allSelected = false,
|
|
1334
1384
|
someSelected = false,
|
|
1335
1385
|
onSelectAll,
|
|
@@ -1401,19 +1451,17 @@ function GridHeader({
|
|
|
1401
1451
|
return classes.join(" ");
|
|
1402
1452
|
}, [sticky]);
|
|
1403
1453
|
return /* @__PURE__ */ jsxs2("div", { className: `${headerClasses} ${className}`, style, role: "row", children: [
|
|
1404
|
-
enableSelection && /* @__PURE__ */ jsx3("div", { className: "grid-header-select
|
|
1405
|
-
|
|
1454
|
+
enableSelection && /* @__PURE__ */ jsx3("div", { className: "grid-header-select", children: /* @__PURE__ */ jsx3(
|
|
1455
|
+
Checkbox,
|
|
1406
1456
|
{
|
|
1407
|
-
type: "checkbox",
|
|
1408
1457
|
checked: allSelected,
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
onChange: onSelectAll,
|
|
1413
|
-
className: "w-4 h-4 rounded border-theme-border",
|
|
1458
|
+
indeterminate: someSelected && !allSelected,
|
|
1459
|
+
onChange: () => onSelectAll == null ? void 0 : onSelectAll(),
|
|
1460
|
+
size: "sm",
|
|
1414
1461
|
"aria-label": "Select all rows"
|
|
1415
1462
|
}
|
|
1416
1463
|
) }),
|
|
1464
|
+
enableExpansion && /* @__PURE__ */ jsx3("div", { className: "grid-header-expand-spacer", "aria-hidden": true }),
|
|
1417
1465
|
visibleColumns.map((col, index) => {
|
|
1418
1466
|
const colState = columnStates.find((cs) => cs.id === col.id) || {
|
|
1419
1467
|
id: col.id,
|
|
@@ -1427,7 +1475,7 @@ function GridHeader({
|
|
|
1427
1475
|
const hasFilter = state.filters.some((f) => f.columnId === col.id);
|
|
1428
1476
|
const existingFilter = state.filters.find((f) => f.columnId === col.id);
|
|
1429
1477
|
const headerText = typeof col.header === "string" ? col.header : col.id;
|
|
1430
|
-
return /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
1478
|
+
return /* @__PURE__ */ jsxs2("div", { className: "relative", style: { position: "relative" }, children: [
|
|
1431
1479
|
/* @__PURE__ */ jsx3(
|
|
1432
1480
|
HeaderCell,
|
|
1433
1481
|
{
|
|
@@ -1443,6 +1491,7 @@ function GridHeader({
|
|
|
1443
1491
|
hasFilter,
|
|
1444
1492
|
isDragging: dragDrop.draggingColumnId === col.id,
|
|
1445
1493
|
isDragOver: dragDrop.dragOverColumnId === col.id,
|
|
1494
|
+
isColumnAutoSized: state.autoSizedColumnIds.has(col.id),
|
|
1446
1495
|
onSort: () => actions.toggleSorting(col.id),
|
|
1447
1496
|
onFilterOpen: () => handleFilterClick(col.id),
|
|
1448
1497
|
onResizeStart: handleResizeStart(col.id, colState.width),
|
|
@@ -1473,11 +1522,59 @@ function GridHeader({
|
|
|
1473
1522
|
import { useCallback as useCallback10 } from "react";
|
|
1474
1523
|
|
|
1475
1524
|
// src/components/GridRow/GridRow.tsx
|
|
1476
|
-
import { useCallback as useCallback9, useMemo as useMemo10, useState as
|
|
1525
|
+
import { useCallback as useCallback9, useMemo as useMemo10, useState as useState6 } from "react";
|
|
1526
|
+
import { Checkbox as Checkbox2 } from "@forgedevstack/bear";
|
|
1477
1527
|
|
|
1478
1528
|
// src/components/GridCell/GridCell.tsx
|
|
1479
|
-
import { useMemo as useMemo9, useCallback as useCallback8 } from "react";
|
|
1480
|
-
import {
|
|
1529
|
+
import { useMemo as useMemo9, useCallback as useCallback8, useRef as useRef4, useEffect as useEffect4, useState as useState5 } from "react";
|
|
1530
|
+
import { Tooltip, Typography } from "@forgedevstack/bear";
|
|
1531
|
+
|
|
1532
|
+
// src/utils/highlight.utils.tsx
|
|
1533
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1534
|
+
function highlightMatch(text, term) {
|
|
1535
|
+
if (!term.trim()) return text;
|
|
1536
|
+
const parts = text.split(new RegExp(`(${escapeRegex(term)})`, "gi"));
|
|
1537
|
+
return parts.map(
|
|
1538
|
+
(part, i) => part.toLowerCase() === term.toLowerCase() ? /* @__PURE__ */ jsx4("mark", { className: "grid-cell-highlight", children: part }, i) : part
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
function escapeRegex(s) {
|
|
1542
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// src/utils/generateSampleData.ts
|
|
1546
|
+
function generateSampleData(columns, rowCount) {
|
|
1547
|
+
const ids = columns.map((c) => c.id);
|
|
1548
|
+
return Array.from({ length: rowCount }, (_, i) => {
|
|
1549
|
+
const row = {};
|
|
1550
|
+
ids.forEach((key) => {
|
|
1551
|
+
if (key === "id" || key === "idNumber") {
|
|
1552
|
+
row[key] = i + 1;
|
|
1553
|
+
} else if (key === "email") {
|
|
1554
|
+
row[key] = `user${i + 1}@example.com`;
|
|
1555
|
+
} else if (key === "name" || key === "firstName" || key === "title") {
|
|
1556
|
+
row[key] = `Sample ${i + 1}`;
|
|
1557
|
+
} else if (key === "status" || key === "role") {
|
|
1558
|
+
row[key] = ["active", "inactive", "pending"][i % 3];
|
|
1559
|
+
} else if (key === "date" || key === "joinDate" || key === "createdAt") {
|
|
1560
|
+
row[key] = new Date(2020 + i % 4, i % 12, i % 28 + 1).toISOString().slice(0, 10);
|
|
1561
|
+
} else if (key === "salary" || key === "amount" || key === "count") {
|
|
1562
|
+
row[key] = 1e3 * (i + 1) + i % 100;
|
|
1563
|
+
} else if (key === "department") {
|
|
1564
|
+
row[key] = ["Engineering", "Design", "Marketing", "Sales", "HR"][i % 5];
|
|
1565
|
+
} else {
|
|
1566
|
+
row[key] = `Value ${i + 1}`;
|
|
1567
|
+
}
|
|
1568
|
+
});
|
|
1569
|
+
if (!("id" in row) && ids.length > 0) {
|
|
1570
|
+
row.id = i + 1;
|
|
1571
|
+
}
|
|
1572
|
+
return row;
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// src/components/GridCell/GridCell.tsx
|
|
1577
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1481
1578
|
var ALIGN_CLASSES2 = {
|
|
1482
1579
|
left: "text-left justify-start",
|
|
1483
1580
|
center: "text-center justify-center",
|
|
@@ -1487,6 +1584,7 @@ function GridCell({
|
|
|
1487
1584
|
column,
|
|
1488
1585
|
row,
|
|
1489
1586
|
rowIndex,
|
|
1587
|
+
rowId,
|
|
1490
1588
|
value,
|
|
1491
1589
|
width,
|
|
1492
1590
|
align = "left",
|
|
@@ -1498,20 +1596,18 @@ function GridCell({
|
|
|
1498
1596
|
stickyOffset = 0,
|
|
1499
1597
|
onClick
|
|
1500
1598
|
}) {
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
[onClick, row, rowIndex, column.id, value]
|
|
1514
|
-
);
|
|
1599
|
+
var _a, _b, _c;
|
|
1600
|
+
const valueRef = useRef4(null);
|
|
1601
|
+
const [overflowTitle, setOverflowTitle] = useState5(void 0);
|
|
1602
|
+
const { state, actions, tableOptions } = useTableContext();
|
|
1603
|
+
const showOverflowTooltip = ((_a = column.showOverflowTooltip) != null ? _a : tableOptions.showOverflowTooltip) !== false;
|
|
1604
|
+
const hasSubCell = Boolean(column.renderSubCell);
|
|
1605
|
+
const trigger = (_c = (_b = column.subCellExpandTrigger) != null ? _b : tableOptions.subCellExpandTrigger) != null ? _c : "both";
|
|
1606
|
+
const showArrow = hasSubCell && (trigger === "arrow" || trigger === "both");
|
|
1607
|
+
const enableCellAutoSize = tableOptions.enableCellAutoSizeOnDoubleClick === true;
|
|
1608
|
+
const cellKey = `${String(rowId)}-${column.id}`;
|
|
1609
|
+
const isSubCellExpanded = state.expandedCellIds.has(cellKey);
|
|
1610
|
+
const isAutoSized = state.autoSizedColumnIds.has(column.id);
|
|
1515
1611
|
const formattedValue = useMemo9(() => {
|
|
1516
1612
|
if (column.render) {
|
|
1517
1613
|
return column.render(value, row, rowIndex);
|
|
@@ -1527,9 +1623,53 @@ function GridCell({
|
|
|
1527
1623
|
}
|
|
1528
1624
|
return String(value);
|
|
1529
1625
|
}, [column, row, rowIndex, value]);
|
|
1626
|
+
useEffect4(() => {
|
|
1627
|
+
var _a2;
|
|
1628
|
+
if (!showOverflowTooltip || !valueRef.current) return;
|
|
1629
|
+
const el = valueRef.current;
|
|
1630
|
+
const truncated = el.scrollWidth > el.clientWidth;
|
|
1631
|
+
const raw = (_a2 = el.textContent) != null ? _a2 : "";
|
|
1632
|
+
setOverflowTitle(truncated && raw ? raw : void 0);
|
|
1633
|
+
}, [showOverflowTooltip, formattedValue]);
|
|
1634
|
+
const handleClick = useCallback8(
|
|
1635
|
+
(e) => {
|
|
1636
|
+
if (onClick) {
|
|
1637
|
+
e.stopPropagation();
|
|
1638
|
+
onClick({
|
|
1639
|
+
row,
|
|
1640
|
+
rowIndex,
|
|
1641
|
+
columnId: column.id,
|
|
1642
|
+
value
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
},
|
|
1646
|
+
[onClick, row, rowIndex, column.id, value]
|
|
1647
|
+
);
|
|
1648
|
+
const handleDoubleClick = useCallback8(
|
|
1649
|
+
(e) => {
|
|
1650
|
+
e.stopPropagation();
|
|
1651
|
+
if (hasSubCell && (trigger === "doubleClick" || trigger === "both")) {
|
|
1652
|
+
actions.toggleCellExpansion(rowId, column.id);
|
|
1653
|
+
} else if (enableCellAutoSize) {
|
|
1654
|
+
actions.toggleColumnAutoSize(column.id);
|
|
1655
|
+
}
|
|
1656
|
+
},
|
|
1657
|
+
[hasSubCell, trigger, enableCellAutoSize, actions, rowId, column.id]
|
|
1658
|
+
);
|
|
1659
|
+
const handleExpandClick = useCallback8(
|
|
1660
|
+
(e) => {
|
|
1661
|
+
e.stopPropagation();
|
|
1662
|
+
actions.toggleCellExpansion(rowId, column.id);
|
|
1663
|
+
},
|
|
1664
|
+
[actions, rowId, column.id]
|
|
1665
|
+
);
|
|
1530
1666
|
const cellStyle = useMemo9(() => {
|
|
1531
1667
|
const baseStyle = { ...style };
|
|
1532
|
-
if (
|
|
1668
|
+
if (isAutoSized) {
|
|
1669
|
+
baseStyle.width = "auto";
|
|
1670
|
+
baseStyle.minWidth = "max-content";
|
|
1671
|
+
baseStyle.maxWidth = "none";
|
|
1672
|
+
} else if (width !== void 0) {
|
|
1533
1673
|
baseStyle.width = typeof width === "number" ? `${width}px` : width;
|
|
1534
1674
|
baseStyle.minWidth = baseStyle.width;
|
|
1535
1675
|
baseStyle.maxWidth = baseStyle.width;
|
|
@@ -1537,7 +1677,7 @@ function GridCell({
|
|
|
1537
1677
|
if (sticky) {
|
|
1538
1678
|
baseStyle.position = "sticky";
|
|
1539
1679
|
baseStyle.zIndex = 1;
|
|
1540
|
-
baseStyle.backgroundColor = "var(--bg-primary, #1e1e1e)";
|
|
1680
|
+
baseStyle.backgroundColor = "var(--gt-bg-primary, #1e1e1e)";
|
|
1541
1681
|
if (sticky === "left") {
|
|
1542
1682
|
baseStyle.left = stickyOffset;
|
|
1543
1683
|
} else if (sticky === "right") {
|
|
@@ -1545,38 +1685,68 @@ function GridCell({
|
|
|
1545
1685
|
}
|
|
1546
1686
|
}
|
|
1547
1687
|
return baseStyle;
|
|
1548
|
-
}, [style, width, sticky, stickyOffset]);
|
|
1688
|
+
}, [style, width, sticky, stickyOffset, isAutoSized]);
|
|
1549
1689
|
const alignClass = ALIGN_CLASSES2[align];
|
|
1550
|
-
const
|
|
1690
|
+
const stickyClass = sticky ? `sticky-${sticky}` : "";
|
|
1691
|
+
const shouldHighlight = state.globalFilter && typeof formattedValue === "string" && (!tableOptions.globalFilterColumns || tableOptions.globalFilterColumns.length === 0 || tableOptions.globalFilterColumns.includes(column.id));
|
|
1692
|
+
const cellContent = shouldHighlight ? highlightMatch(String(formattedValue), state.globalFilter) : formattedValue;
|
|
1551
1693
|
return /* @__PURE__ */ jsxs3(
|
|
1552
1694
|
"div",
|
|
1553
1695
|
{
|
|
1554
1696
|
className: `
|
|
1555
1697
|
grid-cell
|
|
1556
|
-
px-4 py-3
|
|
1557
|
-
flex items-center
|
|
1558
1698
|
${alignClass}
|
|
1559
|
-
${
|
|
1560
|
-
${onClick ? "cursor-pointer
|
|
1699
|
+
${stickyClass}
|
|
1700
|
+
${onClick ? "cursor-pointer" : ""}
|
|
1701
|
+
${hasSubCell ? "grid-cell--has-sub" : ""}
|
|
1702
|
+
${isAutoSized ? "grid-cell--auto-sized" : ""}
|
|
1561
1703
|
${column.cellClassName || ""}
|
|
1562
1704
|
${className}
|
|
1563
1705
|
`.trim(),
|
|
1564
1706
|
style: { ...cellStyle, ...column.cellStyle },
|
|
1565
1707
|
role: "cell",
|
|
1566
1708
|
onClick: onClick ? handleClick : void 0,
|
|
1709
|
+
onDoubleClick: handleDoubleClick,
|
|
1567
1710
|
children: [
|
|
1568
|
-
|
|
1569
|
-
labelText,
|
|
1570
|
-
|
|
1711
|
+
/* @__PURE__ */ jsxs3("div", { className: "grid-cell-inner", children: [
|
|
1712
|
+
showLabel && labelText && /* @__PURE__ */ jsxs3(Typography, { component: "span", variant: "body2", color: "secondary", className: "grid-cell-label", children: [
|
|
1713
|
+
labelText,
|
|
1714
|
+
":"
|
|
1715
|
+
] }),
|
|
1716
|
+
/* @__PURE__ */ jsx5("div", { className: "grid-cell-value-wrapper", style: { minWidth: 0, overflow: "hidden" }, children: overflowTitle ? /* @__PURE__ */ jsx5(Tooltip, { content: overflowTitle, placement: "top", delay: 200, children: /* @__PURE__ */ jsx5(
|
|
1717
|
+
"span",
|
|
1718
|
+
{
|
|
1719
|
+
ref: valueRef,
|
|
1720
|
+
className: `grid-cell-value ${isAutoSized ? "" : "grid-cell-value--truncate"}`,
|
|
1721
|
+
children: /* @__PURE__ */ jsx5(Typography, { component: "span", variant: "body2", className: "grid-cell-value-text", children: cellContent })
|
|
1722
|
+
}
|
|
1723
|
+
) }) : /* @__PURE__ */ jsx5(
|
|
1724
|
+
"span",
|
|
1725
|
+
{
|
|
1726
|
+
ref: valueRef,
|
|
1727
|
+
className: `grid-cell-value ${isAutoSized ? "" : "grid-cell-value--truncate"}`,
|
|
1728
|
+
children: /* @__PURE__ */ jsx5(Typography, { component: "span", variant: "body2", children: cellContent })
|
|
1729
|
+
}
|
|
1730
|
+
) }),
|
|
1731
|
+
showArrow && /* @__PURE__ */ jsx5(
|
|
1732
|
+
"button",
|
|
1733
|
+
{
|
|
1734
|
+
type: "button",
|
|
1735
|
+
className: `grid-cell-expand-trigger ${isSubCellExpanded ? "grid-cell-expand-trigger--expanded" : ""}`,
|
|
1736
|
+
onClick: handleExpandClick,
|
|
1737
|
+
"aria-label": isSubCellExpanded ? "Collapse" : "Expand",
|
|
1738
|
+
"aria-expanded": isSubCellExpanded
|
|
1739
|
+
}
|
|
1740
|
+
)
|
|
1571
1741
|
] }),
|
|
1572
|
-
/* @__PURE__ */
|
|
1742
|
+
hasSubCell && isSubCellExpanded && column.renderSubCell && /* @__PURE__ */ jsx5("div", { className: "grid-cell-subcell", children: column.renderSubCell(row) })
|
|
1573
1743
|
]
|
|
1574
1744
|
}
|
|
1575
1745
|
);
|
|
1576
1746
|
}
|
|
1577
1747
|
|
|
1578
1748
|
// src/components/GridRow/GridRow.tsx
|
|
1579
|
-
import { Fragment as Fragment2, jsx as
|
|
1749
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1580
1750
|
function GridRow({
|
|
1581
1751
|
row,
|
|
1582
1752
|
rowIndex,
|
|
@@ -1600,7 +1770,7 @@ function GridRow({
|
|
|
1600
1770
|
renderExpansion,
|
|
1601
1771
|
getRowId
|
|
1602
1772
|
}) {
|
|
1603
|
-
const [isHovered, setIsHovered] =
|
|
1773
|
+
const [isHovered, setIsHovered] = useState6(false);
|
|
1604
1774
|
const handleClick = useCallback9(() => {
|
|
1605
1775
|
if (isDisabled) return;
|
|
1606
1776
|
onClick == null ? void 0 : onClick(row, rowIndex);
|
|
@@ -1616,10 +1786,13 @@ function GridRow({
|
|
|
1616
1786
|
},
|
|
1617
1787
|
[onContextMenu, row, rowIndex, isDisabled]
|
|
1618
1788
|
);
|
|
1619
|
-
const handleSelectChange = useCallback9(
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1789
|
+
const handleSelectChange = useCallback9(
|
|
1790
|
+
(selected) => {
|
|
1791
|
+
if (isDisabled) return;
|
|
1792
|
+
onSelect == null ? void 0 : onSelect(selected);
|
|
1793
|
+
},
|
|
1794
|
+
[onSelect, isDisabled]
|
|
1795
|
+
);
|
|
1623
1796
|
const handleExpandToggle = useCallback9(() => {
|
|
1624
1797
|
if (isDisabled) return;
|
|
1625
1798
|
onExpand == null ? void 0 : onExpand(!isExpanded);
|
|
@@ -1688,26 +1861,25 @@ function GridRow({
|
|
|
1688
1861
|
onMouseEnter: () => setIsHovered(true),
|
|
1689
1862
|
onMouseLeave: () => setIsHovered(false),
|
|
1690
1863
|
children: [
|
|
1691
|
-
enableSelection && /* @__PURE__ */
|
|
1692
|
-
|
|
1864
|
+
enableSelection && /* @__PURE__ */ jsx6("div", { className: "grid-row-select", children: /* @__PURE__ */ jsx6(
|
|
1865
|
+
Checkbox2,
|
|
1693
1866
|
{
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
onChange: handleSelectChange,
|
|
1867
|
+
checked: isSelected != null ? isSelected : false,
|
|
1868
|
+
onChange: (e) => handleSelectChange(e.target.checked),
|
|
1697
1869
|
disabled: isDisabled,
|
|
1698
|
-
|
|
1870
|
+
size: "sm",
|
|
1699
1871
|
"aria-label": "Select row"
|
|
1700
1872
|
}
|
|
1701
1873
|
) }),
|
|
1702
|
-
enableExpansion && renderExpansion && /* @__PURE__ */
|
|
1874
|
+
enableExpansion && renderExpansion && /* @__PURE__ */ jsx6("div", { className: "grid-row-expand", children: /* @__PURE__ */ jsx6(
|
|
1703
1875
|
"button",
|
|
1704
1876
|
{
|
|
1705
1877
|
onClick: handleExpandToggle,
|
|
1706
1878
|
disabled: isDisabled,
|
|
1707
|
-
className: "
|
|
1879
|
+
className: "grid-row-expand-button",
|
|
1708
1880
|
"aria-label": isExpanded ? "Collapse row" : "Expand row",
|
|
1709
1881
|
"aria-expanded": isExpanded,
|
|
1710
|
-
children: /* @__PURE__ */
|
|
1882
|
+
children: /* @__PURE__ */ jsx6(
|
|
1711
1883
|
"span",
|
|
1712
1884
|
{
|
|
1713
1885
|
className: `transform transition-transform duration-200 ${isExpanded ? "rotate-90" : ""}`,
|
|
@@ -1739,18 +1911,19 @@ function GridRow({
|
|
|
1739
1911
|
}
|
|
1740
1912
|
}
|
|
1741
1913
|
}
|
|
1742
|
-
return /* @__PURE__ */
|
|
1914
|
+
return /* @__PURE__ */ jsx6(
|
|
1743
1915
|
GridCell,
|
|
1744
1916
|
{
|
|
1745
1917
|
column: col,
|
|
1746
1918
|
row,
|
|
1747
1919
|
rowIndex,
|
|
1920
|
+
rowId: getRowId(row),
|
|
1748
1921
|
value: getCellValue(col),
|
|
1749
1922
|
width,
|
|
1750
1923
|
align: col.align,
|
|
1751
1924
|
showLabel: isMobile && showMobileLabels && col.showLabelOnMobile !== false,
|
|
1752
1925
|
labelText: typeof col.header === "string" ? col.header : col.id,
|
|
1753
|
-
className: isMobile ? "w-full
|
|
1926
|
+
className: isMobile ? "w-full-sm flex-shrink-0" : "flex-shrink-0",
|
|
1754
1927
|
sticky: col.sticky,
|
|
1755
1928
|
stickyOffset,
|
|
1756
1929
|
onClick: onCellClick
|
|
@@ -1761,12 +1934,12 @@ function GridRow({
|
|
|
1761
1934
|
]
|
|
1762
1935
|
}
|
|
1763
1936
|
),
|
|
1764
|
-
isExpanded && renderExpansion && /* @__PURE__ */
|
|
1937
|
+
isExpanded && renderExpansion && /* @__PURE__ */ jsx6("div", { className: "grid-row-expansion", children: renderExpansion(row, getRowId(row)) })
|
|
1765
1938
|
] });
|
|
1766
1939
|
}
|
|
1767
1940
|
|
|
1768
1941
|
// src/components/GridBody/GridBody.tsx
|
|
1769
|
-
import { jsx as
|
|
1942
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1770
1943
|
function GridBody({
|
|
1771
1944
|
data,
|
|
1772
1945
|
columns,
|
|
@@ -1807,7 +1980,7 @@ function GridBody({
|
|
|
1807
1980
|
if (data.length === 0) {
|
|
1808
1981
|
return null;
|
|
1809
1982
|
}
|
|
1810
|
-
return /* @__PURE__ */
|
|
1983
|
+
return /* @__PURE__ */ jsx7("div", { className: `grid-body ${className}`, style, role: "rowgroup", children: data.map((row, index) => {
|
|
1811
1984
|
var _a, _b;
|
|
1812
1985
|
const rowId = getRowId(row);
|
|
1813
1986
|
const isSelected = selectedIds.has(rowId);
|
|
@@ -1815,7 +1988,7 @@ function GridBody({
|
|
|
1815
1988
|
const isDisabled = (_a = isRowDisabled == null ? void 0 : isRowDisabled(row)) != null ? _a : false;
|
|
1816
1989
|
const rowClassName = (_b = getRowClassName == null ? void 0 : getRowClassName(row, index)) != null ? _b : "";
|
|
1817
1990
|
const rowStyle = getRowStyle == null ? void 0 : getRowStyle(row, index);
|
|
1818
|
-
return /* @__PURE__ */
|
|
1991
|
+
return /* @__PURE__ */ jsx7(
|
|
1819
1992
|
GridRow,
|
|
1820
1993
|
{
|
|
1821
1994
|
row,
|
|
@@ -1844,181 +2017,11 @@ function GridBody({
|
|
|
1844
2017
|
}) });
|
|
1845
2018
|
}
|
|
1846
2019
|
|
|
1847
|
-
// src/components/
|
|
1848
|
-
import {
|
|
1849
|
-
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1850
|
-
function Pagination({
|
|
1851
|
-
page,
|
|
1852
|
-
pageSize,
|
|
1853
|
-
totalItems,
|
|
1854
|
-
totalPages,
|
|
1855
|
-
pageSizeOptions = [10, 20, 50, 100],
|
|
1856
|
-
showFirstLast = true,
|
|
1857
|
-
showPageNumbers = true,
|
|
1858
|
-
maxPageButtons = FIVE,
|
|
1859
|
-
className = "",
|
|
1860
|
-
style,
|
|
1861
|
-
onPageChange,
|
|
1862
|
-
onPageSizeChange
|
|
1863
|
-
}) {
|
|
1864
|
-
const { state } = useTableContext();
|
|
1865
|
-
const { translations } = state;
|
|
1866
|
-
const canGoPrevious = page > ONE;
|
|
1867
|
-
const canGoNext = page < totalPages;
|
|
1868
|
-
const startItem = (page - ONE) * pageSize + ONE;
|
|
1869
|
-
const endItem = Math.min(page * pageSize, totalItems);
|
|
1870
|
-
const handleFirstPage = useCallback11(() => {
|
|
1871
|
-
onPageChange(ONE);
|
|
1872
|
-
}, [onPageChange]);
|
|
1873
|
-
const handlePreviousPage = useCallback11(() => {
|
|
1874
|
-
if (canGoPrevious) {
|
|
1875
|
-
onPageChange(page - ONE);
|
|
1876
|
-
}
|
|
1877
|
-
}, [canGoPrevious, page, onPageChange]);
|
|
1878
|
-
const handleNextPage = useCallback11(() => {
|
|
1879
|
-
if (canGoNext) {
|
|
1880
|
-
onPageChange(page + ONE);
|
|
1881
|
-
}
|
|
1882
|
-
}, [canGoNext, page, onPageChange]);
|
|
1883
|
-
const handleLastPage = useCallback11(() => {
|
|
1884
|
-
onPageChange(totalPages);
|
|
1885
|
-
}, [onPageChange, totalPages]);
|
|
1886
|
-
const handlePageSizeChange = useCallback11(
|
|
1887
|
-
(event) => {
|
|
1888
|
-
onPageSizeChange(Number(event.target.value));
|
|
1889
|
-
},
|
|
1890
|
-
[onPageSizeChange]
|
|
1891
|
-
);
|
|
1892
|
-
const pageNumbers = useMemo11(() => {
|
|
1893
|
-
if (!showPageNumbers || totalPages <= ONE) return [];
|
|
1894
|
-
const pages = [];
|
|
1895
|
-
const halfMax = Math.floor(maxPageButtons / 2);
|
|
1896
|
-
let start = Math.max(ONE, page - halfMax);
|
|
1897
|
-
let end = Math.min(totalPages, page + halfMax);
|
|
1898
|
-
if (page <= halfMax) {
|
|
1899
|
-
end = Math.min(totalPages, maxPageButtons);
|
|
1900
|
-
}
|
|
1901
|
-
if (page > totalPages - halfMax) {
|
|
1902
|
-
start = Math.max(ONE, totalPages - maxPageButtons + ONE);
|
|
1903
|
-
}
|
|
1904
|
-
if (start > ONE) {
|
|
1905
|
-
pages.push(ONE);
|
|
1906
|
-
if (start > 2) {
|
|
1907
|
-
pages.push("ellipsis");
|
|
1908
|
-
}
|
|
1909
|
-
}
|
|
1910
|
-
for (let i = start; i <= end; i++) {
|
|
1911
|
-
if (!pages.includes(i)) {
|
|
1912
|
-
pages.push(i);
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
if (end < totalPages) {
|
|
1916
|
-
if (end < totalPages - ONE) {
|
|
1917
|
-
pages.push("ellipsis");
|
|
1918
|
-
}
|
|
1919
|
-
pages.push(totalPages);
|
|
1920
|
-
}
|
|
1921
|
-
return pages;
|
|
1922
|
-
}, [page, totalPages, showPageNumbers, maxPageButtons]);
|
|
1923
|
-
if (totalItems === 0) {
|
|
1924
|
-
return null;
|
|
1925
|
-
}
|
|
1926
|
-
return /* @__PURE__ */ jsxs5(
|
|
1927
|
-
"div",
|
|
1928
|
-
{
|
|
1929
|
-
className: `grid-pagination flex flex-wrap items-center justify-between gap-4 px-4 py-3 border-t border-theme-border ${className}`,
|
|
1930
|
-
style,
|
|
1931
|
-
role: "navigation",
|
|
1932
|
-
"aria-label": "Pagination",
|
|
1933
|
-
children: [
|
|
1934
|
-
/* @__PURE__ */ jsxs5("div", { className: "grid-pagination-info flex items-center gap-4", children: [
|
|
1935
|
-
/* @__PURE__ */ jsxs5("div", { className: "grid-pagination-range text-sm text-theme-secondary", children: [
|
|
1936
|
-
startItem,
|
|
1937
|
-
"-",
|
|
1938
|
-
endItem,
|
|
1939
|
-
" ",
|
|
1940
|
-
translations.of,
|
|
1941
|
-
" ",
|
|
1942
|
-
totalItems
|
|
1943
|
-
] }),
|
|
1944
|
-
/* @__PURE__ */ jsxs5("div", { className: "grid-pagination-size flex items-center gap-2", children: [
|
|
1945
|
-
/* @__PURE__ */ jsxs5("label", { htmlFor: "page-size", className: "text-sm text-theme-muted", children: [
|
|
1946
|
-
translations.rowsPerPage,
|
|
1947
|
-
":"
|
|
1948
|
-
] }),
|
|
1949
|
-
/* @__PURE__ */ jsx7(
|
|
1950
|
-
"select",
|
|
1951
|
-
{
|
|
1952
|
-
id: "page-size",
|
|
1953
|
-
value: pageSize,
|
|
1954
|
-
onChange: handlePageSizeChange,
|
|
1955
|
-
className: "px-2 py-1 text-sm rounded border border-theme-border bg-theme-primary text-theme-primary focus:outline-none focus:ring-2 focus:ring-accent-primary",
|
|
1956
|
-
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx7("option", { value: size, children: size }, size))
|
|
1957
|
-
}
|
|
1958
|
-
)
|
|
1959
|
-
] })
|
|
1960
|
-
] }),
|
|
1961
|
-
/* @__PURE__ */ jsxs5("div", { className: "grid-pagination-controls flex items-center gap-1", children: [
|
|
1962
|
-
showFirstLast && /* @__PURE__ */ jsx7(
|
|
1963
|
-
"button",
|
|
1964
|
-
{
|
|
1965
|
-
onClick: handleFirstPage,
|
|
1966
|
-
disabled: !canGoPrevious,
|
|
1967
|
-
className: "p-2 rounded hover:bg-theme-hover disabled:opacity-50 disabled:cursor-not-allowed text-theme-secondary",
|
|
1968
|
-
"aria-label": translations.first,
|
|
1969
|
-
children: "<<"
|
|
1970
|
-
}
|
|
1971
|
-
),
|
|
1972
|
-
/* @__PURE__ */ jsx7(
|
|
1973
|
-
"button",
|
|
1974
|
-
{
|
|
1975
|
-
onClick: handlePreviousPage,
|
|
1976
|
-
disabled: !canGoPrevious,
|
|
1977
|
-
className: "p-2 rounded hover:bg-theme-hover disabled:opacity-50 disabled:cursor-not-allowed text-theme-secondary",
|
|
1978
|
-
"aria-label": translations.previous,
|
|
1979
|
-
children: "<"
|
|
1980
|
-
}
|
|
1981
|
-
),
|
|
1982
|
-
showPageNumbers && /* @__PURE__ */ jsx7("div", { className: "grid-pagination-pages flex items-center gap-1", children: pageNumbers.map(
|
|
1983
|
-
(pageNum, index) => pageNum === "ellipsis" ? /* @__PURE__ */ jsx7("span", { className: "px-2 text-theme-muted", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ jsx7(
|
|
1984
|
-
"button",
|
|
1985
|
-
{
|
|
1986
|
-
onClick: () => onPageChange(pageNum),
|
|
1987
|
-
className: `min-w-[32px] h-8 px-2 rounded text-sm transition-colors ${pageNum === page ? "bg-accent-primary text-white" : "hover:bg-theme-hover text-theme-secondary"}`,
|
|
1988
|
-
"aria-current": pageNum === page ? "page" : void 0,
|
|
1989
|
-
children: pageNum
|
|
1990
|
-
},
|
|
1991
|
-
pageNum
|
|
1992
|
-
)
|
|
1993
|
-
) }),
|
|
1994
|
-
/* @__PURE__ */ jsx7(
|
|
1995
|
-
"button",
|
|
1996
|
-
{
|
|
1997
|
-
onClick: handleNextPage,
|
|
1998
|
-
disabled: !canGoNext,
|
|
1999
|
-
className: "p-2 rounded hover:bg-theme-hover disabled:opacity-50 disabled:cursor-not-allowed text-theme-secondary",
|
|
2000
|
-
"aria-label": translations.next,
|
|
2001
|
-
children: ">"
|
|
2002
|
-
}
|
|
2003
|
-
),
|
|
2004
|
-
showFirstLast && /* @__PURE__ */ jsx7(
|
|
2005
|
-
"button",
|
|
2006
|
-
{
|
|
2007
|
-
onClick: handleLastPage,
|
|
2008
|
-
disabled: !canGoNext,
|
|
2009
|
-
className: "p-2 rounded hover:bg-theme-hover disabled:opacity-50 disabled:cursor-not-allowed text-theme-secondary",
|
|
2010
|
-
"aria-label": translations.last,
|
|
2011
|
-
children: ">>"
|
|
2012
|
-
}
|
|
2013
|
-
)
|
|
2014
|
-
] })
|
|
2015
|
-
]
|
|
2016
|
-
}
|
|
2017
|
-
);
|
|
2018
|
-
}
|
|
2020
|
+
// src/components/GridTable/GridTable.tsx
|
|
2021
|
+
import { Pagination as BearPagination, Typography as Typography3, Select, BearProvider } from "@forgedevstack/bear";
|
|
2019
2022
|
|
|
2020
2023
|
// src/components/Skeleton/Skeleton.tsx
|
|
2021
|
-
import { jsx as jsx8, jsxs as
|
|
2024
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2022
2025
|
function SkeletonCell({ width = DEFAULT_COLUMN_WIDTH, height = 16, animate = true }) {
|
|
2023
2026
|
const widthStyle = typeof width === "number" ? `${width}px` : width;
|
|
2024
2027
|
return /* @__PURE__ */ jsx8(
|
|
@@ -2029,7 +2032,7 @@ function SkeletonCell({ width = DEFAULT_COLUMN_WIDTH, height = 16, animate = tru
|
|
|
2029
2032
|
children: /* @__PURE__ */ jsx8(
|
|
2030
2033
|
"div",
|
|
2031
2034
|
{
|
|
2032
|
-
className: `rounded
|
|
2035
|
+
className: `rounded ${animate ? "animate-pulse" : ""}`,
|
|
2033
2036
|
style: { height: `${height}px`, width: "80%" }
|
|
2034
2037
|
}
|
|
2035
2038
|
)
|
|
@@ -2037,7 +2040,7 @@ function SkeletonCell({ width = DEFAULT_COLUMN_WIDTH, height = 16, animate = tru
|
|
|
2037
2040
|
);
|
|
2038
2041
|
}
|
|
2039
2042
|
function SkeletonRow({ columns, columnWidths, height = 16, animate = true }) {
|
|
2040
|
-
return /* @__PURE__ */ jsx8("div", { className: "grid-skeleton-row
|
|
2043
|
+
return /* @__PURE__ */ jsx8("div", { className: "grid-skeleton-row", children: Array.from({ length: columns }).map((_, index) => {
|
|
2041
2044
|
var _a;
|
|
2042
2045
|
return /* @__PURE__ */ jsx8(
|
|
2043
2046
|
SkeletonCell,
|
|
@@ -2060,8 +2063,8 @@ function Skeleton({
|
|
|
2060
2063
|
showHeader = true,
|
|
2061
2064
|
animate = true
|
|
2062
2065
|
}) {
|
|
2063
|
-
return /* @__PURE__ */
|
|
2064
|
-
showHeader && /* @__PURE__ */ jsx8("div", { className: "grid-skeleton-header
|
|
2066
|
+
return /* @__PURE__ */ jsxs5("div", { className: `grid-skeleton ${className}`, style, role: "status", "aria-label": "Loading", children: [
|
|
2067
|
+
showHeader && /* @__PURE__ */ jsx8("div", { className: "grid-skeleton-header", children: Array.from({ length: columns }).map((_, index) => {
|
|
2065
2068
|
var _a;
|
|
2066
2069
|
return /* @__PURE__ */ jsx8(
|
|
2067
2070
|
"div",
|
|
@@ -2071,7 +2074,7 @@ function Skeleton({
|
|
|
2071
2074
|
children: /* @__PURE__ */ jsx8(
|
|
2072
2075
|
"div",
|
|
2073
2076
|
{
|
|
2074
|
-
className: `rounded
|
|
2077
|
+
className: `rounded ${animate ? "animate-pulse" : ""}`,
|
|
2075
2078
|
style: { height: "12px", width: "60%" }
|
|
2076
2079
|
}
|
|
2077
2080
|
)
|
|
@@ -2092,8 +2095,203 @@ function Skeleton({
|
|
|
2092
2095
|
] });
|
|
2093
2096
|
}
|
|
2094
2097
|
|
|
2098
|
+
// src/components/TableStudioPanel/TableStudioPanel.tsx
|
|
2099
|
+
import { useState as useState7, useCallback as useCallback11 } from "react";
|
|
2100
|
+
import { Typography as Typography2 } from "@forgedevstack/bear";
|
|
2101
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2102
|
+
var DEFAULT_ROW_COUNT = 10;
|
|
2103
|
+
function TableStudioPanel({
|
|
2104
|
+
data,
|
|
2105
|
+
columns,
|
|
2106
|
+
propsSnapshot,
|
|
2107
|
+
onDataChange,
|
|
2108
|
+
open = true,
|
|
2109
|
+
onOpenChange
|
|
2110
|
+
}) {
|
|
2111
|
+
const [activeTab, setActiveTab] = useState7("data");
|
|
2112
|
+
const [generateCount, setGenerateCount] = useState7(DEFAULT_ROW_COUNT);
|
|
2113
|
+
const handleGenerate = useCallback11(() => {
|
|
2114
|
+
if (!onDataChange) return;
|
|
2115
|
+
const count = Math.min(100, Math.max(1, generateCount));
|
|
2116
|
+
const generated = generateSampleData(columns, count);
|
|
2117
|
+
onDataChange(generated);
|
|
2118
|
+
setActiveTab("data");
|
|
2119
|
+
}, [columns, generateCount, onDataChange]);
|
|
2120
|
+
const panelContent = /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2121
|
+
/* @__PURE__ */ jsx9(
|
|
2122
|
+
"div",
|
|
2123
|
+
{
|
|
2124
|
+
style: {
|
|
2125
|
+
display: "flex",
|
|
2126
|
+
borderBottom: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
|
|
2127
|
+
padding: "0.25rem 0",
|
|
2128
|
+
gap: 2
|
|
2129
|
+
},
|
|
2130
|
+
children: ["data", "props", "generate"].map((tab) => /* @__PURE__ */ jsx9(
|
|
2131
|
+
"button",
|
|
2132
|
+
{
|
|
2133
|
+
type: "button",
|
|
2134
|
+
onClick: () => setActiveTab(tab),
|
|
2135
|
+
style: {
|
|
2136
|
+
flex: 1,
|
|
2137
|
+
padding: "0.5rem 0.5rem",
|
|
2138
|
+
border: "none",
|
|
2139
|
+
borderRadius: 4,
|
|
2140
|
+
background: activeTab === tab ? "var(--gt-bg-tertiary)" : "transparent",
|
|
2141
|
+
color: "var(--gt-text-primary)",
|
|
2142
|
+
cursor: "pointer",
|
|
2143
|
+
fontWeight: activeTab === tab ? 600 : 400,
|
|
2144
|
+
fontSize: 12,
|
|
2145
|
+
textTransform: "capitalize"
|
|
2146
|
+
},
|
|
2147
|
+
children: tab
|
|
2148
|
+
},
|
|
2149
|
+
tab
|
|
2150
|
+
))
|
|
2151
|
+
}
|
|
2152
|
+
),
|
|
2153
|
+
/* @__PURE__ */ jsxs6("div", { style: { flex: 1, overflow: "auto", padding: "0.75rem" }, children: [
|
|
2154
|
+
activeTab === "data" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2155
|
+
/* @__PURE__ */ jsxs6(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: [
|
|
2156
|
+
"Data (",
|
|
2157
|
+
data.length,
|
|
2158
|
+
" rows)"
|
|
2159
|
+
] }),
|
|
2160
|
+
/* @__PURE__ */ jsx9(
|
|
2161
|
+
"pre",
|
|
2162
|
+
{
|
|
2163
|
+
style: {
|
|
2164
|
+
margin: 0,
|
|
2165
|
+
fontSize: 11,
|
|
2166
|
+
fontFamily: "monospace",
|
|
2167
|
+
whiteSpace: "pre-wrap",
|
|
2168
|
+
wordBreak: "break-word",
|
|
2169
|
+
color: "var(--gt-text-primary)"
|
|
2170
|
+
},
|
|
2171
|
+
children: JSON.stringify(data, null, 2)
|
|
2172
|
+
}
|
|
2173
|
+
)
|
|
2174
|
+
] }),
|
|
2175
|
+
activeTab === "props" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2176
|
+
/* @__PURE__ */ jsx9(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: "Props" }),
|
|
2177
|
+
/* @__PURE__ */ jsx9("dl", { style: { margin: 0, fontSize: 13, color: "var(--gt-text-primary)" }, children: Object.entries(propsSnapshot).map(([key, value]) => /* @__PURE__ */ jsxs6("div", { style: { marginBottom: "0.5rem" }, children: [
|
|
2178
|
+
/* @__PURE__ */ jsx9("dt", { style: { fontWeight: 600, marginBottom: 2 }, children: key }),
|
|
2179
|
+
/* @__PURE__ */ jsx9("dd", { style: { margin: 0, color: "var(--gt-text-secondary)" }, children: typeof value === "object" && value !== null ? JSON.stringify(value) : String(value) })
|
|
2180
|
+
] }, key)) })
|
|
2181
|
+
] }),
|
|
2182
|
+
activeTab === "generate" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2183
|
+
/* @__PURE__ */ jsx9(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: "Generate sample data" }),
|
|
2184
|
+
/* @__PURE__ */ jsx9("p", { style: { fontSize: 12, color: "var(--gt-text-secondary)", marginBottom: "0.75rem" }, children: "Create rows from column definitions. Uses placeholders for common fields (name, email, id, etc.)." }),
|
|
2185
|
+
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
2186
|
+
/* @__PURE__ */ jsxs6("label", { style: { fontSize: 12, fontWeight: 500 }, children: [
|
|
2187
|
+
"Rows",
|
|
2188
|
+
/* @__PURE__ */ jsx9(
|
|
2189
|
+
"input",
|
|
2190
|
+
{
|
|
2191
|
+
type: "number",
|
|
2192
|
+
min: 1,
|
|
2193
|
+
max: 100,
|
|
2194
|
+
value: generateCount,
|
|
2195
|
+
onChange: (e) => setGenerateCount(Number(e.target.value) || 1),
|
|
2196
|
+
style: {
|
|
2197
|
+
display: "block",
|
|
2198
|
+
marginTop: 4,
|
|
2199
|
+
width: "100%",
|
|
2200
|
+
padding: "6px 8px",
|
|
2201
|
+
borderRadius: 4,
|
|
2202
|
+
border: "1px solid var(--gt-border-color)",
|
|
2203
|
+
background: "var(--gt-bg-primary)",
|
|
2204
|
+
color: "var(--gt-text-primary)"
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
)
|
|
2208
|
+
] }),
|
|
2209
|
+
/* @__PURE__ */ jsx9(
|
|
2210
|
+
"button",
|
|
2211
|
+
{
|
|
2212
|
+
type: "button",
|
|
2213
|
+
onClick: handleGenerate,
|
|
2214
|
+
disabled: !onDataChange,
|
|
2215
|
+
style: {
|
|
2216
|
+
padding: "8px 12px",
|
|
2217
|
+
borderRadius: 6,
|
|
2218
|
+
border: "none",
|
|
2219
|
+
background: onDataChange ? "var(--gt-accent-primary)" : "var(--gt-bg-tertiary)",
|
|
2220
|
+
color: onDataChange ? "#fff" : "var(--gt-text-muted)",
|
|
2221
|
+
cursor: onDataChange ? "pointer" : "not-allowed",
|
|
2222
|
+
fontWeight: 500,
|
|
2223
|
+
fontSize: 13
|
|
2224
|
+
},
|
|
2225
|
+
children: "Generate data"
|
|
2226
|
+
}
|
|
2227
|
+
),
|
|
2228
|
+
!onDataChange && /* @__PURE__ */ jsx9("span", { style: { fontSize: 11, color: "var(--gt-text-muted)" }, children: "Table must use studio with controllable data to generate." })
|
|
2229
|
+
] })
|
|
2230
|
+
] })
|
|
2231
|
+
] })
|
|
2232
|
+
] });
|
|
2233
|
+
const width = 320;
|
|
2234
|
+
const isCollapsed = !open;
|
|
2235
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2236
|
+
/* @__PURE__ */ jsx9(
|
|
2237
|
+
"button",
|
|
2238
|
+
{
|
|
2239
|
+
type: "button",
|
|
2240
|
+
onClick: () => onOpenChange == null ? void 0 : onOpenChange(!open),
|
|
2241
|
+
className: "grid-table-studio-toggle",
|
|
2242
|
+
style: {
|
|
2243
|
+
position: "fixed",
|
|
2244
|
+
right: open ? width : 0,
|
|
2245
|
+
top: "50%",
|
|
2246
|
+
transform: "translateY(-50%)",
|
|
2247
|
+
zIndex: 10001,
|
|
2248
|
+
width: 24,
|
|
2249
|
+
height: 48,
|
|
2250
|
+
border: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
|
|
2251
|
+
borderRight: "none",
|
|
2252
|
+
borderRadius: "8px 0 0 8px",
|
|
2253
|
+
background: "var(--gt-bg-secondary, #f5f5f5)",
|
|
2254
|
+
color: "var(--gt-text-primary)",
|
|
2255
|
+
cursor: "pointer",
|
|
2256
|
+
display: "flex",
|
|
2257
|
+
alignItems: "center",
|
|
2258
|
+
justifyContent: "center",
|
|
2259
|
+
fontSize: 14,
|
|
2260
|
+
boxShadow: " -2px 0 8px rgba(0,0,0,0.08)"
|
|
2261
|
+
},
|
|
2262
|
+
"aria-label": open ? "Close studio panel" : "Open studio panel",
|
|
2263
|
+
children: open ? "\u203A" : "\u2039"
|
|
2264
|
+
}
|
|
2265
|
+
),
|
|
2266
|
+
/* @__PURE__ */ jsx9(
|
|
2267
|
+
"aside",
|
|
2268
|
+
{
|
|
2269
|
+
className: "grid-table-studio-panel",
|
|
2270
|
+
style: {
|
|
2271
|
+
position: "fixed",
|
|
2272
|
+
top: 0,
|
|
2273
|
+
right: 0,
|
|
2274
|
+
bottom: 0,
|
|
2275
|
+
width: isCollapsed ? 0 : width,
|
|
2276
|
+
minWidth: isCollapsed ? 0 : 280,
|
|
2277
|
+
borderLeft: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
|
|
2278
|
+
backgroundColor: "var(--gt-bg-secondary, #f5f5f5)",
|
|
2279
|
+
display: "flex",
|
|
2280
|
+
flexDirection: "column",
|
|
2281
|
+
overflow: "hidden",
|
|
2282
|
+
zIndex: 1e4,
|
|
2283
|
+
boxShadow: isCollapsed ? "none" : "-4px 0 12px rgba(0,0,0,0.08)",
|
|
2284
|
+
transition: "width 0.2s ease, box-shadow 0.2s ease"
|
|
2285
|
+
},
|
|
2286
|
+
"aria-label": "Table studio panel",
|
|
2287
|
+
children: !isCollapsed && panelContent
|
|
2288
|
+
}
|
|
2289
|
+
)
|
|
2290
|
+
] });
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2095
2293
|
// src/components/EmptyState/EmptyState.tsx
|
|
2096
|
-
import { jsx as
|
|
2294
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2097
2295
|
function EmptyState({
|
|
2098
2296
|
title,
|
|
2099
2297
|
description,
|
|
@@ -2109,19 +2307,19 @@ function EmptyState({
|
|
|
2109
2307
|
return /* @__PURE__ */ jsxs7(
|
|
2110
2308
|
"div",
|
|
2111
2309
|
{
|
|
2112
|
-
className: `grid-empty-state
|
|
2310
|
+
className: `grid-empty-state ${className}`,
|
|
2113
2311
|
style,
|
|
2114
2312
|
role: "status",
|
|
2115
2313
|
children: [
|
|
2116
|
-
icon && /* @__PURE__ */
|
|
2117
|
-
!icon && /* @__PURE__ */
|
|
2314
|
+
icon && /* @__PURE__ */ jsx10("div", { className: "grid-empty-icon", children: icon }),
|
|
2315
|
+
!icon && /* @__PURE__ */ jsx10("div", { className: "grid-empty-icon", children: /* @__PURE__ */ jsx10(
|
|
2118
2316
|
"svg",
|
|
2119
2317
|
{
|
|
2120
|
-
className: "
|
|
2318
|
+
className: "icon-lg",
|
|
2121
2319
|
fill: "none",
|
|
2122
2320
|
viewBox: "0 0 24 24",
|
|
2123
2321
|
stroke: "currentColor",
|
|
2124
|
-
children: /* @__PURE__ */
|
|
2322
|
+
children: /* @__PURE__ */ jsx10(
|
|
2125
2323
|
"path",
|
|
2126
2324
|
{
|
|
2127
2325
|
strokeLinecap: "round",
|
|
@@ -2132,25 +2330,25 @@ function EmptyState({
|
|
|
2132
2330
|
)
|
|
2133
2331
|
}
|
|
2134
2332
|
) }),
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
displayDescription && /* @__PURE__ */
|
|
2137
|
-
action && /* @__PURE__ */
|
|
2333
|
+
/* @__PURE__ */ jsx10("h3", { className: "grid-empty-title", children: displayTitle }),
|
|
2334
|
+
displayDescription && /* @__PURE__ */ jsx10("p", { className: "grid-empty-description", children: displayDescription }),
|
|
2335
|
+
action && /* @__PURE__ */ jsx10("div", { className: "grid-empty-action", children: action })
|
|
2138
2336
|
]
|
|
2139
2337
|
}
|
|
2140
2338
|
);
|
|
2141
2339
|
}
|
|
2142
2340
|
|
|
2143
2341
|
// src/components/MobileDrawer/MobileDrawer.tsx
|
|
2144
|
-
import { useEffect as
|
|
2145
|
-
import { jsx as
|
|
2342
|
+
import { useEffect as useEffect5, useCallback as useCallback12 } from "react";
|
|
2343
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2146
2344
|
function DrawerHeader({ title, onClose }) {
|
|
2147
|
-
return /* @__PURE__ */ jsxs8("div", { className: "drawer-header
|
|
2148
|
-
/* @__PURE__ */
|
|
2149
|
-
/* @__PURE__ */
|
|
2345
|
+
return /* @__PURE__ */ jsxs8("div", { className: "drawer-header", children: [
|
|
2346
|
+
/* @__PURE__ */ jsx11("h3", { children: title }),
|
|
2347
|
+
/* @__PURE__ */ jsx11(
|
|
2150
2348
|
"button",
|
|
2151
2349
|
{
|
|
2152
2350
|
onClick: onClose,
|
|
2153
|
-
className: "p-2 rounded
|
|
2351
|
+
className: "p-2 rounded",
|
|
2154
2352
|
"aria-label": "Close",
|
|
2155
2353
|
children: "X"
|
|
2156
2354
|
}
|
|
@@ -2163,30 +2361,30 @@ function FilterContent() {
|
|
|
2163
2361
|
const handleClearAll = useCallback12(() => {
|
|
2164
2362
|
actions.clearFilters();
|
|
2165
2363
|
}, [actions]);
|
|
2166
|
-
return /* @__PURE__ */ jsxs8("div", { className: "drawer-filter-content
|
|
2167
|
-
/* @__PURE__ */ jsxs8("div", {
|
|
2364
|
+
return /* @__PURE__ */ jsxs8("div", { className: "drawer-filter-content", children: [
|
|
2365
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2168
2366
|
/* @__PURE__ */ jsxs8("span", { className: "text-sm text-theme-muted", children: [
|
|
2169
2367
|
filters.length,
|
|
2170
2368
|
" ",
|
|
2171
2369
|
translations.filter,
|
|
2172
2370
|
"(s) active"
|
|
2173
2371
|
] }),
|
|
2174
|
-
filters.length > 0 && /* @__PURE__ */
|
|
2372
|
+
filters.length > 0 && /* @__PURE__ */ jsx11(
|
|
2175
2373
|
"button",
|
|
2176
2374
|
{
|
|
2177
2375
|
onClick: handleClearAll,
|
|
2178
|
-
className: "text-sm
|
|
2376
|
+
className: "text-sm",
|
|
2179
2377
|
children: translations.clearAll
|
|
2180
2378
|
}
|
|
2181
2379
|
)
|
|
2182
2380
|
] }),
|
|
2183
|
-
/* @__PURE__ */
|
|
2381
|
+
/* @__PURE__ */ jsx11("div", { className: "space-y-3", children: columns.filter((col) => col.filterable !== false).map((col) => {
|
|
2184
2382
|
var _a;
|
|
2185
2383
|
const existingFilter = filters.find((f) => f.columnId === col.id);
|
|
2186
2384
|
const headerText = typeof col.header === "string" ? col.header : col.id;
|
|
2187
2385
|
return /* @__PURE__ */ jsxs8("div", { className: "filter-item", children: [
|
|
2188
|
-
/* @__PURE__ */
|
|
2189
|
-
/* @__PURE__ */
|
|
2386
|
+
/* @__PURE__ */ jsx11("label", { className: "block text-sm font-medium text-theme-secondary mb-1", children: headerText }),
|
|
2387
|
+
/* @__PURE__ */ jsx11(
|
|
2190
2388
|
"input",
|
|
2191
2389
|
{
|
|
2192
2390
|
type: "text",
|
|
@@ -2199,7 +2397,7 @@ function FilterContent() {
|
|
|
2199
2397
|
}
|
|
2200
2398
|
},
|
|
2201
2399
|
placeholder: `${translations.filter} ${headerText}...`,
|
|
2202
|
-
className: "w-full px-3 py-2 text-sm rounded
|
|
2400
|
+
className: "w-full px-3 py-2 text-sm rounded"
|
|
2203
2401
|
}
|
|
2204
2402
|
)
|
|
2205
2403
|
] }, col.id);
|
|
@@ -2212,34 +2410,34 @@ function SortContent() {
|
|
|
2212
2410
|
const handleClearAll = useCallback12(() => {
|
|
2213
2411
|
actions.clearSorting();
|
|
2214
2412
|
}, [actions]);
|
|
2215
|
-
return /* @__PURE__ */ jsxs8("div", { className: "drawer-sort-content
|
|
2216
|
-
/* @__PURE__ */ jsxs8("div", {
|
|
2413
|
+
return /* @__PURE__ */ jsxs8("div", { className: "drawer-sort-content", children: [
|
|
2414
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2217
2415
|
/* @__PURE__ */ jsxs8("span", { className: "text-sm text-theme-muted", children: [
|
|
2218
2416
|
sorting.length,
|
|
2219
2417
|
" ",
|
|
2220
2418
|
translations.sort,
|
|
2221
2419
|
"(s) active"
|
|
2222
2420
|
] }),
|
|
2223
|
-
sorting.length > 0 && /* @__PURE__ */
|
|
2421
|
+
sorting.length > 0 && /* @__PURE__ */ jsx11(
|
|
2224
2422
|
"button",
|
|
2225
2423
|
{
|
|
2226
2424
|
onClick: handleClearAll,
|
|
2227
|
-
className: "text-sm
|
|
2425
|
+
className: "text-sm",
|
|
2228
2426
|
children: translations.clearAll
|
|
2229
2427
|
}
|
|
2230
2428
|
)
|
|
2231
2429
|
] }),
|
|
2232
|
-
/* @__PURE__ */
|
|
2430
|
+
/* @__PURE__ */ jsx11("div", { className: "space-y-2", children: columns.filter((col) => col.sortable !== false).map((col) => {
|
|
2233
2431
|
const sortItem = sorting.find((s) => s.columnId === col.id);
|
|
2234
2432
|
const headerText = typeof col.header === "string" ? col.header : col.id;
|
|
2235
2433
|
return /* @__PURE__ */ jsxs8(
|
|
2236
2434
|
"button",
|
|
2237
2435
|
{
|
|
2238
2436
|
onClick: () => actions.toggleSorting(col.id),
|
|
2239
|
-
className: `w-full
|
|
2437
|
+
className: `w-full px-3 py-2 rounded ${sortItem ? "active" : ""}`,
|
|
2240
2438
|
children: [
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2439
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-primary", children: headerText }),
|
|
2440
|
+
/* @__PURE__ */ jsx11("span", { className: "text-xs text-theme-muted", children: (sortItem == null ? void 0 : sortItem.direction) === "asc" ? translations.sortAsc : (sortItem == null ? void 0 : sortItem.direction) === "desc" ? translations.sortDesc : "-" })
|
|
2243
2441
|
]
|
|
2244
2442
|
},
|
|
2245
2443
|
col.id
|
|
@@ -2250,37 +2448,37 @@ function SortContent() {
|
|
|
2250
2448
|
function ColumnsContent() {
|
|
2251
2449
|
const { state, actions } = useTableContext();
|
|
2252
2450
|
const { translations, columns, columnStates } = state;
|
|
2253
|
-
return /* @__PURE__ */ jsxs8("div", { className: "drawer-columns-content
|
|
2254
|
-
/* @__PURE__ */ jsxs8("div", {
|
|
2255
|
-
/* @__PURE__ */
|
|
2256
|
-
/* @__PURE__ */
|
|
2451
|
+
return /* @__PURE__ */ jsxs8("div", { className: "drawer-columns-content", children: [
|
|
2452
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2453
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-muted", children: translations.showColumns }),
|
|
2454
|
+
/* @__PURE__ */ jsx11(
|
|
2257
2455
|
"button",
|
|
2258
2456
|
{
|
|
2259
2457
|
onClick: actions.resetColumns,
|
|
2260
|
-
className: "text-sm
|
|
2458
|
+
className: "text-sm",
|
|
2261
2459
|
children: translations.resetColumns
|
|
2262
2460
|
}
|
|
2263
2461
|
)
|
|
2264
2462
|
] }),
|
|
2265
|
-
/* @__PURE__ */
|
|
2463
|
+
/* @__PURE__ */ jsx11("div", { className: "space-y-2", children: columns.map((col) => {
|
|
2266
2464
|
const colState = columnStates.find((cs) => cs.id === col.id);
|
|
2267
2465
|
const isVisible = (colState == null ? void 0 : colState.visible) !== false;
|
|
2268
2466
|
const headerText = typeof col.header === "string" ? col.header : col.id;
|
|
2269
2467
|
return /* @__PURE__ */ jsxs8(
|
|
2270
2468
|
"label",
|
|
2271
2469
|
{
|
|
2272
|
-
className: "
|
|
2470
|
+
className: "px-3 py-2 rounded cursor-pointer",
|
|
2273
2471
|
children: [
|
|
2274
|
-
/* @__PURE__ */
|
|
2472
|
+
/* @__PURE__ */ jsx11(
|
|
2275
2473
|
"input",
|
|
2276
2474
|
{
|
|
2277
2475
|
type: "checkbox",
|
|
2278
2476
|
checked: isVisible,
|
|
2279
2477
|
onChange: () => actions.toggleColumnVisibility(col.id),
|
|
2280
|
-
className: "w-4 h-4 rounded
|
|
2478
|
+
className: "w-4 h-4 rounded"
|
|
2281
2479
|
}
|
|
2282
2480
|
),
|
|
2283
|
-
/* @__PURE__ */
|
|
2481
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-primary", children: headerText })
|
|
2284
2482
|
]
|
|
2285
2483
|
},
|
|
2286
2484
|
col.id
|
|
@@ -2300,7 +2498,7 @@ function MobileDrawer({
|
|
|
2300
2498
|
className = "",
|
|
2301
2499
|
style
|
|
2302
2500
|
}) {
|
|
2303
|
-
|
|
2501
|
+
useEffect5(() => {
|
|
2304
2502
|
if (isOpen) {
|
|
2305
2503
|
document.body.style.overflow = "hidden";
|
|
2306
2504
|
} else {
|
|
@@ -2310,7 +2508,7 @@ function MobileDrawer({
|
|
|
2310
2508
|
document.body.style.overflow = "";
|
|
2311
2509
|
};
|
|
2312
2510
|
}, [isOpen]);
|
|
2313
|
-
|
|
2511
|
+
useEffect5(() => {
|
|
2314
2512
|
const handleEscape = (e) => {
|
|
2315
2513
|
if (e.key === "Escape" && isOpen) {
|
|
2316
2514
|
onClose();
|
|
@@ -2322,11 +2520,11 @@ function MobileDrawer({
|
|
|
2322
2520
|
if (!isOpen || !content) {
|
|
2323
2521
|
return null;
|
|
2324
2522
|
}
|
|
2325
|
-
return /* @__PURE__ */ jsxs8("div", { className: `mobile-drawer-container
|
|
2326
|
-
/* @__PURE__ */
|
|
2523
|
+
return /* @__PURE__ */ jsxs8("div", { className: `mobile-drawer-container ${className}`, style, children: [
|
|
2524
|
+
/* @__PURE__ */ jsx11(
|
|
2327
2525
|
"div",
|
|
2328
2526
|
{
|
|
2329
|
-
className: "mobile-drawer-overlay
|
|
2527
|
+
className: "mobile-drawer-overlay",
|
|
2330
2528
|
style: {
|
|
2331
2529
|
opacity: DRAWER_OVERLAY_OPACITY,
|
|
2332
2530
|
transitionDuration: `${DRAWER_ANIMATION_DURATION}ms`
|
|
@@ -2338,7 +2536,7 @@ function MobileDrawer({
|
|
|
2338
2536
|
/* @__PURE__ */ jsxs8(
|
|
2339
2537
|
"div",
|
|
2340
2538
|
{
|
|
2341
|
-
className: "mobile-drawer
|
|
2539
|
+
className: "mobile-drawer",
|
|
2342
2540
|
style: {
|
|
2343
2541
|
transitionDuration: `${DRAWER_ANIMATION_DURATION}ms`
|
|
2344
2542
|
},
|
|
@@ -2346,11 +2544,11 @@ function MobileDrawer({
|
|
|
2346
2544
|
"aria-modal": "true",
|
|
2347
2545
|
"aria-labelledby": "drawer-title",
|
|
2348
2546
|
children: [
|
|
2349
|
-
/* @__PURE__ */
|
|
2350
|
-
/* @__PURE__ */ jsxs8("div", { className: "drawer-content
|
|
2351
|
-
content === "filter" && /* @__PURE__ */
|
|
2352
|
-
content === "sort" && /* @__PURE__ */
|
|
2353
|
-
content === "columns" && /* @__PURE__ */
|
|
2547
|
+
/* @__PURE__ */ jsx11(DrawerHeader, { title: DRAWER_TITLES[content], onClose }),
|
|
2548
|
+
/* @__PURE__ */ jsxs8("div", { className: "drawer-content", children: [
|
|
2549
|
+
content === "filter" && /* @__PURE__ */ jsx11(FilterContent, {}),
|
|
2550
|
+
content === "sort" && /* @__PURE__ */ jsx11(SortContent, {}),
|
|
2551
|
+
content === "columns" && /* @__PURE__ */ jsx11(ColumnsContent, {})
|
|
2354
2552
|
] })
|
|
2355
2553
|
]
|
|
2356
2554
|
}
|
|
@@ -2359,7 +2557,7 @@ function MobileDrawer({
|
|
|
2359
2557
|
}
|
|
2360
2558
|
|
|
2361
2559
|
// src/components/GridTable/GridTable.tsx
|
|
2362
|
-
import { jsx as
|
|
2560
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2363
2561
|
function GridTableContent({
|
|
2364
2562
|
data,
|
|
2365
2563
|
columns,
|
|
@@ -2397,10 +2595,18 @@ function GridTableContent({
|
|
|
2397
2595
|
renderHeader,
|
|
2398
2596
|
renderFooter,
|
|
2399
2597
|
className = "",
|
|
2400
|
-
style
|
|
2598
|
+
style,
|
|
2599
|
+
showOverflowTooltip,
|
|
2600
|
+
enableCellAutoSizeOnDoubleClick,
|
|
2601
|
+
subCellExpandTrigger,
|
|
2602
|
+
expandRowOnDoubleClick,
|
|
2603
|
+
themeMode,
|
|
2604
|
+
paginationConfig
|
|
2401
2605
|
}) {
|
|
2606
|
+
var _a, _b;
|
|
2402
2607
|
const { state, actions, computed } = useTableContext();
|
|
2403
2608
|
const { shouldShowMobileView, breakpointValue } = useBreakpoint();
|
|
2609
|
+
const themeClass = themeMode === "dark" ? "dark" : themeMode === "light" ? "light" : void 0;
|
|
2404
2610
|
const getRowIdFn = useCallback13(
|
|
2405
2611
|
(row) => {
|
|
2406
2612
|
if (getRowId) return getRowId(row);
|
|
@@ -2429,6 +2635,22 @@ function GridTableContent({
|
|
|
2429
2635
|
},
|
|
2430
2636
|
[actions]
|
|
2431
2637
|
);
|
|
2638
|
+
const handleRowDoubleClick = useCallback13(
|
|
2639
|
+
(row, index) => {
|
|
2640
|
+
if (expandRowOnDoubleClick) {
|
|
2641
|
+
actions.toggleRowExpansion(getRowIdFn(row));
|
|
2642
|
+
}
|
|
2643
|
+
onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, index);
|
|
2644
|
+
},
|
|
2645
|
+
[expandRowOnDoubleClick, actions, getRowIdFn, onRowDoubleClick]
|
|
2646
|
+
);
|
|
2647
|
+
const handleSelectAll = useCallback13(() => {
|
|
2648
|
+
if (computed.allSelected) {
|
|
2649
|
+
actions.deselectAll();
|
|
2650
|
+
} else {
|
|
2651
|
+
actions.selectAll();
|
|
2652
|
+
}
|
|
2653
|
+
}, [computed.allSelected, actions]);
|
|
2432
2654
|
const handleFilterOpen = useCallback13(
|
|
2433
2655
|
(columnId) => {
|
|
2434
2656
|
if (shouldShowMobileView) {
|
|
@@ -2439,7 +2661,7 @@ function GridTableContent({
|
|
|
2439
2661
|
},
|
|
2440
2662
|
[shouldShowMobileView, actions]
|
|
2441
2663
|
);
|
|
2442
|
-
const containerStyle =
|
|
2664
|
+
const containerStyle = useMemo11(() => {
|
|
2443
2665
|
const baseStyle = { ...style, ...styles.root };
|
|
2444
2666
|
if (dimensions == null ? void 0 : dimensions.width) {
|
|
2445
2667
|
baseStyle.width = breakpointValue(dimensions.width, "auto");
|
|
@@ -2452,24 +2674,24 @@ function GridTableContent({
|
|
|
2452
2674
|
}
|
|
2453
2675
|
return baseStyle;
|
|
2454
2676
|
}, [style, styles.root, dimensions, breakpointValue]);
|
|
2455
|
-
const columnWidths =
|
|
2677
|
+
const columnWidths = useMemo11(() => {
|
|
2456
2678
|
return state.columnStates.map((cs) => cs.width);
|
|
2457
2679
|
}, [state.columnStates]);
|
|
2458
2680
|
if (error) {
|
|
2459
2681
|
const errorMessage = typeof error === "string" ? error : error.message;
|
|
2460
2682
|
if (errorContent) {
|
|
2461
|
-
return /* @__PURE__ */
|
|
2683
|
+
return /* @__PURE__ */ jsx12("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: typeof errorContent === "function" ? errorContent(error) : errorContent });
|
|
2462
2684
|
}
|
|
2463
|
-
return /* @__PURE__ */
|
|
2685
|
+
return /* @__PURE__ */ jsx12("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx12(
|
|
2464
2686
|
EmptyState,
|
|
2465
2687
|
{
|
|
2466
2688
|
title: state.translations.errorLoading,
|
|
2467
2689
|
description: errorMessage,
|
|
2468
|
-
action: onRetry && /* @__PURE__ */
|
|
2690
|
+
action: onRetry && /* @__PURE__ */ jsx12(
|
|
2469
2691
|
"button",
|
|
2470
2692
|
{
|
|
2471
2693
|
onClick: onRetry,
|
|
2472
|
-
className: "px-4 py-2 bg-accent-primary text-white rounded hover:
|
|
2694
|
+
className: "px-4 py-2 bg-accent-primary text-white rounded hover:opacity-90 cursor-pointer",
|
|
2473
2695
|
children: state.translations.retry
|
|
2474
2696
|
}
|
|
2475
2697
|
)
|
|
@@ -2478,9 +2700,9 @@ function GridTableContent({
|
|
|
2478
2700
|
}
|
|
2479
2701
|
if (loading) {
|
|
2480
2702
|
if (loadingContent) {
|
|
2481
|
-
return /* @__PURE__ */
|
|
2703
|
+
return /* @__PURE__ */ jsx12("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: loadingContent });
|
|
2482
2704
|
}
|
|
2483
|
-
return /* @__PURE__ */
|
|
2705
|
+
return /* @__PURE__ */ jsx12("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx12(
|
|
2484
2706
|
Skeleton,
|
|
2485
2707
|
{
|
|
2486
2708
|
rows: 5,
|
|
@@ -2494,44 +2716,44 @@ function GridTableContent({
|
|
|
2494
2716
|
) });
|
|
2495
2717
|
}
|
|
2496
2718
|
const isEmpty = computed.paginatedData.length === 0;
|
|
2497
|
-
|
|
2719
|
+
const tableContent = /* @__PURE__ */ jsxs9(
|
|
2498
2720
|
"div",
|
|
2499
2721
|
{
|
|
2500
|
-
className: `grid-table
|
|
2722
|
+
className: `grid-table rounded-lg border overflow-hidden ${classNames.root || ""} ${className}`,
|
|
2501
2723
|
style: containerStyle,
|
|
2502
2724
|
role: "table",
|
|
2503
2725
|
children: [
|
|
2504
|
-
renderHeader && /* @__PURE__ */
|
|
2505
|
-
showGlobalFilter && /* @__PURE__ */ jsxs9("div", { className: "grid-table-toolbar
|
|
2506
|
-
/* @__PURE__ */ jsxs9("div", { className: "
|
|
2507
|
-
/* @__PURE__ */
|
|
2726
|
+
renderHeader && /* @__PURE__ */ jsx12("div", { className: "grid-table-custom-header", children: renderHeader() }),
|
|
2727
|
+
showGlobalFilter && /* @__PURE__ */ jsxs9("div", { className: "grid-table-toolbar", children: [
|
|
2728
|
+
/* @__PURE__ */ jsxs9("div", { className: "toolbar-search-wrapper", children: [
|
|
2729
|
+
/* @__PURE__ */ jsx12(
|
|
2508
2730
|
"svg",
|
|
2509
2731
|
{
|
|
2510
|
-
className: "
|
|
2732
|
+
className: "search-icon",
|
|
2511
2733
|
fill: "none",
|
|
2512
2734
|
viewBox: "0 0 24 24",
|
|
2513
2735
|
stroke: "currentColor",
|
|
2514
2736
|
strokeWidth: 2,
|
|
2515
|
-
children: /* @__PURE__ */
|
|
2737
|
+
children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" })
|
|
2516
2738
|
}
|
|
2517
2739
|
),
|
|
2518
|
-
/* @__PURE__ */
|
|
2740
|
+
/* @__PURE__ */ jsx12(
|
|
2519
2741
|
"input",
|
|
2520
2742
|
{
|
|
2521
2743
|
type: "text",
|
|
2522
2744
|
value: state.globalFilter,
|
|
2523
2745
|
onChange: (e) => actions.setGlobalFilter(e.target.value),
|
|
2524
2746
|
placeholder: state.translations.search,
|
|
2525
|
-
className: "w-full pl-10 pr-3 py-2 text-sm rounded
|
|
2747
|
+
className: "w-full pl-10 pr-3 py-2 text-sm rounded"
|
|
2526
2748
|
}
|
|
2527
2749
|
),
|
|
2528
|
-
state.globalFilter && /* @__PURE__ */
|
|
2750
|
+
state.globalFilter && /* @__PURE__ */ jsx12(
|
|
2529
2751
|
"button",
|
|
2530
2752
|
{
|
|
2531
2753
|
onClick: () => actions.setGlobalFilter(""),
|
|
2532
|
-
className: "
|
|
2754
|
+
className: "clear-button",
|
|
2533
2755
|
"aria-label": "Clear search",
|
|
2534
|
-
children: /* @__PURE__ */
|
|
2756
|
+
children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
|
|
2535
2757
|
}
|
|
2536
2758
|
)
|
|
2537
2759
|
] }),
|
|
@@ -2539,9 +2761,9 @@ function GridTableContent({
|
|
|
2539
2761
|
"button",
|
|
2540
2762
|
{
|
|
2541
2763
|
onClick: () => actions.clearFilters(),
|
|
2542
|
-
className: "
|
|
2764
|
+
className: "filter-badge",
|
|
2543
2765
|
children: [
|
|
2544
|
-
/* @__PURE__ */
|
|
2766
|
+
/* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }),
|
|
2545
2767
|
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2546
2768
|
state.filters.length,
|
|
2547
2769
|
" filter",
|
|
@@ -2550,38 +2772,38 @@ function GridTableContent({
|
|
|
2550
2772
|
]
|
|
2551
2773
|
}
|
|
2552
2774
|
),
|
|
2553
|
-
shouldShowMobileView && /* @__PURE__ */ jsxs9("div", { className: "
|
|
2554
|
-
/* @__PURE__ */
|
|
2775
|
+
shouldShowMobileView && /* @__PURE__ */ jsxs9("div", { className: "toolbar-actions", children: [
|
|
2776
|
+
/* @__PURE__ */ jsx12(
|
|
2555
2777
|
"button",
|
|
2556
2778
|
{
|
|
2557
2779
|
onClick: () => actions.openMobileDrawer("filter"),
|
|
2558
|
-
className: "
|
|
2780
|
+
className: "toolbar-action-button",
|
|
2559
2781
|
"aria-label": state.translations.filter,
|
|
2560
|
-
children: /* @__PURE__ */
|
|
2782
|
+
children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" }) })
|
|
2561
2783
|
}
|
|
2562
2784
|
),
|
|
2563
|
-
/* @__PURE__ */
|
|
2785
|
+
/* @__PURE__ */ jsx12(
|
|
2564
2786
|
"button",
|
|
2565
2787
|
{
|
|
2566
2788
|
onClick: () => actions.openMobileDrawer("sort"),
|
|
2567
|
-
className: "
|
|
2789
|
+
className: "toolbar-action-button",
|
|
2568
2790
|
"aria-label": state.translations.sort,
|
|
2569
|
-
children: /* @__PURE__ */
|
|
2791
|
+
children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) })
|
|
2570
2792
|
}
|
|
2571
2793
|
),
|
|
2572
|
-
/* @__PURE__ */
|
|
2794
|
+
/* @__PURE__ */ jsx12(
|
|
2573
2795
|
"button",
|
|
2574
2796
|
{
|
|
2575
2797
|
onClick: () => actions.openMobileDrawer("columns"),
|
|
2576
|
-
className: "
|
|
2798
|
+
className: "toolbar-action-button",
|
|
2577
2799
|
"aria-label": state.translations.columns,
|
|
2578
|
-
children: /* @__PURE__ */
|
|
2800
|
+
children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" }) })
|
|
2579
2801
|
}
|
|
2580
2802
|
)
|
|
2581
2803
|
] })
|
|
2582
2804
|
] }),
|
|
2583
2805
|
/* @__PURE__ */ jsxs9("div", { className: "grid-table-container overflow-auto", children: [
|
|
2584
|
-
!shouldShowMobileView && /* @__PURE__ */
|
|
2806
|
+
!shouldShowMobileView && /* @__PURE__ */ jsx12(
|
|
2585
2807
|
GridHeader,
|
|
2586
2808
|
{
|
|
2587
2809
|
columns,
|
|
@@ -2594,24 +2816,25 @@ function GridTableContent({
|
|
|
2594
2816
|
enableDragDrop,
|
|
2595
2817
|
enableResize: enableColumnResize,
|
|
2596
2818
|
enableSelection: enableRowSelection,
|
|
2819
|
+
enableExpansion: enableRowExpansion,
|
|
2597
2820
|
allSelected: computed.allSelected,
|
|
2598
2821
|
someSelected: computed.someSelected,
|
|
2599
|
-
onSelectAll:
|
|
2822
|
+
onSelectAll: handleSelectAll,
|
|
2600
2823
|
onFilterOpen: handleFilterOpen,
|
|
2601
2824
|
getSortDirection: (colId) => {
|
|
2602
|
-
var
|
|
2825
|
+
var _a2;
|
|
2603
2826
|
const sort = state.sorting.find((s) => s.columnId === colId);
|
|
2604
|
-
return (
|
|
2827
|
+
return (_a2 = sort == null ? void 0 : sort.direction) != null ? _a2 : null;
|
|
2605
2828
|
}
|
|
2606
2829
|
}
|
|
2607
2830
|
),
|
|
2608
|
-
isEmpty ? emptyContent || /* @__PURE__ */
|
|
2831
|
+
isEmpty ? emptyContent || /* @__PURE__ */ jsx12(
|
|
2609
2832
|
EmptyState,
|
|
2610
2833
|
{
|
|
2611
2834
|
className: classNames.empty,
|
|
2612
2835
|
style: styles.empty
|
|
2613
2836
|
}
|
|
2614
|
-
) : /* @__PURE__ */
|
|
2837
|
+
) : /* @__PURE__ */ jsx12(
|
|
2615
2838
|
GridBody,
|
|
2616
2839
|
{
|
|
2617
2840
|
data: computed.paginatedData,
|
|
@@ -2626,7 +2849,7 @@ function GridTableContent({
|
|
|
2626
2849
|
selectedIds: state.selectedIds,
|
|
2627
2850
|
expandedIds: state.expandedIds,
|
|
2628
2851
|
onRowClick,
|
|
2629
|
-
onRowDoubleClick,
|
|
2852
|
+
onRowDoubleClick: handleRowDoubleClick,
|
|
2630
2853
|
onCellClick,
|
|
2631
2854
|
onRowSelect: handleRowSelect,
|
|
2632
2855
|
onRowExpand: handleRowExpand,
|
|
@@ -2638,27 +2861,50 @@ function GridTableContent({
|
|
|
2638
2861
|
}
|
|
2639
2862
|
)
|
|
2640
2863
|
] }),
|
|
2641
|
-
showPagination && !isEmpty && /* @__PURE__ */
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2864
|
+
showPagination && !isEmpty && /* @__PURE__ */ jsxs9("div", { className: `grid-pagination ${(_a = classNames.pagination) != null ? _a : ""}`, style: styles.pagination, role: "navigation", "aria-label": "Pagination", children: [
|
|
2865
|
+
/* @__PURE__ */ jsxs9("div", { className: "grid-pagination-info", children: [
|
|
2866
|
+
/* @__PURE__ */ jsxs9(Typography3, { component: "span", variant: "body2", color: "secondary", children: [
|
|
2867
|
+
(state.page - 1) * state.pageSize + 1,
|
|
2868
|
+
"-",
|
|
2869
|
+
Math.min(state.page * state.pageSize, computed.sortedData.length),
|
|
2870
|
+
" ",
|
|
2871
|
+
state.translations.of,
|
|
2872
|
+
" ",
|
|
2873
|
+
computed.sortedData.length
|
|
2874
|
+
] }),
|
|
2875
|
+
/* @__PURE__ */ jsx12(Typography3, { component: "span", variant: "caption", color: "secondary", className: "bear-sr-only", children: state.translations.rowsPerPage }),
|
|
2876
|
+
/* @__PURE__ */ jsx12(
|
|
2877
|
+
Select,
|
|
2878
|
+
{
|
|
2879
|
+
value: String(state.pageSize),
|
|
2880
|
+
onChange: (value) => {
|
|
2881
|
+
const pageSize = Number(value);
|
|
2882
|
+
actions.setPageSize(pageSize);
|
|
2883
|
+
onPageChange == null ? void 0 : onPageChange(1, pageSize);
|
|
2884
|
+
},
|
|
2885
|
+
options: ((_b = paginationConfig == null ? void 0 : paginationConfig.pageSizeOptions) != null ? _b : [10, 20, 50, 100]).map((size) => ({ value: String(size), label: String(size) })),
|
|
2886
|
+
size: "sm"
|
|
2887
|
+
}
|
|
2888
|
+
)
|
|
2889
|
+
] }),
|
|
2890
|
+
/* @__PURE__ */ jsx12("div", { className: "grid-pagination-controls", children: /* @__PURE__ */ jsx12(
|
|
2891
|
+
BearPagination,
|
|
2892
|
+
{
|
|
2893
|
+
count: Math.max(1, computed.totalPages),
|
|
2894
|
+
page: state.page,
|
|
2895
|
+
onChange: (page) => {
|
|
2896
|
+
actions.setPage(page);
|
|
2897
|
+
onPageChange == null ? void 0 : onPageChange(page, state.pageSize);
|
|
2898
|
+
},
|
|
2899
|
+
showFirstLast: true,
|
|
2900
|
+
showPrevNext: true,
|
|
2901
|
+
size: "sm",
|
|
2902
|
+
variant: "outlined"
|
|
2657
2903
|
}
|
|
2658
|
-
}
|
|
2659
|
-
),
|
|
2660
|
-
renderFooter && /* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
2904
|
+
) })
|
|
2905
|
+
] }),
|
|
2906
|
+
renderFooter && /* @__PURE__ */ jsx12("div", { className: "grid-table-custom-footer", children: renderFooter() }),
|
|
2907
|
+
/* @__PURE__ */ jsx12(
|
|
2662
2908
|
MobileDrawer,
|
|
2663
2909
|
{
|
|
2664
2910
|
isOpen: state.showMobileDrawer,
|
|
@@ -2671,6 +2917,10 @@ function GridTableContent({
|
|
|
2671
2917
|
]
|
|
2672
2918
|
}
|
|
2673
2919
|
);
|
|
2920
|
+
if (themeClass) {
|
|
2921
|
+
return /* @__PURE__ */ jsx12("div", { className: themeClass, children: tableContent });
|
|
2922
|
+
}
|
|
2923
|
+
return tableContent;
|
|
2674
2924
|
}
|
|
2675
2925
|
function GridTable({
|
|
2676
2926
|
data,
|
|
@@ -2685,12 +2935,26 @@ function GridTable({
|
|
|
2685
2935
|
sortConfig,
|
|
2686
2936
|
enableMultiSelect = false,
|
|
2687
2937
|
getRowId,
|
|
2938
|
+
showOverflowTooltip,
|
|
2939
|
+
enableCellAutoSizeOnDoubleClick,
|
|
2940
|
+
subCellExpandTrigger,
|
|
2941
|
+
expandRowOnDoubleClick,
|
|
2942
|
+
themeMode,
|
|
2943
|
+
themeOverride,
|
|
2944
|
+
studio = false,
|
|
2688
2945
|
...props
|
|
2689
2946
|
}) {
|
|
2690
|
-
|
|
2947
|
+
var _a, _b;
|
|
2948
|
+
const [studioData, setStudioData] = useState8(data);
|
|
2949
|
+
const [studioOpen, setStudioOpen] = useState8(true);
|
|
2950
|
+
useEffect6(() => {
|
|
2951
|
+
if (studio) setStudioData(data);
|
|
2952
|
+
}, [data, studio]);
|
|
2953
|
+
const effectiveData = studio ? studioData : data;
|
|
2954
|
+
const tableContent = /* @__PURE__ */ jsx12(
|
|
2691
2955
|
TableProvider,
|
|
2692
2956
|
{
|
|
2693
|
-
data,
|
|
2957
|
+
data: effectiveData,
|
|
2694
2958
|
columns,
|
|
2695
2959
|
loading,
|
|
2696
2960
|
error,
|
|
@@ -2703,19 +2967,223 @@ function GridTable({
|
|
|
2703
2967
|
enableMultiSort: sortConfig == null ? void 0 : sortConfig.multiSort,
|
|
2704
2968
|
enableMultiSelect,
|
|
2705
2969
|
getRowId,
|
|
2706
|
-
|
|
2970
|
+
showOverflowTooltip,
|
|
2971
|
+
enableCellAutoSizeOnDoubleClick,
|
|
2972
|
+
subCellExpandTrigger,
|
|
2973
|
+
expandRowOnDoubleClick,
|
|
2974
|
+
children: /* @__PURE__ */ jsx12(
|
|
2707
2975
|
GridTableContent,
|
|
2708
2976
|
{
|
|
2709
|
-
data,
|
|
2977
|
+
data: effectiveData,
|
|
2710
2978
|
columns,
|
|
2711
2979
|
loading,
|
|
2712
2980
|
error,
|
|
2713
2981
|
getRowId,
|
|
2982
|
+
themeMode,
|
|
2983
|
+
paginationConfig,
|
|
2714
2984
|
...props
|
|
2715
2985
|
}
|
|
2716
2986
|
)
|
|
2717
2987
|
}
|
|
2718
2988
|
);
|
|
2989
|
+
const withTheme = themeOverride && Object.keys(themeOverride).length > 0 ? /* @__PURE__ */ jsx12(BearProvider, { theme: themeOverride, defaultMode: themeMode === "dark" ? "dark" : "light", children: tableContent }) : tableContent;
|
|
2990
|
+
if (studio) {
|
|
2991
|
+
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
2992
|
+
/* @__PURE__ */ jsx12("div", { className: "grid-table-studio-main", style: { width: "100%" }, children: withTheme }),
|
|
2993
|
+
/* @__PURE__ */ jsx12(
|
|
2994
|
+
TableStudioPanel,
|
|
2995
|
+
{
|
|
2996
|
+
data: studioData,
|
|
2997
|
+
columns,
|
|
2998
|
+
propsSnapshot: {
|
|
2999
|
+
themeMode,
|
|
3000
|
+
themeOverride,
|
|
3001
|
+
showPagination: (_a = props.showPagination) != null ? _a : true,
|
|
3002
|
+
showGlobalFilter: (_b = props.showGlobalFilter) != null ? _b : true,
|
|
3003
|
+
enableRowSelection: props.enableRowSelection,
|
|
3004
|
+
enableRowExpansion: props.enableRowExpansion
|
|
3005
|
+
},
|
|
3006
|
+
onDataChange: setStudioData,
|
|
3007
|
+
open: studioOpen,
|
|
3008
|
+
onOpenChange: setStudioOpen
|
|
3009
|
+
}
|
|
3010
|
+
)
|
|
3011
|
+
] });
|
|
3012
|
+
}
|
|
3013
|
+
return withTheme;
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
// src/components/Pagination/Pagination.tsx
|
|
3017
|
+
import { useMemo as useMemo12, useCallback as useCallback14 } from "react";
|
|
3018
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3019
|
+
function Pagination({
|
|
3020
|
+
page,
|
|
3021
|
+
pageSize,
|
|
3022
|
+
totalItems,
|
|
3023
|
+
totalPages,
|
|
3024
|
+
pageSizeOptions = [10, 20, 50, 100],
|
|
3025
|
+
showFirstLast = true,
|
|
3026
|
+
showPageNumbers = true,
|
|
3027
|
+
maxPageButtons = FIVE,
|
|
3028
|
+
className = "",
|
|
3029
|
+
style,
|
|
3030
|
+
onPageChange,
|
|
3031
|
+
onPageSizeChange
|
|
3032
|
+
}) {
|
|
3033
|
+
const { state } = useTableContext();
|
|
3034
|
+
const { translations } = state;
|
|
3035
|
+
const canGoPrevious = page > ONE;
|
|
3036
|
+
const canGoNext = page < totalPages;
|
|
3037
|
+
const startItem = (page - ONE) * pageSize + ONE;
|
|
3038
|
+
const endItem = Math.min(page * pageSize, totalItems);
|
|
3039
|
+
const handleFirstPage = useCallback14(() => {
|
|
3040
|
+
onPageChange(ONE);
|
|
3041
|
+
}, [onPageChange]);
|
|
3042
|
+
const handlePreviousPage = useCallback14(() => {
|
|
3043
|
+
if (canGoPrevious) {
|
|
3044
|
+
onPageChange(page - ONE);
|
|
3045
|
+
}
|
|
3046
|
+
}, [canGoPrevious, page, onPageChange]);
|
|
3047
|
+
const handleNextPage = useCallback14(() => {
|
|
3048
|
+
if (canGoNext) {
|
|
3049
|
+
onPageChange(page + ONE);
|
|
3050
|
+
}
|
|
3051
|
+
}, [canGoNext, page, onPageChange]);
|
|
3052
|
+
const handleLastPage = useCallback14(() => {
|
|
3053
|
+
onPageChange(totalPages);
|
|
3054
|
+
}, [onPageChange, totalPages]);
|
|
3055
|
+
const handlePageSizeChange = useCallback14(
|
|
3056
|
+
(event) => {
|
|
3057
|
+
onPageSizeChange(Number(event.target.value));
|
|
3058
|
+
},
|
|
3059
|
+
[onPageSizeChange]
|
|
3060
|
+
);
|
|
3061
|
+
const pageNumbers = useMemo12(() => {
|
|
3062
|
+
if (!showPageNumbers || totalPages <= ONE) return [];
|
|
3063
|
+
const pages = [];
|
|
3064
|
+
const halfMax = Math.floor(maxPageButtons / 2);
|
|
3065
|
+
let start = Math.max(ONE, page - halfMax);
|
|
3066
|
+
let end = Math.min(totalPages, page + halfMax);
|
|
3067
|
+
if (page <= halfMax) {
|
|
3068
|
+
end = Math.min(totalPages, maxPageButtons);
|
|
3069
|
+
}
|
|
3070
|
+
if (page > totalPages - halfMax) {
|
|
3071
|
+
start = Math.max(ONE, totalPages - maxPageButtons + ONE);
|
|
3072
|
+
}
|
|
3073
|
+
if (start > ONE) {
|
|
3074
|
+
pages.push(ONE);
|
|
3075
|
+
if (start > 2) {
|
|
3076
|
+
pages.push("ellipsis");
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
for (let i = start; i <= end; i++) {
|
|
3080
|
+
if (!pages.includes(i)) {
|
|
3081
|
+
pages.push(i);
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
if (end < totalPages) {
|
|
3085
|
+
if (end < totalPages - ONE) {
|
|
3086
|
+
pages.push("ellipsis");
|
|
3087
|
+
}
|
|
3088
|
+
pages.push(totalPages);
|
|
3089
|
+
}
|
|
3090
|
+
return pages;
|
|
3091
|
+
}, [page, totalPages, showPageNumbers, maxPageButtons]);
|
|
3092
|
+
if (totalItems === 0) {
|
|
3093
|
+
return null;
|
|
3094
|
+
}
|
|
3095
|
+
return /* @__PURE__ */ jsxs10(
|
|
3096
|
+
"div",
|
|
3097
|
+
{
|
|
3098
|
+
className: `grid-pagination ${className}`,
|
|
3099
|
+
style,
|
|
3100
|
+
role: "navigation",
|
|
3101
|
+
"aria-label": "Pagination",
|
|
3102
|
+
children: [
|
|
3103
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid-pagination-info", children: [
|
|
3104
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid-pagination-range", children: [
|
|
3105
|
+
startItem,
|
|
3106
|
+
"-",
|
|
3107
|
+
endItem,
|
|
3108
|
+
" ",
|
|
3109
|
+
translations.of,
|
|
3110
|
+
" ",
|
|
3111
|
+
totalItems
|
|
3112
|
+
] }),
|
|
3113
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid-pagination-size", children: [
|
|
3114
|
+
/* @__PURE__ */ jsxs10("label", { htmlFor: "page-size", children: [
|
|
3115
|
+
translations.rowsPerPage,
|
|
3116
|
+
":"
|
|
3117
|
+
] }),
|
|
3118
|
+
/* @__PURE__ */ jsx13(
|
|
3119
|
+
"select",
|
|
3120
|
+
{
|
|
3121
|
+
id: "page-size",
|
|
3122
|
+
value: pageSize,
|
|
3123
|
+
onChange: handlePageSizeChange,
|
|
3124
|
+
className: "px-2 py-1 text-sm rounded",
|
|
3125
|
+
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx13("option", { value: size, children: size }, size))
|
|
3126
|
+
}
|
|
3127
|
+
)
|
|
3128
|
+
] })
|
|
3129
|
+
] }),
|
|
3130
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid-pagination-controls", children: [
|
|
3131
|
+
showFirstLast && /* @__PURE__ */ jsx13(
|
|
3132
|
+
"button",
|
|
3133
|
+
{
|
|
3134
|
+
onClick: handleFirstPage,
|
|
3135
|
+
disabled: !canGoPrevious,
|
|
3136
|
+
className: "p-2 rounded text-theme-secondary",
|
|
3137
|
+
"aria-label": translations.first,
|
|
3138
|
+
children: "<<"
|
|
3139
|
+
}
|
|
3140
|
+
),
|
|
3141
|
+
/* @__PURE__ */ jsx13(
|
|
3142
|
+
"button",
|
|
3143
|
+
{
|
|
3144
|
+
onClick: handlePreviousPage,
|
|
3145
|
+
disabled: !canGoPrevious,
|
|
3146
|
+
className: "p-2 rounded text-theme-secondary",
|
|
3147
|
+
"aria-label": translations.previous,
|
|
3148
|
+
children: "<"
|
|
3149
|
+
}
|
|
3150
|
+
),
|
|
3151
|
+
showPageNumbers && /* @__PURE__ */ jsx13("div", { className: "grid-pagination-pages", children: pageNumbers.map(
|
|
3152
|
+
(pageNum, index) => pageNum === "ellipsis" ? /* @__PURE__ */ jsx13("span", { className: "px-2 text-theme-muted", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ jsx13(
|
|
3153
|
+
"button",
|
|
3154
|
+
{
|
|
3155
|
+
onClick: () => onPageChange(pageNum),
|
|
3156
|
+
className: `min-w-[32px] h-8 px-2 rounded text-sm ${pageNum === page ? "active" : ""}`,
|
|
3157
|
+
"aria-current": pageNum === page ? "page" : void 0,
|
|
3158
|
+
children: pageNum
|
|
3159
|
+
},
|
|
3160
|
+
pageNum
|
|
3161
|
+
)
|
|
3162
|
+
) }),
|
|
3163
|
+
/* @__PURE__ */ jsx13(
|
|
3164
|
+
"button",
|
|
3165
|
+
{
|
|
3166
|
+
onClick: handleNextPage,
|
|
3167
|
+
disabled: !canGoNext,
|
|
3168
|
+
className: "p-2 rounded text-theme-secondary",
|
|
3169
|
+
"aria-label": translations.next,
|
|
3170
|
+
children: ">"
|
|
3171
|
+
}
|
|
3172
|
+
),
|
|
3173
|
+
showFirstLast && /* @__PURE__ */ jsx13(
|
|
3174
|
+
"button",
|
|
3175
|
+
{
|
|
3176
|
+
onClick: handleLastPage,
|
|
3177
|
+
disabled: !canGoNext,
|
|
3178
|
+
className: "p-2 rounded text-theme-secondary",
|
|
3179
|
+
"aria-label": translations.last,
|
|
3180
|
+
children: ">>"
|
|
3181
|
+
}
|
|
3182
|
+
)
|
|
3183
|
+
] })
|
|
3184
|
+
]
|
|
3185
|
+
}
|
|
3186
|
+
);
|
|
2719
3187
|
}
|
|
2720
3188
|
export {
|
|
2721
3189
|
BREAKPOINTS,
|