@patternfly/react-data-view 6.3.0 → 6.4.0-prerelease.3
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/cjs/DataViewTable/DataViewTable.d.ts +4 -0
- package/dist/cjs/DataViewTable/DataViewTable.js +21 -1
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.d.ts +2 -0
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.js +2 -2
- package/dist/cjs/DataViewTableHead/DataViewTableHead.d.ts +2 -0
- package/dist/cjs/DataViewTableHead/DataViewTableHead.js +5 -4
- package/dist/cjs/DataViewTableTree/DataViewTableTree.d.ts +2 -0
- package/dist/cjs/DataViewTableTree/DataViewTableTree.js +28 -1
- package/dist/cjs/DataViewTableTree/DataViewTableTree.test.js +4 -0
- package/dist/cjs/DataViewTh/DataViewTh.d.ts +32 -0
- package/dist/cjs/DataViewTh/DataViewTh.js +222 -0
- package/dist/cjs/Hooks/selection.d.ts +1 -0
- package/dist/cjs/Hooks/selection.js +5 -1
- package/dist/cjs/Hooks/selection.test.js +48 -0
- package/dist/cjs/InternalContext/InternalContext.d.ts +2 -0
- package/dist/esm/DataViewTable/DataViewTable.d.ts +4 -0
- package/dist/esm/DataViewTable/DataViewTable.js +21 -1
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.d.ts +2 -0
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.js +2 -2
- package/dist/esm/DataViewTableHead/DataViewTableHead.d.ts +2 -0
- package/dist/esm/DataViewTableHead/DataViewTableHead.js +5 -4
- package/dist/esm/DataViewTableTree/DataViewTableTree.d.ts +2 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.js +29 -2
- package/dist/esm/DataViewTableTree/DataViewTableTree.test.js +4 -0
- package/dist/esm/DataViewTh/DataViewTh.d.ts +32 -0
- package/dist/esm/DataViewTh/DataViewTh.js +215 -0
- package/dist/esm/Hooks/selection.d.ts +1 -0
- package/dist/esm/Hooks/selection.js +5 -1
- package/dist/esm/Hooks/selection.test.js +48 -0
- package/dist/esm/InternalContext/InternalContext.d.ts +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableResizableColumnsExample.tsx +155 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx +1 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/Table.md +52 -14
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/SelectionExample.tsx +14 -3
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/Toolbar.md +1 -0
- package/release.config.js +1 -1
- package/src/DataViewCheckboxFilter/__snapshots__/DataViewCheckboxFilter.test.tsx.snap +0 -2
- package/src/DataViewFilters/__snapshots__/DataViewFilters.test.tsx.snap +0 -2
- package/src/DataViewTable/DataViewTable.tsx +48 -27
- package/src/DataViewTable/__snapshots__/DataViewTable.test.tsx.snap +10 -18
- package/src/DataViewTableBasic/DataViewTableBasic.tsx +4 -1
- package/src/DataViewTableBasic/__snapshots__/DataViewTableBasic.test.tsx.snap +20 -20
- package/src/DataViewTableHead/DataViewTableHead.tsx +24 -23
- package/src/DataViewTableHead/__snapshots__/DataViewTableHead.test.tsx.snap +15 -15
- package/src/DataViewTableTree/DataViewTableTree.test.tsx +9 -0
- package/src/DataViewTableTree/DataViewTableTree.tsx +35 -1
- package/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap +977 -28
- package/src/DataViewTextFilter/__snapshots__/DataViewTextFilter.test.tsx.snap +0 -3
- package/src/DataViewTh/DataViewTh.tsx +342 -0
- package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +0 -10
- package/src/Hooks/selection.test.tsx +65 -1
- package/src/Hooks/selection.ts +6 -1
- package/src/InternalContext/InternalContext.tsx +2 -0
|
@@ -14,17 +14,18 @@ import { useMemo } from 'react';
|
|
|
14
14
|
import { Th, Thead, Tr } from '@patternfly/react-table';
|
|
15
15
|
import { useInternalContext } from '../InternalContext';
|
|
16
16
|
import { isDataViewThObject } from '../DataViewTable';
|
|
17
|
+
import { DataViewTh as DataViewThElement } from '../DataViewTh/DataViewTh';
|
|
17
18
|
export const DataViewTableHead = (_a) => {
|
|
18
|
-
var { isTreeTable = false, columns, ouiaId = 'DataViewTableHead' } = _a, props = __rest(_a, ["isTreeTable", "columns", "ouiaId"]);
|
|
19
|
+
var { isTreeTable = false, columns, ouiaId = 'DataViewTableHead', hasResizableColumns } = _a, props = __rest(_a, ["isTreeTable", "columns", "ouiaId", "hasResizableColumns"]);
|
|
19
20
|
const { selection } = useInternalContext();
|
|
20
21
|
const { onSelect, isSelected } = selection !== null && selection !== void 0 ? selection : {};
|
|
21
22
|
const cells = useMemo(() => [
|
|
22
|
-
onSelect && isSelected && !isTreeTable ? (_jsx(Th, { screenReaderText:
|
|
23
|
+
onSelect && isSelected && !isTreeTable ? (_jsx(Th, { screenReaderText: "Data selection table head cell" }, "row-select")) : null,
|
|
23
24
|
...columns.map((column, index) => {
|
|
24
25
|
var _a;
|
|
25
|
-
return (_jsx(
|
|
26
|
+
return (_jsx(DataViewThElement, { content: isDataViewThObject(column) ? column.cell : column, resizableProps: isDataViewThObject(column) ? column.resizableProps : undefined, "data-ouia-component-id": `${ouiaId}-th-${index}`, thProps: isDataViewThObject(column) ? ((_a = column === null || column === void 0 ? void 0 : column.props) !== null && _a !== void 0 ? _a : {}) : {}, hasResizableColumns: hasResizableColumns }, index));
|
|
26
27
|
})
|
|
27
|
-
], [columns, ouiaId, onSelect, isSelected, isTreeTable]);
|
|
28
|
+
], [columns, ouiaId, onSelect, isSelected, isTreeTable, hasResizableColumns]);
|
|
28
29
|
return (_jsx(Thead, Object.assign({ "data-ouia-component-id": `${ouiaId}-thead` }, props, { children: _jsx(Tr, { ouiaId: `${ouiaId}-tr-head`, children: cells }) })));
|
|
29
30
|
};
|
|
30
31
|
export default DataViewTableHead;
|
|
@@ -18,6 +18,8 @@ export interface DataViewTableTreeProps extends Omit<TableProps, 'onSelect' | 'r
|
|
|
18
18
|
expandedIcon?: React.ReactNode;
|
|
19
19
|
/** Optional icon for the collapsed parent rows */
|
|
20
20
|
collapsedIcon?: React.ReactNode;
|
|
21
|
+
/** Expand all expandable nodes on initial load */
|
|
22
|
+
expandAll?: boolean;
|
|
21
23
|
/** Custom OUIA ID */
|
|
22
24
|
ouiaId?: string;
|
|
23
25
|
}
|
|
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { useState, useMemo } from 'react';
|
|
13
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
14
14
|
import { Table, Tbody, Td, TreeRowWrapper, } from '@patternfly/react-table';
|
|
15
15
|
import { useInternalContext } from '../InternalContext';
|
|
16
16
|
import { DataViewTableHead } from '../DataViewTableHead';
|
|
@@ -42,11 +42,38 @@ const getNodesAffectedBySelection = (allRows, node, isChecking, isSelected) => {
|
|
|
42
42
|
return Array.from(affectedNodes);
|
|
43
43
|
};
|
|
44
44
|
export const DataViewTableTree = (_a) => {
|
|
45
|
-
var { columns, rows, headStates, bodyStates, leafIcon = null, expandedIcon = null, collapsedIcon = null, ouiaId = 'DataViewTableTree' } = _a, props = __rest(_a, ["columns", "rows", "headStates", "bodyStates", "leafIcon", "expandedIcon", "collapsedIcon", "ouiaId"]);
|
|
45
|
+
var { columns, rows, headStates, bodyStates, leafIcon = null, expandedIcon = null, collapsedIcon = null, expandAll = false, ouiaId = 'DataViewTableTree' } = _a, props = __rest(_a, ["columns", "rows", "headStates", "bodyStates", "leafIcon", "expandedIcon", "collapsedIcon", "expandAll", "ouiaId"]);
|
|
46
46
|
const { selection, activeState } = useInternalContext();
|
|
47
47
|
const { onSelect, isSelected, isSelectDisabled } = selection !== null && selection !== void 0 ? selection : {};
|
|
48
48
|
const [expandedNodeIds, setExpandedNodeIds] = useState([]);
|
|
49
49
|
const [expandedDetailsNodeNames, setExpandedDetailsNodeIds] = useState([]);
|
|
50
|
+
// Helper function to collect all node IDs that have children (are expandable)
|
|
51
|
+
const getExpandableNodeIds = (nodes) => {
|
|
52
|
+
const expandableIds = [];
|
|
53
|
+
const traverse = (nodeList) => {
|
|
54
|
+
nodeList.forEach(node => {
|
|
55
|
+
if (node.children && node.children.length > 0) {
|
|
56
|
+
expandableIds.push(node.id);
|
|
57
|
+
traverse(node.children);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
traverse(nodes);
|
|
62
|
+
return expandableIds;
|
|
63
|
+
};
|
|
64
|
+
// Effect to handle expandAll behavior
|
|
65
|
+
// Memoize the expandable IDs to avoid recalculating when rows object reference changes but structure is the same
|
|
66
|
+
const expandableIds = useMemo(() => getExpandableNodeIds(rows), [rows]);
|
|
67
|
+
// Effect to handle expandAll behavior - only runs when IDs actually change
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (expandAll) {
|
|
70
|
+
setExpandedNodeIds(expandableIds);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
setExpandedNodeIds([]);
|
|
74
|
+
}
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [expandAll, expandableIds.join(',')]);
|
|
50
77
|
const activeHeadState = useMemo(() => activeState ? headStates === null || headStates === void 0 ? void 0 : headStates[activeState] : undefined, [activeState, headStates]);
|
|
51
78
|
const activeBodyState = useMemo(() => activeState ? bodyStates === null || bodyStates === void 0 ? void 0 : bodyStates[activeState] : undefined, [activeState, bodyStates]);
|
|
52
79
|
const nodes = useMemo(() => {
|
|
@@ -74,6 +74,10 @@ describe('DataViewTableTree component', () => {
|
|
|
74
74
|
const { container } = render(_jsx(DataView, { activeState: "error", children: _jsx(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, bodyStates: { error: "Some error" }, rows: [] }) }));
|
|
75
75
|
expect(container).toMatchSnapshot();
|
|
76
76
|
});
|
|
77
|
+
test('should render tree table with all expandable nodes expanded', () => {
|
|
78
|
+
const { container } = render(_jsx(DataView, { selection: mockSelection, children: _jsx(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, expandAll: true, rows: rows, leafIcon: _jsx(LeafIcon, {}), expandedIcon: _jsx(FolderOpenIcon, { "aria-hidden": true }), collapsedIcon: _jsx(FolderIcon, { "aria-hidden": true }) }) }));
|
|
79
|
+
expect(container).toMatchSnapshot();
|
|
80
|
+
});
|
|
77
81
|
test('should render tree table with a loading state', () => {
|
|
78
82
|
const { container } = render(_jsx(DataView, { activeState: "loading", children: _jsx(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, bodyStates: { loading: "Data is loading" }, rows: [] }) }));
|
|
79
83
|
expect(container).toMatchSnapshot();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FC, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react';
|
|
2
|
+
import { ThProps } from '@patternfly/react-table';
|
|
3
|
+
export interface DataViewThResizableProps {
|
|
4
|
+
/** Whether the column is resizable */
|
|
5
|
+
isResizable?: boolean;
|
|
6
|
+
/** Callback after the column is resized. Returns the triggering event, the column id passed in via cell props, and the new width of the column. */
|
|
7
|
+
onResize?: (event: ReactMouseEvent | MouseEvent | ReactKeyboardEvent | KeyboardEvent | TouchEvent, id: string | number | undefined, width: number) => void;
|
|
8
|
+
/** Width of the column */
|
|
9
|
+
width?: number;
|
|
10
|
+
/** Minimum width of the column */
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
/** Increment for keyboard navigation */
|
|
13
|
+
increment?: number;
|
|
14
|
+
/** Increment for keyboard navigation while shift is held */
|
|
15
|
+
shiftIncrement?: number;
|
|
16
|
+
/** Provides an accessible name for the resizable column via a human readable string. */
|
|
17
|
+
resizeButtonAriaLabel?: string;
|
|
18
|
+
/** Screenreader text that gets announced when the column is resized. */
|
|
19
|
+
screenReaderText?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DataViewThProps {
|
|
22
|
+
/** Cell content */
|
|
23
|
+
content: ReactNode;
|
|
24
|
+
/** Resizable props */
|
|
25
|
+
resizableProps?: DataViewThResizableProps;
|
|
26
|
+
/** @hide Indicates whether the table has resizable columns */
|
|
27
|
+
hasResizableColumns?: boolean;
|
|
28
|
+
/** Props passed to Th */
|
|
29
|
+
thProps?: ThProps;
|
|
30
|
+
}
|
|
31
|
+
export declare const DataViewTh: FC<DataViewThProps>;
|
|
32
|
+
export default DataViewTh;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { useState, useCallback, useRef, useEffect, Fragment } from 'react';
|
|
14
|
+
import { Th } from '@patternfly/react-table';
|
|
15
|
+
import { Button, getLanguageDirection } from '@patternfly/react-core';
|
|
16
|
+
import { createUseStyles } from 'react-jss';
|
|
17
|
+
import tableCellPaddingBlockEnd from '@patternfly/react-tokens/dist/esm/c_table_cell_PaddingBlockEnd';
|
|
18
|
+
import tableCellPaddingInlineEnd from '@patternfly/react-tokens/dist/esm/c_table_cell_PaddingInlineEnd';
|
|
19
|
+
import globalFontSizeBodyDefault from '@patternfly/react-tokens/dist/esm/t_global_font_size_body_default';
|
|
20
|
+
const ResizeIcon = () => (_jsx("svg", { className: "pf-v6-svg", viewBox: "0 0 1024 1024", fill: "currentColor", "aria-hidden": "true", role: "img", width: "1em", height: "1em", children: _jsx("path", { fillRule: "evenodd", d: "M52.7,529.8l190.5,161.9c18.6,15.9,50.5,4.7,50.5-17.8v-324c0-22.4-31.8-33.6-50.5-17.8L52.7,494.2c-11.5,9.8-11.5,25.8,0,35.6ZM480.8,12.9h62.4v998.3h-62.4V12.9ZM971.3,529.8l-190.5,161.9c-18.6,15.9-50.5,4.7-50.5-17.8v-324c0-22.4,31.8-33.6,50.5-17.8l190.5,161.9c11.5,9.8,11.5,25.8,0,35.6Z" }) }));
|
|
21
|
+
const useStyles = createUseStyles({
|
|
22
|
+
dataViewResizeableTh: {
|
|
23
|
+
[tableCellPaddingInlineEnd.name]: `calc(${globalFontSizeBodyDefault.var} * 2)`
|
|
24
|
+
},
|
|
25
|
+
dataViewResizableButton: {
|
|
26
|
+
position: 'absolute',
|
|
27
|
+
insetInlineEnd: `calc(${globalFontSizeBodyDefault.var} / 2)`,
|
|
28
|
+
insetBlockEnd: tableCellPaddingBlockEnd.var,
|
|
29
|
+
cursor: 'grab',
|
|
30
|
+
'&:active': {
|
|
31
|
+
cursor: 'grabbing'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
export const DataViewTh = (_a) => {
|
|
36
|
+
var { content, resizableProps = {}, hasResizableColumns = false, thProps } = _a, props = __rest(_a, ["content", "resizableProps", "hasResizableColumns", "thProps"]);
|
|
37
|
+
const thRef = useRef(null);
|
|
38
|
+
const [width, setWidth] = useState((resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.width) ? resizableProps.width : 0);
|
|
39
|
+
// Tracks the current column width for the onResize callback, because the width state is not updated until after the resize is complete
|
|
40
|
+
const trackedWidth = useRef(0);
|
|
41
|
+
const classes = useStyles();
|
|
42
|
+
const isResizable = (resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.isResizable) || false;
|
|
43
|
+
const increment = (resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.increment) || 5;
|
|
44
|
+
const shiftIncrement = (resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.shiftIncrement) || 25;
|
|
45
|
+
const resizeButtonAriaLabel = resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.resizeButtonAriaLabel;
|
|
46
|
+
const onResize = (resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.onResize) || undefined;
|
|
47
|
+
const screenReaderText = (resizableProps === null || resizableProps === void 0 ? void 0 : resizableProps.screenReaderText) || `Column ${width.toFixed(0)} pixels`;
|
|
48
|
+
const dataViewThClassName = isResizable ? classes.dataViewResizeableTh : undefined;
|
|
49
|
+
const resizeButtonRef = useRef(null);
|
|
50
|
+
const setInitialVals = useRef(true);
|
|
51
|
+
const dragOffset = useRef(0);
|
|
52
|
+
const isResizing = useRef(false);
|
|
53
|
+
const isInView = useRef(true);
|
|
54
|
+
if (isResizable && !resizeButtonAriaLabel) {
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.warn('DataViewTh: Missing resizeButtonAriaLabel. An aria label must be passed to each resizable column to provide a context specific label for its resize button.');
|
|
57
|
+
}
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!isResizable) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const observed = resizeButtonRef.current;
|
|
63
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
64
|
+
isInView.current = entry.isIntersecting;
|
|
65
|
+
}, { threshold: 0.3 });
|
|
66
|
+
if (observed) {
|
|
67
|
+
observer.observe(observed);
|
|
68
|
+
}
|
|
69
|
+
return () => {
|
|
70
|
+
if (observed) {
|
|
71
|
+
observer.unobserve(observed);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}, []);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
var _a;
|
|
77
|
+
if ((isResizable || hasResizableColumns) && setInitialVals.current && width === 0) {
|
|
78
|
+
setWidth(((_a = thRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0);
|
|
79
|
+
setInitialVals.current = false;
|
|
80
|
+
}
|
|
81
|
+
}, [isResizable, hasResizableColumns, setInitialVals]);
|
|
82
|
+
const setDragOffset = (e) => {
|
|
83
|
+
var _a, _b;
|
|
84
|
+
const isRTL = getLanguageDirection(thRef.current) === 'rtl';
|
|
85
|
+
const startingMousePos = 'clientX' in e ? e.clientX : e.touches[0].clientX;
|
|
86
|
+
const startingColumnPos = (isRTL ? (_a = thRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left : (_b = thRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().right) || 0;
|
|
87
|
+
dragOffset.current = startingColumnPos - startingMousePos;
|
|
88
|
+
};
|
|
89
|
+
const handleMousedown = (e) => {
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
document.addEventListener('mousemove', callbackMouseMove);
|
|
93
|
+
document.addEventListener('mouseup', callbackMouseUp);
|
|
94
|
+
// When a user begins resizing a column, set the drag offset so the drag motion aligns with the column edge
|
|
95
|
+
if (dragOffset.current === 0) {
|
|
96
|
+
setDragOffset(e);
|
|
97
|
+
}
|
|
98
|
+
isResizing.current = true;
|
|
99
|
+
};
|
|
100
|
+
const handleMouseMove = (e) => {
|
|
101
|
+
const mousePos = e.clientX;
|
|
102
|
+
handleControlMove(e, dragOffset.current + mousePos);
|
|
103
|
+
};
|
|
104
|
+
const handleTouchStart = (e) => {
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
document.addEventListener('touchmove', callbackTouchMove, { passive: false });
|
|
107
|
+
document.addEventListener('touchend', callbackTouchEnd);
|
|
108
|
+
// When a user begins resizing a column, set the drag offset so the drag motion aligns with the column edge
|
|
109
|
+
if (dragOffset.current === 0) {
|
|
110
|
+
setDragOffset(e);
|
|
111
|
+
}
|
|
112
|
+
isResizing.current = true;
|
|
113
|
+
};
|
|
114
|
+
const handleTouchMove = (e) => {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
e.stopImmediatePropagation();
|
|
117
|
+
const touchPos = e.touches[0].clientX;
|
|
118
|
+
handleControlMove(e, touchPos);
|
|
119
|
+
};
|
|
120
|
+
const handleControlMove = (e, controlPosition) => {
|
|
121
|
+
var _a, _b;
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
if (!isResizing.current) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const columnRect = (_a = thRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
127
|
+
if (columnRect === undefined) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const mousePos = controlPosition;
|
|
131
|
+
const isRTL = getLanguageDirection(thRef.current) === 'rtl';
|
|
132
|
+
let newSize = isRTL ? (columnRect === null || columnRect === void 0 ? void 0 : columnRect.right) - mousePos : mousePos - (columnRect === null || columnRect === void 0 ? void 0 : columnRect.left);
|
|
133
|
+
// Prevent the column from shrinking below a specified minimum width
|
|
134
|
+
if (resizableProps.minWidth && newSize < resizableProps.minWidth) {
|
|
135
|
+
newSize = resizableProps.minWidth;
|
|
136
|
+
}
|
|
137
|
+
(_b = thRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty('min-width', newSize + 'px');
|
|
138
|
+
trackedWidth.current = newSize;
|
|
139
|
+
setWidth(newSize);
|
|
140
|
+
};
|
|
141
|
+
const handleMouseup = (e) => {
|
|
142
|
+
var _a;
|
|
143
|
+
if (!isResizing.current) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Reset the isResizing and dragOffset values to their initial states
|
|
147
|
+
isResizing.current = false;
|
|
148
|
+
dragOffset.current = 0;
|
|
149
|
+
// Call the onResize callback with the new width
|
|
150
|
+
onResize && onResize(e, thProps === null || thProps === void 0 ? void 0 : thProps.id, trackedWidth.current);
|
|
151
|
+
// Handle scroll into view when column drag button is moved off screen
|
|
152
|
+
if (resizeButtonRef.current && !isInView.current) {
|
|
153
|
+
(_a = resizeButtonRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
154
|
+
}
|
|
155
|
+
document.removeEventListener('mousemove', callbackMouseMove);
|
|
156
|
+
document.removeEventListener('mouseup', callbackMouseUp);
|
|
157
|
+
};
|
|
158
|
+
const handleTouchEnd = (e) => {
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
if (!isResizing) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Reset the isResizing and dragOffset values to their initial states
|
|
164
|
+
isResizing.current = false;
|
|
165
|
+
dragOffset.current = 0;
|
|
166
|
+
// Call the onResize callback with the new width
|
|
167
|
+
onResize && onResize(e, thProps === null || thProps === void 0 ? void 0 : thProps.id, trackedWidth.current);
|
|
168
|
+
document.removeEventListener('touchmove', callbackTouchMove);
|
|
169
|
+
document.removeEventListener('touchend', callbackTouchEnd);
|
|
170
|
+
};
|
|
171
|
+
const callbackMouseMove = useCallback(handleMouseMove, []);
|
|
172
|
+
const callbackTouchEnd = useCallback(handleTouchEnd, []);
|
|
173
|
+
const callbackTouchMove = useCallback(handleTouchMove, []);
|
|
174
|
+
const callbackMouseUp = useCallback(handleMouseup, []);
|
|
175
|
+
const handleKeys = (e) => {
|
|
176
|
+
var _a, _b;
|
|
177
|
+
const key = e.key;
|
|
178
|
+
if (key === 'Tab') {
|
|
179
|
+
isResizing.current = false;
|
|
180
|
+
}
|
|
181
|
+
if (key !== 'ArrowLeft' && key !== 'ArrowRight') {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
e.preventDefault();
|
|
185
|
+
isResizing.current = true;
|
|
186
|
+
const isRTL = getLanguageDirection(thRef.current) === 'rtl';
|
|
187
|
+
const columnRect = (_a = thRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
188
|
+
let newSize = (columnRect === null || columnRect === void 0 ? void 0 : columnRect.width) || 0;
|
|
189
|
+
let delta = 0;
|
|
190
|
+
const _increment = e.shiftKey ? shiftIncrement : increment;
|
|
191
|
+
if (key === 'ArrowRight') {
|
|
192
|
+
if (isRTL) {
|
|
193
|
+
delta = -_increment;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
delta = _increment;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (key === 'ArrowLeft') {
|
|
200
|
+
if (isRTL) {
|
|
201
|
+
delta = _increment;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
delta = -_increment;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
newSize = newSize + delta;
|
|
208
|
+
(_b = thRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty('min-width', newSize + 'px');
|
|
209
|
+
setWidth(newSize);
|
|
210
|
+
onResize && onResize(e, thProps === null || thProps === void 0 ? void 0 : thProps.id, newSize);
|
|
211
|
+
};
|
|
212
|
+
const resizableContent = (_jsxs(Fragment, { children: [_jsx("div", { "aria-live": "polite", className: "pf-v6-screen-reader", children: screenReaderText }), _jsx(Button, { ref: resizeButtonRef, variant: "plain", hasNoPadding: true, icon: _jsx(ResizeIcon, {}), onMouseDown: handleMousedown, onKeyDown: handleKeys, onTouchStart: handleTouchStart, "aria-label": resizeButtonAriaLabel, className: classes.dataViewResizableButton })] }));
|
|
213
|
+
return (_jsx(Th, Object.assign({}, thProps, props, { style: width > 0 ? { minWidth: width } : undefined, ref: thRef, modifier: "truncate", className: dataViewThClassName }, (isResizable && { additionalContent: resizableContent }), { children: content })));
|
|
214
|
+
};
|
|
215
|
+
export default DataViewTh;
|
|
@@ -14,9 +14,13 @@ export const useDataViewSelection = (props) => {
|
|
|
14
14
|
: setSelected(items ? prev => prev.filter(prevSelected => !(Array.isArray(items) ? items : [items]).some(item => matchOption(item, prevSelected))) : []);
|
|
15
15
|
};
|
|
16
16
|
const isSelected = (item) => Boolean(selected.find(selected => matchOption(selected, item)));
|
|
17
|
+
const setSelectedItems = (items) => {
|
|
18
|
+
setSelected(items);
|
|
19
|
+
};
|
|
17
20
|
return {
|
|
18
21
|
selected,
|
|
19
22
|
onSelect,
|
|
20
|
-
isSelected
|
|
23
|
+
isSelected,
|
|
24
|
+
setSelected: setSelectedItems
|
|
21
25
|
};
|
|
22
26
|
};
|
|
@@ -17,6 +17,7 @@ describe('useDataViewSelection', () => {
|
|
|
17
17
|
selected: [],
|
|
18
18
|
onSelect: expect.any(Function),
|
|
19
19
|
isSelected: expect.any(Function),
|
|
20
|
+
setSelected: expect.any(Function),
|
|
20
21
|
});
|
|
21
22
|
});
|
|
22
23
|
it('should get initial state correctly - with initialSelected', () => {
|
|
@@ -26,6 +27,7 @@ describe('useDataViewSelection', () => {
|
|
|
26
27
|
selected: initialSelected,
|
|
27
28
|
onSelect: expect.any(Function),
|
|
28
29
|
isSelected: expect.any(Function),
|
|
30
|
+
setSelected: expect.any(Function),
|
|
29
31
|
});
|
|
30
32
|
});
|
|
31
33
|
it('should select items correctly - objects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -50,4 +52,50 @@ describe('useDataViewSelection', () => {
|
|
|
50
52
|
expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(true);
|
|
51
53
|
expect(result.current.isSelected({ id: 3, name: 'test2' })).toBe(false);
|
|
52
54
|
});
|
|
55
|
+
it('should have setSelected function in return object', () => {
|
|
56
|
+
const { result } = renderHook(() => useDataViewSelection({ matchOption: (a, b) => a.id === b.id }));
|
|
57
|
+
expect(result.current).toEqual({
|
|
58
|
+
selected: [],
|
|
59
|
+
onSelect: expect.any(Function),
|
|
60
|
+
isSelected: expect.any(Function),
|
|
61
|
+
setSelected: expect.any(Function),
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
it('should set selected items directly using setSelected - objects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
66
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
67
|
+
const newSelected = [{ id: 2, name: 'test2' }, { id: 3, name: 'test3' }];
|
|
68
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
result.current.setSelected(newSelected);
|
|
70
|
+
}));
|
|
71
|
+
expect(result.current.selected).toEqual(newSelected);
|
|
72
|
+
}));
|
|
73
|
+
it('should set selected items directly using setSelected - strings', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const initialSelected = ['test1', 'test2'];
|
|
75
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a === b }));
|
|
76
|
+
const newSelected = ['test3', 'test4', 'test5'];
|
|
77
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
result.current.setSelected(newSelected);
|
|
79
|
+
}));
|
|
80
|
+
expect(result.current.selected).toEqual(newSelected);
|
|
81
|
+
}));
|
|
82
|
+
it('should clear all selections using setSelected with empty array', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
+
const initialSelected = [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }];
|
|
84
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
85
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
result.current.setSelected([]);
|
|
87
|
+
}));
|
|
88
|
+
expect(result.current.selected).toEqual([]);
|
|
89
|
+
}));
|
|
90
|
+
it('should update isSelected correctly after using setSelected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
92
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
93
|
+
const newSelected = [{ id: 2, name: 'test2' }, { id: 3, name: 'test3' }];
|
|
94
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
result.current.setSelected(newSelected);
|
|
96
|
+
}));
|
|
97
|
+
expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(false);
|
|
98
|
+
expect(result.current.isSelected({ id: 2, name: 'test2' })).toBe(true);
|
|
99
|
+
expect(result.current.isSelected({ id: 3, name: 'test3' })).toBe(true);
|
|
100
|
+
}));
|
|
53
101
|
});
|
|
@@ -5,6 +5,8 @@ export interface DataViewSelection {
|
|
|
5
5
|
onSelect: (isSelecting: boolean, items?: any[] | any) => void;
|
|
6
6
|
/** Checks if a specific item is currently selected */
|
|
7
7
|
isSelected: (item: any) => boolean;
|
|
8
|
+
/** Directly sets the selected items */
|
|
9
|
+
setSelected?: (items: any[]) => void;
|
|
8
10
|
/** Determines if selection is disabled for a given item */
|
|
9
11
|
isSelectDisabled?: (item: any) => boolean;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/
|
|
1
|
+
{"root":["../src/index.ts","../src/DataView/DataView.test.tsx","../src/DataView/DataView.tsx","../src/DataView/index.ts","../src/DataViewCheckboxFilter/DataViewCheckboxFilter.test.tsx","../src/DataViewCheckboxFilter/DataViewCheckboxFilter.tsx","../src/DataViewCheckboxFilter/index.ts","../src/DataViewEventsContext/DataViewEventsContext.test.tsx","../src/DataViewEventsContext/DataViewEventsContext.tsx","../src/DataViewEventsContext/index.ts","../src/DataViewFilters/DataViewFilters.test.tsx","../src/DataViewFilters/DataViewFilters.tsx","../src/DataViewFilters/index.tsx","../src/DataViewTable/DataViewTable.test.tsx","../src/DataViewTable/DataViewTable.tsx","../src/DataViewTable/index.ts","../src/DataViewTableBasic/DataViewTableBasic.test.tsx","../src/DataViewTableBasic/DataViewTableBasic.tsx","../src/DataViewTableBasic/index.ts","../src/DataViewTableHead/DataViewTableHead.test.tsx","../src/DataViewTableHead/DataViewTableHead.tsx","../src/DataViewTableHead/index.ts","../src/DataViewTableTree/DataViewTableTree.test.tsx","../src/DataViewTableTree/DataViewTableTree.tsx","../src/DataViewTableTree/index.ts","../src/DataViewTextFilter/DataViewTextFilter.test.tsx","../src/DataViewTextFilter/DataViewTextFilter.tsx","../src/DataViewTextFilter/index.ts","../src/DataViewTh/DataViewTh.tsx","../src/DataViewToolbar/DataViewToolbar.test.tsx","../src/DataViewToolbar/DataViewToolbar.tsx","../src/DataViewToolbar/index.ts","../src/Hooks/filters.test.tsx","../src/Hooks/filters.ts","../src/Hooks/index.ts","../src/Hooks/pagination.test.tsx","../src/Hooks/pagination.ts","../src/Hooks/selection.test.tsx","../src/Hooks/selection.ts","../src/Hooks/sort.test.tsx","../src/Hooks/sort.ts","../src/InternalContext/InternalContext.test.tsx","../src/InternalContext/InternalContext.tsx","../src/InternalContext/index.ts"],"version":"5.9.2"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-data-view",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0-prerelease.3",
|
|
4
4
|
"description": "Data view used for Red Hat projects.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@patternfly/react-component-groups": "^6.1.0",
|
|
35
|
-
"@patternfly/react-core": "
|
|
36
|
-
"@patternfly/react-icons": "
|
|
37
|
-
"@patternfly/react-table": "
|
|
35
|
+
"@patternfly/react-core": "6.4.0-prerelease.1",
|
|
36
|
+
"@patternfly/react-icons": "6.4.0-prerelease.1",
|
|
37
|
+
"@patternfly/react-table": "6.4.0-prerelease.2",
|
|
38
38
|
"clsx": "^2.1.1",
|
|
39
39
|
"react-jss": "^10.10.0"
|
|
40
40
|
},
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@patternfly/documentation-framework": "^6.5.20",
|
|
47
|
-
"@patternfly/patternfly": "
|
|
48
|
-
"@patternfly/react-code-editor": "
|
|
47
|
+
"@patternfly/patternfly": "6.4.0-prerelease.1",
|
|
48
|
+
"@patternfly/react-code-editor": "6.4.0-prerelease.1",
|
|
49
49
|
"@patternfly/patternfly-a11y": "^5.1.0",
|
|
50
50
|
"@types/react": "^18.3.23",
|
|
51
51
|
"@types/react-dom": "^18.3.7",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"react-router": "^6.30.1",
|
|
56
56
|
"react-router-dom": "^6.30.1",
|
|
57
57
|
"rimraf": "^6.0.1",
|
|
58
|
-
"typescript": "^5.
|
|
58
|
+
"typescript": "^5.9.2"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
2
|
+
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
3
|
+
import { Button } from '@patternfly/react-core';
|
|
4
|
+
import { ActionsColumn } from '@patternfly/react-table';
|
|
5
|
+
|
|
6
|
+
interface Repository {
|
|
7
|
+
id: number;
|
|
8
|
+
name: string;
|
|
9
|
+
branches: string | null;
|
|
10
|
+
prs: string | null;
|
|
11
|
+
workspaces: string;
|
|
12
|
+
lastCommit: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const repositories: Repository[] = [
|
|
16
|
+
{
|
|
17
|
+
id: 1,
|
|
18
|
+
name: 'Repository one',
|
|
19
|
+
branches: 'Branch one',
|
|
20
|
+
prs: 'Pull request one',
|
|
21
|
+
workspaces: 'Workspace one',
|
|
22
|
+
lastCommit: 'Timestamp one'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 2,
|
|
26
|
+
name: 'Repository two',
|
|
27
|
+
branches: 'Branch two',
|
|
28
|
+
prs: 'Pull request two',
|
|
29
|
+
workspaces: 'Workspace two',
|
|
30
|
+
lastCommit: 'Timestamp two'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 3,
|
|
34
|
+
name: 'Repository three',
|
|
35
|
+
branches: 'Branch three',
|
|
36
|
+
prs: 'Pull request three',
|
|
37
|
+
workspaces: 'Workspace three',
|
|
38
|
+
lastCommit: 'Timestamp three'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 4,
|
|
42
|
+
name: 'Repository four',
|
|
43
|
+
branches: 'Branch four',
|
|
44
|
+
prs: 'Pull request four',
|
|
45
|
+
workspaces: 'Workspace four',
|
|
46
|
+
lastCommit: 'Timestamp four'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 5,
|
|
50
|
+
name: 'Repository five',
|
|
51
|
+
branches: 'Branch five',
|
|
52
|
+
prs: 'Pull request five',
|
|
53
|
+
workspaces: 'Workspace five',
|
|
54
|
+
lastCommit: 'Timestamp five'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 6,
|
|
58
|
+
name: 'Repository six',
|
|
59
|
+
branches: 'Branch six',
|
|
60
|
+
prs: 'Pull request six',
|
|
61
|
+
workspaces: 'Workspace six',
|
|
62
|
+
lastCommit: 'Timestamp six'
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const rowActions = [
|
|
67
|
+
{
|
|
68
|
+
title: 'Some action',
|
|
69
|
+
onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: <div>Another action</div>,
|
|
73
|
+
onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
isSeparator: true
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: 'Third action',
|
|
80
|
+
onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
// you can also pass props to Tr by returning { row: DataViewTd[], props: TrProps } }
|
|
85
|
+
const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [
|
|
86
|
+
{ id, cell: workspaces, props: { favorites: { isFavorited: true } } },
|
|
87
|
+
{
|
|
88
|
+
cell: (
|
|
89
|
+
<Button href="#" variant="link" isInline>
|
|
90
|
+
{name}
|
|
91
|
+
</Button>
|
|
92
|
+
)
|
|
93
|
+
},
|
|
94
|
+
branches,
|
|
95
|
+
prs,
|
|
96
|
+
workspaces,
|
|
97
|
+
lastCommit,
|
|
98
|
+
{ cell: <ActionsColumn items={rowActions} />, props: { isActionCell: true } }
|
|
99
|
+
]);
|
|
100
|
+
|
|
101
|
+
const ouiaId = 'TableExample';
|
|
102
|
+
|
|
103
|
+
export const ResizableColumnsExample: FunctionComponent = () => {
|
|
104
|
+
const onResize = (
|
|
105
|
+
_e: React.MouseEvent | MouseEvent | React.KeyboardEvent | KeyboardEvent | TouchEvent,
|
|
106
|
+
id: string | number | undefined,
|
|
107
|
+
width: number
|
|
108
|
+
) => {
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
console.log(`resized column id: ${id} width to: ${width.toFixed(0)}px`);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const columns: DataViewTh[] = [
|
|
114
|
+
null,
|
|
115
|
+
'Repositories',
|
|
116
|
+
{
|
|
117
|
+
cell: 'Branches',
|
|
118
|
+
resizableProps: {
|
|
119
|
+
isResizable: true,
|
|
120
|
+
onResize,
|
|
121
|
+
resizeButtonAriaLabel: 'Resize repositories column'
|
|
122
|
+
},
|
|
123
|
+
props: { id: 'repositories' }
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
cell: 'Pull requests',
|
|
127
|
+
resizableProps: {
|
|
128
|
+
isResizable: true,
|
|
129
|
+
onResize,
|
|
130
|
+
resizeButtonAriaLabel: 'Resize pull requests column'
|
|
131
|
+
},
|
|
132
|
+
props: { info: { tooltip: 'More information' }, id: 'pull-requests' }
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
cell: 'This is a really long title',
|
|
136
|
+
resizableProps: {
|
|
137
|
+
isResizable: true,
|
|
138
|
+
onResize,
|
|
139
|
+
resizeButtonAriaLabel: 'Resize this is a really long title column'
|
|
140
|
+
},
|
|
141
|
+
props: { info: { tooltip: 'More information' }, id: 'this-is-a-really-long-title' }
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
cell: 'Last commit',
|
|
145
|
+
resizableProps: {
|
|
146
|
+
isResizable: true,
|
|
147
|
+
onResize,
|
|
148
|
+
resizeButtonAriaLabel: 'Resize last commit column'
|
|
149
|
+
},
|
|
150
|
+
props: { sort: { sortBy: {}, columnIndex: 4 }, id: 'last-commit' }
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
return <DataViewTable isResizable aria-label="Repositories table" ouiaId={ouiaId} columns={columns} rows={rows} />;
|
|
155
|
+
};
|