Skip to content

Commit 86b25dd

Browse files
author
Danny North
committed
WIP doesnt work because of virtualizer bug which im sure is something strange going on
1 parent 5ae06bd commit 86b25dd

File tree

6 files changed

+116
-14
lines changed

6 files changed

+116
-14
lines changed

.vscode/settings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"settings": {
3+
"eslint.format.enable": true,
4+
"editor.codeActionsOnSave": {
5+
"source.fixAll.eslint": true
6+
},
7+
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
8+
"editor.tabSize": 1
9+
}
10+
}

packages/@react-aria/table/src/useTableColumnResize.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function useTableColumnResize(state, item): any {
2121
const columnResizeWidthRef = useRef(null);
2222
const {moveProps} = useMove({
2323
onMoveStart() {
24-
stateRef.current.setCurrentResizeColumn(item.key);
24+
stateRef.current.setCurrentResizeColumn(item);
2525
stateRef.current.addResizedColumn(item.key);
2626
columnResizeWidthRef.current = stateRef.current.getColumnWidth(item.key);
2727
},

packages/@react-spectrum/table/stories/Table.stories.tsx

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {IllustratedMessage} from '@react-spectrum/illustratedmessage';
2828
import {Link} from '@react-spectrum/link';
2929
import {LoadingState, SelectionMode} from '@react-types/shared';
3030
import {Radio, RadioGroup} from '@react-spectrum/radio';
31-
import React, {Key, useState} from 'react';
31+
import React, {Key, useMemo, useState} from 'react';
3232
import {SearchField} from '@react-spectrum/searchfield';
3333
import {storiesOf} from '@storybook/react';
3434
import {Switch} from '@react-spectrum/switch';
@@ -1070,6 +1070,12 @@ storiesOf('TableView', module)
10701070
</TableBody>
10711071
</TableView>
10721072
)
1073+
)
1074+
.add(
1075+
'resizable columns, controlled',
1076+
() => (
1077+
<ResizableColumnsControlled />
1078+
)
10731079
);
10741080

10751081
function AsyncLoadingExample() {
@@ -1419,3 +1425,60 @@ export function TableWithBreadcrumbs() {
14191425
</Flex>
14201426
);
14211427
}
1428+
1429+
function ResizableColumnsControlled() {
1430+
let columns = [
1431+
{
1432+
key: 0,
1433+
label: 'File Name',
1434+
allowsResizing: true,
1435+
width: 300
1436+
},
1437+
{
1438+
key: 1,
1439+
label: 'Type',
1440+
allowsResizing: true,
1441+
width: 200
1442+
},
1443+
{
1444+
key: 2,
1445+
label: 'Size',
1446+
allowsResizing: true,
1447+
width: 96
1448+
}
1449+
];
1450+
1451+
let [columnState, setColumnState] = useState(columns);
1452+
1453+
let onResize = (key, prevWidth, newWidth) => {
1454+
if (newWidth !== prevWidth) {
1455+
let updatedColumnState = columnState.map(c => key === c.key ? {...c, width: newWidth} : c);
1456+
setColumnState(updatedColumnState);
1457+
1458+
}
1459+
1460+
};
1461+
1462+
1463+
return (
1464+
<TableView aria-label="TableView with resizable columns" width={600} height={200}>
1465+
<TableHeader>
1466+
{
1467+
columnState.map(c => useMemo(() => (<Column allowsResizing={c.allowsResizing} width={c.width} onResize={(newWidth) => onResize(c.key, c.width, newWidth)}>{c.label}</Column>), [c.width]))
1468+
}
1469+
</TableHeader>
1470+
<TableBody>
1471+
<Row>
1472+
<Cell>2018 Proposal</Cell>
1473+
<Cell>PDF</Cell>
1474+
<Cell>214 KB</Cell>
1475+
</Row>
1476+
<Row>
1477+
<Cell>Budget</Cell>
1478+
<Cell>XLS</Cell>
1479+
<Cell>120 KB</Cell>
1480+
</Row>
1481+
</TableBody>
1482+
</TableView>
1483+
);
1484+
}

packages/@react-stately/layout/src/TableLayout.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ type TableLayoutOptions<T> = ListLayoutOptions<T> & {
2121
getDefaultWidth: (props) => string | number,
2222
columnWidths: Map<Key, number>,
2323
getColumnWidth: (key: Key) => number,
24-
setColumnWidth: (key: Key, width: number) => void,
24+
setColumnWidth: (column: any, width: number) => void,
2525
hasResizedColumn: (key: Key) => boolean,
26-
currentResizeColumn: Key,
26+
currentResizeColumn: any,
2727
resizeDelta: number
2828
}
2929

@@ -35,9 +35,9 @@ export class TableLayout<T> extends ListLayout<T> {
3535
stickyColumnIndices: number[];
3636
getDefaultWidth: (props) => string | number;
3737
getColumnWidth_: (key: Key) => number;
38-
setColumnWidth: (key: Key, width: number) => void;
38+
setColumnWidth_: (column: any, width: number) => void;
3939
hasResizedColumn: (key: Key) => boolean;
40-
currentResizeColumn: Key;
40+
currentResizeColumn: any;
4141
resizeDelta: number;
4242
wasLoading = false;
4343
isLoading = false;
@@ -47,7 +47,7 @@ export class TableLayout<T> extends ListLayout<T> {
4747
this.getDefaultWidth = options.getDefaultWidth;
4848
this.columnWidths = options.columnWidths;
4949
this.getColumnWidth_ = options.getColumnWidth;
50-
this.setColumnWidth = options.setColumnWidth;
50+
this.setColumnWidth_ = options.setColumnWidth;
5151
this.hasResizedColumn = options.hasResizedColumn;
5252
this.currentResizeColumn = options.currentResizeColumn;
5353
this.columnWidthsRef = this.columnWidths;
@@ -72,11 +72,20 @@ export class TableLayout<T> extends ListLayout<T> {
7272
this.isLoading = loadingState === 'loading' || loadingState === 'loadingMore';
7373

7474
// only rebuild columns that come after the column being resized, if no column is being resized, they will all be built
75-
const resizeIndex = this.collection.columns.findIndex(column => column.key === this.currentResizeColumn);
75+
const resizeIndex = this.collection.columns.findIndex(column => column.key === this.currentResizeColumn?.key);
7676
// if resizing, set the column width for the resized column to the delta bounded by it's min/max
7777
if (resizeIndex > -1) {
7878
const columnProps = this.collection.columns[resizeIndex].props;
79-
this.setColumnWidth(this.currentResizeColumn, Math.max(this.getMinWidth(columnProps?.minWidth), Math.min(this.getMaxWidth(columnProps.maxWidth), this.resizeDelta)));
79+
const boundedResizeDelta = Math.max(this.getMinWidth(columnProps?.minWidth), Math.min(this.getMaxWidth(columnProps.maxWidth), this.resizeDelta));
80+
81+
if (columnProps.width) {
82+
// Controlled component - explicit width is defined and should always win.
83+
// Unsure: Set column width to current width but call onResize with the new width?
84+
this.setColumnWidth_(this.currentResizeColumn, columnProps.width);
85+
columnProps.onResize && columnProps.onResize(boundedResizeDelta);
86+
} else {
87+
this.setColumnWidth(this.currentResizeColumn, boundedResizeDelta);
88+
}
8089
}
8190
const affectedResizeColumns = this.collection.columns.slice(resizeIndex + 1, this.collection.columns.length);
8291
const remainingSpace = this.collection.columns.slice(0, resizeIndex + 1).reduce((acc, column) => acc - this.getColumnWidth_(column.key), this.virtualizer.visibleRect.width);
@@ -92,6 +101,11 @@ export class TableLayout<T> extends ListLayout<T> {
92101
];
93102
}
94103

104+
setColumnWidth(column, newWidth) {
105+
this.setColumnWidth_(column, newWidth);
106+
column.props.onResize && column.props.onResize(newWidth);
107+
}
108+
95109
buildColumnWidths(affectedResizeColumns: GridNode<T>[], remainingSpace: number) {
96110
this.stickyColumnIndices = [];
97111

@@ -110,7 +124,7 @@ export class TableLayout<T> extends ListLayout<T> {
110124
if (this.getIsStatic(width)) {
111125
let w = this.parseWidth(width);
112126
this.columnWidthsRef.set(column.key, w);
113-
this.setColumnWidth(column.key, w);
127+
this.setColumnWidth(column, w);
114128
remainingSpace -= w;
115129
} else {
116130
remainingColumns.add(column);
@@ -132,7 +146,7 @@ export class TableLayout<T> extends ListLayout<T> {
132146
let i = 0;
133147
for (let column of remainingColumns) {
134148
this.columnWidthsRef.set(column.key, remCols[i].columnWidth);
135-
this.setColumnWidth(column.key, remCols[i].columnWidth);
149+
this.setColumnWidth(column, remCols[i].columnWidth);
136150
i++;
137151
}
138152
}

packages/@react-stately/table/src/useTableState.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface TableState<T> extends GridState<T, ITableCollection<T>> {
3737

3838
columnWidths(): Map<Key, number>,
3939
getColumnWidth(key: Key): number,
40-
setColumnWidth(key: Key, width: number),
40+
setColumnWidth(column: any, width: number),
4141

4242
hasResizedColumn(key: Key): boolean,
4343
addResizedColumn(key: Key),
@@ -102,8 +102,8 @@ export function useTableState<T extends object>(
102102
return columnWidthsRef.current.get(key);
103103
}
104104

105-
function setColumnWidthNew(key: Key, width: number) {
106-
columnWidthsRef.current.set(key, width);
105+
function setColumnWidthNew(column: any, width: number) {
106+
columnWidthsRef.current.set(column.key, width);
107107
// new map so that change detection is triggered
108108
setColumnWidths(new Map(columnWidthsRef.current));
109109
}

react-spectrum.code-workspace

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"settings": {
8+
"eslint.format.enable": true,
9+
"editor.codeActionsOnSave": {
10+
"source.fixAll.eslint": true
11+
},
12+
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
13+
"editor.tabSize": 1
14+
}
15+
}

0 commit comments

Comments
 (0)