boneless-table 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -241,7 +241,7 @@ function resolveColumnSettings(settings, column) {
241
241
  const configured = (_a = column.columnDef.meta) == null ? void 0 : _a.bonelessTable;
242
242
  const configuredSizing = configured == null ? void 0 : configured.sizing;
243
243
  return {
244
- sizing: configuredSizing && "widthPx" in configuredSizing ? { widthPx: configuredSizing.widthPx } : __spreadValues(__spreadValues({}, settings.columnDefaults.sizing), configuredSizing),
244
+ sizing: (configuredSizing == null ? void 0 : configuredSizing.widthPx) != null && configuredSizing.minPx == null && configuredSizing.maxPx == null && configuredSizing.flex == null && configuredSizing.resizable == null ? { widthPx: configuredSizing.widthPx } : __spreadValues(__spreadValues({}, settings.columnDefaults.sizing), configuredSizing),
245
245
  align: (_b = configured == null ? void 0 : configured.align) != null ? _b : settings.columnDefaults.align,
246
246
  borders: (_c = configured == null ? void 0 : configured.borders) != null ? _c : settings.columnDefaults.borders,
247
247
  sorting: __spreadValues(__spreadValues({}, settings.columnDefaults.sorting), configured == null ? void 0 : configured.sorting),
@@ -425,11 +425,13 @@ function BonelessTable(_a) {
425
425
  const defaultOrder = useMemo(() => getColumnIds(resolvedColumns), [resolvedColumns]);
426
426
  const scrollerRef = useRef3(null);
427
427
  const headerScrollerRef = useRef3(null);
428
+ const rootRef = useRef3(null);
428
429
  const lastScrollLeftRef = useRef3(0);
429
430
  const columnsButtonRef = useRef3(null);
430
431
  const nearEndTriggeredRef = useRef3(false);
431
432
  const columnMenuId = useId();
432
433
  const [showColumns, setShowColumns] = useState2(false);
434
+ const [headerScrollbarInset, setHeaderScrollbarInset] = useState2(0);
433
435
  const [sorting, setSorting] = useState2((_b2 = (_a2 = tableOptions.initialState) == null ? void 0 : _a2.sorting) != null ? _b2 : []);
434
436
  const [columnFilters, setColumnFilters] = useState2(
435
437
  (_d = (_c = tableOptions.initialState) == null ? void 0 : _c.columnFilters) != null ? _d : []
@@ -441,6 +443,7 @@ function BonelessTable(_a) {
441
443
  (_h = (_g = tableOptions.initialState) == null ? void 0 : _g.columnOrder) != null ? _h : defaultOrder
442
444
  );
443
445
  const [expanded, setExpanded] = useState2((_j = (_i = tableOptions.initialState) == null ? void 0 : _i.expanded) != null ? _j : {});
446
+ const [columnSizing, setColumnSizing] = useState2({});
444
447
  const _k = tableOptions, {
445
448
  state: controlledState,
446
449
  onSortingChange,
@@ -472,8 +475,28 @@ function BonelessTable(_a) {
472
475
  ]);
473
476
  useEffect3(() => {
474
477
  var _a3;
475
- if (scrollToTopOn !== void 0) (_a3 = scrollerRef.current) == null ? void 0 : _a3.scrollTo({ top: 0 });
478
+ if (scrollToTopOn !== void 0) {
479
+ nearEndTriggeredRef.current = false;
480
+ (_a3 = scrollerRef.current) == null ? void 0 : _a3.scrollTo({ top: 0 });
481
+ }
476
482
  }, [scrollToTopOn]);
483
+ useEffect3(() => {
484
+ const scrollerElement = scrollerRef.current;
485
+ if (!scrollerElement) return;
486
+ const syncHeaderScrollbarInset = () => {
487
+ setHeaderScrollbarInset(
488
+ Math.max(0, scrollerElement.offsetWidth - scrollerElement.clientWidth)
489
+ );
490
+ };
491
+ syncHeaderScrollbarInset();
492
+ const resizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(syncHeaderScrollbarInset);
493
+ resizeObserver == null ? void 0 : resizeObserver.observe(scrollerElement);
494
+ window.addEventListener("resize", syncHeaderScrollbarInset);
495
+ return () => {
496
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
497
+ window.removeEventListener("resize", syncHeaderScrollbarInset);
498
+ };
499
+ }, []);
477
500
  const table = useReactTable(__spreadProps(__spreadValues({}, restTableOptions), {
478
501
  data,
479
502
  columns: resolvedColumns,
@@ -508,18 +531,33 @@ function BonelessTable(_a) {
508
531
  var _a3;
509
532
  return (_a3 = columnSettingsById.get(column.id)) != null ? _a3 : resolveColumnSettings(settings, column);
510
533
  };
534
+ const columnResizeVariables = useMemo(
535
+ () => new Map(
536
+ allColumns.map((column, index) => [column.id, `--boneless-table-column-${index}-width`])
537
+ ),
538
+ [allColumns]
539
+ );
540
+ const getColumnResizeVariable = (columnId) => {
541
+ var _a3;
542
+ return (_a3 = columnResizeVariables.get(columnId)) != null ? _a3 : `--boneless-table-column-${columnId}-width`;
543
+ };
511
544
  const grid = visibleColumns.map((column) => {
545
+ var _a3, _b3, _c2;
512
546
  const columnSettings = getColumnSettings(column);
513
- if ("widthPx" in columnSettings.sizing) return `${columnSettings.sizing.widthPx}px`;
514
- return `minmax(${columnSettings.sizing.minPx}px, ${columnSettings.sizing.flex}fr)`;
547
+ const { sizing } = columnSettings;
548
+ const width = (_a3 = columnSizing[column.id]) != null ? _a3 : sizing.widthPx;
549
+ const track = width != null ? `${width}px` : `minmax(${(_b3 = sizing.minPx) != null ? _b3 : settings.columnDefaults.sizing.minPx}px, ${(_c2 = sizing.flex) != null ? _c2 : settings.columnDefaults.sizing.flex}fr)`;
550
+ return `var(${getColumnResizeVariable(column.id)}, ${track})`;
515
551
  }).join(" ");
516
552
  const minWidth = visibleColumns.reduce((width, column) => {
553
+ var _a3, _b3;
517
554
  const { sizing } = getColumnSettings(column);
518
- return width + ("widthPx" in sizing ? sizing.widthPx : sizing.minPx);
555
+ const configuredWidth = (_a3 = columnSizing[column.id]) != null ? _a3 : sizing.widthPx;
556
+ return width + ((_b3 = configuredWidth != null ? configuredWidth : sizing.minPx) != null ? _b3 : settings.columnDefaults.sizing.minPx);
519
557
  }, 0);
520
558
  const gridStyle = {
521
559
  "--boneless-table-grid": grid,
522
- minWidth: `${minWidth}px`
560
+ minWidth: `var(--boneless-table-min-width, ${minWidth}px)`
523
561
  };
524
562
  const tree = treeOption === true ? {} : treeOption === false ? void 0 : treeOption;
525
563
  const treeColumnId = (_m = tree == null ? void 0 : tree.columnId) != null ? _m : (_l = visibleColumns[0]) == null ? void 0 : _l.id;
@@ -537,8 +575,8 @@ function BonelessTable(_a) {
537
575
  [expandableRows, expanded]
538
576
  );
539
577
  useEffect3(() => {
540
- if (!isFetchingMore || !canLoadMore) nearEndTriggeredRef.current = false;
541
- }, [canLoadMore, isFetchingMore]);
578
+ if (!canLoadMore) nearEndTriggeredRef.current = false;
579
+ }, [canLoadMore]);
542
580
  function handleScroll() {
543
581
  const element = scrollerRef.current;
544
582
  if (!element) return;
@@ -557,12 +595,74 @@ function BonelessTable(_a) {
557
595
  onNearEnd();
558
596
  }
559
597
  function resetTable() {
598
+ var _a3;
560
599
  if (onReset) return onReset();
561
600
  table.resetSorting();
562
601
  table.resetColumnFilters();
563
602
  table.resetColumnVisibility();
564
603
  table.setColumnOrder(defaultOrder);
565
604
  table.resetExpanded();
605
+ columnResizeVariables.forEach((property) => {
606
+ var _a4;
607
+ return (_a4 = rootRef.current) == null ? void 0 : _a4.style.removeProperty(property);
608
+ });
609
+ (_a3 = rootRef.current) == null ? void 0 : _a3.style.removeProperty("--boneless-table-min-width");
610
+ setColumnSizing({});
611
+ }
612
+ function resizeColumn(columnId, startWidth, startX, minPx, maxPx) {
613
+ const property = getColumnResizeVariable(columnId);
614
+ const startMinWidth = minWidth;
615
+ let nextWidth = startWidth;
616
+ let hasMoved = false;
617
+ const onMove = (event) => {
618
+ var _a3, _b3;
619
+ nextWidth = constrainColumnWidth(startWidth + event.clientX - startX, minPx, maxPx);
620
+ hasMoved || (hasMoved = nextWidth !== startWidth);
621
+ (_a3 = rootRef.current) == null ? void 0 : _a3.style.setProperty(property, `${nextWidth}px`);
622
+ (_b3 = rootRef.current) == null ? void 0 : _b3.style.setProperty(
623
+ "--boneless-table-min-width",
624
+ `${startMinWidth - startWidth + nextWidth}px`
625
+ );
626
+ };
627
+ const onEnd = () => {
628
+ window.removeEventListener("pointermove", onMove);
629
+ window.removeEventListener("pointerup", onEnd);
630
+ window.removeEventListener("pointercancel", onEnd);
631
+ if (hasMoved) {
632
+ setColumnSizing((current) => __spreadProps(__spreadValues({}, current), { [columnId]: nextWidth }));
633
+ }
634
+ };
635
+ window.addEventListener("pointermove", onMove);
636
+ window.addEventListener("pointerup", onEnd);
637
+ window.addEventListener("pointercancel", onEnd);
638
+ }
639
+ function constrainColumnWidth(width, minPx, maxPx) {
640
+ return Math.min(maxPx != null ? maxPx : Number.POSITIVE_INFINITY, Math.max(minPx, Math.round(width)));
641
+ }
642
+ function getCurrentColumnWidth(columnId, fallback, element) {
643
+ var _a3, _b3, _c2, _d2;
644
+ const column = allColumns.find((item) => item.id === columnId);
645
+ const configuredWidth = column ? getColumnSettings(column).sizing.widthPx : void 0;
646
+ return (_d2 = (_c2 = (_a3 = columnSizing[columnId]) != null ? _a3 : configuredWidth) != null ? _c2 : (_b3 = element == null ? void 0 : element.parentElement) == null ? void 0 : _b3.getBoundingClientRect().width) != null ? _d2 : fallback;
647
+ }
648
+ function handleResizeStart(event, columnId, minPx, maxPx) {
649
+ var _a3, _b3;
650
+ event.preventDefault();
651
+ event.stopPropagation();
652
+ const currentWidth = getCurrentColumnWidth(columnId, minPx, event.currentTarget);
653
+ (_b3 = (_a3 = event.currentTarget).setPointerCapture) == null ? void 0 : _b3.call(_a3, event.pointerId);
654
+ resizeColumn(columnId, currentWidth, event.clientX, minPx, maxPx);
655
+ }
656
+ function handleResizeKeyDown(event, columnId, minPx, maxPx) {
657
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
658
+ event.preventDefault();
659
+ event.stopPropagation();
660
+ const step = event.shiftKey ? 32 : 8;
661
+ const currentWidth = getCurrentColumnWidth(columnId, minPx, event.currentTarget);
662
+ const direction = event.key === "ArrowLeft" ? -1 : 1;
663
+ setColumnSizing((current) => __spreadProps(__spreadValues({}, current), {
664
+ [columnId]: constrainColumnWidth(currentWidth + direction * step, minPx, maxPx)
665
+ }));
566
666
  }
567
667
  function moveColumn(id, direction) {
568
668
  const current = table.getState().columnOrder;
@@ -584,6 +684,11 @@ function BonelessTable(_a) {
584
684
  initialRect: { width: 0, height: 600 }
585
685
  });
586
686
  const estimatedRowSize = virtualization === false ? 58 : (_p = virtualization.estimateSize) != null ? _p : 58;
687
+ const measuredVirtualHeight = rowVirtualizer.getTotalSize();
688
+ const virtualHeight = isVirtualized ? Math.max(
689
+ Number.isFinite(measuredVirtualHeight) ? measuredVirtualHeight : 0,
690
+ rows.length * estimatedRowSize
691
+ ) : void 0;
587
692
  const virtualRows = !isVirtualized ? rows.map((row, index) => ({ index, start: index * 58, key: row.id })) : rowVirtualizer.getVirtualItems().length > 0 ? rowVirtualizer.getVirtualItems() : rows.slice(0, Math.ceil(600 / estimatedRowSize) + ((_q = virtualization.overscan) != null ? _q : 5)).map((row, index) => ({
588
693
  index,
589
694
  start: index * estimatedRowSize,
@@ -707,246 +812,315 @@ function BonelessTable(_a) {
707
812
  flex: "0 0 auto",
708
813
  minWidth: 0,
709
814
  overflow: "hidden",
710
- scrollbarGutter: "stable"
815
+ // The body loses this space to a classic vertical scrollbar on Windows. Reserving the
816
+ // same width here keeps both horizontal scroll ranges identical at their far edge.
817
+ marginInlineEnd: `${headerScrollbarInset}px`
711
818
  };
712
819
  const tableStyle = __spreadValues({
713
820
  "--boneless-table-grid": grid
714
821
  }, scroller === "fill" ? { display: "flex", flexDirection: "column", flex: "1 1 auto", minHeight: 0 } : {});
715
- return /* @__PURE__ */ jsxs3("div", { className: cn(className, classNames.root), "data-slot": "root", style: rootStyle, children: [
716
- renderSlot(toolbar, table, defaultToolbar),
717
- filterPlacement === "above" ? renderedFilters : null,
718
- /* @__PURE__ */ jsxs3(
719
- "div",
720
- {
721
- className: classNames.table,
722
- "data-slot": "table",
723
- style: tableStyle,
724
- "aria-busy": isLoading || isFetchingMore,
725
- role: "table",
726
- children: [
727
- /* @__PURE__ */ jsx4(
728
- "div",
729
- {
730
- className: classNames.headerScroller,
731
- "data-slot": "header-scroller",
732
- ref: headerScrollerRef,
733
- style: headerScrollerStyle,
734
- children: /* @__PURE__ */ jsx4(
822
+ return /* @__PURE__ */ jsxs3(
823
+ "div",
824
+ {
825
+ className: cn(className, classNames.root),
826
+ "data-slot": "root",
827
+ ref: rootRef,
828
+ style: rootStyle,
829
+ children: [
830
+ renderSlot(toolbar, table, defaultToolbar),
831
+ filterPlacement === "above" ? renderedFilters : null,
832
+ /* @__PURE__ */ jsxs3(
833
+ "div",
834
+ {
835
+ className: classNames.table,
836
+ "data-slot": "table",
837
+ style: tableStyle,
838
+ "aria-busy": isLoading || isFetchingMore,
839
+ role: "table",
840
+ children: [
841
+ /* @__PURE__ */ jsx4(
735
842
  "div",
736
843
  {
737
- className: classNames.headerGroup,
738
- "data-slot": "header-group",
739
- role: "rowgroup",
740
- style: gridStyle,
741
- children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx4(
844
+ className: classNames.headerScroller,
845
+ "data-slot": "header-scroller",
846
+ ref: headerScrollerRef,
847
+ style: headerScrollerStyle,
848
+ children: /* @__PURE__ */ jsx4(
742
849
  "div",
743
850
  {
744
- className: classNames.headerRow,
745
- "data-slot": "header-row",
746
- role: "row",
747
- style: { display: "grid", gridTemplateColumns: "var(--boneless-table-grid)" },
748
- children: headerGroup.headers.map((header) => {
749
- const columnSettings = getColumnSettings(header.column);
750
- const direction = header.column.getIsSorted();
751
- const isSortable = !header.isPlaceholder && header.column.getCanSort() && columnSettings.sorting.enabled;
752
- return /* @__PURE__ */ jsx4(
753
- "div",
754
- {
755
- className: classNames.header,
756
- "data-slot": "header",
757
- "data-align": columnSettings.align,
758
- "data-borders": columnSettings.borders,
759
- role: "columnheader",
760
- "aria-colspan": header.colSpan > 1 ? header.colSpan : void 0,
761
- "aria-sort": direction === "asc" ? "ascending" : direction === "desc" ? "descending" : isSortable ? "none" : void 0,
762
- style: { gridColumn: `span ${header.colSpan}` },
763
- children: header.isPlaceholder ? null : isSortable ? /* @__PURE__ */ jsxs3(
764
- "button",
765
- {
766
- className: classNames.headerButton,
767
- "data-align": columnSettings.align,
768
- "data-slot": "header-button",
769
- onClick: header.column.getToggleSortingHandler(),
770
- children: [
771
- /* @__PURE__ */ jsx4("span", { className: classNames.headerLabel, "data-slot": "header-label", children: flexRender(header.column.columnDef.header, header.getContext()) }),
772
- (icons == null ? void 0 : icons.sort) ? /* @__PURE__ */ jsx4(
773
- "span",
774
- {
775
- className: classNames.sortIndicator,
776
- "data-align": columnSettings.align,
777
- "data-slot": "sort-indicator",
778
- "data-reveal": columnSettings.sorting.reveal,
779
- children: icons.sort(direction)
780
- }
781
- ) : null
782
- ]
783
- }
784
- ) : flexRender(header.column.columnDef.header, header.getContext())
785
- },
786
- header.id
787
- );
788
- })
789
- },
790
- headerGroup.id
791
- ))
792
- }
793
- )
794
- }
795
- ),
796
- /* @__PURE__ */ jsxs3(
797
- "div",
798
- {
799
- "aria-label": "Table rows",
800
- className: classNames.scroller,
801
- "data-slot": "scroller",
802
- ref: scrollerRef,
803
- onScroll: handleScroll,
804
- style: scrollerStyle,
805
- tabIndex: 0,
806
- children: [
807
- isLoading ? /* @__PURE__ */ jsx4(
808
- TableSkeleton,
809
- {
810
- columnCount: visibleColumns.length,
811
- rows: skeletonRows,
812
- label: skeletonLabel,
813
- classNames
814
- }
815
- ) : rows.length === 0 ? /* @__PURE__ */ jsx4("div", { className: classNames.emptyState, "data-slot": "empty-state", role: "status", children: emptyState ? typeof emptyState === "function" ? emptyState(table) : emptyState : table.getState().columnFilters.length > 0 ? "No rows match the current filters." : "No rows to display." }) : /* @__PURE__ */ jsx4(
816
- "div",
817
- {
818
- className: classNames.rowGroup,
819
- "data-slot": "row-group",
820
- style: __spreadProps(__spreadValues({}, gridStyle), {
821
- height: `${isVirtualized ? rowVirtualizer.getTotalSize() : "auto"}`,
822
- position: "relative"
823
- }),
824
- role: "rowgroup",
825
- children: virtualRows.map((virtualRow) => {
826
- var _a3;
827
- const row = rows[virtualRow.index];
828
- const href = rowLink ? resolveRowHref(rowLink, row.original) : void 0;
829
- const RowLink = rowLink == null ? void 0 : rowLink.component;
830
- const rowContent = /* @__PURE__ */ jsx4(
851
+ className: classNames.headerGroup,
852
+ "data-slot": "header-group",
853
+ role: "rowgroup",
854
+ style: gridStyle,
855
+ children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx4(
831
856
  "div",
832
857
  {
833
- className: classNames.row,
834
- "data-slot": "row",
858
+ className: classNames.headerRow,
859
+ "data-slot": "header-row",
835
860
  role: "row",
836
861
  style: { display: "grid", gridTemplateColumns: "var(--boneless-table-grid)" },
837
- tabIndex: onRowClick && !href ? 0 : void 0,
838
- onClick: (event) => onRowClick == null ? void 0 : onRowClick(row.original, event),
839
- onKeyDown: (event) => {
840
- if (!onRowClick || href || event.key !== "Enter" && event.key !== " ")
841
- return;
842
- event.preventDefault();
843
- onRowClick(row.original, event);
844
- },
845
- children: row.getVisibleCells().map((cell) => {
846
- var _a4, _b3, _c2;
847
- const columnSettings = getColumnSettings(cell.column);
848
- const title = columnSettings.valueDisplay != null ? String((_a4 = cell.getValue()) != null ? _a4 : "") : void 0;
849
- const isTreeCell = Boolean(tree && cell.column.id === treeColumnId);
850
- const canExpand = row.getCanExpand();
851
- const cellContent = flexRender(cell.column.columnDef.cell, cell.getContext());
862
+ children: headerGroup.headers.map((header) => {
863
+ const columnSettings = getColumnSettings(header.column);
864
+ const direction = header.column.getIsSorted();
865
+ const isSortable = !header.isPlaceholder && header.column.getCanSort() && columnSettings.sorting.enabled;
852
866
  return /* @__PURE__ */ jsx4(
853
867
  "div",
854
868
  {
855
- className: classNames.cell,
856
- "data-slot": "cell",
869
+ className: classNames.header,
870
+ "data-slot": "header",
857
871
  "data-align": columnSettings.align,
858
872
  "data-borders": columnSettings.borders,
859
- role: "cell",
860
- title,
861
- children: isTreeCell ? /* @__PURE__ */ jsxs3(
862
- "div",
863
- {
864
- "data-slot": "tree-content",
865
- style: { paddingInlineStart: `${row.depth * treeIndentPx}px` },
866
- children: [
867
- canExpand ? /* @__PURE__ */ jsx4(
868
- "button",
869
- {
870
- "data-slot": "tree-row-toggle",
871
- type: "button",
872
- "aria-expanded": row.getIsExpanded(),
873
- "aria-label": `${row.getIsExpanded() ? "Collapse" : "Expand"} row`,
874
- onClick: (event) => {
875
- event.stopPropagation();
876
- row.toggleExpanded();
877
- },
878
- children: row.getIsExpanded() ? (_b3 = icons == null ? void 0 : icons.collapse) != null ? _b3 : "\u2212" : (_c2 = icons == null ? void 0 : icons.expand) != null ? _c2 : "+"
879
- }
880
- ) : /* @__PURE__ */ jsx4("span", { "data-slot": "tree-row-toggle-spacer", "aria-hidden": "true" }),
881
- /* @__PURE__ */ jsx4("span", { "data-slot": "tree-value", children: cellContent })
882
- ]
883
- }
884
- ) : cellContent
873
+ role: "columnheader",
874
+ "aria-colspan": header.colSpan > 1 ? header.colSpan : void 0,
875
+ "aria-sort": direction === "asc" ? "ascending" : direction === "desc" ? "descending" : isSortable ? "none" : void 0,
876
+ style: { gridColumn: `span ${header.colSpan}` },
877
+ children: header.isPlaceholder ? null : isSortable ? /* @__PURE__ */ jsxs3(Fragment, { children: [
878
+ /* @__PURE__ */ jsxs3(
879
+ "button",
880
+ {
881
+ className: classNames.headerButton,
882
+ "data-align": columnSettings.align,
883
+ "data-slot": "header-button",
884
+ onClick: header.column.getToggleSortingHandler(),
885
+ children: [
886
+ /* @__PURE__ */ jsx4("span", { className: classNames.headerLabel, "data-slot": "header-label", children: flexRender(header.column.columnDef.header, header.getContext()) }),
887
+ (icons == null ? void 0 : icons.sort) ? /* @__PURE__ */ jsx4(
888
+ "span",
889
+ {
890
+ className: classNames.sortIndicator,
891
+ "data-align": columnSettings.align,
892
+ "data-slot": "sort-indicator",
893
+ "data-reveal": columnSettings.sorting.reveal,
894
+ children: icons.sort(direction)
895
+ }
896
+ ) : null
897
+ ]
898
+ }
899
+ ),
900
+ header.colSpan === 1 && columnSettings.sizing.resizable ? /* @__PURE__ */ jsx4(
901
+ "button",
902
+ {
903
+ "aria-label": `Resize ${header.column.id} column`,
904
+ className: classNames.resizeHandle,
905
+ "data-slot": "resize-handle",
906
+ onKeyDown: (event) => {
907
+ var _a3;
908
+ return handleResizeKeyDown(
909
+ event,
910
+ header.column.id,
911
+ (_a3 = columnSettings.sizing.minPx) != null ? _a3 : settings.columnDefaults.sizing.minPx,
912
+ columnSettings.sizing.maxPx
913
+ );
914
+ },
915
+ onPointerDown: (event) => {
916
+ var _a3;
917
+ return handleResizeStart(
918
+ event,
919
+ header.column.id,
920
+ (_a3 = columnSettings.sizing.minPx) != null ? _a3 : settings.columnDefaults.sizing.minPx,
921
+ columnSettings.sizing.maxPx
922
+ );
923
+ },
924
+ type: "button"
925
+ }
926
+ ) : null
927
+ ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
928
+ flexRender(header.column.columnDef.header, header.getContext()),
929
+ header.colSpan === 1 && columnSettings.sizing.resizable ? /* @__PURE__ */ jsx4(
930
+ "button",
931
+ {
932
+ "aria-label": `Resize ${header.column.id} column`,
933
+ className: classNames.resizeHandle,
934
+ "data-slot": "resize-handle",
935
+ onKeyDown: (event) => {
936
+ var _a3;
937
+ return handleResizeKeyDown(
938
+ event,
939
+ header.column.id,
940
+ (_a3 = columnSettings.sizing.minPx) != null ? _a3 : settings.columnDefaults.sizing.minPx,
941
+ columnSettings.sizing.maxPx
942
+ );
943
+ },
944
+ onPointerDown: (event) => {
945
+ var _a3;
946
+ return handleResizeStart(
947
+ event,
948
+ header.column.id,
949
+ (_a3 = columnSettings.sizing.minPx) != null ? _a3 : settings.columnDefaults.sizing.minPx,
950
+ columnSettings.sizing.maxPx
951
+ );
952
+ },
953
+ type: "button"
954
+ }
955
+ ) : null
956
+ ] })
885
957
  },
886
- cell.id
958
+ header.id
887
959
  );
888
960
  })
889
- }
890
- );
891
- const rowStyle = !isVirtualized ? void 0 : {
892
- position: "absolute",
893
- top: 0,
894
- left: 0,
895
- width: "100%",
896
- transform: `translateY(${virtualRow.start}px)`
897
- };
898
- if (!href || !rowLink || !RowLink || tree && row.getCanExpand())
899
- return /* @__PURE__ */ jsx4(
900
- "div",
901
- {
902
- "data-index": isVirtualized ? virtualRow.index : void 0,
903
- ref: isVirtualized ? rowVirtualizer.measureElement : void 0,
904
- style: rowStyle,
905
- children: rowContent
906
- },
907
- row.id
908
- );
909
- return /* @__PURE__ */ jsx4(
910
- "div",
911
- {
912
- "data-index": isVirtualized ? virtualRow.index : void 0,
913
- ref: isVirtualized ? rowVirtualizer.measureElement : void 0,
914
- style: rowStyle,
915
- children: /* @__PURE__ */ jsx4(
916
- RowLink,
961
+ },
962
+ headerGroup.id
963
+ ))
964
+ }
965
+ )
966
+ }
967
+ ),
968
+ /* @__PURE__ */ jsxs3(
969
+ "div",
970
+ {
971
+ "aria-label": "Table rows",
972
+ className: classNames.scroller,
973
+ "data-slot": "scroller",
974
+ ref: scrollerRef,
975
+ onScroll: handleScroll,
976
+ style: scrollerStyle,
977
+ tabIndex: 0,
978
+ children: [
979
+ isLoading ? /* @__PURE__ */ jsx4(
980
+ TableSkeleton,
981
+ {
982
+ columnCount: visibleColumns.length,
983
+ rows: skeletonRows,
984
+ label: skeletonLabel,
985
+ classNames
986
+ }
987
+ ) : rows.length === 0 ? /* @__PURE__ */ jsx4("div", { className: classNames.emptyState, "data-slot": "empty-state", role: "status", children: emptyState ? typeof emptyState === "function" ? emptyState(table) : emptyState : table.getState().columnFilters.length > 0 ? "No rows match the current filters." : "No rows to display." }) : /* @__PURE__ */ jsx4(
988
+ "div",
989
+ {
990
+ className: classNames.rowGroup,
991
+ "data-slot": "row-group",
992
+ style: __spreadProps(__spreadValues({}, gridStyle), {
993
+ height: isVirtualized ? `${virtualHeight}px` : "auto",
994
+ position: "relative"
995
+ }),
996
+ role: "rowgroup",
997
+ children: virtualRows.map((virtualRow) => {
998
+ var _a3;
999
+ const row = rows[virtualRow.index];
1000
+ const href = rowLink ? resolveRowHref(rowLink, row.original) : void 0;
1001
+ const RowLink = rowLink == null ? void 0 : rowLink.component;
1002
+ const rowContent = /* @__PURE__ */ jsx4(
1003
+ "div",
917
1004
  {
918
- className: (_a3 = classNames.rowLink) != null ? _a3 : "",
919
- href,
920
- "aria-label": resolveRowLinkLabel(rowLink, row.original),
921
- target: rowLink.target,
922
- rel: rowLink.rel,
923
- children: rowContent
1005
+ className: classNames.row,
1006
+ "data-slot": "row",
1007
+ role: "row",
1008
+ style: { display: "grid", gridTemplateColumns: "var(--boneless-table-grid)" },
1009
+ tabIndex: onRowClick && !href ? 0 : void 0,
1010
+ onClick: (event) => onRowClick == null ? void 0 : onRowClick(row.original, event),
1011
+ onKeyDown: (event) => {
1012
+ if (!onRowClick || href || event.key !== "Enter" && event.key !== " ")
1013
+ return;
1014
+ event.preventDefault();
1015
+ onRowClick(row.original, event);
1016
+ },
1017
+ children: row.getVisibleCells().map((cell) => {
1018
+ var _a4, _b3, _c2;
1019
+ const columnSettings = getColumnSettings(cell.column);
1020
+ const title = columnSettings.valueDisplay != null ? String((_a4 = cell.getValue()) != null ? _a4 : "") : void 0;
1021
+ const isTreeCell = Boolean(tree && cell.column.id === treeColumnId);
1022
+ const canExpand = row.getCanExpand();
1023
+ const cellContent = flexRender(cell.column.columnDef.cell, cell.getContext());
1024
+ return /* @__PURE__ */ jsx4(
1025
+ "div",
1026
+ {
1027
+ className: classNames.cell,
1028
+ "data-slot": "cell",
1029
+ "data-align": columnSettings.align,
1030
+ "data-borders": columnSettings.borders,
1031
+ role: "cell",
1032
+ title,
1033
+ children: isTreeCell ? /* @__PURE__ */ jsxs3(
1034
+ "div",
1035
+ {
1036
+ "data-slot": "tree-content",
1037
+ style: { paddingInlineStart: `${row.depth * treeIndentPx}px` },
1038
+ children: [
1039
+ canExpand ? /* @__PURE__ */ jsx4(
1040
+ "button",
1041
+ {
1042
+ "data-slot": "tree-row-toggle",
1043
+ type: "button",
1044
+ "aria-expanded": row.getIsExpanded(),
1045
+ "aria-label": `${row.getIsExpanded() ? "Collapse" : "Expand"} row`,
1046
+ onClick: (event) => {
1047
+ event.stopPropagation();
1048
+ row.toggleExpanded();
1049
+ },
1050
+ children: row.getIsExpanded() ? (_b3 = icons == null ? void 0 : icons.collapse) != null ? _b3 : "\u2212" : (_c2 = icons == null ? void 0 : icons.expand) != null ? _c2 : "+"
1051
+ }
1052
+ ) : /* @__PURE__ */ jsx4("span", { "data-slot": "tree-row-toggle-spacer", "aria-hidden": "true" }),
1053
+ /* @__PURE__ */ jsx4("span", { "data-slot": "tree-value", children: cellContent })
1054
+ ]
1055
+ }
1056
+ ) : cellContent
1057
+ },
1058
+ cell.id
1059
+ );
1060
+ })
924
1061
  }
925
- )
926
- },
927
- row.id
928
- );
929
- })
930
- }
931
- ),
932
- isFetchingMore ? /* @__PURE__ */ jsx4(
933
- TableSkeleton,
934
- {
935
- columnCount: visibleColumns.length,
936
- rows: 3,
937
- label: skeletonLabel,
938
- classNames
939
- }
940
- ) : null
941
- ]
942
- }
943
- )
944
- ]
945
- }
946
- ),
947
- filterPlacement === "below" ? renderedFilters : null,
948
- renderSlot(footer, table, defaultFooter)
949
- ] });
1062
+ );
1063
+ const rowStyle = !isVirtualized ? void 0 : {
1064
+ position: "absolute",
1065
+ top: 0,
1066
+ left: 0,
1067
+ width: "100%",
1068
+ transform: `translateY(${virtualRow.start}px)`
1069
+ };
1070
+ if (!href || !rowLink || !RowLink || tree && row.getCanExpand())
1071
+ return /* @__PURE__ */ jsx4(
1072
+ "div",
1073
+ {
1074
+ "data-index": isVirtualized ? virtualRow.index : void 0,
1075
+ ref: isVirtualized ? rowVirtualizer.measureElement : void 0,
1076
+ style: rowStyle,
1077
+ children: rowContent
1078
+ },
1079
+ row.id
1080
+ );
1081
+ return /* @__PURE__ */ jsx4(
1082
+ "div",
1083
+ {
1084
+ "data-index": isVirtualized ? virtualRow.index : void 0,
1085
+ ref: isVirtualized ? rowVirtualizer.measureElement : void 0,
1086
+ style: rowStyle,
1087
+ children: /* @__PURE__ */ jsx4(
1088
+ RowLink,
1089
+ {
1090
+ className: (_a3 = classNames.rowLink) != null ? _a3 : "",
1091
+ href,
1092
+ "aria-label": resolveRowLinkLabel(rowLink, row.original),
1093
+ target: rowLink.target,
1094
+ rel: rowLink.rel,
1095
+ children: rowContent
1096
+ }
1097
+ )
1098
+ },
1099
+ row.id
1100
+ );
1101
+ })
1102
+ }
1103
+ ),
1104
+ isFetchingMore ? /* @__PURE__ */ jsx4(
1105
+ TableSkeleton,
1106
+ {
1107
+ columnCount: visibleColumns.length,
1108
+ rows: 3,
1109
+ label: skeletonLabel,
1110
+ classNames
1111
+ }
1112
+ ) : null
1113
+ ]
1114
+ }
1115
+ )
1116
+ ]
1117
+ }
1118
+ ),
1119
+ filterPlacement === "below" ? renderedFilters : null,
1120
+ renderSlot(footer, table, defaultFooter)
1121
+ ]
1122
+ }
1123
+ );
950
1124
  }
951
1125
 
952
1126
  // src/index.ts