@mendylanda/ui 0.3.2-dev.56.581b055ea0a9 → 0.3.2-dev.58.0ef9785a4046
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/README.md +15 -0
- package/dist/calendar-locale.d.ts +7 -0
- package/dist/calendar-locale.js +31 -0
- package/dist/class-names.js +1 -1
- package/dist/customization.d.ts +6 -1
- package/dist/customization.js +20 -2
- package/dist/filters/filter-bar.d.ts +1 -1
- package/dist/filters/filter-bar.js +56 -30
- package/dist/filters/filter-collection.js +3 -1
- package/dist/filters/filter-date-editor.js +5 -3
- package/dist/filters/filter-definition.d.ts +3 -2
- package/dist/filters/filter-definition.js +5 -6
- package/dist/filters/filter-menu-focus.js +1 -1
- package/dist/filters/filter-menu-panel.js +13 -9
- package/dist/filters/filter-select-editor.js +6 -4
- package/dist/filters/filter-text-editor.js +5 -3
- package/dist/filters/filters.js +8 -5
- package/dist/filters/index.d.ts +3 -0
- package/dist/filters/index.js +2 -0
- package/dist/filters/use-filter-options.d.ts +1 -1
- package/dist/filters/use-filter-options.js +13 -7
- package/dist/filters/use-filters.js +6 -2
- package/dist/filters/use-url-filters.js +9 -7
- package/dist/locale-context.d.ts +29 -0
- package/dist/locale-context.js +8 -0
- package/dist/locale.d.ts +37 -0
- package/dist/locale.js +26 -0
- package/dist/locales/en.d.ts +113 -0
- package/dist/locales/en.js +112 -0
- package/dist/locales/he.d.ts +116 -0
- package/dist/locales/he.js +116 -0
- package/dist/primitives/calendar.d.ts +1 -1
- package/dist/primitives/calendar.js +15 -10
- package/dist/primitives/dropdown-menu.js +7 -5
- package/dist/primitives/popover.js +3 -1
- package/dist/styles.css +39 -39
- package/dist/styles.tailwind3.css +39 -39
- package/dist/table/table-column-settings.js +27 -13
- package/dist/table/table-controls.js +21 -8
- package/dist/table/table-feedback.js +6 -3
- package/dist/table/table-frame.js +3 -1
- package/dist/table/table-layout.d.ts +1 -1
- package/dist/table/table-layout.js +5 -5
- package/dist/table/table-loading.js +3 -1
- package/dist/table/table-parts.js +15 -11
- package/dist/table/table-view.js +6 -4
- package/dist/table/use-column-window.js +1 -1
- package/dist/table/use-data-table.js +3 -0
- package/dist/table/use-table-interaction.js +12 -8
- package/package.json +8 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { distributeColumnWidths } from "./column-widths.js";
|
|
2
2
|
/** Keep headers, skeletons, and loaded cells on the same column geometry. */
|
|
3
|
-
export function tableLayout(table, viewportWidth, rowHeight) {
|
|
3
|
+
export function tableLayout(table, viewportWidth, rowHeight, direction = "ltr") {
|
|
4
4
|
const columns = [
|
|
5
5
|
...table.getStartVisibleLeafColumns(),
|
|
6
6
|
...table.getCenterVisibleLeafColumns(),
|
|
@@ -28,12 +28,12 @@ export function tableLayout(table, viewportWidth, rowHeight) {
|
|
|
28
28
|
const positions = new Map();
|
|
29
29
|
let offset = 0;
|
|
30
30
|
for (const column of table.getStartVisibleLeafColumns()) {
|
|
31
|
-
positions.set(column.id, { side: "left", offset });
|
|
31
|
+
positions.set(column.id, { side: direction === "rtl" ? "right" : "left", offset });
|
|
32
32
|
offset += size(column);
|
|
33
33
|
}
|
|
34
34
|
offset = 0;
|
|
35
35
|
for (const column of [...table.getEndVisibleLeafColumns()].reverse()) {
|
|
36
|
-
positions.set(column.id, { side: "right", offset });
|
|
36
|
+
positions.set(column.id, { side: direction === "rtl" ? "left" : "right", offset });
|
|
37
37
|
offset += size(column);
|
|
38
38
|
}
|
|
39
39
|
const styles = new Map();
|
|
@@ -54,10 +54,10 @@ export function tableLayout(table, viewportWidth, rowHeight) {
|
|
|
54
54
|
[pin.side]: pin.offset,
|
|
55
55
|
zIndex: 2,
|
|
56
56
|
...(column.id === table.getStartVisibleLeafColumns().at(-1)?.id
|
|
57
|
-
? { borderRightWidth: 4 }
|
|
57
|
+
? { [direction === "rtl" ? "borderLeftWidth" : "borderRightWidth"]: 4 }
|
|
58
58
|
: {}),
|
|
59
59
|
...(column.id === table.getEndVisibleLeafColumns()[0]?.id
|
|
60
|
-
? { borderLeftWidth: 4 }
|
|
60
|
+
? { [direction === "rtl" ? "borderRightWidth" : "borderLeftWidth"]: 4 }
|
|
61
61
|
: {}),
|
|
62
62
|
}
|
|
63
63
|
: {}),
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMendyLocale } from "../locale-context.js";
|
|
2
3
|
import { Fragment } from "react";
|
|
3
4
|
/** Loading shares the live column geometry and its single scroll container. */
|
|
4
5
|
export function TableLoadingRows({ columns, columnGaps, count, width, rowHeight, cellStyle, }) {
|
|
5
|
-
|
|
6
|
+
const { t } = useMendyLocale();
|
|
7
|
+
return (_jsx("div", { role: "status", "aria-label": t("loadingRows"), className: "mui-2bf6510f1330", style: { width }, children: Array.from({ length: count }, (_, index) => (_jsx("div", { "aria-hidden": "true", "data-slot": "table-loading-row", className: "mui-222f930b8752 mui-2bf6510f1330", style: { height: rowHeight }, children: columns.map((column) => (_jsxs(Fragment, { children: [columnGaps.has(column.id) && (_jsx("div", { "aria-hidden": "true", className: "mui-27ead27a81df", style: { width: columnGaps.get(column.id) } })), _jsx("div", { "data-slot": "table-loading-cell", "data-column-id": column.id, className: "mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-bbe39cfb5cc6 mui-3b6d5fc7b061 mui-5b272f3c5076 mui-0f9e6672913a", style: cellStyle(column), children: _jsx("div", { className: "mui-2edce89ef182 mui-56bb14cbd1fe mui-7b3cd77eb999 mui-02e603944040 mui-87ecb59f2d2d mui-237747164b60" }) }, column.id)] }, column.id))) }, index))) }));
|
|
6
8
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMendyLocale } from "../locale-context.js";
|
|
3
4
|
import { Fragment, memo, useMemo } from "react";
|
|
4
5
|
import { constructCell, flexRender } from "@tanstack/react-table";
|
|
5
6
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
|
@@ -8,13 +9,15 @@ import { Checkbox } from "../primitives/checkbox.js";
|
|
|
8
9
|
import { cn } from "../utils.js";
|
|
9
10
|
import { interactiveSelector } from "./clipboard.js";
|
|
10
11
|
export function TableHeaderCell({ table, header, index, style, renderHeader, contentClassName, selectLoaded, }) {
|
|
12
|
+
const { t } = useMendyLocale();
|
|
11
13
|
const column = header.column;
|
|
12
14
|
const definition = column.columnDef;
|
|
13
15
|
const title = definition.label ?? (typeof definition.header === "string" ? definition.header : column.id);
|
|
14
16
|
const sorted = column.getIsSorted();
|
|
15
|
-
return (_jsxs("div", { role: "columnheader", "data-column-id": column.id, "aria-colindex": index + 1, "aria-sort": sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : undefined, style: style, className: "mui-ad936fcbed63 mui-d2d9e1f13413 mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-19e97f3f40e6 mui-3b6d5fc7b061 mui-5b272f3c5076 mui-0f9e6672913a mui-daaac3fbf55e mui-35f35c41d134", children: [selectLoaded && index === 0 && (_jsx(Checkbox, { "aria-label": "
|
|
17
|
+
return (_jsxs("div", { role: "columnheader", "data-column-id": column.id, "aria-colindex": index + 1, "aria-sort": sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : undefined, style: style, className: "mui-ad936fcbed63 mui-d2d9e1f13413 mui-222f930b8752 mui-27ead27a81df mui-71556df3b421 mui-19e97f3f40e6 mui-3b6d5fc7b061 mui-5b272f3c5076 mui-0f9e6672913a mui-daaac3fbf55e mui-35f35c41d134", children: [selectLoaded && index === 0 && (_jsx(Checkbox, { "aria-label": t("selectLoaded"), disabled: selectLoaded.disabled, checked: selectLoaded.checked, onCheckedChange: (value) => table.toggleAllPageRowsSelected(value === true), className: "mui-477d8f4dfce9 mui-94f91922a10e mui-34a57d4b4103 mui-8da02faac748 mui-b8b1747fa763 mui-d2e4a66bb430 mui-978f422895e5 mui-d0c2ae8419e1 mui-e2ed522ed9b7 mui-fa8e1efead3c mui-eaedb91f8774" })), _jsx("div", { className: cn("mui-184ddc11e5f9 mui-7bd5bab6d7f4 mui-d5111d0e9f48", (renderHeader || typeof definition.header === "function") && contentClassName), children: _jsx(TableHeaderContent, { header: header, renderHeader: renderHeader, title: title }) }), column.getCanResize() && (_jsx(TableResizeHandle, { table: table, header: header, title: title, width: Number(style.width) }))] }, column.id));
|
|
16
18
|
}
|
|
17
19
|
function TableBodyRowImpl({ row, rowIndex, start, rowHeight, autoRowHeight, measureElement, rowClassName, renderRowDetail, detailWidth, cellStyle, columns, columnGaps, columnIndexes, contentVersion, contentState, focusedId, copied, contentClassName, onRowClick, onRowActivate, isRowHighlighted, inlineSelection, }) {
|
|
20
|
+
const { t, direction } = useMendyLocale();
|
|
18
21
|
// The engine's getAllCells API eagerly allocates every column. Build only the
|
|
19
22
|
// viewport cells with its public constructor, and release them with this row.
|
|
20
23
|
const cache = useMemo(() => new WeakMap(), [row]);
|
|
@@ -26,7 +29,7 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, autoRowHeight, meas
|
|
|
26
29
|
}
|
|
27
30
|
return cell;
|
|
28
31
|
});
|
|
29
|
-
const rowElement = (_jsx("div", { ref: renderRowDetail ? undefined : measureElement, role: "row", "aria-rowindex": renderRowDetail ? undefined : rowIndex + 2, "aria-selected": row.getIsSelected(), "data-highlighted": row.getIsSelected() || isRowHighlighted?.(row.original), "data-index": rowIndex, className: cn("mui-ad936fcbed63 mui-
|
|
32
|
+
const rowElement = (_jsx("div", { ref: renderRowDetail ? undefined : measureElement, role: "row", "aria-rowindex": renderRowDetail ? undefined : rowIndex + 2, "aria-selected": row.getIsSelected(), "data-highlighted": row.getIsSelected() || isRowHighlighted?.(row.original), "data-index": rowIndex, className: cn("mui-ad936fcbed63 mui-8368bbb62f66 mui-222f930b8752 mui-2bf6510f1330 mui-5b272f3c5076 mui-37ad15a95595 mui-9d7d1760cd8e", rowClassName?.(row.original)), style: {
|
|
30
33
|
height: autoRowHeight ? undefined : rowHeight,
|
|
31
34
|
minHeight: rowHeight,
|
|
32
35
|
top: renderRowDetail ? 0 : start,
|
|
@@ -64,21 +67,22 @@ function TableBodyRowImpl({ row, rowIndex, start, rowHeight, autoRowHeight, meas
|
|
|
64
67
|
}, children: [selected && (_jsx("span", { "aria-hidden": "true", "data-selection-outline": "", className: "mui-33228ff7d583 mui-747355bdc2a2 mui-d7efd1b0b0f9 mui-515f9fdc6db7", style: {
|
|
65
68
|
top: edge?.top ? 0 : -1,
|
|
66
69
|
bottom: edge?.bottom ? -1 : -2,
|
|
67
|
-
left: -Number(cellStyle(cell.column).borderLeftWidth ?? 0),
|
|
68
|
-
right: -Number(cellStyle(cell.column).borderRightWidth ?? 1),
|
|
70
|
+
left: -Number(cellStyle(cell.column).borderLeftWidth ?? (direction === "rtl" ? 1 : 0)),
|
|
71
|
+
right: -Number(cellStyle(cell.column).borderRightWidth ?? (direction === "rtl" ? 0 : 1)),
|
|
69
72
|
borderTopWidth: edge?.top ? 2 : 0,
|
|
70
73
|
borderBottomWidth: edge?.bottom ? 2 : 0,
|
|
71
|
-
borderLeftWidth: edge?.left ? 2 : 0,
|
|
72
|
-
borderRightWidth: edge?.right ? 2 : 0,
|
|
73
|
-
} })), inlineSelection && index === 0 && (_jsx(Checkbox, { "aria-label":
|
|
74
|
+
borderLeftWidth: (direction === "rtl" ? edge?.right : edge?.left) ? 2 : 0,
|
|
75
|
+
borderRightWidth: (direction === "rtl" ? edge?.left : edge?.right) ? 2 : 0,
|
|
76
|
+
} })), inlineSelection && index === 0 && (_jsx(Checkbox, { "aria-label": t("selectRow", { id: rowIndex + 1 }), checked: row.getIsSelected(), disabled: !row.getCanSelect(), onCheckedChange: (value) => row.toggleSelected(value === true), onMouseDown: (event) => event.stopPropagation(), onClick: (event) => event.stopPropagation(), className: "mui-68d781378b03 mui-94f91922a10e mui-34a57d4b4103 mui-8da02faac748 mui-b8b1747fa763 mui-d2e4a66bb430 mui-978f422895e5 mui-d0c2ae8419e1 mui-9c02852bfc55 mui-e2ed522ed9b7 mui-cbd3aed703f7 mui-fa8e1efead3c mui-eaedb91f8774" })), _jsx("div", { className: cn("mui-184ddc11e5f9 mui-81b198a2db84", autoRowHeight ? "mui-726fca123972 mui-37cf9655f30a mui-b5edc3ea7c91" : "mui-7bd696ca6be3 mui-5a3a4ee420c2", contentClassName), children: _jsx(TableCellContent, { cell: cell, renderer: cell.column.columnDef.cell, version: contentVersion, state: contentState }) })] }, cell.id)] }, cell.id));
|
|
74
77
|
}) }, row.id));
|
|
75
78
|
if (!renderRowDetail)
|
|
76
79
|
return rowElement;
|
|
77
80
|
const detail = renderRowDetail(row.original);
|
|
78
|
-
return (_jsxs("div", { ref: measureElement, "data-index": rowIndex, role: "rowgroup", className: "mui-747355bdc2a2 mui-
|
|
81
|
+
return (_jsxs("div", { ref: measureElement, "data-index": rowIndex, role: "rowgroup", className: "mui-747355bdc2a2 mui-8368bbb62f66 mui-2bf6510f1330", style: { top: start }, children: [rowElement, detail != null && (_jsx("div", { role: "row", className: "mui-bbe39cfb5cc6 mui-5b272f3c5076", children: _jsx("div", { role: "gridcell", "aria-colspan": columns.length, className: "mui-964a9431ff49 mui-184ddc11e5f9 mui-094f5333853b", style: { width: detailWidth, maxWidth: "100%", insetInlineStart: 0 }, children: detail }) }))] }));
|
|
79
82
|
}
|
|
80
83
|
export const TableBodyRow = memo(TableBodyRowImpl);
|
|
81
84
|
function TableResizeHandle({ table, header, title, width, }) {
|
|
85
|
+
const { t, direction } = useMendyLocale();
|
|
82
86
|
const column = header.column;
|
|
83
87
|
const beginResize = (event) => {
|
|
84
88
|
if ("touches" in event && event.touches.length > 1)
|
|
@@ -98,16 +102,16 @@ function TableResizeHandle({ table, header, title, width, }) {
|
|
|
98
102
|
columnSizingStart: [[column.id, width]],
|
|
99
103
|
}));
|
|
100
104
|
};
|
|
101
|
-
return (_jsx("div", { role: "separator", tabIndex: 0, "aria-label":
|
|
105
|
+
return (_jsx("div", { role: "separator", tabIndex: 0, "aria-label": t("resizeColumn", { label: title }), "aria-orientation": "vertical", "aria-valuenow": Math.round(width), "aria-valuemin": column.columnDef.minSize ?? 48, "aria-valuemax": column.columnDef.maxSize ?? 1200, onDoubleClick: () => column.resetSize(), onMouseDown: beginResize, onTouchStart: beginResize, onKeyDown: (event) => {
|
|
102
106
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
103
107
|
event.preventDefault();
|
|
104
108
|
event.stopPropagation();
|
|
105
109
|
table.setColumnSizing((sizes) => ({
|
|
106
110
|
...sizes,
|
|
107
|
-
[column.id]: Math.min(column.columnDef.maxSize ?? 1200, Math.max(column.columnDef.minSize ?? 48, width + (event.key === "ArrowLeft" ? -10 : 10))),
|
|
111
|
+
[column.id]: Math.min(column.columnDef.maxSize ?? 1200, Math.max(column.columnDef.minSize ?? 48, width + (event.key === "ArrowLeft" ? -10 : 10) * (direction === "rtl" ? -1 : 1))),
|
|
108
112
|
}));
|
|
109
113
|
}
|
|
110
|
-
}, className: "mui-747355bdc2a2 mui-eb9e48c5dda9 mui-
|
|
114
|
+
}, className: "mui-747355bdc2a2 mui-eb9e48c5dda9 mui-aa7bcba08429 mui-418e44ad4f9e mui-d4ea834145ae mui-2194d094b585 mui-739a9a000791 mui-78905c9e865c mui-4273133a876a mui-2f669cfad5aa mui-2e357972fc10" }));
|
|
111
115
|
}
|
|
112
116
|
function TableHeaderContent({ header, renderHeader, title, }) {
|
|
113
117
|
const column = header.column;
|
package/dist/table/table-view.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMendyLocale } from "../locale-context.js";
|
|
3
4
|
import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
4
5
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
5
6
|
import { TableHeaderCell, TableBodyRow } from "./table-parts.js";
|
|
@@ -14,7 +15,8 @@ import { useTableInteraction } from "./use-table-interaction.js";
|
|
|
14
15
|
import { useTableResults } from "./use-table-results.js";
|
|
15
16
|
import { useInlineRowSelection } from "./use-inline-row-selection.js";
|
|
16
17
|
import { TableFrame } from "./table-frame.js";
|
|
17
|
-
export function TableView({ table, label
|
|
18
|
+
export function TableView({ table, label, height = "auto", layout: layoutMode = "content", footer, rowHeight: rowHeightOption = 44, rowClassName, renderRowDetail, className, contentClassName, emptyState, loadingState, scrollRef, status = "ready", refreshing, error, retry, loadMore, queryKey, filters, renderHeader, onRowClick, onRowActivate, isRowHighlighted, rowSelectionControls = true, onCopyError, }) {
|
|
19
|
+
const { t, direction, code } = useMendyLocale();
|
|
18
20
|
const fill = layoutMode === "fill";
|
|
19
21
|
const { resultKey, hasFilters, clearFilters } = useTableResults(table, queryKey, filters);
|
|
20
22
|
const autoRowHeight = rowHeightOption === "auto" || Boolean(renderRowDetail);
|
|
@@ -46,7 +48,7 @@ export function TableView({ table, label = "Data table", height = "auto", layout
|
|
|
46
48
|
const centerColumns = table.getCenterVisibleLeafColumns();
|
|
47
49
|
const endColumns = table.getEndVisibleLeafColumns();
|
|
48
50
|
const sizing = table.state.columnSizing;
|
|
49
|
-
const layout = useMemo(() => tableLayout(table, viewportWidth, rowHeight), [table, startColumns, centerColumns, endColumns, sizing, viewportWidth, rowHeight]);
|
|
51
|
+
const layout = useMemo(() => tableLayout(table, viewportWidth, rowHeight, direction), [table, startColumns, centerColumns, endColumns, sizing, viewportWidth, rowHeight, direction]);
|
|
50
52
|
const { totalWidth, pinningActive } = layout;
|
|
51
53
|
const { inlineSelection, selectLoaded } = useInlineRowSelection(table, layout.columns, rowSelectionControls);
|
|
52
54
|
const focused = table.getFocusedCell();
|
|
@@ -104,12 +106,12 @@ export function TableView({ table, label = "Data table", height = "auto", layout
|
|
|
104
106
|
virtual,
|
|
105
107
|
]);
|
|
106
108
|
const headersById = new Map(table.getFlatHeaders().map((header) => [header.column.id, header]));
|
|
107
|
-
return (_jsxs(TableFrame, { layout: layoutMode, stretch: height === "100%", footer: footer, children: [_jsx("div", { "aria-live": "polite", className: "mui-32fb090591d9", children: announcement }), _jsxs("div", { ref: setContainer, role: "grid", tabIndex: -1, "aria-label": label, "aria-rowcount": renderRowDetail ? -1 : rows.length + 1 + feedbackRowCount, "aria-colcount": layout.columns.length, "aria-busy": status === "loading" || refreshing, style: {
|
|
109
|
+
return (_jsxs(TableFrame, { layout: layoutMode, stretch: height === "100%", footer: footer, children: [_jsx("div", { "aria-live": "polite", className: "mui-32fb090591d9", children: announcement }), _jsxs("div", { ref: setContainer, role: "grid", tabIndex: -1, "aria-label": label ?? t("dataTable"), dir: direction, lang: code, "aria-rowcount": renderRowDetail ? -1 : rows.length + 1 + feedbackRowCount, "aria-colcount": layout.columns.length, "aria-busy": status === "loading" || refreshing, style: {
|
|
108
110
|
height: fill || height === "auto" ? undefined : height,
|
|
109
111
|
maxHeight: !fill && height === "auto" ? "65dvh" : undefined,
|
|
110
112
|
}, className: cn("mui-d2d9e1f13413 mui-014aadadffad mui-1a26a0d28420 mui-3fa8c572949b mui-4f1a55de40bc mui-5b272f3c5076 mui-c74ab393b96d mui-b30fc56058b6", fill && "mui-410da8dfa8ac mui-7bd5bab6d7f4", className), onKeyDown: onKeyDown, children: [_jsx("div", { role: "row", "aria-rowindex": 1, className: "mui-964a9431ff49 mui-98599e4ee250 mui-4e8f0a87a0dc mui-222f930b8752 mui-2bf6510f1330 mui-bbe39cfb5cc6 mui-5b272f3c5076", style: { width: totalWidth }, children: columns.map((column) => (_jsxs(Fragment, { children: [columnGaps.has(column.id) && (_jsx("div", { "aria-hidden": "true", className: "mui-27ead27a81df", style: { width: columnGaps.get(column.id) } })), _jsx(TableHeaderCell, { table: table, header: headersById.get(column.id), index: columnIndexes.get(column.id), style: cellStyle(column), renderHeader: renderHeader, contentClassName: contentClassName, selectLoaded: selectLoaded }, column.id)] }, column.id))) }), _jsx(TableInitialState, { columnCount: layout.columns.length, status: status, hasRows: rows.length > 0, loadingState: loadingState ?? (_jsx(TableLoadingRows, { columns: columns, columnGaps: columnGaps, width: totalWidth, rowHeight: rowHeight, cellStyle: cellStyle, count: !fill && height === "auto"
|
|
111
113
|
? 8
|
|
112
|
-
: Math.max(1, Math.ceil(((virtual.scrollRect?.height ?? 400) - rowHeight) / rowHeight)) })), emptyState: emptyState, hasFilters: hasFilters, pageIndex: table.state.pagination.pageIndex, clearFilters: clearFilters, firstPage: () => table.setPageIndex(0), error: error, retry: retry }), _jsx("div", { role: "rowgroup", className: "mui-d2d9e1f13413 mui-2bf6510f1330", style: { height: virtual.getTotalSize(), width: totalWidth }, children: items.map((item) => (_jsx(TableBodyRow, { row: rows[item.index], rowIndex: item.index, start: item.start, rowHeight: rowHeight, autoRowHeight: autoRowHeight, measureElement: autoRowHeight ? virtual.measureElement : undefined, rowClassName: rowClassName, renderRowDetail: renderRowDetail, detailWidth: viewportWidth ?? totalWidth, cellStyle: cellStyle, columns: columns, columnGaps: columnGaps, columnIndexes: columnIndexes, contentVersion: table.options, contentState: table.state, focusedId: focused?.id, copied: copied, contentClassName: contentClassName, onRowClick: onRowClick, onRowActivate: onRowActivate, isRowHighlighted: isRowHighlighted, inlineSelection: inlineSelection }, item.key))) }), hasRefreshError && (_jsx(TableFeedbackRow, { columnCount: layout.columns.length, rowIndex: rows.length + 2, className: "mui-964a9431ff49 mui-30150dd033ab", children: _jsxs("div", { role: "alert", className: "mui-5b272f3c5076 mui-094f5333853b", children: [error ?? "
|
|
114
|
+
: Math.max(1, Math.ceil(((virtual.scrollRect?.height ?? 400) - rowHeight) / rowHeight)) })), emptyState: emptyState, hasFilters: hasFilters, pageIndex: table.state.pagination.pageIndex, clearFilters: clearFilters, firstPage: () => table.setPageIndex(0), error: error, retry: retry }), _jsx("div", { role: "rowgroup", className: "mui-d2d9e1f13413 mui-2bf6510f1330", style: { height: virtual.getTotalSize(), width: totalWidth }, children: items.map((item) => (_jsx(TableBodyRow, { row: rows[item.index], rowIndex: item.index, start: item.start, rowHeight: rowHeight, autoRowHeight: autoRowHeight, measureElement: autoRowHeight ? virtual.measureElement : undefined, rowClassName: rowClassName, renderRowDetail: renderRowDetail, detailWidth: viewportWidth ?? totalWidth, cellStyle: cellStyle, columns: columns, columnGaps: columnGaps, columnIndexes: columnIndexes, contentVersion: table.options, contentState: table.state, focusedId: focused?.id, copied: copied, contentClassName: contentClassName, onRowClick: onRowClick, onRowActivate: onRowActivate, isRowHighlighted: isRowHighlighted, inlineSelection: inlineSelection }, item.key))) }), hasRefreshError && (_jsx(TableFeedbackRow, { columnCount: layout.columns.length, rowIndex: rows.length + 2, className: "mui-964a9431ff49 mui-30150dd033ab", children: _jsxs("div", { role: "alert", className: "mui-5b272f3c5076 mui-094f5333853b", children: [error ?? t("refreshError"), retry && (_jsx(Button, { onClick: retry, variant: "outline", size: "sm", children: t("retry") }))] }) })), loadMore?.available && (_jsx(TableLoadMore, { loadMore: loadMore, columnCount: layout.columns.length, rowIndex: rows.length + 2 + Number(hasInitialFeedback || hasRefreshError), onLoad: () => {
|
|
113
115
|
requested.current = null;
|
|
114
116
|
void Promise.resolve()
|
|
115
117
|
.then(() => loadMore.load())
|
|
@@ -18,7 +18,7 @@ export function useColumnWindow(layout, container, viewportWidth, focusedColumn,
|
|
|
18
18
|
const element = container.current;
|
|
19
19
|
if (!element)
|
|
20
20
|
return;
|
|
21
|
-
const measure = () => setScrollLeft(element.scrollLeft);
|
|
21
|
+
const measure = () => setScrollLeft(Math.abs(element.scrollLeft));
|
|
22
22
|
measure();
|
|
23
23
|
element.addEventListener("scroll", measure, { passive: true });
|
|
24
24
|
return () => element.removeEventListener("scroll", measure);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { useTable } from "@tanstack/react-table";
|
|
4
|
+
import { useMendyLocale } from "../locale-context.js";
|
|
4
5
|
import { tableFeaturesDefault } from "./features.js";
|
|
5
6
|
import { useStableArray } from "./use-stable-array.js";
|
|
6
7
|
import { reconcilePreferences } from "./state.js";
|
|
@@ -28,6 +29,7 @@ export function applyTablePreferences(table, input) {
|
|
|
28
29
|
table.setColumnPinning(value.columnPinning);
|
|
29
30
|
}
|
|
30
31
|
export function useDataTable({ rows: inputRows, columns: inputColumns, processing, preferences, ...options }) {
|
|
32
|
+
const { direction } = useMendyLocale();
|
|
31
33
|
const rows = useStableArray(inputRows);
|
|
32
34
|
const columns = useStableArray(inputColumns);
|
|
33
35
|
const defaults = useMemo(() => reconcilePreferences(null, columns, options.initialState), [columns, options.initialState]);
|
|
@@ -37,6 +39,7 @@ export function useDataTable({ rows: inputRows, columns: inputColumns, processin
|
|
|
37
39
|
data: rows,
|
|
38
40
|
columns,
|
|
39
41
|
defaultColumn: { size: 180, minSize: 48, maxSize: 1200, ...options.defaultColumn },
|
|
42
|
+
columnResizeDirection: options.columnResizeDirection ?? direction,
|
|
40
43
|
columnResizeMode: options.columnResizeMode ?? "onChange",
|
|
41
44
|
enableCellSelection: options.enableCellSelection ?? true,
|
|
42
45
|
enableRowSelection: options.enableRowSelection ??
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useMendyLocale } from "../locale-context.js";
|
|
2
3
|
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
3
4
|
import { interactiveSelector, selectedCellsText } from "./clipboard.js";
|
|
4
5
|
export function useTableInteraction({ table, pinningActive, container, queryKey, onRowActivate, onCopyError, scrollToIndex, }) {
|
|
5
6
|
const rows = table.getRowModel().rows;
|
|
7
|
+
const { t, direction: readingDirection } = useMendyLocale();
|
|
6
8
|
const columns = [
|
|
7
9
|
...table.getStartVisibleLeafColumns(),
|
|
8
10
|
...table.getCenterVisibleLeafColumns(),
|
|
@@ -69,14 +71,14 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
69
71
|
await navigator.clipboard.writeText(text);
|
|
70
72
|
if (!mounted.current)
|
|
71
73
|
return;
|
|
72
|
-
setAnnouncement("
|
|
74
|
+
setAnnouncement(t("copied"));
|
|
73
75
|
setCopied(true);
|
|
74
76
|
clearTimeout(copyTimer.current);
|
|
75
77
|
copyTimer.current = setTimeout(() => setCopied(false), 300);
|
|
76
78
|
}
|
|
77
79
|
catch (reason) {
|
|
78
80
|
if (mounted.current) {
|
|
79
|
-
setAnnouncement("
|
|
81
|
+
setAnnouncement(t("copyError"));
|
|
80
82
|
onCopyError?.(reason);
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -97,10 +99,12 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
97
99
|
const endWidth = !pinningActive
|
|
98
100
|
? 0
|
|
99
101
|
: table.getEndVisibleLeafColumns().reduce((sum, col) => sum + col.getSize(), 0);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
container.current.scrollLeft += box.
|
|
102
|
+
const leftWidth = readingDirection === "rtl" ? endWidth : startWidth;
|
|
103
|
+
const rightWidth = readingDirection === "rtl" ? startWidth : endWidth;
|
|
104
|
+
if (box.left < viewport.left + leftWidth)
|
|
105
|
+
container.current.scrollLeft += box.left - viewport.left - leftWidth;
|
|
106
|
+
else if (box.right > viewport.right - rightWidth)
|
|
107
|
+
container.current.scrollLeft += box.right - viewport.right + rightWidth;
|
|
104
108
|
}
|
|
105
109
|
});
|
|
106
110
|
}
|
|
@@ -129,8 +133,8 @@ export function useTableInteraction({ table, pinningActive, container, queryKey,
|
|
|
129
133
|
const directions = {
|
|
130
134
|
ArrowUp: "up",
|
|
131
135
|
ArrowDown: "down",
|
|
132
|
-
ArrowLeft: "left",
|
|
133
|
-
ArrowRight: "right",
|
|
136
|
+
ArrowLeft: readingDirection === "rtl" ? "right" : "left",
|
|
137
|
+
ArrowRight: readingDirection === "rtl" ? "left" : "right",
|
|
134
138
|
};
|
|
135
139
|
const direction = directions[event.key];
|
|
136
140
|
if (direction) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mendylanda/ui",
|
|
3
|
-
"version": "0.3.2-dev.
|
|
3
|
+
"version": "0.3.2-dev.58.0ef9785a4046",
|
|
4
4
|
"description": "Mendy Landa’s reusable React components. Typed filters and tables with shared interaction behavior and customizable UI.",
|
|
5
5
|
"homepage": "https://ui.mendylanda.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -66,6 +66,11 @@
|
|
|
66
66
|
"types": "./dist/table/index.d.ts",
|
|
67
67
|
"import": "./dist/table/index.js",
|
|
68
68
|
"default": "./dist/table/index.js"
|
|
69
|
+
},
|
|
70
|
+
"./locales/*": {
|
|
71
|
+
"types": "./dist/locales/*.d.ts",
|
|
72
|
+
"import": "./dist/locales/*.js",
|
|
73
|
+
"default": "./dist/locales/*.js"
|
|
69
74
|
}
|
|
70
75
|
},
|
|
71
76
|
"publishConfig": {
|
|
@@ -74,6 +79,7 @@
|
|
|
74
79
|
"dependencies": {
|
|
75
80
|
"@hello-pangea/dnd": "18.0.1",
|
|
76
81
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
82
|
+
"@radix-ui/react-direction": "^1.1.4",
|
|
77
83
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
78
84
|
"@radix-ui/react-label": "^2.1.7",
|
|
79
85
|
"@radix-ui/react-popover": "1.1.15",
|
|
@@ -112,5 +118,5 @@
|
|
|
112
118
|
"build": "tsc -p tsconfig.build.json && node scripts/build-css.mjs",
|
|
113
119
|
"typecheck": "tsc -p tsconfig.build.json --noEmit"
|
|
114
120
|
},
|
|
115
|
-
"gitHead": "
|
|
121
|
+
"gitHead": "0ef9785a4046cf8030396c3278c4231b866fcef4"
|
|
116
122
|
}
|