Skip to content

Commit 7990727

Browse files
committed
Add EventTrap for handling selection & expansion of rows in TreeGrid
1 parent a52fec1 commit 7990727

File tree

5 files changed

+69
-51
lines changed

5 files changed

+69
-51
lines changed

components/tree-grid/__docs__/storybook-stories.jsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ storiesOf(TREE_GRID, module)
1111
<div className="slds-p-around_medium">{getStory()}</div>
1212
))
1313
.add('Default', () => <Default action={action} />)
14-
.add('Single Select', () => (
15-
<Default action={action} selectRows="single" />
16-
))
14+
.add('Single Select', () => <Default action={action} selectRows="single" />)
1715
.add('w/o Border', () => <Default action={action} isBorderless />)
1816
.add('Single Select w/o Border', () => (
1917
<Default action={action} selectRows="single" isBorderless />

components/tree-grid/__examples__/default.jsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class Example extends React.Component {
182182
nodes: this.props.nodes || sampleData,
183183
isIndeterminate: false,
184184
allSelect: false,
185-
selectedNode: null
185+
selectedNode: null,
186186
};
187187

188188
getNodes = (node) =>
@@ -236,8 +236,7 @@ class Example extends React.Component {
236236
eventName: 'Select Branch',
237237
data,
238238
});
239-
if(this.props.selectRows !== "single")
240-
{
239+
if (this.props.selectRows !== 'single') {
241240
const curr = this.state.nodes;
242241
curr[data.node.id].selected = data.selected;
243242
const selectedCount = this.countSelected(curr['0'].nodes);
@@ -250,12 +249,13 @@ class Example extends React.Component {
250249
isIndeterminate = null;
251250
}
252251
this.setState({ nodes: curr, isIndeterminate, allSelect });
253-
}
254-
else {
252+
} else {
255253
const { nodes, selectedNode } = this.state;
256254
nodes[data.node.id].selected = true;
257-
if(selectedNode != null) { nodes[selectedNode].selected = false; }
258-
this.setState({ nodes, selectedNode: data.node.id })
255+
if (selectedNode != null) {
256+
nodes[selectedNode].selected = false;
257+
}
258+
this.setState({ nodes, selectedNode: data.node.id });
259259
}
260260
};
261261

components/tree-grid/__examples__/headless.jsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ class Example extends React.Component {
135135
this.setState({ nodes: updated });
136136
};
137137

138+
findChildren = (node) => {
139+
if (node.type === 'branch') {
140+
let list = [];
141+
node.nodes.forEach((child) => {
142+
const c = this.findChildren(this.state.nodes[child]);
143+
list = [...c, child, ...list];
144+
});
145+
return list;
146+
}
147+
return [];
148+
};
149+
138150
handleSelection = (event, data) => {
139151
log({
140152
action: this.props.action,

components/tree-grid/index.jsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import classNames from 'classnames';
1010
// shortid is a short, non-sequential, url-friendly, unique id generator
1111
import shortid from 'shortid';
1212
import assign from 'lodash.assign';
13+
import isFunction from 'lodash.isfunction';
1314

1415
import { TREE_GRID } from '../../utilities/constants';
1516
import TreeGridColumn from './column';
@@ -73,15 +74,15 @@ const propTypes = {
7374
/**
7475
* Callback function for selection of rows
7576
*/
76-
onSelect: PropTypes.func.isRequired,
77+
onSelect: PropTypes.func,
7778
/**
7879
* Callback function for selection of all rows
7980
*/
80-
onSelectAll: PropTypes.func.isRequired,
81+
onSelectAll: PropTypes.func,
8182
/**
8283
* Callback function for expansion of rows
8384
*/
84-
onExpand: PropTypes.func.isRequired,
85+
onExpand: PropTypes.func,
8586
/**
8687
* Whether the TreeGrid is headless
8788
*/
@@ -168,16 +169,10 @@ class TreeGrid extends React.Component {
168169
});
169170
};
170171

171-
handleSelection = (event, data) => {
172-
this.props.onSelect(event, data);
173-
};
174-
175172
handleSelectAll = (event, data) => {
176-
this.props.onSelectAll(event, data);
177-
};
178-
179-
handleExpansion = (event, data) => {
180-
this.props.onExpand(event, data);
173+
if (isFunction(this.props.onSelectAll)) {
174+
this.props.onSelectAll(event, data);
175+
}
181176
};
182177

183178
render() {
@@ -208,6 +203,7 @@ class TreeGrid extends React.Component {
208203
id={this.getId()}
209204
aria-readonly="true"
210205
aria-multiselectable={this.props.selectRows === 'multiple'}
206+
/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role */
211207
role="treegrid"
212208
className={classNames(
213209
'slds-table',
@@ -272,8 +268,8 @@ class TreeGrid extends React.Component {
272268
flattenedNodes={this.state.flattenedNodes}
273269
focusedNodeIndex={this.state.focusedNodeIndex}
274270
columns={columns}
275-
onSelect={this.handleSelection}
276-
onExpand={this.handleExpansion}
271+
onSelect={this.props.onSelect}
272+
onExpand={this.props.onExpand}
277273
onFocus={this.handleFocus}
278274
selectRows={this.props.selectRows}
279275
moreActionsDropdown={this.props.moreActionsDropdown}

components/tree-grid/private/item.jsx

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,19 @@ import PropTypes from 'prop-types';
33
import classNames from 'classnames';
44
import shortid from 'shortid';
55
import findIndex from 'lodash.findindex';
6+
import isFunction from 'lodash.isfunction';
67

78
import { TREE_GRID_ITEM } from '../../../utilities/constants';
89
import Checkbox from '../../checkbox';
910
import TreeGridCell from './cell';
1011

12+
import EventUtil from '../../../utilities/event';
1113
import KEYS from '../../../utilities/key-code';
1214
import mapKeyEventCallbacks from '../../../utilities/key-callbacks';
1315

1416
const Item = (props) => {
1517
const isFocused = props.treeIndex === props.focusedNodeIndex;
1618

17-
const handleExpansion = (event) => {
18-
props.onExpand(event, {
19-
node: props.row,
20-
expanded: !props.row.expanded,
21-
});
22-
};
23-
24-
const handleSelection = (event) => {
25-
props.onSelect(event, {
26-
node: props.row,
27-
selected: !props.row.selected,
28-
});
29-
};
30-
3119
const findNextNode = (flattenedNodes, node) => {
3220
const nodes = flattenedNodes.map((flattenedNode) => flattenedNode.node);
3321
const index = findIndex(nodes, { id: node.id });
@@ -43,6 +31,26 @@ const Item = (props) => {
4331
return flattenedNodes[index];
4432
};
4533

34+
const handleExpansion = (event) => {
35+
if (isFunction(props.onExpand)) {
36+
EventUtil.trap(event);
37+
props.onExpand(event, {
38+
node: props.row,
39+
expanded: !props.row.expanded,
40+
});
41+
}
42+
};
43+
44+
const handleSelection = (event) => {
45+
if (isFunction(props.onSelect)) {
46+
EventUtil.trap(event);
47+
props.onSelect(event, {
48+
node: props.row,
49+
selected: !props.row.selected,
50+
});
51+
}
52+
};
53+
4654
const handleKeyDownDown = (event) => {
4755
const flattenedNode = findNextNode(props.flattenedNodes, props.row);
4856
props.onFocus(event, flattenedNode);
@@ -54,21 +62,25 @@ const Item = (props) => {
5462
};
5563

5664
const handleKeyDownLeft = (event) => {
57-
props.onExpand(event, {
58-
node: props.row,
59-
expanded: false,
60-
});
65+
if (props.row.nodes !== undefined) {
66+
if (isFunction(props.onExpand)) {
67+
props.onExpand(event, {
68+
node: props.row,
69+
expanded: false,
70+
});
71+
}
72+
}
6173
};
6274

6375
const handleKeyDownRight = (event) => {
64-
props.onExpand(event, {
65-
node: props.row,
66-
expanded: true,
67-
});
68-
};
69-
70-
const handleKeyDownEnter = (event) => {
71-
handleSelection(event);
76+
if (props.row.nodes !== undefined) {
77+
if (isFunction(props.onExpand)) {
78+
props.onExpand(event, {
79+
node: props.row,
80+
expanded: true,
81+
});
82+
}
83+
}
7284
};
7385

7486
const handleKeyDown = (event) => {
@@ -78,7 +90,7 @@ const Item = (props) => {
7890
[KEYS.UP]: { callback: (e) => handleKeyDownUp(e) },
7991
[KEYS.LEFT]: { callback: (e) => handleKeyDownLeft(e) },
8092
[KEYS.RIGHT]: { callback: (e) => handleKeyDownRight(e) },
81-
[KEYS.ENTER]: { callback: (e) => handleKeyDownEnter(e) },
93+
[KEYS.ENTER]: { callback: (e) => handleSelection(e) },
8294
},
8395
});
8496
};

0 commit comments

Comments
 (0)