@wallarm-org/design-system 1.20.4 → 1.21.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.
- package/dist/components/Select/Select.d.ts +3 -1
- package/dist/components/Select/Select.js +6 -3
- package/dist/components/Table/EditableCell/EditableSelectCell.d.ts +1 -1
- package/dist/components/Table/EditableCell/EditableSelectCell.js +4 -1
- package/dist/components/Table/StickyGroupParent.js +7 -8
- package/dist/components/Table/TableBody/TableBodyCell.d.ts +3 -1
- package/dist/components/Table/TableBody/TableBodyCell.js +8 -1
- package/dist/components/Table/TableBody/TableBodyRowDndContext.d.ts +5 -0
- package/dist/components/Table/TableBody/TableBodyRowDndContext.js +65 -21
- package/dist/components/Table/TableBody/TableRowOverlay.js +2 -1
- package/dist/components/Table/TableColGroup.js +20 -17
- package/dist/components/Table/TableContext/TableProvider.js +3 -1
- package/dist/components/Table/TableContext/types.d.ts +1 -0
- package/dist/components/Table/TableHead.js +13 -8
- package/dist/components/Table/TableLoadingState.js +19 -13
- package/dist/components/Table/TableMasterCellActions.js +2 -5
- package/dist/components/Table/TableRow.js +37 -12
- package/dist/components/Table/TableRowExpanded.js +3 -2
- package/dist/components/Table/hooks/useStickyGroupParent.js +3 -1
- package/dist/components/Table/lib/constants.d.ts +1 -1
- package/dist/components/Table/lib/constants.js +1 -1
- package/dist/components/Table/lib/createDragHandleColumn.js +3 -3
- package/dist/components/Table/lib/useRowDnd.js +3 -13
- package/dist/components/Table/types.d.ts +8 -0
- package/dist/metadata/components.json +15 -4
- package/package.json +1 -1
|
@@ -3,9 +3,11 @@ import { type TestableProps } from '../../utils/testId';
|
|
|
3
3
|
type SelectNativeProps<T extends CollectionItem> = Omit<SelectRootProps<T>, 'positioning' | 'lazyMount' | 'unmountOnExit'>;
|
|
4
4
|
export interface SelectBaseProps {
|
|
5
5
|
loading?: boolean;
|
|
6
|
+
/** Override default floating positioning (merged with DS defaults). */
|
|
7
|
+
positioning?: SelectRootProps<CollectionItem>['positioning'];
|
|
6
8
|
}
|
|
7
9
|
type SelectProps<T extends CollectionItem> = SelectNativeProps<T> & SelectBaseProps & TestableProps;
|
|
8
|
-
export declare function Select<T extends CollectionItem>({ children, loading, disabled, 'data-testid': testId, ...props }: SelectProps<T>): import("react").JSX.Element;
|
|
10
|
+
export declare function Select<T extends CollectionItem>({ children, loading, disabled, positioning: positioningOverride, 'data-testid': testId, ...props }: SelectProps<T>): import("react").JSX.Element;
|
|
9
11
|
export declare namespace Select {
|
|
10
12
|
var displayName: string;
|
|
11
13
|
}
|
|
@@ -3,14 +3,17 @@ import { useMemo } from "react";
|
|
|
3
3
|
import { Select } from "@ark-ui/react/select";
|
|
4
4
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
5
5
|
import { SelectSharedProvider } from "./SelectSharedContext/index.js";
|
|
6
|
-
const Select_Select = ({ children, loading = false, disabled = false, 'data-testid': testId, ...props })=>{
|
|
6
|
+
const Select_Select = ({ children, loading = false, disabled = false, positioning: positioningOverride, 'data-testid': testId, ...props })=>{
|
|
7
7
|
const positioning = useMemo(()=>({
|
|
8
8
|
offset: {
|
|
9
9
|
mainAxis: 4
|
|
10
10
|
},
|
|
11
11
|
gutter: 4,
|
|
12
|
-
overflowPadding: 4
|
|
13
|
-
|
|
12
|
+
overflowPadding: 4,
|
|
13
|
+
...positioningOverride
|
|
14
|
+
}), [
|
|
15
|
+
positioningOverride
|
|
16
|
+
]);
|
|
14
17
|
return /*#__PURE__*/ jsx(TestIdProvider, {
|
|
15
18
|
value: testId,
|
|
16
19
|
children: /*#__PURE__*/ jsx(SelectSharedProvider, {
|
|
@@ -11,7 +11,7 @@ export interface EditableSelectCellProps extends NativeProps, TestableProps {
|
|
|
11
11
|
items: SelectDataItem[];
|
|
12
12
|
/** Read-mode rendering of the selected value (e.g. a `Badge`). */
|
|
13
13
|
children?: ReactNode;
|
|
14
|
-
/** Shown when nothing is selected. Defaults to `'Select
|
|
14
|
+
/** Shown when nothing is selected. Defaults to `'Select'`. */
|
|
15
15
|
placeholder?: ReactNode;
|
|
16
16
|
ref?: Ref<HTMLDivElement>;
|
|
17
17
|
}
|
|
@@ -6,7 +6,7 @@ import { cn } from "../../../utils/cn.js";
|
|
|
6
6
|
import { useTestId } from "../../../utils/testId.js";
|
|
7
7
|
import { Select as index_js_Select, SelectContent, SelectOption, SelectOptionIndicator, SelectOptionText, SelectPositioner, createListCollection } from "../../Select/index.js";
|
|
8
8
|
import { editableCellIcon, editableCellPlaceholder, editableCellValue, editableCellVariants } from "./classes.js";
|
|
9
|
-
const EditableSelectCell = ({ value, onCommit, items, children, placeholder = 'Select
|
|
9
|
+
const EditableSelectCell = ({ value, onCommit, items, children, placeholder = 'Select', className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
10
10
|
const testId = useTestId(void 0, testIdProp);
|
|
11
11
|
const collection = useMemo(()=>createListCollection({
|
|
12
12
|
items
|
|
@@ -21,6 +21,9 @@ const EditableSelectCell = ({ value, onCommit, items, children, placeholder = 'S
|
|
|
21
21
|
value
|
|
22
22
|
] : [],
|
|
23
23
|
"data-testid": testId,
|
|
24
|
+
positioning: {
|
|
25
|
+
placement: 'bottom-start'
|
|
26
|
+
},
|
|
24
27
|
onValueChange: (details)=>{
|
|
25
28
|
const next = details.value[0];
|
|
26
29
|
if (next && next !== value) onCommit(next);
|
|
@@ -59,19 +59,18 @@ const StickyGroupParent = ({ tableWidth, headerHeight })=>{
|
|
|
59
59
|
useWindowScroll,
|
|
60
60
|
headerHeight
|
|
61
61
|
]);
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const isSelected = stickyRow.getIsAllSubRowsSelected();
|
|
62
|
+
const cells = stickyRow?.getVisibleCells();
|
|
63
|
+
const systemCells = cells?.filter((c)=>SYSTEM_COLUMN_IDS.has(c.column.id));
|
|
64
|
+
const dataCells = cells?.filter((c)=>!SYSTEM_COLUMN_IDS.has(c.column.id));
|
|
65
|
+
const firstDataCell = dataCells?.[0];
|
|
66
|
+
const isSelected = stickyRow?.getIsAllSubRowsSelected();
|
|
68
67
|
return /*#__PURE__*/ jsx("div", {
|
|
69
|
-
className: "sticky z-
|
|
68
|
+
className: "sticky z-[21] h-0 overflow-visible pointer-events-none",
|
|
70
69
|
style: {
|
|
71
70
|
top: headerHeight
|
|
72
71
|
},
|
|
73
72
|
"aria-hidden": "true",
|
|
74
|
-
children: /*#__PURE__*/ jsx("div", {
|
|
73
|
+
children: stickyRow && /*#__PURE__*/ jsx("div", {
|
|
75
74
|
className: "overflow-hidden",
|
|
76
75
|
style: {
|
|
77
76
|
height: rowRef.current?.offsetHeight ?? 40
|
|
@@ -10,8 +10,10 @@ interface TableBodyCellProps<T extends RowData> {
|
|
|
10
10
|
lastRow?: boolean;
|
|
11
11
|
dragListeners?: ReturnType<typeof useSortable>['listeners'];
|
|
12
12
|
dragAttributes?: ReturnType<typeof useSortable>['attributes'];
|
|
13
|
+
/** Orange line indicator for row drag-and-drop placement */
|
|
14
|
+
dropIndicator?: 'above' | 'below';
|
|
13
15
|
}
|
|
14
|
-
export declare function TableBodyCell<T extends RowData>({ cell, colSpan, className, disablePinnedShadow, lastRow, dragListeners, dragAttributes, }: TableBodyCellProps<T>): import("react").JSX.Element;
|
|
16
|
+
export declare function TableBodyCell<T extends RowData>({ cell, colSpan, className, disablePinnedShadow, lastRow, dragListeners, dragAttributes, dropIndicator, }: TableBodyCellProps<T>): import("react").JSX.Element;
|
|
15
17
|
export declare namespace TableBodyCell {
|
|
16
18
|
var displayName: string;
|
|
17
19
|
}
|
|
@@ -8,7 +8,11 @@ import { TABLE_EXPAND_COLUMN_ID, getAlignClass, getExpandBorderClass, getPinning
|
|
|
8
8
|
import { Td } from "../primitives/index.js";
|
|
9
9
|
import { useTableContext } from "../TableContext/index.js";
|
|
10
10
|
import { TableMasterCellActions } from "../TableMasterCellActions.js";
|
|
11
|
-
const
|
|
11
|
+
const DROP_INDICATOR_SHADOW = {
|
|
12
|
+
above: 'inset 0 2px 0 0 var(--color-border-strong-warning)',
|
|
13
|
+
below: 'inset 0 -2px 0 0 var(--color-border-strong-warning)'
|
|
14
|
+
};
|
|
15
|
+
const TableBodyCell = ({ cell, colSpan, className, disablePinnedShadow, lastRow, dragListeners, dragAttributes, dropIndicator })=>{
|
|
12
16
|
const { allLeafColumns, masterColumnId } = useTableContext();
|
|
13
17
|
const testId = useTestId('body-cell');
|
|
14
18
|
const column = cell.column;
|
|
@@ -74,6 +78,9 @@ const TableBodyCell = ({ cell, colSpan, className, disablePinnedShadow, lastRow,
|
|
|
74
78
|
...dndStyle,
|
|
75
79
|
...isCut && {
|
|
76
80
|
overflow: 'hidden'
|
|
81
|
+
},
|
|
82
|
+
...dropIndicator && {
|
|
83
|
+
boxShadow: DROP_INDICATOR_SHADOW[dropIndicator]
|
|
77
84
|
}
|
|
78
85
|
},
|
|
79
86
|
colSpan: colSpan,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { type FC, type ReactNode } from 'react';
|
|
2
|
+
interface RowDndIndicatorState {
|
|
3
|
+
activeId: string | null;
|
|
4
|
+
overId: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare const useRowDndIndicator: () => RowDndIndicatorState;
|
|
2
7
|
interface TableBodyRowDndContextProps {
|
|
3
8
|
children: ReactNode;
|
|
4
9
|
}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useMemo, useState } from "react";
|
|
2
|
+
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
3
3
|
import { DndContext, DragOverlay, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
|
|
4
4
|
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
5
5
|
import { useTableContext } from "../TableContext/index.js";
|
|
6
6
|
import { TableRowOverlay } from "./TableRowOverlay.js";
|
|
7
|
+
const ROW_DND_INDICATOR_DEFAULT = {
|
|
8
|
+
activeId: null,
|
|
9
|
+
overId: null
|
|
10
|
+
};
|
|
11
|
+
const RowDndIndicatorContext = /*#__PURE__*/ createContext(ROW_DND_INDICATOR_DEFAULT);
|
|
12
|
+
const useRowDndIndicator = ()=>useContext(RowDndIndicatorContext);
|
|
13
|
+
const CURSOR_STYLE_ATTR = 'data-table-row-drag';
|
|
14
|
+
function setCursorGrabbing() {
|
|
15
|
+
const style = document.createElement('style');
|
|
16
|
+
style.setAttribute(CURSOR_STYLE_ATTR, '');
|
|
17
|
+
style.textContent = '* { cursor: grabbing !important; }';
|
|
18
|
+
document.head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
function resetCursor() {
|
|
21
|
+
document.head.querySelector(`style[${CURSOR_STYLE_ATTR}]`)?.remove();
|
|
22
|
+
}
|
|
7
23
|
const TableBodyRowDndContext = ({ children })=>{
|
|
8
24
|
const { rowDndEnabled, onRowReorder } = useTableContext();
|
|
9
25
|
if (!rowDndEnabled) return children;
|
|
@@ -19,19 +35,37 @@ const TableBodyRowDndContextInner = ({ children, onRowReorder })=>{
|
|
|
19
35
|
rows
|
|
20
36
|
]);
|
|
21
37
|
const [activeRow, setActiveRow] = useState(null);
|
|
38
|
+
const [activeId, setActiveId] = useState(null);
|
|
39
|
+
const [overId, setOverId] = useState(null);
|
|
40
|
+
const indicatorState = useMemo(()=>({
|
|
41
|
+
activeId,
|
|
42
|
+
overId
|
|
43
|
+
}), [
|
|
44
|
+
activeId,
|
|
45
|
+
overId
|
|
46
|
+
]);
|
|
22
47
|
const sensors = useSensors(useSensor(PointerSensor, {
|
|
23
48
|
activationConstraint: {
|
|
24
49
|
distance: 5
|
|
25
50
|
}
|
|
26
51
|
}), useSensor(KeyboardSensor));
|
|
27
52
|
const handleDragStart = useCallback((event)=>{
|
|
28
|
-
const
|
|
53
|
+
const id = String(event.active.id);
|
|
54
|
+
const row = rows.find((r)=>r.id === id);
|
|
29
55
|
setActiveRow(row ?? null);
|
|
56
|
+
setActiveId(id);
|
|
57
|
+
setCursorGrabbing();
|
|
30
58
|
}, [
|
|
31
59
|
rows
|
|
32
60
|
]);
|
|
61
|
+
const handleDragOver = useCallback((event)=>{
|
|
62
|
+
setOverId(event.over ? String(event.over.id) : null);
|
|
63
|
+
}, []);
|
|
33
64
|
const handleDragEnd = useCallback((event)=>{
|
|
34
65
|
setActiveRow(null);
|
|
66
|
+
setActiveId(null);
|
|
67
|
+
setOverId(null);
|
|
68
|
+
resetCursor();
|
|
35
69
|
const { active, over } = event;
|
|
36
70
|
if (!over || active.id === over.id) return;
|
|
37
71
|
onRowReorder?.({
|
|
@@ -43,26 +77,36 @@ const TableBodyRowDndContextInner = ({ children, onRowReorder })=>{
|
|
|
43
77
|
]);
|
|
44
78
|
const handleDragCancel = useCallback(()=>{
|
|
45
79
|
setActiveRow(null);
|
|
80
|
+
setActiveId(null);
|
|
81
|
+
setOverId(null);
|
|
82
|
+
resetCursor();
|
|
46
83
|
}, []);
|
|
47
|
-
return /*#__PURE__*/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
return /*#__PURE__*/ jsx(RowDndIndicatorContext.Provider, {
|
|
85
|
+
value: indicatorState,
|
|
86
|
+
children: /*#__PURE__*/ jsxs(DndContext, {
|
|
87
|
+
sensors: sensors,
|
|
88
|
+
collisionDetection: closestCenter,
|
|
89
|
+
onDragStart: handleDragStart,
|
|
90
|
+
onDragOver: handleDragOver,
|
|
91
|
+
onDragEnd: handleDragEnd,
|
|
92
|
+
onDragCancel: handleDragCancel,
|
|
93
|
+
children: [
|
|
94
|
+
/*#__PURE__*/ jsx(SortableContext, {
|
|
95
|
+
items: rowIds,
|
|
96
|
+
strategy: verticalListSortingStrategy,
|
|
97
|
+
children: children
|
|
98
|
+
}),
|
|
99
|
+
/*#__PURE__*/ jsx(DragOverlay, {
|
|
100
|
+
style: {
|
|
101
|
+
cursor: 'grabbing'
|
|
102
|
+
},
|
|
103
|
+
children: activeRow ? /*#__PURE__*/ jsx(TableRowOverlay, {
|
|
104
|
+
row: activeRow
|
|
105
|
+
}) : null
|
|
106
|
+
})
|
|
107
|
+
]
|
|
108
|
+
})
|
|
65
109
|
});
|
|
66
110
|
};
|
|
67
111
|
TableBodyRowDndContext.displayName = 'TableBodyRowDndContext';
|
|
68
|
-
export { TableBodyRowDndContext };
|
|
112
|
+
export { TableBodyRowDndContext, useRowDndIndicator };
|
|
@@ -10,7 +10,8 @@ const TableRowOverlayInner = ({ row })=>{
|
|
|
10
10
|
return /*#__PURE__*/ jsx("table", {
|
|
11
11
|
className: "w-full table-fixed border-collapse",
|
|
12
12
|
style: {
|
|
13
|
-
tableLayout: 'fixed'
|
|
13
|
+
tableLayout: 'fixed',
|
|
14
|
+
cursor: 'grabbing'
|
|
14
15
|
},
|
|
15
16
|
children: /*#__PURE__*/ jsx("tbody", {
|
|
16
17
|
children: /*#__PURE__*/ jsx(Tr, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { TABLE_DRAG_HANDLE_COLUMN_ID, TABLE_EXPAND_COLUMN_ID, TABLE_SELECT_COLUMN_ID } from "./lib/index.js";
|
|
3
3
|
import { useTableContext } from "./TableContext/index.js";
|
|
4
4
|
const SYSTEM_COLUMN_IDS = new Set([
|
|
@@ -7,27 +7,30 @@ const SYSTEM_COLUMN_IDS = new Set([
|
|
|
7
7
|
TABLE_DRAG_HANDLE_COLUMN_ID
|
|
8
8
|
]);
|
|
9
9
|
const TableColGroup = ({ tableWidth })=>{
|
|
10
|
-
const { table } = useTableContext();
|
|
10
|
+
const { table, stretch } = useTableContext();
|
|
11
11
|
const columns = table.getVisibleLeafColumns();
|
|
12
12
|
const isFixed = (col)=>SYSTEM_COLUMN_IDS.has(col.id) || !col.getCanResize() && col.columnDef.minSize === col.columnDef.maxSize || col.columnDef.meta?.resizeType === 'cut';
|
|
13
13
|
const fixedWidth = columns.filter(isFixed).reduce((sum, c)=>sum + c.getSize(), 0);
|
|
14
14
|
const totalFlexSize = columns.filter((c)=>!isFixed(c)).reduce((sum, c)=>sum + c.getSize(), 0);
|
|
15
15
|
const availableForFlex = tableWidth - fixedWidth;
|
|
16
|
-
return /*#__PURE__*/
|
|
17
|
-
children:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
return /*#__PURE__*/ jsxs("colgroup", {
|
|
17
|
+
children: [
|
|
18
|
+
columns.map((col)=>{
|
|
19
|
+
if (isFixed(col) || !stretch) return /*#__PURE__*/ jsx("col", {
|
|
20
|
+
style: {
|
|
21
|
+
width: col.getSize()
|
|
22
|
+
}
|
|
23
|
+
}, col.id);
|
|
24
|
+
if (0 === totalFlexSize) return /*#__PURE__*/ jsx("col", {}, col.id);
|
|
25
|
+
const pixelWidth = col.getSize() / totalFlexSize * availableForFlex;
|
|
26
|
+
return /*#__PURE__*/ jsx("col", {
|
|
27
|
+
style: {
|
|
28
|
+
width: pixelWidth
|
|
29
|
+
}
|
|
30
|
+
}, col.id);
|
|
31
|
+
}),
|
|
32
|
+
!stretch && /*#__PURE__*/ jsx("col", {}, "_filler")
|
|
33
|
+
]
|
|
31
34
|
});
|
|
32
35
|
};
|
|
33
36
|
TableColGroup.displayName = 'TableColGroup';
|
|
@@ -15,7 +15,7 @@ const toTanStackPinning = (p, pinnedLeft)=>({
|
|
|
15
15
|
end: p?.right ?? []
|
|
16
16
|
});
|
|
17
17
|
const TableProvider = (props)=>{
|
|
18
|
-
const { data, columns, isLoading = false, isLoadingPrevious = false, skeletonCount = TABLE_SKELETON_ROWS, children, getRowId, sorting: sortingProp, onSortingChange, manualSorting = false, rowSelection: rowSelectionProp, onRowSelectionChange, enableSelectAllRows = true, onSelectAllRows, columnSizing: columnSizingProp, onColumnSizingChange, columnPinning: columnPinningProp, onColumnPinningChange, columnOrder: columnOrderProp, onColumnOrderChange, grouping: groupingProp, onGroupingChange, expanded: expandedProp, onExpandedChange, renderGroupRow, getSubRows, renderExpandedRow, columnVisibility: columnVisibilityProp, onColumnVisibilityChange, defaultColumnVisibility, defaultColumnOrder, columnGroups, virtualized, estimateRowHeight, overscan = TABLE_VIRTUALIZATION_OVERSCAN, onEndReached, onEndReachedThreshold, onStartReached, onStartReachedThreshold, initialScrollToRowId, onRowReorder, onMasterCellClick, activeRowId: activeRowIdProp, onSettingsOpenChange } = props;
|
|
18
|
+
const { data, columns, isLoading = false, isLoadingPrevious = false, skeletonCount = TABLE_SKELETON_ROWS, children, getRowId, sorting: sortingProp, onSortingChange, manualSorting = false, rowSelection: rowSelectionProp, onRowSelectionChange, enableSelectAllRows = true, onSelectAllRows, columnSizing: columnSizingProp, onColumnSizingChange, columnPinning: columnPinningProp, onColumnPinningChange, columnOrder: columnOrderProp, onColumnOrderChange, grouping: groupingProp, onGroupingChange, expanded: expandedProp, onExpandedChange, renderGroupRow, getSubRows, renderExpandedRow, columnVisibility: columnVisibilityProp, onColumnVisibilityChange, defaultColumnVisibility, defaultColumnOrder, columnGroups, virtualized, stretch = true, estimateRowHeight, overscan = TABLE_VIRTUALIZATION_OVERSCAN, onEndReached, onEndReachedThreshold, onStartReached, onStartReachedThreshold, initialScrollToRowId, onRowReorder, onMasterCellClick, activeRowId: activeRowIdProp, onSettingsOpenChange } = props;
|
|
19
19
|
const masterCellActiveRowId = activeRowIdProp ?? null;
|
|
20
20
|
const sortingEnabled = !!onSortingChange;
|
|
21
21
|
const selectionEnabled = !!onRowSelectionChange;
|
|
@@ -203,6 +203,7 @@ const TableProvider = (props)=>{
|
|
|
203
203
|
visibilityEnabled,
|
|
204
204
|
hasSubRowGrouping: !!getSubRows,
|
|
205
205
|
virtualized,
|
|
206
|
+
stretch,
|
|
206
207
|
renderExpandedRow: renderExpandedRow,
|
|
207
208
|
estimateRowHeight,
|
|
208
209
|
overscan,
|
|
@@ -245,6 +246,7 @@ const TableProvider = (props)=>{
|
|
|
245
246
|
visibilityEnabled,
|
|
246
247
|
getSubRows,
|
|
247
248
|
virtualized,
|
|
249
|
+
stretch,
|
|
248
250
|
renderExpandedRow,
|
|
249
251
|
estimateRowHeight,
|
|
250
252
|
overscan,
|
|
@@ -25,6 +25,7 @@ export interface TableContextValue<T extends RowData> {
|
|
|
25
25
|
visibilityEnabled: boolean;
|
|
26
26
|
hasSubRowGrouping: boolean;
|
|
27
27
|
virtualized: TableVirtualized | undefined;
|
|
28
|
+
stretch: boolean;
|
|
28
29
|
renderExpandedRow?: (row: Row<DSTableFeatures, T>) => ReactNode;
|
|
29
30
|
estimateRowHeight?: (index: number) => number;
|
|
30
31
|
overscan: number;
|
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
|
-
import { THead, Tr } from "./primitives/index.js";
|
|
4
|
+
import { THead, Th, Tr } from "./primitives/index.js";
|
|
5
5
|
import { useTableContext } from "./TableContext/index.js";
|
|
6
6
|
import { TableHeadCell } from "./TableHeadCell.js";
|
|
7
7
|
const TableHead = ()=>{
|
|
8
|
-
const { table } = useTableContext();
|
|
8
|
+
const { table, stretch } = useTableContext();
|
|
9
9
|
const testId = useTestId('head');
|
|
10
10
|
const hasTextDescription = table.getAllLeafColumns().some((col)=>col.columnDef.meta?.description?.type === 'text');
|
|
11
11
|
return /*#__PURE__*/ jsx(THead, {
|
|
12
12
|
className: cn('sticky top-0 z-30', hasTextDescription ? 'h-48' : 'h-32'),
|
|
13
13
|
"data-testid": testId,
|
|
14
|
-
children: table.getHeaderGroups().map((headerGroup)=>/*#__PURE__*/
|
|
15
|
-
children:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
children: table.getHeaderGroups().map((headerGroup)=>/*#__PURE__*/ jsxs(Tr, {
|
|
15
|
+
children: [
|
|
16
|
+
headerGroup.headers.map((header)=>/*#__PURE__*/ jsx(TableHeadCell, {
|
|
17
|
+
header: header,
|
|
18
|
+
hasTextDescription: hasTextDescription
|
|
19
|
+
}, header.id)),
|
|
20
|
+
!stretch && /*#__PURE__*/ jsx(Th, {
|
|
21
|
+
"aria-hidden": true
|
|
22
|
+
})
|
|
23
|
+
]
|
|
19
24
|
}, headerGroup.id))
|
|
20
25
|
});
|
|
21
26
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Fragment, jsx } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
4
|
import { Skeleton } from "../Skeleton/index.js";
|
|
5
5
|
import { Td, Tr } from "./primitives/index.js";
|
|
6
6
|
import { useTableContext } from "./TableContext/index.js";
|
|
7
7
|
const TableLoadingState = ({ position = 'end', count })=>{
|
|
8
|
-
const { table, skeletonCount } = useTableContext();
|
|
8
|
+
const { table, skeletonCount, stretch } = useTableContext();
|
|
9
9
|
const testId = useTestId('start' === position ? 'loading-start' : 'loading');
|
|
10
10
|
const columns = table.getVisibleLeafColumns();
|
|
11
11
|
const lastRowIdx = (count ?? skeletonCount) - 1;
|
|
@@ -14,19 +14,25 @@ const TableLoadingState = ({ position = 'end', count })=>{
|
|
|
14
14
|
length: count ?? skeletonCount
|
|
15
15
|
}, (_, rowIdx)=>{
|
|
16
16
|
const key = `skeleton-${rowIdx}`;
|
|
17
|
-
return /*#__PURE__*/
|
|
17
|
+
return /*#__PURE__*/ jsxs(Tr, {
|
|
18
18
|
"data-testid": 0 === rowIdx ? testId : void 0,
|
|
19
19
|
"data-loading-position": position,
|
|
20
|
-
children:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
children: [
|
|
21
|
+
columns.map((column)=>/*#__PURE__*/ jsx(Td, {
|
|
22
|
+
className: cn('px-16 py-8 border-b border-r border-border-primary-light', 'end' === position && rowIdx === lastRowIdx && 'border-b-0'),
|
|
23
|
+
style: {
|
|
24
|
+
width: column.getSize()
|
|
25
|
+
},
|
|
26
|
+
children: /*#__PURE__*/ jsx(Skeleton, {
|
|
27
|
+
width: "100%",
|
|
28
|
+
height: "20px"
|
|
29
|
+
})
|
|
30
|
+
}, column.id)),
|
|
31
|
+
!stretch && /*#__PURE__*/ jsx(Td, {
|
|
32
|
+
pinned: false,
|
|
33
|
+
"aria-hidden": true
|
|
34
|
+
})
|
|
35
|
+
]
|
|
30
36
|
}, key);
|
|
31
37
|
})
|
|
32
38
|
});
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
const TableMasterCellActions = ({ children })=>/*#__PURE__*/ jsx("div", {
|
|
4
|
-
className: cn('shrink-0
|
|
5
|
-
children:
|
|
6
|
-
className: "overflow-hidden flex items-center gap-2",
|
|
7
|
-
children: children
|
|
8
|
-
})
|
|
4
|
+
className: cn('shrink-0 pl-4 pr-4 flex items-center gap-2', 'opacity-0 pointer-events-none', 'group-hover/row:opacity-100 group-hover/row:pointer-events-auto', 'group-data-[selected]/row:opacity-100 group-data-[selected]/row:pointer-events-auto', 'group-data-[preview-active]/row:opacity-100 group-data-[preview-active]/row:pointer-events-auto'),
|
|
5
|
+
children: children
|
|
9
6
|
});
|
|
10
7
|
TableMasterCellActions.displayName = 'TableMasterCellActions';
|
|
11
8
|
export { TableMasterCellActions };
|
|
@@ -5,6 +5,7 @@ import { useTestId } from "../../utils/testId.js";
|
|
|
5
5
|
import { TABLE_DRAG_HANDLE_COLUMN_ID, TABLE_EXPAND_COLUMN_ID, TABLE_SELECT_COLUMN_ID, useRowDnd } from "./lib/index.js";
|
|
6
6
|
import { Td, Tr } from "./primitives/index.js";
|
|
7
7
|
import { TableBodyCell } from "./TableBody/TableBodyCell.js";
|
|
8
|
+
import { useRowDndIndicator } from "./TableBody/TableBodyRowDndContext.js";
|
|
8
9
|
import { useTableContext } from "./TableContext/index.js";
|
|
9
10
|
import { TableRowExpanded } from "./TableRowExpanded.js";
|
|
10
11
|
const SYSTEM_COLUMN_IDS = new Set([
|
|
@@ -13,9 +14,10 @@ const SYSTEM_COLUMN_IDS = new Set([
|
|
|
13
14
|
TABLE_DRAG_HANDLE_COLUMN_ID
|
|
14
15
|
]);
|
|
15
16
|
const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
16
|
-
const { table, expandingEnabled, activeRowId, isLoading, renderExpandedRow } = useTableContext();
|
|
17
|
+
const { table, expandingEnabled, activeRowId, isLoading, renderExpandedRow, stretch, hasSubRowGrouping, allLeafColumns } = useTableContext();
|
|
17
18
|
const testId = useTestId('row');
|
|
18
19
|
const { canDnd, isDragging, setNodeRef, style: dndStyle, attributes, listeners } = useRowDnd(row);
|
|
20
|
+
const { activeId, overId } = useRowDndIndicator();
|
|
19
21
|
const isGroupParent = row.subRows.length > 0;
|
|
20
22
|
const isSelected = isGroupParent ? row.getIsAllSubRowsSelected() : row.getIsSelected();
|
|
21
23
|
const isPreviewActive = activeRowId === row.id;
|
|
@@ -38,6 +40,11 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
|
38
40
|
const systemCells = cells.filter((c)=>SYSTEM_COLUMN_IDS.has(c.column.id));
|
|
39
41
|
const dataCells = cells.filter((c)=>!SYSTEM_COLUMN_IDS.has(c.column.id));
|
|
40
42
|
const firstDataCell = dataCells[0];
|
|
43
|
+
const stickyStyle = hasSubRowGrouping && row.getIsExpanded() ? {
|
|
44
|
+
position: 'sticky',
|
|
45
|
+
top: allLeafColumns.some((c)=>c.columnDef.meta?.description?.type === 'text') ? 48 : 32,
|
|
46
|
+
zIndex: 20
|
|
47
|
+
} : void 0;
|
|
41
48
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
42
49
|
children: [
|
|
43
50
|
/*#__PURE__*/ jsxs(Tr, {
|
|
@@ -49,6 +56,7 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
|
49
56
|
"data-selected": isSelected || void 0,
|
|
50
57
|
"data-preview-active": isPreviewActive || void 0,
|
|
51
58
|
"aria-selected": isSelected || void 0,
|
|
59
|
+
style: stickyStyle,
|
|
52
60
|
children: [
|
|
53
61
|
systemCells.map((cell)=>/*#__PURE__*/ jsx(TableBodyCell, {
|
|
54
62
|
cell: cell,
|
|
@@ -67,7 +75,11 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
|
67
75
|
width: cell.column.getSize()
|
|
68
76
|
},
|
|
69
77
|
"aria-hidden": "true"
|
|
70
|
-
}, cell.id))
|
|
78
|
+
}, cell.id)),
|
|
79
|
+
!stretch && /*#__PURE__*/ jsx(Td, {
|
|
80
|
+
pinned: false,
|
|
81
|
+
"aria-hidden": true
|
|
82
|
+
})
|
|
71
83
|
]
|
|
72
84
|
}),
|
|
73
85
|
expandingEnabled && /*#__PURE__*/ jsx(TableRowExpanded, {
|
|
@@ -77,9 +89,15 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
|
77
89
|
]
|
|
78
90
|
});
|
|
79
91
|
}
|
|
92
|
+
let dropIndicator;
|
|
93
|
+
if (overId === row.id && null != activeId && activeId !== row.id) {
|
|
94
|
+
const activeIndex = flatRows.findIndex((r)=>r.id === activeId);
|
|
95
|
+
const overIndex = flatRows.findIndex((r)=>r.id === row.id);
|
|
96
|
+
if (-1 !== activeIndex && -1 !== overIndex) dropIndicator = activeIndex < overIndex ? 'below' : 'above';
|
|
97
|
+
}
|
|
80
98
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
81
99
|
children: [
|
|
82
|
-
/*#__PURE__*/
|
|
100
|
+
/*#__PURE__*/ jsxs(Tr, {
|
|
83
101
|
ref: composedRef,
|
|
84
102
|
"data-index": dataIndex,
|
|
85
103
|
"data-row-id": row.id,
|
|
@@ -91,15 +109,22 @@ const TableRowInner = ({ row, ref, 'data-index': dataIndex })=>{
|
|
|
91
109
|
"aria-selected": isSelected || void 0,
|
|
92
110
|
"data-depth": row.depth > 0 ? row.depth : void 0,
|
|
93
111
|
style: dndStyle,
|
|
94
|
-
children:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
children: [
|
|
113
|
+
row.getVisibleCells().map((cell)=>{
|
|
114
|
+
const isDragHandle = cell.column.id === TABLE_DRAG_HANDLE_COLUMN_ID;
|
|
115
|
+
return /*#__PURE__*/ jsx(TableBodyCell, {
|
|
116
|
+
cell: cell,
|
|
117
|
+
dragListeners: isDragHandle ? listeners : void 0,
|
|
118
|
+
dragAttributes: isDragHandle ? attributes : void 0,
|
|
119
|
+
lastRow: isLastRow,
|
|
120
|
+
dropIndicator: dropIndicator
|
|
121
|
+
}, cell.id);
|
|
122
|
+
}),
|
|
123
|
+
!stretch && /*#__PURE__*/ jsx(Td, {
|
|
124
|
+
pinned: false,
|
|
125
|
+
"aria-hidden": true
|
|
126
|
+
})
|
|
127
|
+
]
|
|
103
128
|
}),
|
|
104
129
|
expandingEnabled && /*#__PURE__*/ jsx(TableRowExpanded, {
|
|
105
130
|
row: row,
|
|
@@ -5,12 +5,13 @@ import { TABLE_EXPAND_COLUMN_ID } from "./lib/index.js";
|
|
|
5
5
|
import { Td, Tr } from "./primitives/index.js";
|
|
6
6
|
import { useTableContext } from "./TableContext/index.js";
|
|
7
7
|
const TableRowExpanded = ({ row, dndStyle, lastRow })=>{
|
|
8
|
-
const { table, renderExpandedRow } = useTableContext();
|
|
8
|
+
const { table, stretch, renderExpandedRow } = useTableContext();
|
|
9
9
|
const testId = useTestId('row-expanded');
|
|
10
10
|
if (!row.getIsExpanded() || !renderExpandedRow) return null;
|
|
11
11
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
12
12
|
const hasExpandColumn = visibleColumns.some((col)=>col.id === TABLE_EXPAND_COLUMN_ID);
|
|
13
|
-
const
|
|
13
|
+
const fillerOffset = stretch ? 0 : 1;
|
|
14
|
+
const contentColSpan = (hasExpandColumn ? visibleColumns.length - 1 : visibleColumns.length) + fillerOffset;
|
|
14
15
|
return /*#__PURE__*/ jsxs(Tr, {
|
|
15
16
|
"data-testid": testId,
|
|
16
17
|
style: dndStyle,
|
|
@@ -55,6 +55,7 @@ const useStickyGroupParent = (options)=>{
|
|
|
55
55
|
const [pushUpOffset, setPushUpOffset] = useState(0);
|
|
56
56
|
const rafRef = useRef(0);
|
|
57
57
|
const prevStickyRowIdRef = useRef(null);
|
|
58
|
+
const prevOffsetRef = useRef(0);
|
|
58
59
|
const compute = useCallback(()=>{
|
|
59
60
|
if (!enabled) {
|
|
60
61
|
if (null !== prevStickyRowIdRef.current) {
|
|
@@ -98,8 +99,9 @@ const useStickyGroupParent = (options)=>{
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
const newId = foundRow?.id ?? null;
|
|
101
|
-
if (newId !== prevStickyRowIdRef.current ||
|
|
102
|
+
if (newId !== prevStickyRowIdRef.current || offset !== prevOffsetRef.current) {
|
|
102
103
|
prevStickyRowIdRef.current = newId;
|
|
104
|
+
prevOffsetRef.current = offset;
|
|
103
105
|
setStickyRow(foundRow);
|
|
104
106
|
setPushUpOffset(offset);
|
|
105
107
|
}
|
|
@@ -8,7 +8,7 @@ export declare const TABLE_SELECT_COLUMN_WIDTH = 33;
|
|
|
8
8
|
export declare const TABLE_EXPAND_COLUMN_ID = "_expand";
|
|
9
9
|
export declare const TABLE_EXPAND_COLUMN_WIDTH = 33;
|
|
10
10
|
export declare const TABLE_DRAG_HANDLE_COLUMN_ID = "_dragHandle";
|
|
11
|
-
export declare const TABLE_DRAG_HANDLE_COLUMN_WIDTH =
|
|
11
|
+
export declare const TABLE_DRAG_HANDLE_COLUMN_WIDTH = 24;
|
|
12
12
|
export declare const TABLE_END_REACHED_THRESHOLD = 200;
|
|
13
13
|
export declare const TABLE_START_REACHED_THRESHOLD = 200;
|
|
14
14
|
/** Minimum time (ms) between successive edge-reached callbacks. */
|
|
@@ -7,7 +7,7 @@ const TABLE_SELECT_COLUMN_WIDTH = 33;
|
|
|
7
7
|
const TABLE_EXPAND_COLUMN_ID = '_expand';
|
|
8
8
|
const TABLE_EXPAND_COLUMN_WIDTH = 33;
|
|
9
9
|
const TABLE_DRAG_HANDLE_COLUMN_ID = '_dragHandle';
|
|
10
|
-
const TABLE_DRAG_HANDLE_COLUMN_WIDTH =
|
|
10
|
+
const TABLE_DRAG_HANDLE_COLUMN_WIDTH = 24;
|
|
11
11
|
const TABLE_END_REACHED_THRESHOLD = 200;
|
|
12
12
|
const TABLE_START_REACHED_THRESHOLD = 200;
|
|
13
13
|
const SCROLL_EDGE_COOLDOWN_MS = 200;
|
|
@@ -11,13 +11,13 @@ const createDragHandleColumn = ()=>({
|
|
|
11
11
|
enableHiding: false,
|
|
12
12
|
enablePinning: false,
|
|
13
13
|
meta: {
|
|
14
|
-
headerClassName: 'px-
|
|
15
|
-
cellClassName: 'px-
|
|
14
|
+
headerClassName: 'px-4 py-4',
|
|
15
|
+
cellClassName: 'px-4 py-8'
|
|
16
16
|
},
|
|
17
17
|
header: ()=>null,
|
|
18
18
|
cell: ()=>/*#__PURE__*/ jsx(GripVertical, {
|
|
19
19
|
size: "sm",
|
|
20
|
-
className: "text-text-
|
|
20
|
+
className: "text-text-secondary"
|
|
21
21
|
})
|
|
22
22
|
});
|
|
23
23
|
export { createDragHandleColumn };
|
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
import { useSortable } from "@dnd-kit/sortable";
|
|
2
|
-
import { CSS } from "@dnd-kit/utilities";
|
|
3
2
|
import { useTableContext } from "../TableContext/useTableContext.js";
|
|
4
3
|
const useRowDnd = (row)=>{
|
|
5
4
|
const { rowDndEnabled } = useTableContext();
|
|
6
5
|
const canDnd = rowDndEnabled && 0 === row.subRows.length;
|
|
7
|
-
const { attributes, listeners, setNodeRef,
|
|
6
|
+
const { attributes, listeners, setNodeRef, isDragging } = useSortable({
|
|
8
7
|
id: row.id,
|
|
9
8
|
disabled: !canDnd
|
|
10
9
|
});
|
|
11
|
-
const style = canDnd ? {
|
|
12
|
-
|
|
13
|
-
...transform,
|
|
14
|
-
x: 0
|
|
15
|
-
} : null),
|
|
16
|
-
transition,
|
|
17
|
-
...isDragging && {
|
|
18
|
-
opacity: 0.5,
|
|
19
|
-
position: 'relative',
|
|
20
|
-
zIndex: 100
|
|
21
|
-
}
|
|
10
|
+
const style = canDnd && isDragging ? {
|
|
11
|
+
opacity: 0.4
|
|
22
12
|
} : {};
|
|
23
13
|
return {
|
|
24
14
|
canDnd,
|
|
@@ -247,6 +247,14 @@ export interface TableProps<T> extends TestableProps {
|
|
|
247
247
|
onSettingsOpenChange?: (open: boolean) => void;
|
|
248
248
|
/** Enable row virtualization. `'container'` virtualizes within the scroll container; `'window'` virtualizes against the browser window. */
|
|
249
249
|
virtualized?: TableVirtualized;
|
|
250
|
+
/**
|
|
251
|
+
* Whether columns stretch proportionally to fill the container width.
|
|
252
|
+
* When `false`, columns use their defined sizes and the table may be
|
|
253
|
+
* narrower than its container.
|
|
254
|
+
*
|
|
255
|
+
* Default: `true`.
|
|
256
|
+
*/
|
|
257
|
+
stretch?: boolean;
|
|
250
258
|
estimateRowHeight?: (index: number) => number;
|
|
251
259
|
overscan?: number;
|
|
252
260
|
/** Callback fired when the user scrolls near the end (bottom) of the table */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.20.
|
|
3
|
-
"generatedAt": "2026-09-
|
|
2
|
+
"version": "1.20.4",
|
|
3
|
+
"generatedAt": "2026-09-16T18:12:26.773Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -79360,6 +79360,12 @@
|
|
|
79360
79360
|
"required": false,
|
|
79361
79361
|
"description": "Enable row virtualization. `'container'` virtualizes within the scroll container; `'window'` virtualizes against the browser window."
|
|
79362
79362
|
},
|
|
79363
|
+
{
|
|
79364
|
+
"name": "stretch",
|
|
79365
|
+
"type": "boolean | undefined",
|
|
79366
|
+
"required": false,
|
|
79367
|
+
"description": "Whether columns stretch proportionally to fill the container width.\nWhen `false`, columns use their defined sizes and the table may be\nnarrower than its container.\n\nDefault: `true`."
|
|
79368
|
+
},
|
|
79363
79369
|
{
|
|
79364
79370
|
"name": "estimateRowHeight",
|
|
79365
79371
|
"type": "((index: number) => number) | undefined",
|
|
@@ -80672,7 +80678,7 @@
|
|
|
80672
80678
|
"name": "placeholder",
|
|
80673
80679
|
"type": "ReactNode",
|
|
80674
80680
|
"required": false,
|
|
80675
|
-
"description": "Shown when nothing is selected. Defaults to `'Select
|
|
80681
|
+
"description": "Shown when nothing is selected. Defaults to `'Select'`."
|
|
80676
80682
|
},
|
|
80677
80683
|
{
|
|
80678
80684
|
"name": "color",
|
|
@@ -85364,6 +85370,11 @@
|
|
|
85364
85370
|
"code": "() => {\n const [sorting, setSorting] = useState<TableSortingState>([{ id: 'firstDetected', desc: true }]);\n\n return (\n <Table\n data={securityEvents}\n columns={securityColumns}\n getRowId={row => row.id}\n sorting={sorting}\n onSortingChange={setSorting}\n />\n );\n}",
|
|
85365
85371
|
"description": "The minimum — `data`, `columns`, `getRowId` and a column to open sorted on. The header stays\nput as the body scrolls."
|
|
85366
85372
|
},
|
|
85373
|
+
{
|
|
85374
|
+
"name": "NoStretch",
|
|
85375
|
+
"code": "() => {\n const narrowColumns: TableColumnDef<SecurityEvent>[] = [\n securityColumnHelper.accessor('objectName', {\n header: 'Object name',\n size: 200,\n }),\n securityColumnHelper.accessor('status', {\n header: 'Status',\n size: 120,\n }),\n securityColumnHelper.accessor('requests', {\n header: 'Requests',\n size: 100,\n }),\n ];\n\n return (\n <Table data={securityEvents} columns={narrowColumns} getRowId={row => row.id} stretch={false} />\n );\n}",
|
|
85376
|
+
"description": "`stretch={false}` — columns keep their defined widths and do not expand to fill the container.\nEmpty space appears on the right when the total column width is less than the container width."
|
|
85377
|
+
},
|
|
85367
85378
|
{
|
|
85368
85379
|
"name": "WithPagination",
|
|
85369
85380
|
"code": "() => {\n const allData = useMemo(() => createLargeSecurityEvents(47), []);\n const { pageData, ...pagination } = useClientPagination(allData, 10);\n\n return (\n <VStack gap={12}>\n <Table data={pageData} columns={securityColumns} getRowId={row => row.id} />\n <Pagination {...pagination} align='right' aria-label='Security events'>\n <PaginationPageSize options={[10, 25, 50]} />\n <PaginationPrevious />\n <PaginationList />\n <PaginationNext />\n </Pagination>\n </VStack>\n );\n}",
|
|
@@ -85551,7 +85562,7 @@
|
|
|
85551
85562
|
},
|
|
85552
85563
|
{
|
|
85553
85564
|
"name": "InlineCellEditing",
|
|
85554
|
-
"code": "() => {\n const [data, setData] = useState<SecurityEvent[]>(() => securityEvents.slice(0, 6));\n // Category starts unselected for every row, so the select shows its placeholder.\n const [categories, setCategories] = useState<Record<string, string>>({});\n\n const updateCell = useCallback(\n <K extends keyof SecurityEvent>(rowId: string, key: K, value: SecurityEvent[K]) => {\n setData(prev => prev.map(row => (row.id === rowId ? { ...row, [key]: value } : row)));\n },\n [],\n );\n\n const columns = useMemo<TableColumnDef<SecurityEvent>[]>(\n () => [\n // The first column is the Table's pinned \"master\" column — keep it\n // read-only; editable cells live in the plain columns after it.\n securityColumnHelper.accessor('sourceIp', {\n header: 'Source',\n size: 200,\n meta: { resizeType: 'cut' as const },\n cell: ({ getValue }) => <Text size='sm'>{getValue()}</Text>,\n }),\n securityColumnHelper.accessor('objectName', {\n header: 'Object name',\n size: 400,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row, getValue }) => (\n <EditableTextCell\n value={getValue()}\n aria-label='Edit object name'\n onCommit={value => updateCell(row.id, 'objectName', value)}\n />\n ),\n }),\n securityColumnHelper.accessor('status', {\n header: 'Status',\n size: 200,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row, getValue }) => (\n <EditableSelectCell\n value={getValue()}\n items={statusItems}\n onCommit={value => updateCell(row.id, 'status', value as SecurityEvent['status'])}\n >\n <StatusBadge value={getValue()} />\n </EditableSelectCell>\n ),\n }),\n // Empty-by-default select: consumer supplies the `placeholder` text.\n securityColumnHelper.display({\n id: 'category',\n header: 'Category',\n size: 200,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row }) => {\n const value = categories[row.id] ?? '';\n return (\n <EditableSelectCell\n value={value}\n items={categoryItems}\n placeholder='Select
|
|
85565
|
+
"code": "() => {\n const [data, setData] = useState<SecurityEvent[]>(() => securityEvents.slice(0, 6));\n // Category starts unselected for every row, so the select shows its placeholder.\n const [categories, setCategories] = useState<Record<string, string>>({});\n\n const updateCell = useCallback(\n <K extends keyof SecurityEvent>(rowId: string, key: K, value: SecurityEvent[K]) => {\n setData(prev => prev.map(row => (row.id === rowId ? { ...row, [key]: value } : row)));\n },\n [],\n );\n\n const columns = useMemo<TableColumnDef<SecurityEvent>[]>(\n () => [\n // The first column is the Table's pinned \"master\" column — keep it\n // read-only; editable cells live in the plain columns after it.\n securityColumnHelper.accessor('sourceIp', {\n header: 'Source',\n size: 200,\n meta: { resizeType: 'cut' as const },\n cell: ({ getValue }) => <Text size='sm'>{getValue()}</Text>,\n }),\n securityColumnHelper.accessor('objectName', {\n header: 'Object name',\n size: 400,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row, getValue }) => (\n <EditableTextCell\n value={getValue()}\n aria-label='Edit object name'\n onCommit={value => updateCell(row.id, 'objectName', value)}\n />\n ),\n }),\n securityColumnHelper.accessor('status', {\n header: 'Status',\n size: 200,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row, getValue }) => (\n <EditableSelectCell\n value={getValue()}\n items={statusItems}\n onCommit={value => updateCell(row.id, 'status', value as SecurityEvent['status'])}\n >\n <StatusBadge value={getValue()} />\n </EditableSelectCell>\n ),\n }),\n // Empty-by-default select: consumer supplies the `placeholder` text.\n securityColumnHelper.display({\n id: 'category',\n header: 'Category',\n size: 200,\n meta: EDITABLE_CELL_COLUMN_META,\n cell: ({ row }) => {\n const value = categories[row.id] ?? '';\n return (\n <EditableSelectCell\n value={value}\n items={categoryItems}\n placeholder='Select'\n aria-label='Edit category'\n onCommit={next => setCategories(prev => ({ ...prev, [row.id]: next }))}\n >\n {categoryItems.find(item => item.value === value)?.label}\n </EditableSelectCell>\n );\n },\n }),\n securityColumnHelper.accessor('parameter', {\n header: 'Parameters',\n size: 240,\n meta: { resizeType: 'cut' as const },\n cell: ({ getValue }) => <InlineCodeSnippet code={getValue()} size='sm' copyable={false} />,\n }),\n ],\n [updateCell, categories],\n );\n\n return (\n <VStack gap={12} align='stretch'>\n <span className='sb-annotation'>click a cell to edit it</span>\n <Table data={data} columns={columns} getRowId={row => row.id} />\n </VStack>\n );\n}"
|
|
85555
85566
|
},
|
|
85556
85567
|
{
|
|
85557
85568
|
"name": "StickyGroupParentStory",
|