Skip to content

Commit 6455bb8

Browse files
committed
refactor props to single interface, add aria label to button, add shift key behavior, refactor logic so default col widths are set for all columns in resizable table
1 parent 89fef7d commit 6455bb8

File tree

5 files changed

+57
-57
lines changed

5 files changed

+57
-57
lines changed

packages/module/patternfly-docs/generated/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ module.exports = {
1414
'/extensions/data-view/table/react': {
1515
id: "Table",
1616
title: "Data view table",
17-
toc: [{"text":"Configuring rows and columns"},[{"text":"Table example"}],{"text":"Tree table"},[{"text":"Tree table example"}],{"text":"Sorting"},[{"text":"Sorting example"},{"text":"Sorting state"}],{"text":"States"},[{"text":"Empty"},{"text":"Error"},{"text":"Loading"}]],
18-
examples: ["Table example","Tree table example","Sorting example","Empty","Error","Loading"],
17+
toc: [{"text":"Configuring rows and columns"},[{"text":"Table example"},{"text":"Resizable columns"}],{"text":"Tree table"},[{"text":"Tree table example"}],{"text":"Sorting"},[{"text":"Sorting example"},{"text":"Sorting state"}],{"text":"States"},[{"text":"Empty"},{"text":"Error"},{"text":"Loading"}]],
18+
examples: ["Table example","Resizable columns","Tree table example","Sorting example","Empty","Error","Loading"],
1919
section: "extensions",
2020
subsection: "Data view",
2121
source: "react",

packages/module/src/DataViewTable/DataViewTable.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,8 @@
1-
import { FC, ReactNode, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react';
1+
import { FC, ReactNode } from 'react';
22
import { TdProps, ThProps, TrProps, InnerScrollContainer } from '@patternfly/react-table';
33
import { DataViewTableTree, DataViewTableTreeProps } from '../DataViewTableTree';
44
import { DataViewTableBasic, DataViewTableBasicProps } from '../DataViewTableBasic';
5-
6-
// Table resizable typings
7-
export interface DataViewThResizableProps {
8-
/** Whether the column is resizable */
9-
isResizable?: boolean;
10-
/** Callback after the column is resized */
11-
onResize?: (
12-
event: ReactMouseEvent | MouseEvent | ReactKeyboardEvent | KeyboardEvent | TouchEvent,
13-
width: number
14-
) => void;
15-
/** Width of the column */
16-
width?: number;
17-
/** Minimum width of the column */
18-
minWidth?: number;
19-
/** Increment for keyboard navigation */
20-
increment?: number;
21-
}
5+
import { DataViewThResizableProps } from '../DataViewTh/DataViewTh';
226

237
// Table head typings
248
export type DataViewTh =
@@ -83,7 +67,7 @@ export const DataViewTable: FC<DataViewTableProps> = (props) => {
8367
const { isResizable, ...rest } = props;
8468
return isResizable ? (
8569
<InnerScrollContainer>
86-
<DataViewTableBasic {...rest} />
70+
<DataViewTableBasic hasResizableColumns {...rest} />
8771
</InnerScrollContainer>
8872
) : (
8973
<DataViewTableBasic {...rest} />

packages/module/src/DataViewTableBasic/DataViewTableBasic.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export interface DataViewTableBasicProps extends Omit<TableProps, 'onSelect' | '
2323
bodyStates?: Partial<Record<DataViewState | string, React.ReactNode>>
2424
/** Custom OUIA ID */
2525
ouiaId?: string;
26+
/** @hide Indicates if the table is resizable */
27+
hasResizableColumns?: boolean;
2628
}
2729

2830
export const DataViewTableBasic: FC<DataViewTableBasicProps> = ({
@@ -31,6 +33,7 @@ export const DataViewTableBasic: FC<DataViewTableBasicProps> = ({
3133
ouiaId = 'DataViewTableBasic',
3234
headStates,
3335
bodyStates,
36+
hasResizableColumns,
3437
...props
3538
}: DataViewTableBasicProps) => {
3639
const { selection, activeState, isSelectable } = useInternalContext();
@@ -74,7 +77,7 @@ export const DataViewTableBasic: FC<DataViewTableBasicProps> = ({
7477

7578
return (
7679
<Table aria-label="Data table" ouiaId={ouiaId} {...props}>
77-
{ activeHeadState || <DataViewTableHead columns={columns} ouiaId={ouiaId} /> }
80+
{ activeHeadState || <DataViewTableHead columns={columns} ouiaId={ouiaId} hasResizableColumns={hasResizableColumns} /> }
7881
{ activeBodyState || <Tbody>{renderedRows}</Tbody> }
7982
</Table>
8083
);

packages/module/src/DataViewTableHead/DataViewTableHead.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ export interface DataViewTableHeadProps extends TheadProps {
1212
columns: DataViewTh[];
1313
/** Custom OUIA ID */
1414
ouiaId?: string;
15+
/** @hide Indicates whether table is resizable */
16+
hasResizableColumns?: boolean;
1517
}
1618

1719
export const DataViewTableHead: FC<DataViewTableHeadProps> = ({
1820
isTreeTable = false,
1921
columns,
2022
ouiaId = 'DataViewTableHead',
23+
hasResizableColumns,
2124
...props
2225
}: DataViewTableHeadProps) => {
2326
const { selection } = useInternalContext();
@@ -35,10 +38,11 @@ export const DataViewTableHead: FC<DataViewTableHeadProps> = ({
3538
resizableProps={isDataViewThObject(column) ? column.resizableProps : undefined}
3639
data-ouia-component-id={`${ouiaId}-th-${index}`}
3740
props={isDataViewThObject(column) ? (column?.props ?? {}) : {}}
41+
hasResizableColumns={hasResizableColumns}
3842
/>
3943
))
4044
],
41-
[ columns, ouiaId, onSelect, isSelected, isTreeTable ]
45+
[ columns, ouiaId, onSelect, isSelected, isTreeTable, hasResizableColumns ]
4246
);
4347

4448
return (

packages/module/src/DataViewTh/DataViewTh.tsx

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,53 @@ import {
1111
} from 'react';
1212
import { Th, ThProps } from '@patternfly/react-table';
1313
import { Button, getLanguageDirection } from '@patternfly/react-core';
14-
14+
export interface DataViewThResizableProps {
15+
/** Whether the column is resizable */
16+
isResizable?: boolean;
17+
/** Callback after the column is resized */
18+
onResize?: (
19+
event: ReactMouseEvent | MouseEvent | ReactKeyboardEvent | KeyboardEvent | TouchEvent,
20+
width: number
21+
) => void;
22+
/** Width of the column */
23+
width?: number;
24+
/** Minimum width of the column */
25+
minWidth?: number;
26+
/** Increment for keyboard navigation */
27+
increment?: number;
28+
/** Increment for keyboard navigation while shift is held */
29+
shiftIncrement?: number;
30+
/** Aria label for the resize button */
31+
resizeButtonAriaLabel?: string;
32+
}
1533
export interface DataViewThProps {
1634
/** Cell content */
1735
content: ReactNode;
1836
/** Resizable props */
19-
resizableProps?: {
20-
/** Whether the column is resizable */
21-
isResizable?: boolean;
22-
/** Callback after the column is resized */
23-
onResize?: (
24-
event: ReactMouseEvent | MouseEvent | ReactKeyboardEvent | KeyboardEvent | TouchEvent,
25-
width: number
26-
) => void;
27-
/** Width of the column */
28-
width?: number;
29-
/** Minimum width of the column */
30-
minWidth?: number;
31-
/** Increment for keyboard navigation */
32-
increment?: number;
33-
};
37+
resizableProps?: DataViewThResizableProps;
38+
/** @hide Indicates whether the table has resizable columns */
39+
hasResizableColumns?: boolean;
3440
/** Props passed to Th */
3541
props?: ThProps;
3642
}
3743

3844
export const DataViewTh: FC<DataViewThProps> = ({
39-
resizableProps = {
40-
isResizable: false,
41-
width: 0,
42-
increment: 10
43-
},
4445
content,
46+
resizableProps = {},
47+
hasResizableColumns = false,
4548
props: thProps,
4649
...restProps
4750
}: DataViewThProps) => {
4851
const thRef = useRef<HTMLTableCellElement>(null);
4952

50-
const isResizable = resizableProps.isResizable;
53+
const isResizable = resizableProps?.isResizable || false;
54+
const increment = resizableProps?.increment || 5;
55+
const shiftIncrement = resizableProps?.shiftIncrement || 25;
56+
const resizeButtonAriaLabel = resizableProps?.resizeButtonAriaLabel || `Resize ${content}`;
57+
const onResize = resizableProps?.onResize || undefined;
58+
5159
const resizeButtonRef = useRef<HTMLButtonElement>(null);
52-
const [ width, setWidth ] = useState(resizableProps.width ? resizableProps.width : 0);
53-
const increment = resizableProps.increment || 5;
54-
const onResize = resizableProps.onResize;
60+
const [ width, setWidth ] = useState(resizableProps?.width ? resizableProps.width : 0);
5561
const setInitialVals = useRef(true);
5662
const dragOffset = useRef(0);
5763
const isResizing = useRef(false);
@@ -83,11 +89,11 @@ export const DataViewTh: FC<DataViewThProps> = ({
8389
}, []);
8490

8591
useEffect(() => {
86-
if (isResizable && setInitialVals.current && width === 0) {
92+
if ((isResizable || hasResizableColumns) && setInitialVals.current && width === 0) {
8793
setWidth(thRef.current?.getBoundingClientRect().width || 0);
8894
setInitialVals.current = false;
8995
}
90-
}, [ isResizable, setInitialVals ]);
96+
}, [ isResizable, hasResizableColumns, setInitialVals ]);
9197

9298
const setDragOffset = (e: ReactMouseEvent | ReactTouchEvent) => {
9399
const isRTL = getLanguageDirection(thRef.current as HTMLElement) === 'rtl';
@@ -205,18 +211,18 @@ export const DataViewTh: FC<DataViewThProps> = ({
205211
const callbackTouchMove = useCallback(handleTouchMove, []);
206212
const callbackMouseUp = useCallback(handleMouseup, []);
207213

208-
const handleKeys = (e: React.KeyboardEvent) => {
214+
const handleKeys = (e: ReactKeyboardEvent) => {
209215
const key = e.key;
210216

211-
if (key !== 'Escape' && key !== 'Enter' && key !== 'ArrowLeft' && key !== 'ArrowRight') {
217+
if (key !== 'Enter' && key !== 'ArrowLeft' && key !== 'ArrowRight' && key !== 'Tab' && key !== 'Space') {
212218
if (isResizing) {
213219
e.preventDefault();
214220
}
215221
return;
216222
}
217223
e.preventDefault();
218224

219-
if (key === 'Escape' || key === 'Enter') {
225+
if (key === 'Enter' || key === 'Tab' || key === 'Space') {
220226
onResize && onResize(e, currWidth);
221227
}
222228

@@ -225,17 +231,19 @@ export const DataViewTh: FC<DataViewThProps> = ({
225231

226232
let newSize = columnRect?.width || 0;
227233
let delta = 0;
234+
const _increment = e.shiftKey ? shiftIncrement : increment;
235+
228236
if (key === 'ArrowRight') {
229237
if (isRTL) {
230-
delta = -increment;
238+
delta = -_increment;
231239
} else {
232-
delta = increment;
240+
delta = _increment;
233241
}
234242
} else if (key === 'ArrowLeft') {
235243
if (isRTL) {
236-
delta = increment;
244+
delta = _increment;
237245
} else {
238-
delta = -increment;
246+
delta = -_increment;
239247
}
240248
}
241249
newSize = newSize + delta;
@@ -255,6 +263,7 @@ export const DataViewTh: FC<DataViewThProps> = ({
255263
onKeyDown={handleKeys}
256264
onTouchStart={handleTouchStart}
257265
style={{ float: 'inline-end' }}
266+
aria-label={resizeButtonAriaLabel}
258267
>
259268
test
260269
</Button>

0 commit comments

Comments
 (0)