@alaarab/ogrid-react-fluent 2.1.15 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -589,11 +589,19 @@
589
589
  white-space: nowrap;
590
590
  user-select: none;
591
591
  outline: none;
592
+ contain: content;
592
593
  }
593
594
  .ogrid-fluent__DataGridTable-module__cellContent:focus-visible {
594
595
  outline: none;
595
596
  }
596
- .ogrid-fluent__DataGridTable-module__activeCellContent {
597
+ .ogrid-fluent__DataGridTable-module__pinnedColLeft .ogrid-fluent__DataGridTable-module__cellContent,
598
+ .ogrid-fluent__DataGridTable-module__pinnedColRight .ogrid-fluent__DataGridTable-module__cellContent {
599
+ contain: none;
600
+ }
601
+ .ogrid-fluent__DataGridTable-module__dataTable:not([data-virtual-scroll]) tbody tr {
602
+ content-visibility: auto;
603
+ }
604
+ .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__activeCellContent.ogrid-fluent__DataGridTable-module__activeCellContent {
597
605
  outline: 2px solid var(--ogrid-selection-color, #217346);
598
606
  outline-offset: -1px;
599
607
  z-index: var(--ogrid-z-active-cell, 2);
@@ -601,7 +609,7 @@
601
609
  overflow: visible;
602
610
  background: var(--ogrid-active-cell-bg, rgba(0, 0, 0, 0.02));
603
611
  }
604
- .ogrid-fluent__DataGridTable-module__editingCellContent {
612
+ .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__editingCellContent.ogrid-fluent__DataGridTable-module__editingCellContent {
605
613
  width: 100%;
606
614
  height: 100%;
607
615
  display: flex;
@@ -624,9 +632,13 @@
624
632
  .ogrid-fluent__DataGridTable-module__tableWrapper [data-drag-anchor] {
625
633
  background: var(--ogrid-bg, #fff);
626
634
  }
627
- .ogrid-fluent__DataGridTable-module__activeCellContent[data-drag-anchor],
628
- .ogrid-fluent__DataGridTable-module__activeCellContent[data-drag-range] {
635
+ .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__activeCellContent.ogrid-fluent__DataGridTable-module__activeCellContent[data-drag-anchor],
636
+ .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__activeCellContent.ogrid-fluent__DataGridTable-module__activeCellContent[data-drag-range] {
637
+ outline: none;
638
+ }
639
+ .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__activeCellContent.ogrid-fluent__DataGridTable-module__activeCellContent.ogrid-fluent__DataGridTable-module__inRange {
629
640
  outline: none;
641
+ background: var(--ogrid-bg, #fff);
630
642
  }
631
643
  .ogrid-fluent__DataGridTable-module__tableWrapper .ogrid-fluent__DataGridTable-module__cellCut {
632
644
  background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04));
@@ -660,6 +672,20 @@
660
672
  width: 100%;
661
673
  font-variant-numeric: tabular-nums;
662
674
  }
675
+ .ogrid-fluent__DataGridTable-module__columnLetterRow {
676
+ background: var(--ogrid-column-letter-bg, var(--ogrid-header-bg));
677
+ }
678
+ .ogrid-fluent__DataGridTable-module__columnLetterCell {
679
+ text-align: center;
680
+ font-size: 11px;
681
+ font-weight: 500;
682
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
683
+ padding: 2px 4px;
684
+ background: var(--ogrid-column-letter-bg, var(--ogrid-header-bg));
685
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
686
+ user-select: none;
687
+ font-variant-numeric: tabular-nums;
688
+ }
663
689
  .ogrid-fluent__DataGridTable-module__statusBar {
664
690
  display: flex;
665
691
  align-items: center;
@@ -865,6 +891,7 @@
865
891
  --ogrid-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.08);
866
892
  --ogrid-pinned-shadow: rgba(0, 0, 0, 0.1);
867
893
  --ogrid-loading-overlay: rgba(255, 255, 255, 0.7);
894
+ --ogrid-formula-error-color: #d32f2f;
868
895
  --ogrid-selection: #217346;
869
896
  --ogrid-bg-range: rgba(33, 115, 70, 0.12);
870
897
  --ogrid-bg-selected: #e6f0fb;
@@ -899,6 +926,7 @@
899
926
  --ogrid-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.25);
900
927
  --ogrid-pinned-shadow: rgba(0, 0, 0, 0.3);
901
928
  --ogrid-loading-overlay: rgba(0, 0, 0, 0.7);
929
+ --ogrid-formula-error-color: #ef5350;
902
930
  --ogrid-selection: #2ea043;
903
931
  --ogrid-bg-range: rgba(46, 160, 67, 0.15);
904
932
  --ogrid-bg-selected: #1a3a5c;
@@ -933,6 +961,7 @@
933
961
  --ogrid-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.25);
934
962
  --ogrid-pinned-shadow: rgba(0, 0, 0, 0.3);
935
963
  --ogrid-loading-overlay: rgba(0, 0, 0, 0.7);
964
+ --ogrid-formula-error-color: #ef5350;
936
965
  --ogrid-selection: #2ea043;
937
966
  --ogrid-bg-range: rgba(46, 160, 67, 0.15);
938
967
  --ogrid-bg-selected: #1a3a5c;
package/dist/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import './index.css';
2
- import { useColumnHeaderFilterState, getColumnHeaderFilterStateParams, DateFilterContent, renderFilterContent, areGridRowPropsEqual, usePaginationControls, createOGrid, useListVirtualizer, STOP_PROPAGATION, useDataGridTableOrchestration, useColumnMeta, getCellRenderDescriptor, buildInlineEditorProps, buildPopoverEditorProps, POPOVER_ANCHOR_STYLE, resolveCellDisplayContent, resolveCellStyle, getCellInteractionProps, CURSOR_CELL_STYLE, CellErrorBoundary, GRID_ROOT_STYLE, PREVENT_DEFAULT, getHeaderFilterConfig, MarchingAntsOverlay, NOOP, useColumnChooserState, BaseInlineCellEditor, BaseDropIndicator, BaseEmptyState, GridContextMenu as GridContextMenu$1, BaseColumnHeaderMenu, StatusBar as StatusBar$1, BaseLoadingOverlay } from '@alaarab/ogrid-react';
2
+ import { useColumnHeaderFilterState, getColumnHeaderFilterStateParams, DateFilterContent, renderFilterContent, areGridRowPropsEqual, usePaginationControls, createOGrid, useListVirtualizer, STOP_PROPAGATION, useDataGridTableOrchestration, useColumnMeta, getCellRenderDescriptor, buildInlineEditorProps, buildPopoverEditorProps, POPOVER_ANCHOR_STYLE, resolveCellDisplayContent, resolveCellStyle, getCellInteractionProps, CURSOR_CELL_STYLE, CellErrorBoundary, GRID_ROOT_STYLE, PREVENT_DEFAULT, indexToColumnLetter, getHeaderFilterConfig, MarchingAntsOverlay, NOOP, useColumnChooserState, BaseInlineCellEditor, partitionColumnsForVirtualization, BaseDropIndicator, BaseEmptyState, GridContextMenu as GridContextMenu$1, BaseColumnHeaderMenu, StatusBar as StatusBar$1, BaseLoadingOverlay } from '@alaarab/ogrid-react';
3
3
  export { BaseColumnHeaderMenu, BaseDropIndicator, BaseEmptyState, BaseInlineCellEditor, BaseLoadingOverlay, CELL_PADDING, CHECKBOX_COLUMN_WIDTH, COLUMN_HEADER_MENU_ITEMS, CURSOR_CELL_STYLE, CellErrorBoundary, DEFAULT_MIN_COLUMN_WIDTH, DateFilterContent, EmptyState, GRID_BORDER_RADIUS, GRID_CONTEXT_MENU_ITEMS, GRID_ROOT_STYLE, GridContextMenu, MAX_PAGE_BUTTONS, MarchingAntsOverlay, NOOP, OGridLayout, PAGE_SIZE_OPTIONS, POPOVER_ANCHOR_STYLE, PREVENT_DEFAULT, ROW_NUMBER_COLUMN_WIDTH, STOP_PROPAGATION, SideBar, StatusBar, UndoRedoStack, areGridRowPropsEqual, booleanParser, buildCsvHeader, buildCsvRows, buildHeaderRows, buildInlineEditorProps, buildPopoverEditorProps, clampSelectionToBounds, computeAggregations, computeAutoScrollSpeed, computeTabNavigation, createOGrid, currencyParser, dateParser, deriveFilterOptionsFromData, editorInputStyle, editorWrapperStyle, emailParser, escapeCsvValue, exportToCsv, findCtrlArrowTarget, flattenColumns, formatCellValueForTsv, formatSelectionAsTsv, formatShortcut, getCellInteractionProps, getCellRenderDescriptor, getCellValue, getColumnHeaderFilterStateParams, getColumnHeaderMenuItems, getContextMenuHandlers, getDataGridStatusBarConfig, getDateFilterContentProps, getFilterField, getHeaderFilterConfig, getMultiSelectFilterFields, getPaginationViewModel, getStatusBarParts, isInSelectionRange, isRowInRange, mergeFilter, normalizeSelectionRange, numberParser, parseTsvClipboard, parseValue, processClientSideData, rangesEqual, renderFilterContent, resolveCellDisplayContent, resolveCellStyle, richSelectDropdownStyle, richSelectNoMatchesStyle, richSelectOptionHighlightedStyle, richSelectOptionStyle, richSelectWrapperStyle, selectChevronStyle, selectDisplayStyle, selectEditorStyle, toUserLike, triggerCsvDownload, useActiveCell, useCellEditing, useCellSelection, useClipboard, useColumnChooserState, useColumnHeaderFilterState, useColumnMeta, useColumnReorder, useColumnResize, useContextMenu, useDataGridState, useDataGridTableOrchestration, useDateFilterState, useDebounce, useFillHandle, useFilterOptions, useInlineCellEditorState, useKeyboardNavigation, useLatestRef, useListVirtualizer, useMultiSelectFilterState, useOGrid, usePaginationControls, usePeopleFilterState, useRichSelectState, useRowSelection, useSelectState, useSideBarState, useTableLayout, useTextFilterState, useUndoRedo, useVirtualScroll } from '@alaarab/ogrid-react';
4
- import * as React from 'react';
4
+ import * as React2 from 'react';
5
5
  import { useCallback, useRef, useEffect } from 'react';
6
6
  import { createPortal } from 'react-dom';
7
7
  import { Popover, PopoverSurface, Button, Select, TableRow, TableCell, Checkbox, Table, TableHeader, TableHeaderCell, TableBody } from '@fluentui/react-components';
@@ -262,7 +262,7 @@ var PeopleFilterPopover = ({
262
262
  selectedUser && /* @__PURE__ */ jsx("div", { className: ColumnHeaderFilter_module_default.popoverActions, onClick: onPopoverClick, children: /* @__PURE__ */ jsx("button", { type: "button", className: ColumnHeaderFilter_module_default.clearButton, onClick: onClearUser, children: "Clear Filter" }) })
263
263
  ] });
264
264
  PeopleFilterPopover.displayName = "PeopleFilterPopover";
265
- var ColumnHeaderFilter = React.memo((props) => {
265
+ var ColumnHeaderFilter = React2.memo((props) => {
266
266
  const {
267
267
  columnName,
268
268
  filterType,
@@ -286,8 +286,8 @@ var ColumnHeaderFilter = React.memo((props) => {
286
286
  handleInputClick,
287
287
  handleInputKeyDown
288
288
  } = handlers;
289
- const filterBtnRef = React.useRef(null);
290
- const fluentRenderers = React.useMemo(() => ({
289
+ const filterBtnRef = React2.useRef(null);
290
+ const fluentRenderers = React2.useMemo(() => ({
291
291
  renderMultiSelect: (p) => /* @__PURE__ */ jsx(
292
292
  MultiSelectFilterPopover,
293
293
  {
@@ -456,12 +456,15 @@ var DataGridTable_module_default = {
456
456
  "activeCellContent": "ogrid-fluent__DataGridTable-module__activeCellContent",
457
457
  "editingCellContent": "ogrid-fluent__DataGridTable-module__editingCellContent",
458
458
  "cellInRange": "ogrid-fluent__DataGridTable-module__cellInRange",
459
+ "inRange": "ogrid-fluent__DataGridTable-module__inRange",
459
460
  "cellCut": "ogrid-fluent__DataGridTable-module__cellCut",
460
461
  "fillHandle": "ogrid-fluent__DataGridTable-module__fillHandle",
461
462
  "selectionHeaderCellInner": "ogrid-fluent__DataGridTable-module__selectionHeaderCellInner",
462
463
  "selectionCellInner": "ogrid-fluent__DataGridTable-module__selectionCellInner",
463
464
  "rowNumberHeaderCellInner": "ogrid-fluent__DataGridTable-module__rowNumberHeaderCellInner",
464
465
  "rowNumberCellInner": "ogrid-fluent__DataGridTable-module__rowNumberCellInner",
466
+ "columnLetterRow": "ogrid-fluent__DataGridTable-module__columnLetterRow",
467
+ "columnLetterCell": "ogrid-fluent__DataGridTable-module__columnLetterCell",
465
468
  "statusBar": "ogrid-fluent__DataGridTable-module__statusBar",
466
469
  "statusBarItem": "ogrid-fluent__DataGridTable-module__statusBarItem",
467
470
  "statusBarLabel": "ogrid-fluent__DataGridTable-module__statusBarLabel",
@@ -536,6 +539,7 @@ function LoadingOverlay({ message }) {
536
539
  function DropIndicator({ dropIndicatorX, wrapperLeft }) {
537
540
  return /* @__PURE__ */ jsx(BaseDropIndicator, { dropIndicatorX, wrapperLeft, className: DataGridTable_module_default.dropIndicator });
538
541
  }
542
+ var SPACER_TD_STYLE = { padding: 0, border: "none" };
539
543
  function GridRowInner(props) {
540
544
  const {
541
545
  item,
@@ -550,7 +554,10 @@ function GridRowInner(props) {
550
554
  lastMouseShiftRef,
551
555
  hasCheckboxCol,
552
556
  hasRowNumbersCol,
553
- rowNumberOffset
557
+ rowNumberOffset,
558
+ leftSpacerWidth,
559
+ rightSpacerWidth,
560
+ globalColIndexMap
554
561
  } = props;
555
562
  return /* @__PURE__ */ jsxs(
556
563
  TableRow,
@@ -580,21 +587,112 @@ function GridRowInner(props) {
580
587
  }
581
588
  ) }),
582
589
  hasRowNumbersCol && /* @__PURE__ */ jsx(TableCell, { className: DataGridTable_module_default.rowNumberCellWrapper, children: /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.rowNumberCellInner, children: rowNumberOffset + rowIndex + 1 }) }),
583
- visibleCols.map((col, colIdx) => /* @__PURE__ */ jsx(
584
- TableCell,
585
- {
586
- "data-column-id": col.columnId,
587
- className: columnMeta.cellClasses[col.columnId] || void 0,
588
- style: columnMeta.cellStyles[col.columnId],
589
- children: renderCellContent(item, col, rowIndex, colIdx)
590
- },
591
- col.columnId
592
- ))
590
+ leftSpacerWidth != null && leftSpacerWidth > 0 && /* @__PURE__ */ jsx("td", { style: { ...SPACER_TD_STYLE, width: leftSpacerWidth, minWidth: leftSpacerWidth }, "aria-hidden": true }),
591
+ visibleCols.map((col, colIdx) => {
592
+ const globalIdx = globalColIndexMap ? globalColIndexMap[colIdx] : colIdx;
593
+ return /* @__PURE__ */ jsx(
594
+ TableCell,
595
+ {
596
+ "data-column-id": col.columnId,
597
+ className: columnMeta.cellClasses[col.columnId] || void 0,
598
+ style: columnMeta.cellStyles[col.columnId],
599
+ children: renderCellContent(item, col, rowIndex, globalIdx)
600
+ },
601
+ col.columnId
602
+ );
603
+ }),
604
+ rightSpacerWidth != null && rightSpacerWidth > 0 && /* @__PURE__ */ jsx("td", { style: { ...SPACER_TD_STYLE, width: rightSpacerWidth, minWidth: rightSpacerWidth }, "aria-hidden": true })
593
605
  ]
594
606
  }
595
607
  );
596
608
  }
597
- var GridRow = React.memo(GridRowInner, areGridRowPropsEqual);
609
+ var GridRow = React2.memo(GridRowInner, areGridRowPropsEqual);
610
+ function FluentTableBody(props) {
611
+ const {
612
+ virtualScrollEnabled,
613
+ visibleRange,
614
+ columnRange,
615
+ items,
616
+ getRowId,
617
+ selectedRowIds,
618
+ visibleCols,
619
+ columnMeta,
620
+ renderCellContent,
621
+ handleSingleRowClick,
622
+ handleRowCheckboxChange,
623
+ lastMouseShiftRef,
624
+ hasCheckboxCol,
625
+ hasRowNumbersCol,
626
+ rowNumberOffset,
627
+ selectionRange,
628
+ activeCell,
629
+ cutRange,
630
+ copyRange,
631
+ isDragging,
632
+ editingCell,
633
+ pinnedColumns
634
+ } = props;
635
+ const partition = React2.useMemo(() => {
636
+ if (!columnRange) return null;
637
+ const p = partitionColumnsForVirtualization(
638
+ visibleCols,
639
+ columnRange,
640
+ pinnedColumns
641
+ );
642
+ return p;
643
+ }, [visibleCols, columnRange, pinnedColumns]);
644
+ const { rowCols, globalColIndexMap, leftSpacerWidth, rightSpacerWidth } = React2.useMemo(() => {
645
+ if (!partition) {
646
+ return { rowCols: visibleCols, globalColIndexMap: void 0, leftSpacerWidth: void 0, rightSpacerWidth: void 0 };
647
+ }
648
+ const combined = [...partition.pinnedLeft, ...partition.virtualizedUnpinned, ...partition.pinnedRight];
649
+ const idxMap = combined.map((col) => visibleCols.indexOf(col));
650
+ return {
651
+ rowCols: combined,
652
+ globalColIndexMap: idxMap,
653
+ leftSpacerWidth: partition.leftSpacerWidth,
654
+ rightSpacerWidth: partition.rightSpacerWidth
655
+ };
656
+ }, [partition, visibleCols]);
657
+ const renderRow = (item, rowIndex) => {
658
+ const rowIdStr = getRowId(item);
659
+ return /* @__PURE__ */ jsx(
660
+ GridRow,
661
+ {
662
+ item,
663
+ rowIndex,
664
+ rowId: rowIdStr,
665
+ isSelected: selectedRowIds.has(rowIdStr),
666
+ visibleCols: rowCols,
667
+ columnMeta,
668
+ renderCellContent,
669
+ handleSingleRowClick,
670
+ handleRowCheckboxChange,
671
+ lastMouseShiftRef,
672
+ hasCheckboxCol,
673
+ hasRowNumbersCol,
674
+ rowNumberOffset,
675
+ selectionRange,
676
+ activeCell,
677
+ cutRange,
678
+ copyRange,
679
+ isDragging,
680
+ editingRowId: editingCell?.rowId ?? null,
681
+ leftSpacerWidth,
682
+ rightSpacerWidth,
683
+ globalColIndexMap
684
+ },
685
+ rowIdStr
686
+ );
687
+ };
688
+ return /* @__PURE__ */ jsxs(TableBody, { children: [
689
+ virtualScrollEnabled && visibleRange.offsetTop > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetTop }, "aria-hidden": true }),
690
+ virtualScrollEnabled ? items.slice(visibleRange.startIndex, visibleRange.endIndex + 1).map(
691
+ (item, i) => renderRow(item, visibleRange.startIndex + i)
692
+ ) : items.map((item, rowIndex) => renderRow(item, rowIndex)),
693
+ virtualScrollEnabled && visibleRange.offsetBottom > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetBottom }, "aria-hidden": true })
694
+ ] });
695
+ }
598
696
  function DataGridTableInner(props) {
599
697
  const o = useDataGridTableOrchestration({ props });
600
698
  const {
@@ -611,6 +709,8 @@ function DataGridTableInner(props) {
611
709
  handleHeaderMouseDown,
612
710
  virtualScrollEnabled,
613
711
  visibleRange,
712
+ columnRange,
713
+ onHorizontalScroll,
614
714
  items,
615
715
  getRowId,
616
716
  emptyState,
@@ -628,6 +728,7 @@ function DataGridTableInner(props) {
628
728
  headerRows,
629
729
  allowOverflowX,
630
730
  fitToContent,
731
+ showColumnLetters,
631
732
  editCallbacks,
632
733
  interactionHandlers,
633
734
  cellDescriptorInputRef,
@@ -722,9 +823,9 @@ function DataGridTableInner(props) {
722
823
  ] });
723
824
  } else {
724
825
  const displayContent = resolveCellDisplayContent(col, item, descriptor.displayValue);
725
- const cellStyle = resolveCellStyle(col, item);
826
+ const cellStyle = resolveCellStyle(col, item, descriptor.displayValue);
726
827
  const styledContent = cellStyle ? /* @__PURE__ */ jsx("span", { style: cellStyle, children: displayContent }) : displayContent;
727
- const cellClassNames = `${DataGridTable_module_default.cellContent}${descriptor.isActive ? ` ${DataGridTable_module_default.activeCellContent}` : ""}${descriptor.isInRange && !descriptor.isActive ? ` ${DataGridTable_module_default.cellInRange}` : ""}${descriptor.isInCutRange ? ` ${DataGridTable_module_default.cellCut}` : ""}${descriptor.isInCopyRange ? ` ${DataGridTable_module_default.cellCopied}` : ""}`;
828
+ const cellClassNames = `${DataGridTable_module_default.cellContent}${descriptor.isActive ? ` ${DataGridTable_module_default.activeCellContent}` : ""}${descriptor.isActive && descriptor.isInRange ? ` ${DataGridTable_module_default.inRange}` : ""}${descriptor.isInRange && !descriptor.isActive ? ` ${DataGridTable_module_default.cellInRange}` : ""}${descriptor.isInCutRange ? ` ${DataGridTable_module_default.cellCut}` : ""}${descriptor.isInCopyRange ? ` ${DataGridTable_module_default.cellCopied}` : ""}`;
728
829
  const interactionProps = getCellInteractionProps(descriptor, col.columnId, interactionHandlers);
729
830
  content = /* @__PURE__ */ jsxs(
730
831
  "div",
@@ -759,6 +860,7 @@ function DataGridTableInner(props) {
759
860
  onMouseDown: (e) => {
760
861
  lastMouseShiftRef.current = e.shiftKey;
761
862
  },
863
+ onScroll: onHorizontalScroll ? (e) => onHorizontalScroll(e.target.scrollLeft) : void 0,
762
864
  className: `${DataGridTable_module_default.tableWrapper} ${rowSelection !== "none" ? DataGridTable_module_default.selectableGrid : ""} ${DataGridTable_module_default[`density-${density}`] || ""}`,
763
865
  role: "region",
764
866
  "aria-label": ariaLabel ?? (ariaLabelledBy ? void 0 : "Data grid"),
@@ -781,144 +883,126 @@ function DataGridTableInner(props) {
781
883
  },
782
884
  children: [
783
885
  /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.tableScrollContent, children: /* @__PURE__ */ jsx("div", { className: isLoading && items.length > 0 ? DataGridTable_module_default.loadingDimmed : void 0, children: /* @__PURE__ */ jsxs("div", { className: DataGridTable_module_default.tableWidthAnchor, ref: tableContainerRef, children: [
784
- /* @__PURE__ */ jsxs(Table, { role: "grid", className: DataGridTable_module_default.dataTable, children: [
785
- /* @__PURE__ */ jsx(
886
+ /* @__PURE__ */ jsxs(Table, { role: "grid", className: DataGridTable_module_default.dataTable, "data-virtual-scroll": virtualScrollEnabled ? "" : void 0, children: [
887
+ /* @__PURE__ */ jsxs(
786
888
  TableHeader,
787
889
  {
788
890
  className: o.stickyHeader ? DataGridTable_module_default.stickyHeader : void 0,
789
- children: headerRows.map((row, rowIdx) => /* @__PURE__ */ jsxs(TableRow, { children: [
790
- rowIdx === headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx(TableHeaderCell, { className: DataGridTable_module_default.selectionHeaderCellWrapper, children: /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.selectionHeaderCellInner, children: /* @__PURE__ */ jsx(
791
- Checkbox,
792
- {
793
- checked: allSelected ? true : someSelected ? "mixed" : false,
794
- onChange: (_, data) => handleSelectAll(!!data.checked),
795
- "aria-label": "Select all rows"
796
- }
797
- ) }) }, "__selection__"),
798
- rowIdx === 0 && rowIdx < headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx("th", { rowSpan: headerRows.length - 1 }, "__selection_placeholder__"),
799
- rowIdx === headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx(TableHeaderCell, { className: DataGridTable_module_default.rowNumberHeaderCellWrapper, children: /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.rowNumberHeaderCellInner, children: "#" }) }, "__row_number__"),
800
- rowIdx === 0 && rowIdx < headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx("th", { rowSpan: headerRows.length - 1 }, "__row_number_placeholder__"),
801
- row.map((cell, cellIdx) => {
802
- if (cell.isGroup) {
803
- return /* @__PURE__ */ jsx("th", { colSpan: cell.colSpan, className: DataGridTable_module_default.groupHeaderCell, scope: "colgroup", children: cell.label }, cellIdx);
804
- }
805
- if (!cell.columnDef) return null;
806
- const col = cell.columnDef;
807
- const isSorted = props.sortBy === col.columnId;
808
- const ariaSort = isSorted ? props.sortDirection === "asc" ? "ascending" : "descending" : void 0;
809
- return /* @__PURE__ */ jsxs(
810
- TableHeaderCell,
891
+ children: [
892
+ showColumnLetters && /* @__PURE__ */ jsxs(TableRow, { children: [
893
+ hasCheckboxCol && /* @__PURE__ */ jsx("th", { className: DataGridTable_module_default.columnLetterCell }),
894
+ hasRowNumbersCol && /* @__PURE__ */ jsx("th", { className: DataGridTable_module_default.columnLetterCell }),
895
+ visibleCols.map((col, colIdx) => /* @__PURE__ */ jsx(
896
+ "th",
811
897
  {
812
- scope: "col",
813
- "data-column-id": col.columnId,
814
- className: columnMeta.hdrClasses[col.columnId] || void 0,
815
- style: {
816
- ...columnMeta.hdrStyles[col.columnId],
817
- ...columnReorder ? { cursor: isReorderDragging ? "grabbing" : "grab" } : void 0
818
- },
819
- "aria-sort": ariaSort,
820
- onMouseDown: columnReorder ? (e) => handleHeaderMouseDown(col.columnId, e) : void 0,
821
- children: [
822
- /* @__PURE__ */ jsxs("div", { className: DataGridTable_module_default.headerCellContent, children: [
823
- /* @__PURE__ */ jsx(ColumnHeaderFilter, { ...getHeaderFilterConfig(col, headerFilterInput) }),
898
+ className: `${DataGridTable_module_default.columnLetterCell}${columnMeta.hdrClasses[col.columnId] ? ` ${columnMeta.hdrClasses[col.columnId]}` : ""}`,
899
+ style: columnMeta.hdrStyles[col.columnId],
900
+ children: indexToColumnLetter(colIdx)
901
+ },
902
+ col.columnId
903
+ ))
904
+ ] }),
905
+ headerRows.map((row, rowIdx) => /* @__PURE__ */ jsxs(TableRow, { children: [
906
+ rowIdx === headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx(TableHeaderCell, { className: DataGridTable_module_default.selectionHeaderCellWrapper, children: /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.selectionHeaderCellInner, children: /* @__PURE__ */ jsx(
907
+ Checkbox,
908
+ {
909
+ checked: allSelected ? true : someSelected ? "mixed" : false,
910
+ onChange: (_, data) => handleSelectAll(!!data.checked),
911
+ "aria-label": "Select all rows"
912
+ }
913
+ ) }) }, "__selection__"),
914
+ rowIdx === 0 && rowIdx < headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx("th", { rowSpan: headerRows.length - 1 }, "__selection_placeholder__"),
915
+ rowIdx === headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx(TableHeaderCell, { className: DataGridTable_module_default.rowNumberHeaderCellWrapper, children: /* @__PURE__ */ jsx("div", { className: DataGridTable_module_default.rowNumberHeaderCellInner, children: "#" }) }, "__row_number__"),
916
+ rowIdx === 0 && rowIdx < headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx("th", { rowSpan: headerRows.length - 1 }, "__row_number_placeholder__"),
917
+ row.map((cell, cellIdx) => {
918
+ if (cell.isGroup) {
919
+ return /* @__PURE__ */ jsx("th", { colSpan: cell.colSpan, className: DataGridTable_module_default.groupHeaderCell, scope: "colgroup", children: cell.label }, cellIdx);
920
+ }
921
+ if (!cell.columnDef) return null;
922
+ const col = cell.columnDef;
923
+ const isSorted = props.sortBy === col.columnId;
924
+ const ariaSort = isSorted ? props.sortDirection === "asc" ? "ascending" : "descending" : void 0;
925
+ return /* @__PURE__ */ jsxs(
926
+ TableHeaderCell,
927
+ {
928
+ scope: "col",
929
+ "data-column-id": col.columnId,
930
+ className: columnMeta.hdrClasses[col.columnId] || void 0,
931
+ style: {
932
+ ...columnMeta.hdrStyles[col.columnId],
933
+ ...columnReorder ? { cursor: isReorderDragging ? "grabbing" : "grab" } : void 0
934
+ },
935
+ "aria-sort": ariaSort,
936
+ onMouseDown: columnReorder ? (e) => handleHeaderMouseDown(col.columnId, e) : void 0,
937
+ children: [
938
+ /* @__PURE__ */ jsxs("div", { className: DataGridTable_module_default.headerCellContent, children: [
939
+ /* @__PURE__ */ jsx(ColumnHeaderFilter, { ...getHeaderFilterConfig(col, headerFilterInput) }),
940
+ /* @__PURE__ */ jsx(
941
+ "button",
942
+ {
943
+ className: DataGridTable_module_default.headerMenuTrigger,
944
+ onClick: (e) => {
945
+ e.stopPropagation();
946
+ headerMenu.open(col.columnId, e.currentTarget);
947
+ },
948
+ "aria-label": "Column options",
949
+ title: "Column options",
950
+ children: "\u22EE"
951
+ }
952
+ )
953
+ ] }),
824
954
  /* @__PURE__ */ jsx(
825
- "button",
955
+ "div",
826
956
  {
827
- className: DataGridTable_module_default.headerMenuTrigger,
828
- onClick: (e) => {
829
- e.stopPropagation();
830
- headerMenu.open(col.columnId, e.currentTarget);
957
+ className: DataGridTable_module_default.resizeHandle,
958
+ role: "separator",
959
+ "aria-orientation": "vertical",
960
+ onMouseDown: (e) => {
961
+ setActiveCell(null);
962
+ interaction.setSelectionRange(null);
963
+ wrapperRef.current?.focus({ preventScroll: true });
964
+ handleResizeStart(e, col);
831
965
  },
832
- "aria-label": "Column options",
833
- title: "Column options",
834
- children: "\u22EE"
966
+ onDoubleClick: (e) => handleResizeDoubleClick(e, col),
967
+ "aria-label": `Resize ${col.name}`
835
968
  }
836
969
  )
837
- ] }),
838
- /* @__PURE__ */ jsx(
839
- "div",
840
- {
841
- className: DataGridTable_module_default.resizeHandle,
842
- role: "separator",
843
- "aria-orientation": "vertical",
844
- onMouseDown: (e) => {
845
- setActiveCell(null);
846
- interaction.setSelectionRange(null);
847
- wrapperRef.current?.focus({ preventScroll: true });
848
- handleResizeStart(e, col);
849
- },
850
- onDoubleClick: (e) => handleResizeDoubleClick(e, col),
851
- "aria-label": `Resize ${col.name}`
852
- }
853
- )
854
- ]
855
- },
856
- col.columnId
857
- );
858
- })
859
- ] }, rowIdx))
970
+ ]
971
+ },
972
+ col.columnId
973
+ );
974
+ })
975
+ ] }, rowIdx))
976
+ ]
860
977
  }
861
978
  ),
862
- !showEmptyInGrid && /* @__PURE__ */ jsxs(TableBody, { children: [
863
- virtualScrollEnabled && visibleRange.offsetTop > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetTop }, "aria-hidden": true }),
864
- virtualScrollEnabled ? items.slice(visibleRange.startIndex, visibleRange.endIndex + 1).map((item, i) => {
865
- const rowIndex = visibleRange.startIndex + i;
866
- const rowIdStr = getRowId(item);
867
- return /* @__PURE__ */ jsx(
868
- GridRow,
869
- {
870
- item,
871
- rowIndex,
872
- rowId: rowIdStr,
873
- isSelected: selectedRowIds.has(rowIdStr),
874
- visibleCols,
875
- columnMeta,
876
- renderCellContent,
877
- handleSingleRowClick,
878
- handleRowCheckboxChange,
879
- lastMouseShiftRef,
880
- hasCheckboxCol,
881
- hasRowNumbersCol,
882
- rowNumberOffset,
883
- selectionRange,
884
- activeCell: interaction.activeCell,
885
- cutRange,
886
- copyRange,
887
- isDragging,
888
- editingRowId: editingCell?.rowId ?? null
889
- },
890
- rowIdStr
891
- );
892
- }) : items.map((item, rowIndex) => {
893
- const rowIdStr = getRowId(item);
894
- return /* @__PURE__ */ jsx(
895
- GridRow,
896
- {
897
- item,
898
- rowIndex,
899
- rowId: rowIdStr,
900
- isSelected: selectedRowIds.has(rowIdStr),
901
- visibleCols,
902
- columnMeta,
903
- renderCellContent,
904
- handleSingleRowClick,
905
- handleRowCheckboxChange,
906
- lastMouseShiftRef,
907
- hasCheckboxCol,
908
- hasRowNumbersCol,
909
- rowNumberOffset,
910
- selectionRange,
911
- activeCell: interaction.activeCell,
912
- cutRange,
913
- copyRange,
914
- isDragging,
915
- editingRowId: editingCell?.rowId ?? null
916
- },
917
- rowIdStr
918
- );
919
- }),
920
- virtualScrollEnabled && visibleRange.offsetBottom > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetBottom }, "aria-hidden": true })
921
- ] })
979
+ !showEmptyInGrid && /* @__PURE__ */ jsx(
980
+ FluentTableBody,
981
+ {
982
+ virtualScrollEnabled,
983
+ visibleRange,
984
+ columnRange,
985
+ items,
986
+ getRowId,
987
+ selectedRowIds,
988
+ visibleCols,
989
+ columnMeta,
990
+ renderCellContent,
991
+ handleSingleRowClick,
992
+ handleRowCheckboxChange,
993
+ lastMouseShiftRef,
994
+ hasCheckboxCol,
995
+ hasRowNumbersCol,
996
+ rowNumberOffset,
997
+ selectionRange,
998
+ activeCell: interaction.activeCell,
999
+ cutRange,
1000
+ copyRange,
1001
+ isDragging,
1002
+ editingCell,
1003
+ pinnedColumns: pinning.pinnedColumns
1004
+ }
1005
+ )
922
1006
  ] }),
923
1007
  isReorderDragging && dropIndicatorX != null && /* @__PURE__ */ jsx(DropIndicator, { dropIndicatorX, wrapperLeft: wrapperRef.current?.getBoundingClientRect().left ?? 0 }),
924
1008
  /* @__PURE__ */ jsx(
@@ -997,7 +1081,7 @@ function DataGridTableInner(props) {
997
1081
  isLoading && /* @__PURE__ */ jsx(LoadingOverlay, { message: loadingMessage })
998
1082
  ] });
999
1083
  }
1000
- var DataGridTable = React.memo(DataGridTableInner);
1084
+ var DataGridTable = React2.memo(DataGridTableInner);
1001
1085
 
1002
1086
  // src/ColumnChooser/ColumnChooser.module.scss
1003
1087
  var ColumnChooser_module_default = {
@@ -1099,7 +1183,7 @@ var PaginationControls_module_default = {
1099
1183
  "pageSizeLabel": "ogrid-fluent__PaginationControls-module__pageSizeLabel",
1100
1184
  "pageSizeSelect": "ogrid-fluent__PaginationControls-module__pageSizeSelect"
1101
1185
  };
1102
- var PaginationControls = React.memo((props) => {
1186
+ var PaginationControls = React2.memo((props) => {
1103
1187
  const { currentPage, pageSize, totalCount, onPageChange, onPageSizeChange, pageSizeOptions, entityLabelPlural, className } = props;
1104
1188
  const { labelPlural, vm, handlePageSizeChange } = usePaginationControls({
1105
1189
  currentPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid-react-fluent",
3
- "version": "2.1.15",
3
+ "version": "2.3.0",
4
4
  "description": "OGrid React Fluent implementation – DataGrid-powered data table with sorting, filtering, pagination, column chooser, and CSV export.",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -41,7 +41,7 @@
41
41
  "node": ">=18"
42
42
  },
43
43
  "dependencies": {
44
- "@alaarab/ogrid-react": "2.1.15"
44
+ "@alaarab/ogrid-react": "2.3.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@fluentui/react-components": "^9.0.0",