Skip to content

Commit 37659cc

Browse files
authored
Merge pull request #864 from YannickRe/v2-dev
[V2] Fix default item selection in TreeView
2 parents ebdca02 + 7cd071f commit 37659cc

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

docs/documentation/docs/controls/TreeView.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { TreeView, ITreeItem, TreeViewSelectionMode } from "@pnp/spfx-controls-r
3434
items={treeitems}
3535
defaultExpanded={false}
3636
selectionMode={TreeViewSelectionMode.Multiple}
37-
selectChildrenIfParentSelected={true}
37+
selectChildrenMode={SelectChildrenMode.Select | SelectChildrenMode.Unselect}
3838
showCheckboxes={true}
3939
treeItemActionsDisplayMode={TreeItemActionsDisplayMode.ContextualMenu}
4040
defaultSelectedKeys={['key1', 'key2']}
@@ -91,7 +91,8 @@ The `TreeView` control can be configured with the following properties:
9191
| items | ITreeItem[] | yes | An array of tree items to display. refer [example](#example-of-array-of-tree-items-used-to-render-control-as-in-first-screenshot). |
9292
| defaultExpanded | boolean | no | Specify if the tree items are displayed as expanded by default (defaults to false. |
9393
| selectionMode | enum | no | Specifies the selection mode of tree view (defaults to Single selection). |
94-
| selectChildrenIfParentSelected | boolean | no | Specifies if the childrens should be selected when parent item is selected (defaults to false). |
94+
| selectChildrenIfParentSelected | boolean | no | Specifies if the children should be selected when parent item is selected (defaults to false). __Deprecated__: prefer usage of `selectChildrenMode` for more flexibility. |
95+
| selectChildrenMode | SelectChildrenMode | no | Specifies if the children should be selected when parent item is selected (defaults to None). Flagged enum, values can be combined eg. `SelectChildrenMode.Select \| SelectChildrenMode.Unselect` |
9596
| showCheckboxes | boolean | yes | Specify if the checkboxes should be displayed for selection. |
9697
| treeItemActionsDisplayMode | TreeItemActionsDisplayMode | no | Specifies the display mode of the tree item actions. |
9798
| defaultSelectedKeys | string[] | no | Specifies keys of items to be selected by default. |
@@ -111,6 +112,19 @@ Specifies the selection mode of tree item.
111112
| Multiple |
112113
| None |
113114
115+
Enum `SelectChildrenMode`
116+
117+
Specifies when the children of a selected item need to be automatically selected.
118+
119+
| Value | Description |
120+
|----------|------------------------------------------------------------------|
121+
| None | Children are never selected |
122+
| Select | When selecting an item, its children are also selected |
123+
| Unselect | When unselecting an item, its children are also unselected |
124+
| Mount | When the component is mounted, all children of selected items are also selected |
125+
| Update | When the component receives new props, all children of selected items are also selected |
126+
| All | Shorthand for a combination of all of the above, same as `SelectChildrenMode.Select \| SelectChildrenMode.Unselect \| SelectChildrenMode.Mount \| SelectChildrenMode.Update` | |
127+
114128
Interface `ITreeItem`
115129
116130
Each tree item in the `treeitems` property is defined as `ITreeItem` as follows:

src/controls/treeView/ITreeViewProps.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ export enum TreeViewSelectionMode {
1010
None = 2
1111
}
1212

13+
export enum SelectChildrenMode {
14+
None = 0,
15+
Select = 1 << 0, // 0001
16+
Unselect = 1 << 1, // 0010
17+
Mount = 1 << 2, // 0100
18+
Update = 1 << 3, // 1000
19+
All = ~(~0 << 4) // 1111
20+
}
21+
1322
/**
1423
* TreeView properties interface
1524
*/
@@ -29,10 +38,16 @@ export interface ITreeViewProps {
2938
*/
3039
selectionMode?: TreeViewSelectionMode;
3140
/**
41+
* @deprecated Use selectChildrenMode instead.
3242
* Specifies if the childrens should be selected when parent is selected.
3343
* By default this is set to false.
3444
*/
3545
selectChildrenIfParentSelected?: boolean;
46+
/**
47+
* Specifies if the childrens should be selected when parent is selected. Flagged enum, so values can be combined eg. SelectChildrenMode.Select | SelectChildrenMode.Unselect
48+
* By default this is set to None.
49+
*/
50+
selectChildrenMode?: SelectChildrenMode;
3651
/**
3752
* Specifies if the checkboxes should be displayed for selection.
3853
*/

src/controls/treeView/TreeView.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import styles from './TreeView.module.scss';
33
import uniqBy from 'lodash/uniqBy';
4-
import { ITreeViewProps, TreeViewSelectionMode } from './ITreeViewProps';
4+
import { ITreeViewProps, SelectChildrenMode, TreeViewSelectionMode } from './ITreeViewProps';
55
import { ITreeViewState } from './ITreeViewState';
66
import { ITreeItem } from './ITreeItem';
77
import TreeItem from './TreeItem';
@@ -68,6 +68,11 @@ export class TreeView extends React.Component<ITreeViewProps, ITreeViewState> {
6868
if (selectedChildren) {
6969
this.selectAllChildren(item, selectedItems);
7070
}
71+
else {
72+
if (item.children) {
73+
selectedItems.push(...this.getSelectedItems(item.children, selectedKeys, selectedChildren));
74+
}
75+
}
7176
}
7277
else {
7378
if (item.children) {
@@ -138,7 +143,7 @@ export class TreeView extends React.Component<ITreeViewProps, ITreeViewState> {
138143
// Add the checked term
139144
selectedItems.push(item);
140145

141-
if (this.props.selectChildrenIfParentSelected) {
146+
if (this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Select)) {
142147
this.selectAllChildren(item, selectedItems);
143148
}
144149

@@ -163,7 +168,7 @@ export class TreeView extends React.Component<ITreeViewProps, ITreeViewState> {
163168
let unselectArray: string[] = [];
164169
unselectArray.push(item.key);
165170

166-
if (this.props.selectChildrenIfParentSelected) {
171+
if (this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Unselect)) {
167172
this.unSelectChildren(item, unselectArray);
168173
}
169174

@@ -181,14 +186,30 @@ export class TreeView extends React.Component<ITreeViewProps, ITreeViewState> {
181186
}
182187
}
183188

189+
private checkIfChildrenShouldBeSelected(testMode: SelectChildrenMode) {
190+
let selectChildrenMode = SelectChildrenMode.None;
191+
if (this.props.selectChildrenMode) {
192+
selectChildrenMode = this.props.selectChildrenMode;
193+
}
194+
else {
195+
if (this.props.selectChildrenIfParentSelected) {
196+
selectChildrenMode = SelectChildrenMode.All;
197+
}
198+
}
199+
200+
if ((selectChildrenMode & testMode) === testMode) {
201+
return true;
202+
}
203+
return false;
204+
}
205+
184206
public componentDidMount() {
185207
const {
186208
items,
187-
defaultSelectedKeys,
188-
selectChildrenIfParentSelected
209+
defaultSelectedKeys
189210
} = this.props;
190211
if (defaultSelectedKeys) {
191-
const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, selectChildrenIfParentSelected);
212+
const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Mount));
192213
this.setState({
193214
activeItems: selectedItems
194215
});
@@ -198,11 +219,10 @@ export class TreeView extends React.Component<ITreeViewProps, ITreeViewState> {
198219
public componentWillReceiveProps(nextProps: ITreeViewProps): void {
199220
const {
200221
items,
201-
defaultSelectedKeys,
202-
selectChildrenIfParentSelected,
222+
defaultSelectedKeys
203223
} = nextProps;
204224
if (defaultSelectedKeys) {
205-
const selectedItems = !defaultSelectedKeys ? [] : this.getSelectedItems(items, defaultSelectedKeys, selectChildrenIfParentSelected);
225+
const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Update));
206226
this.setState({
207227
activeItems: selectedItems
208228
});

0 commit comments

Comments
 (0)