@ornery/ui-grid-react 0.1.5 → 0.1.6

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,3 +1,6 @@
1
+ // src/UiGrid.tsx
2
+ import React from "react";
3
+
1
4
  // src/useGridState.ts
2
5
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
6
 
@@ -28,9 +31,9 @@ function computeViewportRows(viewportHeight, rowHeight) {
28
31
  // src/useGridState.ts
29
32
  import {
30
33
  createGridApi,
31
- getCellValue as getCellValue2,
34
+ getCellValue,
32
35
  setPathValue,
33
- SORT_DIRECTIONS as SORT_DIRECTIONS2,
36
+ SORT_DIRECTIONS,
34
37
  defaultGridEngine,
35
38
  resolveGridLabels,
36
39
  gridColumnWidth as gridColumnWidth2,
@@ -86,679 +89,47 @@ import {
86
89
  FEATURE_COLUMN_MOVING,
87
90
  FEATURE_CSV_EXPORT,
88
91
  FEATURE_AUTO_RESIZE,
89
- FEATURE_PINNING
92
+ FEATURE_PINNING,
93
+ buildInitialPinnedState,
94
+ computePinnedOffset,
95
+ isColumnPinnable,
96
+ isPinningEnabled,
97
+ applyGridSortStateCommand,
98
+ updateGridFilterCommand,
99
+ clearGridFiltersCommand,
100
+ clearGridGroupingCommand,
101
+ moveGridColumnCommand,
102
+ seekGridPaginationCommand,
103
+ setGridPaginationPageSizeCommand,
104
+ sortGridColumnCommand,
105
+ toggleGridRowExpansionCommand,
106
+ expandAllGridRowsCommand,
107
+ collapseAllGridRowsCommand,
108
+ toggleGridTreeRowCommand,
109
+ setGridTreeRowExpandedCommand,
110
+ expandAllGridTreeRowsCommand,
111
+ collapseAllGridTreeRowsCommand,
112
+ beginGridCellEditCommand,
113
+ commitGridCellEditCommand,
114
+ cancelGridCellEditCommand,
115
+ maybeRequestInfiniteScrollCommand,
116
+ completeGridInfiniteScrollDataLoadCommand,
117
+ resetGridInfiniteScrollCommand,
118
+ saveGridInfiniteScrollPercentageCommand,
119
+ setGridInfiniteScrollDirectionsCommand,
120
+ restoreGridStateCommand,
121
+ pinGridColumnCommand,
122
+ raiseGridRenderingComplete,
123
+ raiseGridRowsRendered,
124
+ raiseGridRowsVisibleChanged,
125
+ raiseGridCanvasHeightChanged,
126
+ raiseGridDimensionChanged,
127
+ raiseGridScrollBegin,
128
+ raiseGridScrollEnd,
129
+ raiseGridBenchmarkComplete,
130
+ downloadGridCsvFile,
131
+ observeGridHostSize
90
132
  } from "@ornery/ui-grid";
91
-
92
- // ../ui-grid/src/lib/grid/grid.core.pagination.ts
93
- function seekGridPage(page, totalPages) {
94
- return Math.min(Math.max(page, 1), Math.max(totalPages, 1));
95
- }
96
- function resolveGridPageSize(pageSize) {
97
- return Number.isFinite(pageSize) && pageSize > 0 ? pageSize : null;
98
- }
99
-
100
- // ../ui-grid/src/lib/grid/grid.constants.ts
101
- var SORT_DIRECTIONS = {
102
- asc: "asc",
103
- desc: "desc",
104
- none: "none"
105
- };
106
-
107
- // ../ui-grid/src/lib/grid/grid.utils.ts
108
- var PROTECTED_PATH_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
109
- function getPathValue(record, path) {
110
- return path.split(".").reduce((current, part) => {
111
- if (current === null || current === void 0 || typeof current !== "object") {
112
- return void 0;
113
- }
114
- if (PROTECTED_PATH_SEGMENTS.has(part)) {
115
- return void 0;
116
- }
117
- if (!Object.prototype.hasOwnProperty.call(current, part)) {
118
- return void 0;
119
- }
120
- return current[part];
121
- }, record);
122
- }
123
- function getCellValue(row, column) {
124
- if (column.valueGetter) {
125
- return column.valueGetter(row);
126
- }
127
- if (column.field) {
128
- return getPathValue(row, column.field);
129
- }
130
- return row[column.name];
131
- }
132
-
133
- // ../ui-grid/src/lib/grid/grid.core.identity.ts
134
- function buildGridSortState(columnName, direction) {
135
- return {
136
- columnName,
137
- direction: direction ?? SORT_DIRECTIONS.asc
138
- };
139
- }
140
-
141
- // ../ui-grid/src/lib/grid/grid.core.edit.ts
142
- function beginGridEditSession(rowId, columnName, editingValue) {
143
- const position = { rowId, columnName };
144
- return {
145
- focusedCell: position,
146
- editingCell: position,
147
- editingValue
148
- };
149
- }
150
- function clearGridEditSession() {
151
- return {
152
- editingCell: null,
153
- editingValue: ""
154
- };
155
- }
156
- function stringifyGridEditorValue(value) {
157
- if (value instanceof Date) {
158
- return value.toISOString().slice(0, 10);
159
- }
160
- return value === null || value === void 0 ? "" : String(value);
161
- }
162
-
163
- // ../ui-grid/src/lib/grid/grid.core.infinite-scroll.ts
164
- function maybeRequestInfiniteScrollData(context) {
165
- if (context.state.dataLoading) {
166
- return { request: null, nextState: context.state };
167
- }
168
- if (context.state.scrollUp && context.startIndex <= context.threshold) {
169
- return {
170
- request: "top",
171
- nextState: {
172
- ...context.state,
173
- dataLoading: true,
174
- previousVisibleRows: context.visibleRows
175
- }
176
- };
177
- }
178
- if (context.state.scrollDown && context.startIndex + context.viewportRows >= Math.max(context.visibleRows - context.threshold, 0)) {
179
- return {
180
- request: "bottom",
181
- nextState: {
182
- ...context.state,
183
- dataLoading: true,
184
- previousVisibleRows: context.visibleRows
185
- }
186
- };
187
- }
188
- return { request: null, nextState: context.state };
189
- }
190
- function completeInfiniteScrollDataLoad(state, scrollUp, scrollDown) {
191
- return {
192
- ...state,
193
- scrollUp,
194
- scrollDown,
195
- dataLoading: false
196
- };
197
- }
198
- function resetInfiniteScrollState(scrollUp, scrollDown) {
199
- return {
200
- scrollUp,
201
- scrollDown,
202
- dataLoading: false,
203
- previousVisibleRows: 0
204
- };
205
- }
206
- function saveInfiniteScrollPercentage(state, visibleRows) {
207
- return {
208
- ...state,
209
- previousVisibleRows: visibleRows
210
- };
211
- }
212
- function setInfiniteScrollDirectionsState(state, scrollUp, scrollDown) {
213
- return {
214
- ...state,
215
- scrollUp,
216
- scrollDown
217
- };
218
- }
219
-
220
- // ../ui-grid/src/lib/grid/grid.core.row-state.ts
221
- function toggleGridRowExpanded(expandedRows, rowId) {
222
- const expanded = !expandedRows[rowId];
223
- return {
224
- expanded,
225
- nextExpandedRows: {
226
- ...expandedRows,
227
- [rowId]: expanded
228
- }
229
- };
230
- }
231
- function expandAllGridRows(rows) {
232
- const nextExpandedRows = {};
233
- for (const row of rows) {
234
- nextExpandedRows[row.id] = true;
235
- }
236
- return nextExpandedRows;
237
- }
238
- function setGridTreeRowExpanded(expandedTreeRows, rowId, expanded) {
239
- return {
240
- ...expandedTreeRows,
241
- [rowId]: expanded
242
- };
243
- }
244
- function toggleGridTreeRowExpanded(expandedTreeRows, rowId) {
245
- const expanded = !expandedTreeRows[rowId];
246
- return {
247
- expanded,
248
- nextExpandedTreeRows: setGridTreeRowExpanded(expandedTreeRows, rowId, expanded)
249
- };
250
- }
251
- function expandAllGridTreeRows(rows) {
252
- const nextExpandedTreeRows = {};
253
- for (const row of rows) {
254
- if (row.hasChildren) {
255
- nextExpandedTreeRows[row.id] = true;
256
- }
257
- }
258
- return nextExpandedTreeRows;
259
- }
260
-
261
- // ../ui-grid/src/lib/grid/grid.core.state.ts
262
- function normalizeGridSavedState(state) {
263
- const normalized = {};
264
- if (Array.isArray(state.columnOrder)) {
265
- normalized.columnOrder = state.columnOrder.filter(
266
- (columnName) => typeof columnName === "string" && isSafeStateKey(columnName)
267
- );
268
- }
269
- if (state.filters && typeof state.filters === "object") {
270
- normalized.filters = Object.entries(state.filters).reduce(
271
- (accumulator, [key, value]) => {
272
- if (typeof key === "string" && isSafeStateKey(key) && typeof value === "string") {
273
- accumulator[key] = value;
274
- }
275
- return accumulator;
276
- },
277
- {}
278
- );
279
- }
280
- if (state.sort && typeof state.sort === "object") {
281
- normalized.sort = {
282
- columnName: typeof state.sort.columnName === "string" && isSafeStateKey(state.sort.columnName) ? state.sort.columnName : null,
283
- direction: state.sort.direction === SORT_DIRECTIONS.asc || state.sort.direction === SORT_DIRECTIONS.desc ? state.sort.direction : SORT_DIRECTIONS.none
284
- };
285
- }
286
- if (Array.isArray(state.grouping)) {
287
- normalized.grouping = state.grouping.filter(
288
- (columnName) => typeof columnName === "string" && isSafeStateKey(columnName)
289
- );
290
- }
291
- if (state.pagination && typeof state.pagination === "object") {
292
- const paginationCurrentPage = Number(state.pagination.paginationCurrentPage);
293
- const paginationPageSize = Number(state.pagination.paginationPageSize);
294
- normalized.pagination = {
295
- paginationCurrentPage: Number.isFinite(paginationCurrentPage) && paginationCurrentPage > 0 ? Math.floor(paginationCurrentPage) : 1,
296
- paginationPageSize: Number.isFinite(paginationPageSize) && paginationPageSize >= 0 ? Math.floor(paginationPageSize) : 0
297
- };
298
- }
299
- if (state.expandable && typeof state.expandable === "object") {
300
- normalized.expandable = normalizeBooleanMap(state.expandable);
301
- }
302
- if (state.treeView && typeof state.treeView === "object") {
303
- normalized.treeView = normalizeBooleanMap(state.treeView);
304
- }
305
- if (state.pinning && typeof state.pinning === "object") {
306
- normalized.pinning = Object.entries(state.pinning).reduce(
307
- (acc, [key, value]) => {
308
- if (typeof key === "string" && isSafeStateKey(key) && (value === "left" || value === "right")) {
309
- acc[key] = value;
310
- }
311
- return acc;
312
- },
313
- {}
314
- );
315
- }
316
- return normalized;
317
- }
318
- function normalizeBooleanMap(value) {
319
- return Object.entries(value).reduce((accumulator, [key, entry]) => {
320
- if (typeof key === "string" && isSafeStateKey(key) && typeof entry === "boolean") {
321
- accumulator[key] = entry;
322
- }
323
- return accumulator;
324
- }, {});
325
- }
326
- function isSafeStateKey(value) {
327
- return value !== "__proto__" && value !== "constructor" && value !== "prototype";
328
- }
329
-
330
- // ../ui-grid/src/lib/grid/grid.core.pinning.ts
331
- function isPinningEnabled(options) {
332
- return options.enablePinning === true;
333
- }
334
- function isColumnPinnable(options, column) {
335
- return isPinningEnabled(options) && column.enablePinning !== false;
336
- }
337
- function pinColumnState(current, columnName, direction) {
338
- const next = { ...current };
339
- if (direction === "none") {
340
- delete next[columnName];
341
- } else {
342
- next[columnName] = direction;
343
- }
344
- return next;
345
- }
346
- function buildInitialPinnedState(columns) {
347
- const state = {};
348
- for (const col of columns) {
349
- if (col.pinnedLeft) state[col.name] = "left";
350
- else if (col.pinnedRight) state[col.name] = "right";
351
- }
352
- return state;
353
- }
354
- function computePinnedOffset(visibleColumns, pinnedColumns, column) {
355
- const direction = pinnedColumns[column.name];
356
- if (!direction) return null;
357
- function resolveColumnWidthForOffset(column2) {
358
- const w = column2.width;
359
- if (!w) return "11rem";
360
- if (w.includes("fr") || w.includes("minmax")) return "11rem";
361
- return w;
362
- }
363
- if (direction === "left") {
364
- const offsetParts = [];
365
- for (const col of visibleColumns) {
366
- if (col.name === column.name) break;
367
- if (pinnedColumns[col.name] === "left") {
368
- offsetParts.push(resolveColumnWidthForOffset(col));
369
- }
370
- }
371
- return {
372
- side: "left",
373
- offset: offsetParts.length > 0 ? `calc(${offsetParts.join(" + ")})` : "0px"
374
- };
375
- }
376
- if (direction === "right") {
377
- const offsetParts = [];
378
- const reversed = [...visibleColumns].reverse();
379
- for (const col of reversed) {
380
- if (col.name === column.name) break;
381
- if (pinnedColumns[col.name] === "right") {
382
- offsetParts.push(resolveColumnWidthForOffset(col));
383
- }
384
- }
385
- return {
386
- side: "right",
387
- offset: offsetParts.length > 0 ? `calc(${offsetParts.join(" + ")})` : "0px"
388
- };
389
- }
390
- return null;
391
- }
392
-
393
- // ../ui-grid/src/lib/grid/ui-grid.events.ts
394
- function raiseGridRenderingComplete(gridApi) {
395
- gridApi.core.raise.renderingComplete(gridApi);
396
- }
397
- function raiseGridRowsRendered(gridApi, rows) {
398
- gridApi.core.raise.rowsRendered(rows);
399
- }
400
- function raiseGridRowsVisibleChanged(gridApi, rows) {
401
- gridApi.core.raise.rowsVisibleChanged(rows);
402
- }
403
- function raiseGridCanvasHeightChanged(gridApi, oldHeight, newHeight) {
404
- gridApi.core.raise.canvasHeightChanged(oldHeight, newHeight);
405
- }
406
- function raiseGridDimensionChanged(gridApi, oldHeight, oldWidth, newHeight, newWidth) {
407
- gridApi.core.raise.gridDimensionChanged(oldHeight, oldWidth, newHeight, newWidth);
408
- }
409
- function raiseGridScrollBegin(gridApi) {
410
- gridApi.core.raise.scrollBegin();
411
- }
412
- function raiseGridScrollEnd(gridApi) {
413
- gridApi.core.raise.scrollEnd();
414
- }
415
- function raiseGridSortChanged(gridApi, sortState) {
416
- gridApi.core.raise.sortChanged(sortState.columnName, sortState.direction);
417
- }
418
- function raiseGridFilterChanged(gridApi, filters) {
419
- gridApi.core.raise.filterChanged(filters);
420
- }
421
- function raiseGridGroupingChanged(gridApi, groupByColumns) {
422
- gridApi.core.raise.groupingChanged(groupByColumns);
423
- }
424
- function raiseGridColumnOrderChanged(gridApi, order) {
425
- gridApi.core.raise.columnOrderChanged(order);
426
- }
427
- function raiseGridBenchmarkComplete(gridApi, result) {
428
- gridApi.core.raise.benchmarkComplete(result);
429
- }
430
- function raiseGridPaginationChanged(gridApi, currentPage, pageSize) {
431
- gridApi.pagination.raise.paginationChanged(currentPage, pageSize);
432
- }
433
- function raiseGridExpandableRowStateChanged(gridApi, row, expanded) {
434
- gridApi.expandable.raise.rowExpandedStateChanged(row, expanded);
435
- }
436
- function raiseGridTreeRowStateChanged(gridApi, row, expanded) {
437
- if (expanded) {
438
- gridApi.treeBase.raise.rowExpanded(row);
439
- return;
440
- }
441
- gridApi.treeBase.raise.rowCollapsed(row);
442
- }
443
- function raiseGridNeedMoreData(gridApi, request) {
444
- if (request === "top") {
445
- gridApi.infiniteScroll.raise.needLoadMoreDataTop();
446
- return;
447
- }
448
- gridApi.infiniteScroll.raise.needLoadMoreData();
449
- }
450
- function raiseGridBeginCellEdit(gridApi, rowEntity, column, triggerEvent) {
451
- gridApi.edit.raise.beginCellEdit(rowEntity, column, triggerEvent);
452
- }
453
- function raiseGridAfterCellEdit(gridApi, rowEntity, column, newValue, oldValue) {
454
- gridApi.edit.raise.afterCellEdit(rowEntity, column, newValue, oldValue);
455
- }
456
- function raiseGridCancelCellEdit(gridApi, rowEntity, column) {
457
- gridApi.edit.raise.cancelCellEdit(rowEntity, column);
458
- }
459
- function raiseGridColumnPinned(gridApi, columnName, direction) {
460
- gridApi.pinning.raise.columnPinned(columnName, direction);
461
- }
462
-
463
- // ../ui-grid/src/lib/grid/ui-grid.state.ts
464
- function moveArrayItem(items, fromIndex, toIndex) {
465
- const next = [...items];
466
- const [item] = next.splice(fromIndex, 1);
467
- if (item === void 0) {
468
- return next;
469
- }
470
- next.splice(toIndex, 0, item);
471
- return next;
472
- }
473
- function moveGridColumnOrderState(current, fromIndex, toIndex) {
474
- return moveArrayItem(current, fromIndex, toIndex);
475
- }
476
- function createGridRestoreMutationPlan(state) {
477
- const normalizedState = normalizeGridSavedState(state);
478
- const plan = {};
479
- if (normalizedState.columnOrder) {
480
- plan.columnOrder = normalizedState.columnOrder;
481
- }
482
- if (normalizedState.filters) {
483
- plan.filters = normalizedState.filters;
484
- }
485
- if (normalizedState.sort) {
486
- plan.sort = normalizedState.sort;
487
- }
488
- if (normalizedState.grouping) {
489
- plan.grouping = normalizedState.grouping;
490
- }
491
- if (normalizedState.pagination) {
492
- plan.pagination = {
493
- currentPage: normalizedState.pagination.paginationCurrentPage,
494
- pageSize: normalizedState.pagination.paginationPageSize
495
- };
496
- }
497
- if (normalizedState.expandable) {
498
- plan.expandable = normalizedState.expandable;
499
- }
500
- if (normalizedState.treeView) {
501
- plan.treeView = normalizedState.treeView;
502
- }
503
- if (normalizedState.pinning) {
504
- plan.pinning = normalizedState.pinning;
505
- }
506
- return plan;
507
- }
508
-
509
- // ../ui-grid/src/lib/grid/ui-grid.commands.ts
510
- function applyGridSortStateCommand(gridApi, setSortState, sortState) {
511
- setSortState(sortState);
512
- raiseGridSortChanged(gridApi, sortState);
513
- }
514
- function sortGridColumnCommand(gridApi, setSortState, columnName, direction) {
515
- applyGridSortStateCommand(gridApi, setSortState, buildGridSortState(columnName, direction));
516
- }
517
- function updateGridFilterCommand(gridApi, updateFilters, getFilters, columnName, value) {
518
- updateFilters((current) => ({
519
- ...current,
520
- [columnName]: value
521
- }));
522
- raiseGridFilterChanged(gridApi, getFilters());
523
- }
524
- function clearGridFiltersCommand(gridApi, setFilters) {
525
- const nextFilters = {};
526
- setFilters(nextFilters);
527
- raiseGridFilterChanged(gridApi, nextFilters);
528
- }
529
- function clearGridGroupingCommand(gridApi, setGroupByColumns, shouldRaise = true) {
530
- const nextGrouping = [];
531
- setGroupByColumns(nextGrouping);
532
- if (shouldRaise) {
533
- raiseGridGroupingChanged(gridApi, nextGrouping);
534
- }
535
- }
536
- function moveGridColumnCommand(gridApi, canMoveColumns, updateColumnOrder, fromIndex, toIndex) {
537
- if (!canMoveColumns) {
538
- return;
539
- }
540
- updateColumnOrder((current) => {
541
- const next = moveGridColumnOrderState(current, fromIndex, toIndex);
542
- raiseGridColumnOrderChanged(gridApi, next);
543
- return next;
544
- });
545
- }
546
- function pinGridColumnCommand(gridApi, isPinningEnabled2, setPinnedColumns, getCurrentPinnedColumns, columnName, direction) {
547
- if (!isPinningEnabled2) return;
548
- const next = pinColumnState(getCurrentPinnedColumns(), columnName, direction);
549
- setPinnedColumns(next);
550
- raiseGridColumnPinned(gridApi, columnName, direction);
551
- }
552
- function seekGridPaginationCommand(gridApi, setCurrentPage, getTotalPages, getEffectivePageSize, page) {
553
- const nextPage = seekGridPage(page, getTotalPages());
554
- setCurrentPage(nextPage);
555
- raiseGridPaginationChanged(gridApi, nextPage, getEffectivePageSize());
556
- }
557
- function setGridPaginationPageSizeCommand(gridApi, setPageSize, setCurrentPage, pageSize) {
558
- const nextPageSize = resolveGridPageSize(pageSize);
559
- if (nextPageSize === null) {
560
- return;
561
- }
562
- setPageSize(nextPageSize);
563
- setCurrentPage(1);
564
- raiseGridPaginationChanged(gridApi, 1, nextPageSize);
565
- }
566
- function restoreGridStateCommand(gridApi, state, access) {
567
- const restorePlan = createGridRestoreMutationPlan(state);
568
- if (restorePlan.columnOrder) {
569
- access.setColumnOrder(restorePlan.columnOrder);
570
- }
571
- if (restorePlan.filters) {
572
- access.setActiveFilters(restorePlan.filters);
573
- raiseGridFilterChanged(gridApi, restorePlan.filters);
574
- }
575
- if (restorePlan.sort) {
576
- access.setSortState(restorePlan.sort);
577
- }
578
- if (restorePlan.grouping) {
579
- access.setGroupByColumns(restorePlan.grouping);
580
- raiseGridGroupingChanged(gridApi, restorePlan.grouping);
581
- }
582
- if (restorePlan.pagination) {
583
- access.setCurrentPage(restorePlan.pagination.currentPage);
584
- access.setPageSize(restorePlan.pagination.pageSize);
585
- raiseGridPaginationChanged(
586
- gridApi,
587
- restorePlan.pagination.currentPage,
588
- access.getEffectivePageSize()
589
- );
590
- }
591
- if (restorePlan.expandable) {
592
- access.setExpandedRows(restorePlan.expandable);
593
- }
594
- if (restorePlan.treeView) {
595
- access.setExpandedTreeRows(restorePlan.treeView);
596
- }
597
- if (restorePlan.pinning && typeof access.setPinnedColumns === "function") {
598
- access.setPinnedColumns(restorePlan.pinning);
599
- for (const [col, dir] of Object.entries(restorePlan.pinning)) {
600
- raiseGridColumnPinned(gridApi, col, dir);
601
- }
602
- }
603
- }
604
- function toggleGridRowExpansionCommand(gridApi, canExpandRows, currentExpandedRows, rowId, setExpandedRows, findRowById) {
605
- if (!canExpandRows) {
606
- return;
607
- }
608
- const { expanded, nextExpandedRows } = toggleGridRowExpanded(currentExpandedRows, rowId);
609
- setExpandedRows(nextExpandedRows);
610
- const gridRow = findRowById(rowId);
611
- if (!gridRow) {
612
- return;
613
- }
614
- gridRow.expanded = expanded;
615
- raiseGridExpandableRowStateChanged(gridApi, gridRow, expanded);
616
- }
617
- function expandAllGridRowsCommand(buildRows, data, setExpandedRows) {
618
- setExpandedRows(expandAllGridRows(buildRows(data)));
619
- }
620
- function collapseAllGridRowsCommand(setExpandedRows) {
621
- setExpandedRows({});
622
- }
623
- function toggleGridTreeRowCommand(gridApi, currentExpandedTreeRows, rowId, setExpandedTreeRows, findRowById) {
624
- const { expanded, nextExpandedTreeRows } = toggleGridTreeRowExpanded(
625
- currentExpandedTreeRows,
626
- rowId
627
- );
628
- setExpandedTreeRows(nextExpandedTreeRows);
629
- const gridRow = findRowById(rowId);
630
- if (gridRow) {
631
- raiseGridTreeRowStateChanged(gridApi, gridRow, expanded);
632
- }
633
- }
634
- function setGridTreeRowExpandedCommand(gridApi, currentExpandedTreeRows, rowId, expanded, setExpandedTreeRows, findRowById) {
635
- setExpandedTreeRows(setGridTreeRowExpanded(currentExpandedTreeRows, rowId, expanded));
636
- const gridRow = findRowById(rowId);
637
- if (gridRow) {
638
- raiseGridTreeRowStateChanged(gridApi, gridRow, expanded);
639
- }
640
- }
641
- function expandAllGridTreeRowsCommand(buildRows, data, setExpandedTreeRows) {
642
- setExpandedTreeRows(expandAllGridTreeRows(buildRows(data)));
643
- }
644
- function collapseAllGridTreeRowsCommand(setExpandedTreeRows) {
645
- setExpandedTreeRows({});
646
- }
647
- function beginGridCellEditCommand(gridApi, access, row, column, currentValue, triggerEvent, initialValue) {
648
- const nextEditSession = beginGridEditSession(
649
- row.id,
650
- column.name,
651
- initialValue ?? stringifyGridEditorValue(currentValue)
652
- );
653
- access.setFocusedCell(nextEditSession.focusedCell);
654
- access.setEditingCell(nextEditSession.editingCell);
655
- access.setEditingValue(nextEditSession.editingValue);
656
- raiseGridBeginCellEdit(gridApi, row.entity, column, triggerEvent);
657
- return nextEditSession.editingCell;
658
- }
659
- function commitGridCellEditCommand(gridApi, access) {
660
- const editingCell = access.getEditingCell();
661
- if (!editingCell) {
662
- return { committed: false };
663
- }
664
- const row = access.findRowById(editingCell.rowId);
665
- const column = access.findColumnByName(editingCell.columnName);
666
- if (!row || !column) {
667
- access.setEditingCell(null);
668
- return { committed: false };
669
- }
670
- const oldValue = getCellValue(row.entity, column);
671
- const newValue = access.parseEditedValue(column, access.getEditingValue(), oldValue);
672
- access.setCellValue(row.entity, column, newValue);
673
- const clearedEditSession = clearGridEditSession();
674
- access.setEditingCell(clearedEditSession.editingCell);
675
- raiseGridAfterCellEdit(gridApi, row.entity, column, newValue, oldValue);
676
- access.setEditingValue(clearedEditSession.editingValue);
677
- return {
678
- committed: true,
679
- focusTarget: { rowId: row.id, columnName: column.name },
680
- row,
681
- column
682
- };
683
- }
684
- function cancelGridCellEditCommand(gridApi, access) {
685
- const editingCell = access.getEditingCell();
686
- if (!editingCell) {
687
- return {};
688
- }
689
- const row = access.findRowById(editingCell.rowId);
690
- const column = access.findColumnByName(editingCell.columnName);
691
- const clearedEditSession = clearGridEditSession();
692
- access.setEditingCell(clearedEditSession.editingCell);
693
- access.setEditingValue(clearedEditSession.editingValue);
694
- if (!row || !column) {
695
- return {};
696
- }
697
- raiseGridCancelCellEdit(gridApi, row.entity, column);
698
- return { focusTarget: editingCell };
699
- }
700
- function maybeRequestInfiniteScrollCommand(gridApi, access) {
701
- if (!access.enabled || !access.virtualizationEnabled) {
702
- return;
703
- }
704
- const { request, nextState } = maybeRequestInfiniteScrollData({
705
- state: access.state,
706
- startIndex: access.startIndex,
707
- visibleRows: access.visibleRows,
708
- viewportRows: access.viewportRows,
709
- threshold: access.threshold
710
- });
711
- if (request === "top" || request === "bottom") {
712
- access.setState(nextState);
713
- raiseGridNeedMoreData(gridApi, request);
714
- }
715
- }
716
- function completeGridInfiniteScrollDataLoadCommand(currentState, setState, scrollUp, scrollDown) {
717
- setState(completeInfiniteScrollDataLoad(currentState, scrollUp, scrollDown));
718
- return Promise.resolve();
719
- }
720
- function resetGridInfiniteScrollCommand(setState, scrollUp, scrollDown) {
721
- setState(resetInfiniteScrollState(scrollUp, scrollDown));
722
- }
723
- function saveGridInfiniteScrollPercentageCommand(currentState, visibleRows, setState) {
724
- setState(saveInfiniteScrollPercentage(currentState, visibleRows));
725
- }
726
- function setGridInfiniteScrollDirectionsCommand(currentState, setState, scrollUp, scrollDown) {
727
- setState(setInfiniteScrollDirectionsState(currentState, scrollUp, scrollDown));
728
- }
729
-
730
- // ../ui-grid/src/lib/grid/ui-grid.host.ts
731
- function observeGridHostSize(hostElement, onSizeChange) {
732
- if (typeof ResizeObserver === "undefined") {
733
- return null;
734
- }
735
- const observer = new ResizeObserver((entries) => {
736
- const entry = entries[0];
737
- if (!entry) {
738
- return;
739
- }
740
- onSizeChange({
741
- height: Math.round(entry.contentRect.height),
742
- width: Math.round(entry.contentRect.width)
743
- });
744
- });
745
- observer.observe(hostElement);
746
- return observer;
747
- }
748
- function downloadGridCsvFile(csv, filename) {
749
- if (typeof Blob === "undefined" || typeof URL === "undefined" || typeof document === "undefined") {
750
- return;
751
- }
752
- const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
753
- const url = URL.createObjectURL(blob);
754
- const link = document.createElement("a");
755
- link.href = url;
756
- link.download = filename;
757
- link.click();
758
- URL.revokeObjectURL(url);
759
- }
760
-
761
- // src/useGridState.ts
762
133
  function escapeCssSelectorValue(value) {
763
134
  const nativeEscape = globalThis.CSS?.escape;
764
135
  if (typeof nativeEscape === "function") {
@@ -796,7 +167,7 @@ function useGridState(options, onRegisterApi) {
796
167
  const [hiddenRowReasons, setHiddenRowReasons] = useState({});
797
168
  const [sortState, setSortState] = useState({
798
169
  columnName: null,
799
- direction: SORT_DIRECTIONS2.none
170
+ direction: SORT_DIRECTIONS.none
800
171
  });
801
172
  const [focusedCell, setFocusedCell] = useState(null);
802
173
  const [editingCell, setEditingCell] = useState(null);
@@ -857,8 +228,17 @@ function useGridState(options, onRegisterApi) {
857
228
  optionsRef.current = options;
858
229
  const rowSize = options.rowHeight ?? 44;
859
230
  const visibleColumns = useMemo(() => {
860
- return orderVisibleColumns(options.columnDefs, columnOrder);
861
- }, [options.columnDefs, columnOrder]);
231
+ const orderedColumns = orderVisibleColumns(options.columnDefs, columnOrder);
232
+ const pinnedEntries = Object.entries(pinnedColumns);
233
+ if (pinnedEntries.length === 0) {
234
+ return orderedColumns;
235
+ }
236
+ const columnByName = new Map(orderedColumns.map((column) => [column.name, column]));
237
+ const pinnedLeft = pinnedEntries.filter(([, direction]) => direction === "left").map(([columnName]) => columnByName.get(columnName)).filter((column) => column !== void 0);
238
+ const pinnedRight = pinnedEntries.filter(([, direction]) => direction === "right").map(([columnName]) => columnByName.get(columnName)).filter((column) => column !== void 0);
239
+ const centerColumns = orderedColumns.filter((column) => pinnedColumns[column.name] === void 0);
240
+ return [...pinnedLeft, ...centerColumns, ...pinnedRight];
241
+ }, [options.columnDefs, columnOrder, pinnedColumns]);
862
242
  const visibleColumnsRef = useRef(visibleColumns);
863
243
  visibleColumnsRef.current = visibleColumns;
864
244
  const pipeline = useMemo(() => {
@@ -1321,7 +701,7 @@ function useGridState(options, onRegisterApi) {
1321
701
  );
1322
702
  const startCellEditFn = useCallback(
1323
703
  (row, column, triggerEvent, initialValue) => {
1324
- const currentValue = getCellValue2(row.entity, column);
704
+ const currentValue = getCellValue(row.entity, column);
1325
705
  const focusToken = ++editorFocusTokenRef.current;
1326
706
  const ec = beginGridCellEditCommand(
1327
707
  gridApiRef.current,
@@ -1481,7 +861,7 @@ function useGridState(options, onRegisterApi) {
1481
861
  );
1482
862
  setSortState({
1483
863
  columnName: initialSort?.name ?? null,
1484
- direction: initialSort?.sort?.direction ?? SORT_DIRECTIONS2.none
864
+ direction: initialSort?.sort?.direction ?? SORT_DIRECTIONS.none
1485
865
  });
1486
866
  onRegisterApi?.(gridApi);
1487
867
  raiseGridRenderingComplete(gridApi);
@@ -1542,7 +922,7 @@ function useGridState(options, onRegisterApi) {
1542
922
  []
1543
923
  );
1544
924
  const sortDirectionFn = useCallback((column) => {
1545
- return sortStateRef.current.columnName === column.name ? sortStateRef.current.direction : SORT_DIRECTIONS2.none;
925
+ return sortStateRef.current.columnName === column.name ? sortStateRef.current.direction : SORT_DIRECTIONS.none;
1546
926
  }, []);
1547
927
  const sortButtonLabelFn = useCallback(
1548
928
  (column) => {
@@ -1668,10 +1048,10 @@ function useGridState(options, onRegisterApi) {
1668
1048
  }, []);
1669
1049
  const toggleSortFn = useCallback((column) => {
1670
1050
  if (!FEATURE_SORTING || !isGridColumnSortable(optionsRef.current, column)) return;
1671
- const currentDirection = sortStateRef.current.columnName === column.name ? sortStateRef.current.direction : SORT_DIRECTIONS2.none;
1672
- const nextDirection = currentDirection === SORT_DIRECTIONS2.none ? SORT_DIRECTIONS2.asc : currentDirection === SORT_DIRECTIONS2.asc ? SORT_DIRECTIONS2.desc : SORT_DIRECTIONS2.none;
1051
+ const currentDirection = sortStateRef.current.columnName === column.name ? sortStateRef.current.direction : SORT_DIRECTIONS.none;
1052
+ const nextDirection = currentDirection === SORT_DIRECTIONS.none ? SORT_DIRECTIONS.asc : currentDirection === SORT_DIRECTIONS.asc ? SORT_DIRECTIONS.desc : SORT_DIRECTIONS.none;
1673
1053
  applyGridSortStateCommand(gridApiRef.current, (state) => setSortState(state), {
1674
- columnName: nextDirection === SORT_DIRECTIONS2.none ? null : column.name,
1054
+ columnName: nextDirection === SORT_DIRECTIONS.none ? null : column.name,
1675
1055
  direction: nextDirection
1676
1056
  });
1677
1057
  }, []);
@@ -2024,6 +1404,7 @@ function useVirtualScroll(options) {
2024
1404
  totalHeight: virtualWindow.totalHeight,
2025
1405
  offsetY: virtualWindow.offsetY,
2026
1406
  onScroll,
1407
+ setScrollTop,
2027
1408
  viewportRef,
2028
1409
  scrollTop
2029
1410
  };
@@ -2072,10 +1453,82 @@ function UiGrid({
2072
1453
  viewportHeight: options.viewportHeight ?? 560,
2073
1454
  overscan: 3
2074
1455
  });
1456
+ const headerGridRef = React.useRef(null);
1457
+ const filterGridRef = React.useRef(null);
1458
+ const [openPinMenuColumn, setOpenPinMenuColumn] = React.useState(null);
1459
+ const [headerStickyHeight, setHeaderStickyHeight] = React.useState(0);
1460
+ const [filterStickyHeight, setFilterStickyHeight] = React.useState(0);
1461
+ const stickyChromeHeight = headerStickyHeight + filterStickyHeight;
1462
+ const scrollContainerHeight = `${(options.viewportHeight ?? 560) + stickyChromeHeight}px`;
1463
+ const eventPathIncludesClass = React.useCallback((event, className2) => {
1464
+ const eventPath = typeof event.composedPath === "function" ? event.composedPath() : event.target ? [event.target] : [];
1465
+ return eventPath.some((target) => {
1466
+ if (!target || typeof target !== "object" || !("classList" in target)) {
1467
+ return false;
1468
+ }
1469
+ const classList = target.classList;
1470
+ return classList?.contains(className2) ?? false;
1471
+ });
1472
+ }, []);
1473
+ const isPinMenuOpen = React.useCallback(
1474
+ (column) => openPinMenuColumn === column.name,
1475
+ [openPinMenuColumn]
1476
+ );
1477
+ const pinButtonLabel = React.useCallback(
1478
+ (column) => state.isPinned(column) ? labels.unpin : labels.pinColumn,
1479
+ [labels, state]
1480
+ );
1481
+ const onPinTrigger = React.useCallback(
1482
+ (column, event) => {
1483
+ event?.stopPropagation();
1484
+ if (state.isPinned(column)) {
1485
+ setOpenPinMenuColumn(null);
1486
+ state.gridApi.pinning.pinColumn(column.name, "none");
1487
+ return;
1488
+ }
1489
+ setOpenPinMenuColumn((current) => current === column.name ? null : column.name);
1490
+ },
1491
+ [state]
1492
+ );
1493
+ const choosePinDirection = React.useCallback(
1494
+ (column, direction, event) => {
1495
+ event?.stopPropagation();
1496
+ setOpenPinMenuColumn(null);
1497
+ state.gridApi.pinning.pinColumn(column.name, direction);
1498
+ },
1499
+ [state]
1500
+ );
1501
+ React.useLayoutEffect(() => {
1502
+ setHeaderStickyHeight(headerGridRef.current?.offsetHeight ?? 0);
1503
+ setFilterStickyHeight(filterGridRef.current?.offsetHeight ?? 0);
1504
+ }, [visibleColumns, filteringFeature, options.enableFiltering]);
1505
+ React.useEffect(() => {
1506
+ if (!openPinMenuColumn) {
1507
+ return;
1508
+ }
1509
+ const handleDocumentClick = (event) => {
1510
+ if (eventPathIncludesClass(event, "pin-control")) {
1511
+ return;
1512
+ }
1513
+ setOpenPinMenuColumn(null);
1514
+ };
1515
+ const handleDocumentEscape = (event) => {
1516
+ if (event.key === "Escape") {
1517
+ setOpenPinMenuColumn(null);
1518
+ }
1519
+ };
1520
+ document.addEventListener("click", handleDocumentClick);
1521
+ document.addEventListener("keydown", handleDocumentEscape);
1522
+ return () => {
1523
+ document.removeEventListener("click", handleDocumentClick);
1524
+ document.removeEventListener("keydown", handleDocumentEscape);
1525
+ };
1526
+ }, [eventPathIncludesClass, openPinMenuColumn]);
2075
1527
  const itemsToRender = virtualizationEnabled ? displayItems.slice(virtualScroll.visibleRange.start, virtualScroll.visibleRange.end) : displayItems;
2076
- const onViewportScroll = (event) => {
2077
- virtualScroll.onScroll(event);
2078
- const startIndex = Math.floor(event.currentTarget.scrollTop / rowSize);
1528
+ const onGridTableScroll = (event) => {
1529
+ const bodyScrollTop = Math.max(0, event.currentTarget.scrollTop - stickyChromeHeight);
1530
+ virtualScroll.setScrollTop(bodyScrollTop);
1531
+ const startIndex = Math.floor(bodyScrollTop / rowSize);
2079
1532
  state.onViewportScroll(startIndex);
2080
1533
  };
2081
1534
  function renderDisplayItem(item) {
@@ -2315,260 +1768,320 @@ function UiGrid({
2315
1768
  ] }),
2316
1769
  /* @__PURE__ */ jsx("p", { children: "`gridOptions` compatibility layer: sorting, filtering, grouping, column moving, templating, and virtualized rendering." })
2317
1770
  ] }),
2318
- /* @__PURE__ */ jsxs("div", { className: "grid-table ui-grid-contents-wrapper", "data-part": "grid-table", children: [
2319
- /* @__PURE__ */ jsx(
2320
- "div",
2321
- {
2322
- className: "header-grid ui-grid-header ui-grid-header-canvas",
2323
- "data-part": "header",
2324
- role: "row",
2325
- style: { gridTemplateColumns },
2326
- children: visibleColumns.map((column) => {
2327
- const pinned = state.isPinned(column);
2328
- const pinOffset = pinned ? state.pinnedOffset(column) : null;
2329
- return /* @__PURE__ */ jsxs(
2330
- "div",
2331
- {
2332
- className: `header-cell ui-grid-header-cell${sortingFeature && state.sortDirection(column) !== "none" ? " is-active" : ""}${pinned ? " is-pinned" : ""}`,
2333
- "data-part": "header-cell",
2334
- role: "columnheader",
2335
- "aria-sort": sortingFeature ? state.sortAriaSort(column) : void 0,
2336
- style: {
2337
- position: pinned ? "sticky" : void 0,
2338
- left: pinOffset?.side === "left" ? pinOffset.offset : void 0,
2339
- right: pinOffset?.side === "right" ? pinOffset.offset : void 0,
2340
- zIndex: pinned ? 2 : void 0
2341
- },
2342
- children: [
2343
- /* @__PURE__ */ jsx("span", { className: "header-label", children: state.headerLabel(column) }),
2344
- /* @__PURE__ */ jsxs("div", { className: "header-actions", children: [
2345
- sortingFeature && /* @__PURE__ */ jsxs(
2346
- "button",
2347
- {
2348
- type: "button",
2349
- className: `header-action${!state.isColumnSortable(column) ? " header-action-disabled" : ""}`,
2350
- disabled: !state.isColumnSortable(column),
2351
- "aria-label": state.sortButtonLabel(column),
2352
- title: state.sortButtonLabel(column),
2353
- onClick: () => state.toggleSort(column),
2354
- children: [
2355
- renderSortIcon(column),
2356
- /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: state.sortButtonLabel(column) })
2357
- ]
2358
- }
2359
- ),
2360
- groupingFeature && state.isGroupingEnabled() && column.enableGrouping !== false && /* @__PURE__ */ jsxs(
2361
- "button",
2362
- {
2363
- type: "button",
2364
- className: `chip-action${state.isGrouped(column) ? " chip-action-active" : ""}`,
2365
- "data-part": "group-toggle",
2366
- "aria-label": state.groupingButtonLabel(column),
2367
- title: state.groupingButtonLabel(column),
2368
- onClick: (e) => state.toggleGrouping(column, e),
2369
- children: [
2370
- /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M4 6h8v4H4V6Zm0 8h8v4H4v-4Zm10-8h6v4h-6V6Zm0 8h6v4h-6v-4Z" }) }),
2371
- /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: state.groupingButtonLabel(column) })
2372
- ]
2373
- }
2374
- ),
2375
- state.pinningFeature && state.isPinningEnabled() && state.isColumnPinnable(column) && /* @__PURE__ */ jsxs(
2376
- "button",
2377
- {
2378
- type: "button",
2379
- className: `chip-action${pinned ? " chip-action-active" : ""}`,
2380
- "data-part": "pin-toggle",
2381
- "aria-label": pinned ? labels.unpin : labels.pinLeft,
2382
- title: pinned ? labels.unpin : labels.pinLeft,
2383
- onClick: () => state.togglePin(column),
2384
- children: [
2385
- /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M16 12V4h1V2H7v2h1v8l-2 2v2h5v6l1 1 1-1v-6h5v-2l-2-2z" }) }),
2386
- /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: pinned ? labels.unpin : labels.pinLeft })
2387
- ]
2388
- }
2389
- )
2390
- ] })
2391
- ]
2392
- },
2393
- column.name
2394
- );
2395
- })
2396
- }
2397
- ),
2398
- filteringFeature && state.isFilteringEnabled() && /* @__PURE__ */ jsx(
2399
- "div",
2400
- {
2401
- className: "filter-grid ui-grid-header",
2402
- "data-part": "filters",
2403
- style: { gridTemplateColumns },
2404
- children: visibleColumns.map((column) => {
2405
- const pinned = state.isPinned(column);
2406
- const pinOffset = pinned ? state.pinnedOffset(column) : null;
2407
- return /* @__PURE__ */ jsxs(
2408
- "label",
2409
- {
2410
- className: `filter-cell ui-grid-filter-container${pinned ? " is-pinned" : ""}`,
2411
- "data-part": "filter-cell",
2412
- style: {
2413
- position: pinned ? "sticky" : void 0,
2414
- left: pinOffset?.side === "left" ? pinOffset.offset : void 0,
2415
- right: pinOffset?.side === "right" ? pinOffset.offset : void 0,
2416
- zIndex: pinned ? 2 : void 0
2417
- },
2418
- children: [
2419
- /* @__PURE__ */ jsxs("span", { className: "sr-only ui-grid-sr-only", children: [
2420
- labels.filterColumn,
2421
- " ",
2422
- state.headerLabel(column)
2423
- ] }),
2424
- /* @__PURE__ */ jsx(
2425
- "input",
2426
- {
2427
- className: "ui-grid-filter-input",
2428
- type: "text",
2429
- defaultValue: state.filterValue(column.name),
2430
- placeholder: state.filterPlaceholder(column),
2431
- disabled: state.isFilterInputDisabled(column),
2432
- onChange: (e) => state.updateFilter(column.name, e.target.value)
2433
- }
2434
- )
2435
- ]
2436
- },
2437
- column.name
2438
- );
2439
- })
2440
- }
2441
- ),
2442
- displayItems.length > 0 ? virtualizationEnabled ? /* @__PURE__ */ jsx(
2443
- "div",
2444
- {
2445
- className: "grid-viewport ui-grid-viewport",
2446
- "data-part": "viewport",
2447
- ref: virtualScroll.viewportRef,
2448
- style: { height: viewportHeightPx, overflow: "auto", position: "relative" },
2449
- onScroll: onViewportScroll,
2450
- children: /* @__PURE__ */ jsx("div", { style: { height: `${virtualScroll.totalHeight}px`, position: "relative" }, children: /* @__PURE__ */ jsx(
1771
+ /* @__PURE__ */ jsxs(
1772
+ "div",
1773
+ {
1774
+ className: "grid-table ui-grid-contents-wrapper",
1775
+ "data-part": "grid-table",
1776
+ style: virtualizationEnabled ? { height: scrollContainerHeight, overflowY: "auto" } : void 0,
1777
+ onScroll: virtualizationEnabled ? onGridTableScroll : void 0,
1778
+ children: [
1779
+ /* @__PURE__ */ jsx(
2451
1780
  "div",
2452
1781
  {
2453
- className: "body-grid ui-grid-canvas",
1782
+ className: "header-grid ui-grid-header ui-grid-header-canvas",
1783
+ "data-part": "header",
1784
+ role: "row",
1785
+ ref: headerGridRef,
1786
+ style: { gridTemplateColumns },
1787
+ children: visibleColumns.map((column) => {
1788
+ const pinned = state.isPinned(column);
1789
+ const pinOffset = pinned ? state.pinnedOffset(column) : null;
1790
+ const pinMenuOpen = isPinMenuOpen(column);
1791
+ return /* @__PURE__ */ jsxs(
1792
+ "div",
1793
+ {
1794
+ className: `header-cell ui-grid-header-cell${sortingFeature && state.sortDirection(column) !== "none" ? " is-active" : ""}${pinned ? " is-pinned" : ""}${pinMenuOpen ? " is-pin-menu-open" : ""}`,
1795
+ "data-part": "header-cell",
1796
+ role: "columnheader",
1797
+ "aria-sort": sortingFeature ? state.sortAriaSort(column) : void 0,
1798
+ style: {
1799
+ position: pinned ? "sticky" : void 0,
1800
+ left: pinOffset?.side === "left" ? pinOffset.offset : void 0,
1801
+ right: pinOffset?.side === "right" ? pinOffset.offset : void 0,
1802
+ zIndex: pinMenuOpen ? 8 : pinned ? 2 : void 0
1803
+ },
1804
+ children: [
1805
+ /* @__PURE__ */ jsx("span", { className: "header-label", children: state.headerLabel(column) }),
1806
+ /* @__PURE__ */ jsxs("div", { className: "header-actions", children: [
1807
+ sortingFeature && /* @__PURE__ */ jsxs(
1808
+ "button",
1809
+ {
1810
+ type: "button",
1811
+ className: `header-action${!state.isColumnSortable(column) ? " header-action-disabled" : ""}`,
1812
+ disabled: !state.isColumnSortable(column),
1813
+ "aria-label": state.sortButtonLabel(column),
1814
+ title: state.sortButtonLabel(column),
1815
+ onClick: () => state.toggleSort(column),
1816
+ children: [
1817
+ renderSortIcon(column),
1818
+ /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: state.sortButtonLabel(column) })
1819
+ ]
1820
+ }
1821
+ ),
1822
+ groupingFeature && state.isGroupingEnabled() && column.enableGrouping !== false && /* @__PURE__ */ jsxs(
1823
+ "button",
1824
+ {
1825
+ type: "button",
1826
+ className: `chip-action${state.isGrouped(column) ? " chip-action-active" : ""}`,
1827
+ "data-part": "group-toggle",
1828
+ "aria-label": state.groupingButtonLabel(column),
1829
+ title: state.groupingButtonLabel(column),
1830
+ onClick: (e) => state.toggleGrouping(column, e),
1831
+ children: [
1832
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M4 6h8v4H4V6Zm0 8h8v4H4v-4Zm10-8h6v4h-6V6Zm0 8h6v4h-6v-4Z" }) }),
1833
+ /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: state.groupingButtonLabel(column) })
1834
+ ]
1835
+ }
1836
+ ),
1837
+ state.pinningFeature && state.isPinningEnabled() && state.isColumnPinnable(column) && /* @__PURE__ */ jsxs("div", { className: `pin-control${pinMenuOpen ? " pin-control-open" : ""}`, onClick: (event) => event.stopPropagation(), children: [
1838
+ /* @__PURE__ */ jsxs(
1839
+ "button",
1840
+ {
1841
+ type: "button",
1842
+ className: `chip-action pin-trigger${pinned || pinMenuOpen ? " chip-action-active" : ""}`,
1843
+ "data-part": "pin-toggle",
1844
+ "aria-label": pinButtonLabel(column),
1845
+ title: pinButtonLabel(column),
1846
+ "aria-haspopup": pinned ? void 0 : "menu",
1847
+ "aria-expanded": pinned ? void 0 : pinMenuOpen,
1848
+ onClick: (event) => onPinTrigger(column, event),
1849
+ children: [
1850
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M16 12V4h1V2H7v2h1v8l-2 2v2h5v6l1 1 1-1v-6h5v-2l-2-2z" }) }),
1851
+ /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: pinButtonLabel(column) })
1852
+ ]
1853
+ }
1854
+ ),
1855
+ /* @__PURE__ */ jsxs(
1856
+ "div",
1857
+ {
1858
+ className: "pin-menu",
1859
+ "data-part": "pin-menu",
1860
+ role: "menu",
1861
+ "aria-label": "Pin options",
1862
+ "aria-hidden": !pinMenuOpen,
1863
+ children: [
1864
+ /* @__PURE__ */ jsxs(
1865
+ "button",
1866
+ {
1867
+ type: "button",
1868
+ className: "pin-menu-action",
1869
+ "data-part": "pin-left-action",
1870
+ role: "menuitem",
1871
+ "aria-label": labels.pinLeft,
1872
+ title: labels.pinLeft,
1873
+ tabIndex: pinMenuOpen ? 0 : -1,
1874
+ onClick: (event) => choosePinDirection(column, "left", event),
1875
+ children: [
1876
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M10 6 4 12l6 6v-4h10v-4H10V6z" }) }),
1877
+ /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: labels.pinLeft })
1878
+ ]
1879
+ }
1880
+ ),
1881
+ /* @__PURE__ */ jsxs(
1882
+ "button",
1883
+ {
1884
+ type: "button",
1885
+ className: "pin-menu-action",
1886
+ "data-part": "pin-right-action",
1887
+ role: "menuitem",
1888
+ "aria-label": labels.pinRight,
1889
+ title: labels.pinRight,
1890
+ tabIndex: pinMenuOpen ? 0 : -1,
1891
+ onClick: (event) => choosePinDirection(column, "right", event),
1892
+ children: [
1893
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: false, children: /* @__PURE__ */ jsx("path", { d: "M14 6v4H4v4h10v4l6-6-6-6z" }) }),
1894
+ /* @__PURE__ */ jsx("span", { className: "sr-only ui-grid-sr-only", children: labels.pinRight })
1895
+ ]
1896
+ }
1897
+ )
1898
+ ]
1899
+ }
1900
+ )
1901
+ ] })
1902
+ ] })
1903
+ ]
1904
+ },
1905
+ column.name
1906
+ );
1907
+ })
1908
+ }
1909
+ ),
1910
+ filteringFeature && state.isFilteringEnabled() && /* @__PURE__ */ jsx(
1911
+ "div",
1912
+ {
1913
+ className: "filter-grid ui-grid-header",
1914
+ "data-part": "filters",
1915
+ ref: filterGridRef,
1916
+ style: { gridTemplateColumns, ["--ui-grid-header-sticky-top"]: `${headerStickyHeight}px` },
1917
+ children: visibleColumns.map((column) => {
1918
+ const pinned = state.isPinned(column);
1919
+ const pinOffset = pinned ? state.pinnedOffset(column) : null;
1920
+ return /* @__PURE__ */ jsxs(
1921
+ "label",
1922
+ {
1923
+ className: `filter-cell ui-grid-filter-container${pinned ? " is-pinned" : ""}`,
1924
+ "data-part": "filter-cell",
1925
+ style: {
1926
+ position: pinned ? "sticky" : void 0,
1927
+ left: pinOffset?.side === "left" ? pinOffset.offset : void 0,
1928
+ right: pinOffset?.side === "right" ? pinOffset.offset : void 0,
1929
+ zIndex: pinned ? 2 : void 0
1930
+ },
1931
+ children: [
1932
+ /* @__PURE__ */ jsxs("span", { className: "sr-only ui-grid-sr-only", children: [
1933
+ labels.filterColumn,
1934
+ " ",
1935
+ state.headerLabel(column)
1936
+ ] }),
1937
+ /* @__PURE__ */ jsx(
1938
+ "input",
1939
+ {
1940
+ className: "ui-grid-filter-input",
1941
+ type: "text",
1942
+ defaultValue: state.filterValue(column.name),
1943
+ placeholder: state.filterPlaceholder(column),
1944
+ disabled: state.isFilterInputDisabled(column),
1945
+ onChange: (e) => state.updateFilter(column.name, e.target.value)
1946
+ }
1947
+ )
1948
+ ]
1949
+ },
1950
+ column.name
1951
+ );
1952
+ })
1953
+ }
1954
+ ),
1955
+ displayItems.length > 0 ? virtualizationEnabled ? /* @__PURE__ */ jsx("div", { className: "grid-virtual-spacer", style: { height: `${virtualScroll.totalHeight}px` }, children: /* @__PURE__ */ jsx(
1956
+ "div",
1957
+ {
1958
+ className: "body-grid ui-grid-canvas grid-virtual-body",
2454
1959
  "data-part": "body",
2455
1960
  role: "rowgroup",
2456
1961
  style: {
2457
1962
  gridTemplateColumns,
2458
1963
  position: "absolute",
2459
- top: 0,
2460
- left: 0,
2461
- right: 0,
2462
- transform: `translateY(${virtualScroll.offsetY}px)`
1964
+ top: `${virtualScroll.offsetY}px`,
1965
+ left: 0
2463
1966
  },
2464
1967
  children: itemsToRender.map(renderDisplayItem)
2465
1968
  }
2466
- ) })
2467
- }
2468
- ) : /* @__PURE__ */ jsx(
2469
- "div",
2470
- {
2471
- className: "body-grid ui-grid-canvas",
2472
- "data-part": "body",
2473
- role: "rowgroup",
2474
- style: { gridTemplateColumns },
2475
- children: displayItems.map(renderDisplayItem)
2476
- }
2477
- ) : /* @__PURE__ */ jsxs("div", { className: "empty-state ui-grid-no-row-overlay", "data-part": "empty-state", children: [
2478
- /* @__PURE__ */ jsx("strong", { children: options.emptyMessage ?? labels.emptyHeading }),
2479
- /* @__PURE__ */ jsx("p", { children: labels.emptyDescription })
2480
- ] }),
2481
- paginationFeature && state.showPaginationControls() && /* @__PURE__ */ jsxs(
2482
- "footer",
2483
- {
2484
- className: "pagination-bar ui-grid-pagination",
2485
- "data-part": "pagination",
2486
- role: "navigation",
2487
- "aria-label": labels.paginationPage,
2488
- children: [
2489
- /* @__PURE__ */ jsx("p", { children: state.paginationSummary() }),
2490
- /* @__PURE__ */ jsxs("div", { className: "pagination-controls", children: [
2491
- /* @__PURE__ */ jsxs(
2492
- "button",
2493
- {
2494
- type: "button",
2495
- className: "action action-secondary pagination-button",
2496
- "aria-label": labels.paginationPrevious,
2497
- disabled: paginationCurrentPage <= 1,
2498
- onClick: () => state.previousPage(),
2499
- children: [
2500
- /* @__PURE__ */ jsx(
2501
- "svg",
2502
- {
2503
- className: "pagination-icon",
2504
- viewBox: "0 0 24 24",
2505
- "aria-hidden": "true",
2506
- focusable: false,
2507
- children: /* @__PURE__ */ jsx("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" })
2508
- }
2509
- ),
2510
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationPrevious })
2511
- ]
2512
- }
2513
- ),
2514
- /* @__PURE__ */ jsxs("span", { children: [
2515
- labels.paginationPage,
2516
- " ",
2517
- paginationCurrentPage,
2518
- " ",
2519
- labels.paginationOf,
2520
- " ",
2521
- paginationTotalPages
2522
- ] }),
2523
- /* @__PURE__ */ jsxs(
2524
- "button",
2525
- {
2526
- type: "button",
2527
- className: "action action-secondary pagination-button",
2528
- "aria-label": labels.paginationNext,
2529
- disabled: paginationCurrentPage >= paginationTotalPages,
2530
- onClick: () => state.nextPage(),
2531
- children: [
1969
+ ) }) : /* @__PURE__ */ jsx(
1970
+ "div",
1971
+ {
1972
+ className: "body-grid ui-grid-canvas",
1973
+ "data-part": "body",
1974
+ role: "rowgroup",
1975
+ style: { gridTemplateColumns },
1976
+ children: displayItems.map(renderDisplayItem)
1977
+ }
1978
+ ) : /* @__PURE__ */ jsxs("div", { className: "empty-state ui-grid-no-row-overlay", "data-part": "empty-state", children: [
1979
+ /* @__PURE__ */ jsx("strong", { children: options.emptyMessage ?? labels.emptyHeading }),
1980
+ /* @__PURE__ */ jsx("p", { children: labels.emptyDescription })
1981
+ ] }),
1982
+ paginationFeature && state.showPaginationControls() && /* @__PURE__ */ jsxs(
1983
+ "footer",
1984
+ {
1985
+ className: "pagination-bar ui-grid-pagination",
1986
+ "data-part": "pagination",
1987
+ role: "navigation",
1988
+ "aria-label": labels.paginationPage,
1989
+ children: [
1990
+ /* @__PURE__ */ jsx("p", { children: state.paginationSummary() }),
1991
+ /* @__PURE__ */ jsxs("div", { className: "pagination-controls", children: [
1992
+ /* @__PURE__ */ jsxs(
1993
+ "button",
1994
+ {
1995
+ type: "button",
1996
+ className: "action action-secondary pagination-button",
1997
+ "aria-label": labels.paginationPrevious,
1998
+ disabled: paginationCurrentPage <= 1,
1999
+ onClick: () => state.previousPage(),
2000
+ children: [
2001
+ /* @__PURE__ */ jsx(
2002
+ "svg",
2003
+ {
2004
+ className: "pagination-icon",
2005
+ viewBox: "0 0 24 24",
2006
+ "aria-hidden": "true",
2007
+ focusable: false,
2008
+ children: /* @__PURE__ */ jsx("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" })
2009
+ }
2010
+ ),
2011
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationPrevious })
2012
+ ]
2013
+ }
2014
+ ),
2015
+ /* @__PURE__ */ jsxs("span", { children: [
2016
+ labels.paginationPage,
2017
+ " ",
2018
+ paginationCurrentPage,
2019
+ " ",
2020
+ labels.paginationOf,
2021
+ " ",
2022
+ paginationTotalPages
2023
+ ] }),
2024
+ /* @__PURE__ */ jsxs(
2025
+ "button",
2026
+ {
2027
+ type: "button",
2028
+ className: "action action-secondary pagination-button",
2029
+ "aria-label": labels.paginationNext,
2030
+ disabled: paginationCurrentPage >= paginationTotalPages,
2031
+ onClick: () => state.nextPage(),
2032
+ children: [
2033
+ /* @__PURE__ */ jsx(
2034
+ "svg",
2035
+ {
2036
+ className: "pagination-icon",
2037
+ viewBox: "0 0 24 24",
2038
+ "aria-hidden": "true",
2039
+ focusable: false,
2040
+ children: /* @__PURE__ */ jsx("path", { d: "M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z" })
2041
+ }
2042
+ ),
2043
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationNext })
2044
+ ]
2045
+ }
2046
+ ),
2047
+ state.pageSizeOptions().length > 0 && /* @__PURE__ */ jsxs("label", { className: "pagination-size", children: [
2048
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationRows }),
2532
2049
  /* @__PURE__ */ jsx(
2533
- "svg",
2050
+ "select",
2534
2051
  {
2535
- className: "pagination-icon",
2536
- viewBox: "0 0 24 24",
2537
- "aria-hidden": "true",
2538
- focusable: false,
2539
- children: /* @__PURE__ */ jsx("path", { d: "M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z" })
2052
+ "aria-label": labels.paginationRows,
2053
+ value: paginationSelectedPageSize,
2054
+ onChange: (e) => state.onPageSizeChange(e.target.value),
2055
+ children: state.pageSizeOptions().map((size) => /* @__PURE__ */ jsx("option", { value: size, children: size }, size))
2540
2056
  }
2541
- ),
2542
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationNext })
2543
- ]
2544
- }
2545
- ),
2546
- state.pageSizeOptions().length > 0 && /* @__PURE__ */ jsxs("label", { className: "pagination-size", children: [
2547
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: labels.paginationRows }),
2548
- /* @__PURE__ */ jsx(
2549
- "select",
2550
- {
2551
- "aria-label": labels.paginationRows,
2552
- value: paginationSelectedPageSize,
2553
- onChange: (e) => state.onPageSizeChange(e.target.value),
2554
- children: state.pageSizeOptions().map((size) => /* @__PURE__ */ jsx("option", { value: size, children: size }, size))
2555
- }
2556
- )
2557
- ] })
2558
- ] })
2559
- ]
2560
- }
2561
- )
2562
- ] })
2057
+ )
2058
+ ] })
2059
+ ] })
2060
+ ]
2061
+ }
2062
+ )
2063
+ ]
2064
+ }
2065
+ )
2563
2066
  ]
2564
2067
  }
2565
2068
  )
2566
2069
  ] }) });
2567
2070
  }
2568
2071
 
2072
+ // src/mountUiGrid.tsx
2073
+ import React2 from "react";
2074
+ import { createRoot } from "react-dom/client";
2075
+ function mountUiGrid(container, props) {
2076
+ const root = createRoot(container);
2077
+ root.render(React2.createElement(UiGrid, props));
2078
+ return root;
2079
+ }
2080
+
2569
2081
  // src/rustWasmGridEngine.ts
2570
2082
  import { registerRustWasmGridEngine } from "@ornery/ui-grid";
2571
- var uiGridWasmModulePath = "../../../dist/ui-grid-wasm/ui_grid_wasm.js";
2083
+ var uiGridWasmModulePath = "../../../dist/ui-grid-wasm-web/ui_grid_wasm.js";
2084
+ var uiGridWasmBinaryPath = "/dist/ui-grid-wasm-web/ui_grid_wasm_bg.wasm";
2572
2085
  function registerReactUiGridWasmEngineFromModule(module) {
2573
2086
  registerRustWasmGridEngine({
2574
2087
  buildPipeline(context) {
@@ -2581,6 +2094,7 @@ async function enableReactUiGridWasmEngine() {
2581
2094
  /* @vite-ignore */
2582
2095
  uiGridWasmModulePath
2583
2096
  );
2097
+ await module.default(uiGridWasmBinaryPath);
2584
2098
  registerReactUiGridWasmEngineFromModule(module);
2585
2099
  }
2586
2100
 
@@ -2594,6 +2108,7 @@ export {
2594
2108
  computeViewportRows,
2595
2109
  enableReactUiGridWasmEngine,
2596
2110
  formatPaginationSummary,
2111
+ mountUiGrid,
2597
2112
  orderVisibleColumns,
2598
2113
  registerReactUiGridWasmEngineFromModule,
2599
2114
  resolveBenchmarkIterations,