Skip to content

Commit

Permalink
[TreeView] Add public API and expose focus method (mui#12143)
Browse files Browse the repository at this point in the history
Signed-off-by: Nora <72460825+noraleonte@users.noreply.github.com>
Co-authored-by: Flavien DELANGLE <flaviendelangle@gmail.com>
  • Loading branch information
2 people authored and thomasmoon committed Sep 6, 2024
1 parent fdfc2b6 commit 337f1e5
Show file tree
Hide file tree
Showing 37 changed files with 543 additions and 35 deletions.
2 changes: 2 additions & 0 deletions docs/data/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ const pages: MuiPage[] = [
{ pathname: '/x/react-tree-view/simple-tree-view/selection' },
{ pathname: '/x/react-tree-view/simple-tree-view/expansion' },
{ pathname: '/x/react-tree-view/simple-tree-view/customization' },
{ pathname: '/x/react-tree-view/simple-tree-view/focus' },
],
},
{
Expand All @@ -500,6 +501,7 @@ const pages: MuiPage[] = [
{ pathname: '/x/react-tree-view/rich-tree-view/items' },
{ pathname: '/x/react-tree-view/rich-tree-view/selection' },
{ pathname: '/x/react-tree-view/rich-tree-view/expansion' },
{ pathname: '/x/react-tree-view/rich-tree-view/focus' },
],
},
{
Expand Down
54 changes: 54 additions & 0 deletions docs/data/tree-view/rich-tree-view/focus/FocusedRichTreeView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';

import { useTreeViewApiRef } from '@mui/x-tree-view/hooks/useTreeViewApiRef';

const MUI_X_PRODUCTS = [
{
id: 'grid',
label: 'Data Grid',
children: [
{ id: 'grid-community', label: '@mui/x-data-grid' },
{ id: 'grid-pro', label: '@mui/x-data-grid-pro' },
{ id: 'grid-premium', label: '@mui/x-data-grid-premium' },
],
},
{
id: 'pickers',
label: 'Date and Time Pickers',
children: [
{ id: 'pickers-community', label: '@mui/x-date-pickers' },
{ id: 'pickers-pro', label: '@mui/x-date-pickers-pro' },
],
},
{
id: 'charts',
label: 'Charts',
children: [{ id: 'charts-community', label: '@mui/x-charts' }],
},
{
id: 'tree-view',
label: 'Tree View',
children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }],
},
];

export default function FocusedRichTreeView() {
const apiRef = useTreeViewApiRef();
const handleButtonClick = (event) => {
apiRef.current?.focusNode(event, 'pickers');
};

return (
<Box sx={{ flexGrow: 1, maxWidth: 400 }}>
<Box sx={{ mb: 1 }}>
<Button onClick={handleButtonClick}>Focus pickers node</Button>
</Box>
<Box sx={{ height: 264, flexGrow: 1 }}>
<RichTreeView items={MUI_X_PRODUCTS} apiRef={apiRef} />
</Box>
</Box>
);
}
54 changes: 54 additions & 0 deletions docs/data/tree-view/rich-tree-view/focus/FocusedRichTreeView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
import { TreeViewBaseItem } from '@mui/x-tree-view/models';
import { useTreeViewApiRef } from '@mui/x-tree-view/hooks/useTreeViewApiRef';

const MUI_X_PRODUCTS: TreeViewBaseItem[] = [
{
id: 'grid',
label: 'Data Grid',
children: [
{ id: 'grid-community', label: '@mui/x-data-grid' },
{ id: 'grid-pro', label: '@mui/x-data-grid-pro' },
{ id: 'grid-premium', label: '@mui/x-data-grid-premium' },
],
},
{
id: 'pickers',
label: 'Date and Time Pickers',
children: [
{ id: 'pickers-community', label: '@mui/x-date-pickers' },
{ id: 'pickers-pro', label: '@mui/x-date-pickers-pro' },
],
},
{
id: 'charts',
label: 'Charts',
children: [{ id: 'charts-community', label: '@mui/x-charts' }],
},
{
id: 'tree-view',
label: 'Tree View',
children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }],
},
];

export default function FocusedRichTreeView() {
const apiRef = useTreeViewApiRef();
const handleButtonClick = (event: React.SyntheticEvent) => {
apiRef.current?.focusNode(event, 'pickers');
};

return (
<Box sx={{ flexGrow: 1, maxWidth: 400 }}>
<Box sx={{ mb: 1 }}>
<Button onClick={handleButtonClick}>Focus pickers node</Button>
</Box>
<Box sx={{ height: 264, flexGrow: 1 }}>
<RichTreeView items={MUI_X_PRODUCTS} apiRef={apiRef} />
</Box>
</Box>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Box sx={{ mb: 1 }}>
<Button onClick={handleButtonClick}>Focus pickers node</Button>
</Box>
<Box sx={{ height: 264, flexGrow: 1 }}>
<RichTreeView items={MUI_X_PRODUCTS} apiRef={apiRef} />
</Box>
36 changes: 36 additions & 0 deletions docs/data/tree-view/rich-tree-view/focus/focus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
productId: x-tree-view
title: Rich Tree View - Focus
components: RichTreeView, TreeItem
packageName: '@mui/x-tree-view'
githubLabel: 'component: tree view'
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
---

# Rich Tree View - Focus

<p class="description">Learn how to focus Tree View items.</p>

## Focus a specific node

You can use the the `apiRef.focusNode` method to focus a specific node.
This methods receives two parameters: `event` and `nodeId`.

:::success
To use the `apiRef` object, you need to initialize it using the `useTreeViewApiRef` hook as follows:

```tsx
const apiRef = useTreeViewApiRef();

return <RichTreeView apiRef={apiRef} items={ITEMS}>;
```

`apiRef` will be undefined during the first render and will then contain methods allowing you to imperatively interact with the Tree View.
:::

:::info
This method only works with nodes that are currently visible.
Calling `apiRef.focusNode` on a node whose parent is collapsed will do nothing.
:::

{{"demo": "FocusedRichTreeView.js"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
import { TreeItem } from '@mui/x-tree-view/TreeItem';
import { useTreeViewApiRef } from '@mui/x-tree-view/hooks/useTreeViewApiRef';

export default function FocusedSimpleTreeView() {
const apiRef = useTreeViewApiRef();
const handleButtonClick = (event) => {
apiRef.current?.focusNode(event, 'pickers');
};

return (
<Box sx={{ flexGrow: 1, maxWidth: 400 }}>
<Box sx={{ mb: 1 }}>
<Button onClick={handleButtonClick}>Focus pickers node</Button>
</Box>
<Box sx={{ minHeight: 264, flexGrow: 1 }}>
<SimpleTreeView apiRef={apiRef}>
<TreeItem nodeId="grid" label="Data Grid">
<TreeItem nodeId="grid-community" label="@mui/x-data-grid" />
<TreeItem nodeId="grid-pro" label="@mui/x-data-grid-pro" />
<TreeItem nodeId="grid-premium" label="@mui/x-data-grid-premium" />
</TreeItem>
<TreeItem nodeId="pickers" label="Date and Time Pickers">
<TreeItem nodeId="pickers-community" label="@mui/x-date-pickers" />
<TreeItem nodeId="pickers-pro" label="@mui/x-date-pickers-pro" />
</TreeItem>
<TreeItem nodeId="charts" label="Charts">
<TreeItem nodeId="charts-community" label="@mui/x-charts" />
</TreeItem>
<TreeItem nodeId="tree-view" label="Tree View">
<TreeItem nodeId="tree-view-community" label="@mui/x-tree-view" />
</TreeItem>
</SimpleTreeView>
</Box>
</Box>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
import { TreeItem } from '@mui/x-tree-view/TreeItem';
import { useTreeViewApiRef } from '@mui/x-tree-view/hooks/useTreeViewApiRef';

export default function FocusedSimpleTreeView() {
const apiRef = useTreeViewApiRef();
const handleButtonClick = (event: React.SyntheticEvent) => {
apiRef.current?.focusNode(event, 'pickers');
};

return (
<Box sx={{ flexGrow: 1, maxWidth: 400 }}>
<Box sx={{ mb: 1 }}>
<Button onClick={handleButtonClick}>Focus pickers node</Button>
</Box>
<Box sx={{ minHeight: 264, flexGrow: 1 }}>
<SimpleTreeView apiRef={apiRef}>
<TreeItem nodeId="grid" label="Data Grid">
<TreeItem nodeId="grid-community" label="@mui/x-data-grid" />
<TreeItem nodeId="grid-pro" label="@mui/x-data-grid-pro" />
<TreeItem nodeId="grid-premium" label="@mui/x-data-grid-premium" />
</TreeItem>
<TreeItem nodeId="pickers" label="Date and Time Pickers">
<TreeItem nodeId="pickers-community" label="@mui/x-date-pickers" />
<TreeItem nodeId="pickers-pro" label="@mui/x-date-pickers-pro" />
</TreeItem>
<TreeItem nodeId="charts" label="Charts">
<TreeItem nodeId="charts-community" label="@mui/x-charts" />
</TreeItem>
<TreeItem nodeId="tree-view" label="Tree View">
<TreeItem nodeId="tree-view-community" label="@mui/x-tree-view" />
</TreeItem>
</SimpleTreeView>
</Box>
</Box>
);
}
36 changes: 36 additions & 0 deletions docs/data/tree-view/simple-tree-view/focus/focus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
productId: x-tree-view
title: Simple Tree View - Focus
components: SimpleTreeView, TreeItem
packageName: '@mui/x-tree-view'
githubLabel: 'component: tree view'
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
---

# Simple Tree View - Focus

<p class="description">Learn how to focus Tree View items.</p>

## Focus a specific node

You can use the the `apiRef.focusNode` method to focus a specific node.
This methods receives two parameters: `event` and `nodeId`.

:::success
To use the `apiRef` object, you need to initialize it using the `useTreeViewApiRef` hook as follows:

```tsx
const apiRef = useTreeViewApiRef();

return <SimpleTreeView apiRef={apiRef}>{children}</SimpleTreeView>;
```

`apiRef` will be undefined during the first render and will then contain methods allowing you to imperatively interact with the Tree View.
:::

:::info
This method only works with nodes that are currently visible.
Calling `apiRef.focusNode` on a node whose parent is collapsed will do nothing.
:::

{{"demo": "FocusedSimpleTreeView.js"}}
3 changes: 2 additions & 1 deletion docs/pages/x/api/tree-view/rich-tree-view.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"props": {
"apiRef": { "type": { "name": "shape", "description": "{ current?: { focusNode: func } }" } },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"defaultExpandedNodes": {
"type": { "name": "arrayOf", "description": "Array&lt;string&gt;" },
Expand Down Expand Up @@ -128,6 +129,6 @@
"forwardsRefTo": "HTMLUListElement",
"filename": "/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/expansion/\">Rich Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/items/\">Rich Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/selection/\">Rich Tree View - Selection</a></li></ul>",
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/expansion/\">Rich Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/focus/\">Rich Tree View - Focus</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/items/\">Rich Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/selection/\">Rich Tree View - Selection</a></li></ul>",
"cssComponent": false
}
3 changes: 2 additions & 1 deletion docs/pages/x/api/tree-view/simple-tree-view.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"props": {
"apiRef": { "type": { "name": "shape", "description": "{ current?: { focusNode: func } }" } },
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"defaultExpandedNodes": {
Expand Down Expand Up @@ -93,6 +94,6 @@
"forwardsRefTo": "HTMLUListElement",
"filename": "/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/customization/\">Simple Tree View - Customization</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/expansion/\">Simple Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/items/\">Simple Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/selection/\">Simple Tree View - Selection</a></li></ul>",
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/customization/\">Simple Tree View - Customization</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/expansion/\">Simple Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/focus/\">Simple Tree View - Focus</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/items/\">Simple Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/selection/\">Simple Tree View - Selection</a></li></ul>",
"cssComponent": false
}
2 changes: 1 addition & 1 deletion docs/pages/x/api/tree-view/tree-item.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@
"forwardsRefTo": "HTMLLIElement",
"filename": "/packages/x-tree-view/src/TreeItem/TreeItem.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/expansion/\">Rich Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/items/\">Rich Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/selection/\">Rich Tree View - Selection</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/customization/\">Simple Tree View - Customization</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/expansion/\">Simple Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/items/\">Simple Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/selection/\">Simple Tree View - Selection</a></li></ul>",
"demos": "<ul><li><a href=\"/x/react-tree-view/getting-started/\">Tree View - Getting Started</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/expansion/\">Rich Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/focus/\">Rich Tree View - Focus</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/items/\">Rich Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/rich-tree-view/selection/\">Rich Tree View - Selection</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/customization/\">Simple Tree View - Customization</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/expansion/\">Simple Tree View - Expansion</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/focus/\">Simple Tree View - Focus</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/items/\">Simple Tree View - Items</a></li>\n<li><a href=\"/x/react-tree-view/simple-tree-view/selection/\">Simple Tree View - Selection</a></li></ul>",
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/pages/x/api/tree-view/tree-view.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"props": {
"apiRef": { "type": { "name": "shape", "description": "{ current?: { focusNode: func } }" } },
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"defaultExpandedNodes": {
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/react-tree-view/rich-tree-view/focus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import * as pageProps from 'docsx/data/tree-view/rich-tree-view/focus/focus.md?@mui/markdown';

export default function Page() {
return <MarkdownDocs {...pageProps} />;
}
7 changes: 7 additions & 0 deletions docs/pages/x/react-tree-view/simple-tree-view/focus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import * as pageProps from 'docsx/data/tree-view/simple-tree-view/focus/focus.md?@mui/markdown';

export default function Page() {
return <MarkdownDocs {...pageProps} />;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"componentDescription": "",
"propDescriptions": {
"apiRef": {
"description": "The ref object that allows Tree View manipulation. Can be instantiated with <code>useTreeViewApiRef()</code>."
},
"classes": { "description": "Override or extend the styles applied to the component." },
"defaultExpandedNodes": {
"description": "Expanded node ids. Used when the item&#39;s expansion is not controlled."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"componentDescription": "",
"propDescriptions": {
"apiRef": {
"description": "The ref object that allows Tree View manipulation. Can be instantiated with <code>useTreeViewApiRef()</code>."
},
"children": { "description": "The content of the component." },
"classes": { "description": "Override or extend the styles applied to the component." },
"defaultExpandedNodes": {
Expand Down
3 changes: 3 additions & 0 deletions docs/translations/api-docs/tree-view/tree-view/tree-view.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"componentDescription": "This component has been deprecated in favor of the new `SimpleTreeView` component.\nYou can have a look at how to migrate to the new component in the v7 [migration guide](https://next.mui.com/x/migration/migration-tree-view-v6/#use-simpletreeview-instead-of-treeview)",
"propDescriptions": {
"apiRef": {
"description": "The ref object that allows Tree View manipulation. Can be instantiated with <code>useTreeViewApiRef()</code>."
},
"children": { "description": "The content of the component." },
"classes": { "description": "Override or extend the styles applied to the component." },
"defaultExpandedNodes": {
Expand Down
8 changes: 8 additions & 0 deletions packages/x-tree-view/src/RichTreeView/RichTreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ RichTreeView.propTypes = {
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
*/
apiRef: PropTypes.shape({
current: PropTypes.shape({
focusNode: PropTypes.func.isRequired,
}),
}),
/**
* Override or extend the styles applied to the component.
*/
Expand Down
Loading

0 comments on commit 337f1e5

Please sign in to comment.