Skip to content

Commit 4380774

Browse files
joshwoodingEsoterikStare
authored andcommitted
[Treeview] Add node selection support (mui#18357)
1 parent 52a81e2 commit 4380774

19 files changed

+1500
-622
lines changed

docs/pages/api/tree-item.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Any other props supplied will be provided to the root element (native element).
4848
|:-----|:-------------|:------------|
4949
| <span class="prop-name">root</span> | <span class="prop-name">.MuiTreeItem-root</span> | Styles applied to the root element.
5050
| <span class="prop-name">expanded</span> | <span class="prop-name">.Mui-expanded</span> | Pseudo-class applied to the root element when expanded.
51+
| <span class="prop-name">selected</span> | <span class="prop-name">.Mui-selected</span> | Pseudo-class applied to the root element when selected.
5152
| <span class="prop-name">group</span> | <span class="prop-name">.MuiTreeItem-group</span> | Styles applied to the `role="group"` element.
5253
| <span class="prop-name">content</span> | <span class="prop-name">.MuiTreeItem-content</span> | Styles applied to the tree node content.
5354
| <span class="prop-name">iconContainer</span> | <span class="prop-name">.MuiTreeItem-iconContainer</span> | Styles applied to the tree node icon and collapse/expand icon.

docs/pages/api/tree-view.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
3131
| <span class="prop-name">defaultExpanded</span> | <span class="prop-type">Array&lt;string&gt;</span> | <span class="prop-default">[]</span> | Expanded node ids. (Uncontrolled) |
3232
| <span class="prop-name">defaultExpandIcon</span> | <span class="prop-type">node</span> | | The default icon used to expand the node. |
3333
| <span class="prop-name">defaultParentIcon</span> | <span class="prop-type">node</span> | | The default icon displayed next to a parent node. This is applied to all parent nodes and can be overridden by the TreeItem `icon` prop. |
34+
| <span class="prop-name">defaultSelected</span> | <span class="prop-type">Array&lt;string&gt;<br>&#124;&nbsp;string</span> | <span class="prop-default">[]</span> | Selected node ids. (Uncontrolled) When `multiSelect` is true this takes an array of strings; when false (default) a string. |
35+
| <span class="prop-name">disableSelection</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true` selection is disabled. |
3436
| <span class="prop-name">expanded</span> | <span class="prop-type">Array&lt;string&gt;</span> | | Expanded node ids. (Controlled) |
37+
| <span class="prop-name">multiSelect</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If true `ctrl` and `shift` will trigger multiselect. |
38+
| <span class="prop-name">onNodeSelect</span> | <span class="prop-type">func</span> | | Callback fired when tree items are selected/unselected.<br><br>**Signature:**<br>`function(event: object, value: undefined) => void`<br>*event:* The event source of the callback<br>*value:* of the selected nodes. When `multiSelect` is true this is an array of strings; when false (default) a string. |
3539
| <span class="prop-name">onNodeToggle</span> | <span class="prop-type">func</span> | | Callback fired when tree items are expanded/collapsed.<br><br>**Signature:**<br>`function(event: object, nodeIds: array) => void`<br>*event:* The event source of the callback.<br>*nodeIds:* The ids of the expanded nodes. |
40+
| <span class="prop-name">selected</span> | <span class="prop-type">Array&lt;string&gt;<br>&#124;&nbsp;string</span> | | Selected node ids. (Controlled) When `multiSelect` is true this takes an array of strings; when false (default) a string. |
3641

3742
The `ref` is forwarded to the root element.
3843

docs/src/pages/components/tree-view/ControlledTreeView.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ const useStyles = makeStyles({
1616
export default function ControlledTreeView() {
1717
const classes = useStyles();
1818
const [expanded, setExpanded] = React.useState([]);
19+
const [selected, setSelected] = React.useState([]);
1920

20-
const handleChange = (event, nodes) => {
21-
setExpanded(nodes);
21+
const handleToggle = (event, nodeIds) => {
22+
setExpanded(nodeIds);
23+
};
24+
25+
const handleSelect = (event, nodeIds) => {
26+
setSelected(nodeIds);
2227
};
2328

2429
return (
@@ -27,7 +32,9 @@ export default function ControlledTreeView() {
2732
defaultCollapseIcon={<ExpandMoreIcon />}
2833
defaultExpandIcon={<ChevronRightIcon />}
2934
expanded={expanded}
30-
onNodeToggle={handleChange}
35+
selected={selected}
36+
onNodeToggle={handleToggle}
37+
onNodeSelect={handleSelect}
3138
>
3239
<TreeItem nodeId="1" label="Applications">
3340
<TreeItem nodeId="2" label="Calendar" />

docs/src/pages/components/tree-view/ControlledTreeView.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ const useStyles = makeStyles({
1616
export default function ControlledTreeView() {
1717
const classes = useStyles();
1818
const [expanded, setExpanded] = React.useState<string[]>([]);
19+
const [selected, setSelected] = React.useState<string[]>([]);
1920

20-
const handleChange = (event: React.ChangeEvent<{}>, nodes: string[]) => {
21-
setExpanded(nodes);
21+
const handleToggle = (event: React.ChangeEvent<{}>, nodeIds: string[]) => {
22+
setExpanded(nodeIds);
23+
};
24+
25+
const handleSelect = (event: React.ChangeEvent<{}>, nodeIds: string[]) => {
26+
setSelected(nodeIds);
2227
};
2328

2429
return (
@@ -27,7 +32,9 @@ export default function ControlledTreeView() {
2732
defaultCollapseIcon={<ExpandMoreIcon />}
2833
defaultExpandIcon={<ChevronRightIcon />}
2934
expanded={expanded}
30-
onNodeToggle={handleChange}
35+
selected={selected}
36+
onNodeToggle={handleToggle}
37+
onNodeSelect={handleSelect}
3138
>
3239
<TreeItem nodeId="1" label="Applications">
3340
<TreeItem nodeId="2" label="Calendar" />

docs/src/pages/components/tree-view/CustomizedTreeView.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is requir
99

1010
function MinusSquare(props) {
1111
return (
12-
<SvgIcon fontSize="inherit" {...props}>
12+
<SvgIcon fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
1313
{/* tslint:disable-next-line: max-line-length */}
1414
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z" />
1515
</SvgIcon>
@@ -18,7 +18,7 @@ function MinusSquare(props) {
1818

1919
function PlusSquare(props) {
2020
return (
21-
<SvgIcon fontSize="inherit" {...props}>
21+
<SvgIcon fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
2222
{/* tslint:disable-next-line: max-line-length */}
2323
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 12.977h-4.923v4.896q0 .401-.281.682t-.682.281v0q-.375 0-.669-.281t-.294-.682v-4.896h-4.923q-.401 0-.682-.294t-.281-.669v0q0-.401.281-.682t.682-.281h4.923v-4.896q0-.401.294-.682t.669-.281v0q.401 0 .682.281t.281.682v4.896h4.923q.401 0 .682.281t.281.682v0q0 .375-.281.669t-.682.294z" />
2424
</SvgIcon>
@@ -27,7 +27,7 @@ function PlusSquare(props) {
2727

2828
function CloseSquare(props) {
2929
return (
30-
<SvgIcon className="close" fontSize="inherit" {...props}>
30+
<SvgIcon className="close" fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
3131
{/* tslint:disable-next-line: max-line-length */}
3232
<path d="M17.485 17.512q-.281.281-.682.281t-.696-.268l-4.12-4.147-4.12 4.147q-.294.268-.696.268t-.682-.281-.281-.682.294-.669l4.12-4.147-4.12-4.147q-.294-.268-.294-.669t.281-.682.682-.281.696 .268l4.12 4.147 4.12-4.147q.294-.268.696-.268t.682.281 .281.669-.294.682l-4.12 4.147 4.12 4.147q.294.268 .294.669t-.281.682zM22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0z" />
3333
</SvgIcon>
@@ -61,8 +61,8 @@ const StyledTreeItem = withStyles(theme => ({
6161
},
6262
},
6363
group: {
64-
marginLeft: 12,
65-
paddingLeft: 12,
64+
marginLeft: 7,
65+
paddingLeft: 18,
6666
borderLeft: `1px dashed ${fade(theme.palette.text.primary, 0.4)}`,
6767
},
6868
}))(props => <TreeItem {...props} TransitionComponent={TransitionComponent} />);

docs/src/pages/components/tree-view/CustomizedTreeView.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { TransitionProps } from '@material-ui/core/transitions';
99

1010
function MinusSquare(props: SvgIconProps) {
1111
return (
12-
<SvgIcon fontSize="inherit" {...props}>
12+
<SvgIcon fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
1313
{/* tslint:disable-next-line: max-line-length */}
1414
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z" />
1515
</SvgIcon>
@@ -18,7 +18,7 @@ function MinusSquare(props: SvgIconProps) {
1818

1919
function PlusSquare(props: SvgIconProps) {
2020
return (
21-
<SvgIcon fontSize="inherit" {...props}>
21+
<SvgIcon fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
2222
{/* tslint:disable-next-line: max-line-length */}
2323
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 12.977h-4.923v4.896q0 .401-.281.682t-.682.281v0q-.375 0-.669-.281t-.294-.682v-4.896h-4.923q-.401 0-.682-.294t-.281-.669v0q0-.401.281-.682t.682-.281h4.923v-4.896q0-.401.294-.682t.669-.281v0q.401 0 .682.281t.281.682v4.896h4.923q.401 0 .682.281t.281.682v0q0 .375-.281.669t-.682.294z" />
2424
</SvgIcon>
@@ -27,7 +27,7 @@ function PlusSquare(props: SvgIconProps) {
2727

2828
function CloseSquare(props: SvgIconProps) {
2929
return (
30-
<SvgIcon className="close" fontSize="inherit" {...props}>
30+
<SvgIcon className="close" fontSize="inherit" style={{ width: 14, height: 14 }} {...props}>
3131
{/* tslint:disable-next-line: max-line-length */}
3232
<path d="M17.485 17.512q-.281.281-.682.281t-.696-.268l-4.12-4.147-4.12 4.147q-.294.268-.696.268t-.682-.281-.281-.682.294-.669l4.12-4.147-4.12-4.147q-.294-.268-.294-.669t.281-.682.682-.281.696 .268l4.12 4.147 4.12-4.147q.294-.268.696-.268t.682.281 .281.669-.294.682l-4.12 4.147 4.12 4.147q.294.268 .294.669t-.281.682zM22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0z" />
3333
</SvgIcon>
@@ -55,8 +55,8 @@ const StyledTreeItem = withStyles((theme: Theme) =>
5555
},
5656
},
5757
group: {
58-
marginLeft: 12,
59-
paddingLeft: 12,
58+
marginLeft: 7,
59+
paddingLeft: 18,
6060
borderLeft: `1px dashed ${fade(theme.palette.text.primary, 0.4)}`,
6161
},
6262
}),

docs/src/pages/components/tree-view/FileSystemNavigator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import TreeItem from '@material-ui/lab/TreeItem';
77

88
const useStyles = makeStyles({
99
root: {
10-
height: 216,
10+
height: 240,
1111
flexGrow: 1,
1212
maxWidth: 400,
1313
},
@@ -28,6 +28,7 @@ export default function FileSystemNavigator() {
2828
<TreeItem nodeId="4" label="Webstorm" />
2929
</TreeItem>
3030
<TreeItem nodeId="5" label="Documents">
31+
<TreeItem nodeId="10" label="OSS" />
3132
<TreeItem nodeId="6" label="Material-UI">
3233
<TreeItem nodeId="7" label="src">
3334
<TreeItem nodeId="8" label="index.js" />

docs/src/pages/components/tree-view/FileSystemNavigator.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import TreeItem from '@material-ui/lab/TreeItem';
77

88
const useStyles = makeStyles({
99
root: {
10-
height: 216,
10+
height: 240,
1111
flexGrow: 1,
1212
maxWidth: 400,
1313
},
@@ -28,6 +28,7 @@ export default function FileSystemNavigator() {
2828
<TreeItem nodeId="4" label="Webstorm" />
2929
</TreeItem>
3030
<TreeItem nodeId="5" label="Documents">
31+
<TreeItem nodeId="10" label="OSS" />
3132
<TreeItem nodeId="6" label="Material-UI">
3233
<TreeItem nodeId="7" label="src">
3334
<TreeItem nodeId="8" label="index.js" />

docs/src/pages/components/tree-view/GmailTreeView.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ import ArrowRightIcon from '@material-ui/icons/ArrowRight';
1717
const useTreeItemStyles = makeStyles(theme => ({
1818
root: {
1919
color: theme.palette.text.secondary,
20-
'&:focus > $content': {
20+
'&:hover > $content': {
21+
backgroundColor: theme.palette.action.hover,
22+
},
23+
'&:focus > $content, &$selected > $content': {
2124
backgroundColor: `var(--tree-view-bg-color, ${theme.palette.grey[400]})`,
2225
color: 'var(--tree-view-color)',
2326
},
27+
'&:focus > $content $label, &:hover > $content $label, &$selected > $content $label': {
28+
backgroundColor: 'transparent',
29+
},
2430
},
2531
content: {
2632
color: theme.palette.text.secondary,
@@ -39,6 +45,7 @@ const useTreeItemStyles = makeStyles(theme => ({
3945
},
4046
},
4147
expanded: {},
48+
selected: {},
4249
label: {
4350
fontWeight: 'inherit',
4451
color: 'inherit',
@@ -82,6 +89,7 @@ function StyledTreeItem(props) {
8289
root: classes.root,
8390
content: classes.content,
8491
expanded: classes.expanded,
92+
selected: classes.selected,
8593
group: classes.group,
8694
label: classes.label,
8795
}}

docs/src/pages/components/tree-view/GmailTreeView.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,16 @@ const useTreeItemStyles = makeStyles((theme: Theme) =>
3333
createStyles({
3434
root: {
3535
color: theme.palette.text.secondary,
36-
'&:focus > $content': {
36+
'&:hover > $content': {
37+
backgroundColor: theme.palette.action.hover,
38+
},
39+
'&:focus > $content, &$selected > $content': {
3740
backgroundColor: `var(--tree-view-bg-color, ${theme.palette.grey[400]})`,
3841
color: 'var(--tree-view-color)',
3942
},
43+
'&:focus > $content $label, &:hover > $content $label, &$selected > $content $label': {
44+
backgroundColor: 'transparent',
45+
},
4046
},
4147
content: {
4248
color: theme.palette.text.secondary,
@@ -55,6 +61,7 @@ const useTreeItemStyles = makeStyles((theme: Theme) =>
5561
},
5662
},
5763
expanded: {},
64+
selected: {},
5865
label: {
5966
fontWeight: 'inherit',
6067
color: 'inherit',
@@ -99,6 +106,7 @@ function StyledTreeItem(props: StyledTreeItemProps) {
99106
root: classes.root,
100107
content: classes.content,
101108
expanded: classes.expanded,
109+
selected: classes.selected,
102110
group: classes.group,
103111
label: classes.label,
104112
}}

0 commit comments

Comments
 (0)