boneless-table 0.1.0 → 0.1.1
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.d.mts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.js +96 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +106 -80
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -45,12 +45,12 @@ import {
|
|
|
45
45
|
useEffect as useEffect3,
|
|
46
46
|
useId,
|
|
47
47
|
useMemo,
|
|
48
|
-
useRef as
|
|
48
|
+
useRef as useRef3,
|
|
49
49
|
useState as useState2
|
|
50
50
|
} from "react";
|
|
51
51
|
|
|
52
52
|
// src/column-filter.tsx
|
|
53
|
-
import { useEffect, useState } from "react";
|
|
53
|
+
import { useEffect, useRef, useState } from "react";
|
|
54
54
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
55
55
|
function ColumnFilter({
|
|
56
56
|
column,
|
|
@@ -62,10 +62,13 @@ function ColumnFilter({
|
|
|
62
62
|
var _a, _b;
|
|
63
63
|
const value = String((_a = column.getFilterValue()) != null ? _a : "");
|
|
64
64
|
const [inputValue, setInputValue] = useState(value);
|
|
65
|
+
const lastColumnValueRef = useRef(value);
|
|
65
66
|
useEffect(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if (value !== lastColumnValueRef.current) {
|
|
68
|
+
lastColumnValueRef.current = value;
|
|
69
|
+
setInputValue(value);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
69
72
|
if (settings.type !== "text" || inputValue === value) return;
|
|
70
73
|
if (debounceMs <= 0) {
|
|
71
74
|
column.setFilterValue(inputValue || void 0);
|
|
@@ -109,7 +112,7 @@ function ColumnFilter({
|
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
// src/column-menu.tsx
|
|
112
|
-
import { useEffect as useEffect2, useRef } from "react";
|
|
115
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
113
116
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
114
117
|
function ColumnMenu({
|
|
115
118
|
table,
|
|
@@ -121,8 +124,8 @@ function ColumnMenu({
|
|
|
121
124
|
triggerRef
|
|
122
125
|
}) {
|
|
123
126
|
var _a;
|
|
124
|
-
const menuRef =
|
|
125
|
-
const closeButtonRef =
|
|
127
|
+
const menuRef = useRef2(null);
|
|
128
|
+
const closeButtonRef = useRef2(null);
|
|
126
129
|
useEffect2(() => {
|
|
127
130
|
var _a2;
|
|
128
131
|
(_a2 = closeButtonRef.current) == null ? void 0 : _a2.focus();
|
|
@@ -218,7 +221,7 @@ var defaultBonelessTableSettings = {
|
|
|
218
221
|
borders: "none",
|
|
219
222
|
sorting: { enabled: true, reveal: "hover" }
|
|
220
223
|
},
|
|
221
|
-
interactions: {
|
|
224
|
+
interactions: { horizontalOverflow: "auto" }
|
|
222
225
|
};
|
|
223
226
|
function mergeBonelessTableSettings(override, base = defaultBonelessTableSettings) {
|
|
224
227
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -337,7 +340,7 @@ function resolveRowLinkLabel(link, row) {
|
|
|
337
340
|
}
|
|
338
341
|
|
|
339
342
|
// src/boneless-table.tsx
|
|
340
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
343
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
341
344
|
function moveItem(order, id, direction) {
|
|
342
345
|
const index = order.indexOf(id);
|
|
343
346
|
const target = index + direction;
|
|
@@ -372,6 +375,8 @@ function BonelessTable(_a) {
|
|
|
372
375
|
scroller = "auto",
|
|
373
376
|
toolbar = true,
|
|
374
377
|
toolbarLayout,
|
|
378
|
+
filters = true,
|
|
379
|
+
filterPlacement = "above",
|
|
375
380
|
footer = true,
|
|
376
381
|
totalCount,
|
|
377
382
|
resultLabel = "rows",
|
|
@@ -401,6 +406,8 @@ function BonelessTable(_a) {
|
|
|
401
406
|
"scroller",
|
|
402
407
|
"toolbar",
|
|
403
408
|
"toolbarLayout",
|
|
409
|
+
"filters",
|
|
410
|
+
"filterPlacement",
|
|
404
411
|
"footer",
|
|
405
412
|
"totalCount",
|
|
406
413
|
"resultLabel",
|
|
@@ -416,13 +423,13 @@ function BonelessTable(_a) {
|
|
|
416
423
|
const settings = useMemo(() => mergeBonelessTableSettings(settingsOverride), [settingsOverride]);
|
|
417
424
|
const resolvedColumns = useMemo(() => withDefaultCells(resolveColumns(columns)), [columns]);
|
|
418
425
|
const defaultOrder = useMemo(() => getColumnIds(resolvedColumns), [resolvedColumns]);
|
|
419
|
-
const scrollerRef =
|
|
420
|
-
const headerScrollerRef =
|
|
421
|
-
const
|
|
422
|
-
const
|
|
426
|
+
const scrollerRef = useRef3(null);
|
|
427
|
+
const headerScrollerRef = useRef3(null);
|
|
428
|
+
const lastScrollLeftRef = useRef3(0);
|
|
429
|
+
const columnsButtonRef = useRef3(null);
|
|
430
|
+
const nearEndTriggeredRef = useRef3(false);
|
|
423
431
|
const columnMenuId = useId();
|
|
424
432
|
const [showColumns, setShowColumns] = useState2(false);
|
|
425
|
-
const [headerScrollbarGutter, setHeaderScrollbarGutter] = useState2(0);
|
|
426
433
|
const [sorting, setSorting] = useState2((_b2 = (_a2 = tableOptions.initialState) == null ? void 0 : _a2.sorting) != null ? _b2 : []);
|
|
427
434
|
const [columnFilters, setColumnFilters] = useState2(
|
|
428
435
|
(_d = (_c = tableOptions.initialState) == null ? void 0 : _c.columnFilters) != null ? _d : []
|
|
@@ -467,18 +474,6 @@ function BonelessTable(_a) {
|
|
|
467
474
|
var _a3;
|
|
468
475
|
if (scrollToTopOn !== void 0) (_a3 = scrollerRef.current) == null ? void 0 : _a3.scrollTo({ top: 0 });
|
|
469
476
|
}, [scrollToTopOn]);
|
|
470
|
-
useEffect3(() => {
|
|
471
|
-
const scroller2 = scrollerRef.current;
|
|
472
|
-
if (!scroller2) return;
|
|
473
|
-
const syncHeaderScrollbarGutter = () => {
|
|
474
|
-
setHeaderScrollbarGutter(Math.max(0, scroller2.offsetWidth - scroller2.clientWidth));
|
|
475
|
-
};
|
|
476
|
-
syncHeaderScrollbarGutter();
|
|
477
|
-
if (typeof ResizeObserver === "undefined") return;
|
|
478
|
-
const observer = new ResizeObserver(syncHeaderScrollbarGutter);
|
|
479
|
-
observer.observe(scroller2);
|
|
480
|
-
return () => observer.disconnect();
|
|
481
|
-
}, []);
|
|
482
477
|
const table = useReactTable(__spreadProps(__spreadValues({}, restTableOptions), {
|
|
483
478
|
data,
|
|
484
479
|
columns: resolvedColumns,
|
|
@@ -547,13 +542,17 @@ function BonelessTable(_a) {
|
|
|
547
542
|
function handleScroll() {
|
|
548
543
|
const element = scrollerRef.current;
|
|
549
544
|
if (!element) return;
|
|
550
|
-
if (
|
|
545
|
+
if (element.scrollLeft !== lastScrollLeftRef.current) {
|
|
546
|
+
lastScrollLeftRef.current = element.scrollLeft;
|
|
547
|
+
if (headerScrollerRef.current) headerScrollerRef.current.scrollLeft = element.scrollLeft;
|
|
548
|
+
}
|
|
549
|
+
if (!onNearEnd) return;
|
|
551
550
|
const isNearEnd = element.scrollHeight - element.scrollTop - element.clientHeight < nearEndOffset;
|
|
552
551
|
if (!isNearEnd) {
|
|
553
552
|
nearEndTriggeredRef.current = false;
|
|
554
553
|
return;
|
|
555
554
|
}
|
|
556
|
-
if (!
|
|
555
|
+
if (!canLoadMore || isFetchingMore || nearEndTriggeredRef.current) return;
|
|
557
556
|
nearEndTriggeredRef.current = true;
|
|
558
557
|
onNearEnd();
|
|
559
558
|
}
|
|
@@ -596,10 +595,13 @@ function BonelessTable(_a) {
|
|
|
596
595
|
(_a3 = columnsButtonRef.current) == null ? void 0 : _a3.focus();
|
|
597
596
|
}
|
|
598
597
|
const toolbarSummary = /* @__PURE__ */ jsxs3("div", { className: classNames.toolbarSummary, "data-slot": "toolbar-summary", children: [
|
|
599
|
-
/* @__PURE__ */ jsx4("strong", { children: total.toLocaleString() }),
|
|
598
|
+
/* @__PURE__ */ jsx4("strong", { className: classNames.toolbarCount, "data-slot": "toolbar-count", children: total.toLocaleString() }),
|
|
600
599
|
" ",
|
|
601
|
-
resultLabel,
|
|
602
|
-
resultHint ? /* @__PURE__ */
|
|
600
|
+
/* @__PURE__ */ jsx4("span", { className: classNames.toolbarLabel, "data-slot": "toolbar-label", children: resultLabel }),
|
|
601
|
+
resultHint ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
602
|
+
" ",
|
|
603
|
+
/* @__PURE__ */ jsx4("span", { className: classNames.toolbarHint, "data-slot": "toolbar-hint", children: resultHint })
|
|
604
|
+
] }) : null
|
|
603
605
|
] });
|
|
604
606
|
const toolbarActions = /* @__PURE__ */ jsxs3("div", { className: classNames.toolbarActions, "data-slot": "toolbar-actions", children: [
|
|
605
607
|
tree && expandableRows.length > 0 ? /* @__PURE__ */ jsxs3(
|
|
@@ -651,6 +653,43 @@ function BonelessTable(_a) {
|
|
|
651
653
|
toolbarSummary,
|
|
652
654
|
toolbarActions
|
|
653
655
|
] });
|
|
656
|
+
const filterHeaders = table.getLeafHeaders().filter((header) => !header.isPlaceholder && getColumnSettings(header.column).filtering);
|
|
657
|
+
const defaultFilters = filterHeaders.length > 0 ? /* @__PURE__ */ jsx4(
|
|
658
|
+
"div",
|
|
659
|
+
{
|
|
660
|
+
"aria-label": "Table filters",
|
|
661
|
+
className: classNames.filters,
|
|
662
|
+
"data-slot": "filters",
|
|
663
|
+
role: "group",
|
|
664
|
+
children: filterHeaders.map((header) => {
|
|
665
|
+
var _a3, _b3;
|
|
666
|
+
const filterSettings = getColumnSettings(header.column).filtering;
|
|
667
|
+
return /* @__PURE__ */ jsxs3(
|
|
668
|
+
"div",
|
|
669
|
+
{
|
|
670
|
+
className: classNames.filterItem,
|
|
671
|
+
"data-column-id": header.column.id,
|
|
672
|
+
"data-slot": "filter-item",
|
|
673
|
+
children: [
|
|
674
|
+
/* @__PURE__ */ jsx4("span", { className: classNames.filterLabel, "data-slot": "filter-label", children: (_b3 = (_a3 = header.column.columnDef.meta) == null ? void 0 : _a3.columnLabel) != null ? _b3 : typeof header.column.columnDef.header === "string" || typeof header.column.columnDef.header === "number" ? String(header.column.columnDef.header) : header.column.id }),
|
|
675
|
+
/* @__PURE__ */ jsx4(
|
|
676
|
+
ColumnFilter,
|
|
677
|
+
{
|
|
678
|
+
className: classNames.filter,
|
|
679
|
+
column: header.column,
|
|
680
|
+
settings: filterSettings,
|
|
681
|
+
icon: filterSettings.type === "text" ? icons == null ? void 0 : icons.search : void 0,
|
|
682
|
+
debounceMs: filterDebounceMs
|
|
683
|
+
}
|
|
684
|
+
)
|
|
685
|
+
]
|
|
686
|
+
},
|
|
687
|
+
header.id
|
|
688
|
+
);
|
|
689
|
+
})
|
|
690
|
+
}
|
|
691
|
+
) : null;
|
|
692
|
+
const renderedFilters = renderSlot(filters, table, defaultFilters);
|
|
654
693
|
const defaultFooter = /* @__PURE__ */ jsxs3("footer", { className: classNames.footer, "data-slot": "footer", children: [
|
|
655
694
|
"Showing ",
|
|
656
695
|
shown.toLocaleString(),
|
|
@@ -661,13 +700,21 @@ function BonelessTable(_a) {
|
|
|
661
700
|
] });
|
|
662
701
|
const rootStyle = scroller === "fill" ? { display: "flex", flexDirection: "column", minHeight: 0 } : void 0;
|
|
663
702
|
const scrollerStyle = __spreadValues({
|
|
664
|
-
overflowX: settings.interactions.horizontalOverflow
|
|
703
|
+
overflowX: settings.interactions.horizontalOverflow,
|
|
704
|
+
scrollbarGutter: "stable"
|
|
665
705
|
}, scroller === "fill" ? { flex: "1 1 auto", minHeight: 0, overflowY: "auto" } : {});
|
|
706
|
+
const headerScrollerStyle = {
|
|
707
|
+
flex: "0 0 auto",
|
|
708
|
+
minWidth: 0,
|
|
709
|
+
overflow: "hidden",
|
|
710
|
+
scrollbarGutter: "stable"
|
|
711
|
+
};
|
|
666
712
|
const tableStyle = __spreadValues({
|
|
667
713
|
"--boneless-table-grid": grid
|
|
668
714
|
}, scroller === "fill" ? { display: "flex", flexDirection: "column", flex: "1 1 auto", minHeight: 0 } : {});
|
|
669
715
|
return /* @__PURE__ */ jsxs3("div", { className: cn(className, classNames.root), "data-slot": "root", style: rootStyle, children: [
|
|
670
716
|
renderSlot(toolbar, table, defaultToolbar),
|
|
717
|
+
filterPlacement === "above" ? renderedFilters : null,
|
|
671
718
|
/* @__PURE__ */ jsxs3(
|
|
672
719
|
"div",
|
|
673
720
|
{
|
|
@@ -680,14 +727,10 @@ function BonelessTable(_a) {
|
|
|
680
727
|
/* @__PURE__ */ jsx4(
|
|
681
728
|
"div",
|
|
682
729
|
{
|
|
730
|
+
className: classNames.headerScroller,
|
|
683
731
|
"data-slot": "header-scroller",
|
|
684
732
|
ref: headerScrollerRef,
|
|
685
|
-
style:
|
|
686
|
-
flex: "0 0 auto",
|
|
687
|
-
minWidth: 0,
|
|
688
|
-
overflow: "hidden",
|
|
689
|
-
paddingInlineEnd: headerScrollbarGutter || void 0
|
|
690
|
-
},
|
|
733
|
+
style: headerScrollerStyle,
|
|
691
734
|
children: /* @__PURE__ */ jsx4(
|
|
692
735
|
"div",
|
|
693
736
|
{
|
|
@@ -703,11 +746,10 @@ function BonelessTable(_a) {
|
|
|
703
746
|
role: "row",
|
|
704
747
|
style: { display: "grid", gridTemplateColumns: "var(--boneless-table-grid)" },
|
|
705
748
|
children: headerGroup.headers.map((header) => {
|
|
706
|
-
var _a3;
|
|
707
749
|
const columnSettings = getColumnSettings(header.column);
|
|
708
750
|
const direction = header.column.getIsSorted();
|
|
709
751
|
const isSortable = !header.isPlaceholder && header.column.getCanSort() && columnSettings.sorting.enabled;
|
|
710
|
-
return /* @__PURE__ */
|
|
752
|
+
return /* @__PURE__ */ jsx4(
|
|
711
753
|
"div",
|
|
712
754
|
{
|
|
713
755
|
className: classNames.header,
|
|
@@ -718,47 +760,28 @@ function BonelessTable(_a) {
|
|
|
718
760
|
"aria-colspan": header.colSpan > 1 ? header.colSpan : void 0,
|
|
719
761
|
"aria-sort": direction === "asc" ? "ascending" : direction === "desc" ? "descending" : isSortable ? "none" : void 0,
|
|
720
762
|
style: { gridColumn: `span ${header.colSpan}` },
|
|
721
|
-
children:
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
children:
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
"span",
|
|
733
|
-
{
|
|
734
|
-
className: classNames.sortIndicator,
|
|
735
|
-
"data-align": columnSettings.align,
|
|
736
|
-
"data-slot": "sort-indicator",
|
|
737
|
-
"data-reveal": columnSettings.sorting.reveal,
|
|
738
|
-
children: icons.sort(direction)
|
|
739
|
-
}
|
|
740
|
-
) : null
|
|
741
|
-
]
|
|
742
|
-
}
|
|
743
|
-
) : flexRender(header.column.columnDef.header, header.getContext()),
|
|
744
|
-
!header.isPlaceholder && columnSettings.filtering ? /* @__PURE__ */ jsx4(
|
|
745
|
-
"div",
|
|
746
|
-
{
|
|
747
|
-
className: classNames.filter,
|
|
748
|
-
"data-slot": "filter",
|
|
749
|
-
"data-reveal": (_a3 = columnSettings.filtering.reveal) != null ? _a3 : settings.interactions.filterReveal,
|
|
750
|
-
children: /* @__PURE__ */ jsx4(
|
|
751
|
-
ColumnFilter,
|
|
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",
|
|
752
774
|
{
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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)
|
|
757
780
|
}
|
|
758
|
-
)
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
781
|
+
) : null
|
|
782
|
+
]
|
|
783
|
+
}
|
|
784
|
+
) : flexRender(header.column.columnDef.header, header.getContext())
|
|
762
785
|
},
|
|
763
786
|
header.id
|
|
764
787
|
);
|
|
@@ -773,11 +796,13 @@ function BonelessTable(_a) {
|
|
|
773
796
|
/* @__PURE__ */ jsxs3(
|
|
774
797
|
"div",
|
|
775
798
|
{
|
|
799
|
+
"aria-label": "Table rows",
|
|
776
800
|
className: classNames.scroller,
|
|
777
801
|
"data-slot": "scroller",
|
|
778
802
|
ref: scrollerRef,
|
|
779
803
|
onScroll: handleScroll,
|
|
780
804
|
style: scrollerStyle,
|
|
805
|
+
tabIndex: 0,
|
|
781
806
|
children: [
|
|
782
807
|
isLoading ? /* @__PURE__ */ jsx4(
|
|
783
808
|
TableSkeleton,
|
|
@@ -919,6 +944,7 @@ function BonelessTable(_a) {
|
|
|
919
944
|
]
|
|
920
945
|
}
|
|
921
946
|
),
|
|
947
|
+
filterPlacement === "below" ? renderedFilters : null,
|
|
922
948
|
renderSlot(footer, table, defaultFooter)
|
|
923
949
|
] });
|
|
924
950
|
}
|