Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TreeView] Add public API and expose focus method #12143

Merged
merged 23 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/data/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,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 @@ -495,6 +496,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`.
noraleonte marked this conversation as resolved.
Show resolved Hide resolved

:::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"}}
noraleonte marked this conversation as resolved.
Show resolved Hide resolved
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({
noraleonte marked this conversation as resolved.
Show resolved Hide resolved
current: PropTypes.shape({
focusNode: PropTypes.func.isRequired,
}),
}),
/**
* Override or extend the styles applied to the component.
*/
Expand Down
Loading
Loading