diff --git a/docs/MultiLevelMenu.md b/docs/MultiLevelMenu.md new file mode 100644 index 00000000000..50668d08d36 --- /dev/null +++ b/docs/MultiLevelMenu.md @@ -0,0 +1,202 @@ +--- +layout: default +title: "The MultiLevelMenu Component" +--- + +# `` + +This [Enterprise Edition](https://marmelab.com/ra-enterprise) component adds support for nested sub menus in the left navigation bar. + +![multilevel menu](https://marmelab.com/ra-enterprise/modules/assets/ra-multilevelmenu-item.gif) + +When a React-admin application grows significantly, [the default `` component](./Menu.md) might not be the best solution. The `` can help unclutter the navigation: it renders a menu with an infinite number of levels and sub menus. Menu Items that are not at the top level are rendered inside a collapsible panel. + +Test it live on [the Enterprise Edition Storybook](https://storybook.ra-enterprise.marmelab.com/?path=/story/ra-navigation-multilevelmenu--with-icons). + +## Usage + +Create a custom Menu component using `` as root instead of ``. Menu entries should be `` components. They are very similar to the default `` from react-admin, except that they accept other `` as their children. + +For instance, here is how to create a menu with sub menus for each artist genre. The menu target is actually the same page - the artists list - but with a different filter: + +```jsx +import { MultiLevelMenu } from '@react-admin/ra-navigation'; + +import DashboardIcon from '@mui/icons-material/Dashboard'; +import MusicIcon from '@mui/icons-material/MusicNote'; +import PeopleIcon from '@mui/icons-material/People'; + +const MyMenu = () => ( + + } /> + } /> + {/* The empty filter is required to avoid falling back to the previously set filter */} + }> + + + + + + + + + +); +``` + +Note that each `` requires a unique `name` attribute. + +Then, create a custom layout using [the `` component](./Layout.md) and pass your custom menu component to it. Make sure you wrap the layout with the `` component. + +```jsx +// in src/MyLayout.js +import { Layout } from 'react-admin'; +import { AppLocationContext } from '@react-admin/ra-navigation'; + +import { MyMenu } from './MyMenu'; + +export const MyLayout = (props) => ( + + + +); +``` + +`` is necessary because `ra-navigation` doesn't use the URL to detect the current location. Instead, page components *declare* their location using a custom hook (`useDefineAppLocation()`). This allows complex site maps, with multiple levels of nesting. That's the reason why each `` requires a unique `name`, that matches a particular page location. Check [the ra-navigation documentation](https://marmelab.com/ra-enterprise/modules/ra-navigation) to learn more about App Location. + +Finally, pass this custom layout to the `` component + +```jsx +// in src/App.js +import { Admin, Resource } from "react-admin"; + +import { MyLayout } from './MyLayout'; + +const App = () => ( + + // ... + +); +``` + +## Props + +| Prop | Required | Type | Default | Description | +| ------------- | -------- | ----------- | -------- | -------------------------------------- | +| `children` | Optional | `ReactNode` | - | The Menu Items to be rendered. | +| `initialOpen` | Optional | `boolean` | `false` | Whether the menu is initially open. | +| `sx` | Optional | `SxProps` | - | Style overrides, powered by MUI System | + +Additional props are passed down to the root `
` component. + +## `children` + +Pass `` children to `` to define the main menu entries. + +```jsx +// in src/MyMenu.js +import { MultiLevelMenu } from "@react-admin/ra-navigation"; + +import DashboardIcon from '@mui/icons-material/Dashboard'; +import MusicIcon from '@mui/icons-material/MusicNote'; +import PeopleIcon from '@mui/icons-material/People'; + +const MyMenu = () => ( + + } /> + } /> + } /> + +); +``` + +Check [the `` section](#MultiLevelMenuitem) for more information. + +## `initialOpen` + +All the items of a `` can be opened initially by setting `initialOpen` to `true`. + +```jsx +export const MyMenu = () => ( + + // ... + +); +``` + +## `sx`: CSS API + +Pass an `sx` prop to customize the style of the main component and the underlying elements. + +{% raw %} +```jsx +export const MyMenu = () => ( + + // ... + +); +``` +{% endraw %} + +To override the style of `` using the [MUI style overrides](https://mui.com/customization/theme-components/), use the `RaMenuRoot` key. + +## `` + +The `` component displays a menu item with a label and an icon. + +```jsx +} +/> +``` + +It requires the following props: + +- `name`: the name of the location to match. This is used to highlight the current location. +- `to`: the location to link to. +- `label`: The menu item label. + +It accepts optional props: + +- `icon`: the icon to display. +- `children`: Other `` children. +- `sx`: Style overrides, powered by MUI System + +Additional props are passed down to [the underling MUI `` component](https://mui.com/api/list-item/#listitem-api). + +## Creating Menu Items For Resources + +If you want to render a custom menu item and the default resource menu items, use the `useResourceDefinitions` hook to retrieve the list of resources and create one menu item per resource. + +```jsx +// in src/MyMenu.js +import { createElement } from 'react'; +import { useResourceDefinitions } from 'react-admin'; +import { MultiLevelMenu } from "@react-admin/ra-navigation"; +import LabelIcon from '@mui/icons-material/Label'; + +export const MyMenu = () => { + const resources = useResourceDefinitions(); + + return ( + + {Object.keys(resources).map(name => ( + + ))} + } /> + + ); +}; +``` diff --git a/docs/navigation.html b/docs/navigation.html index dcde93024e0..69d3972b451 100644 --- a/docs/navigation.html +++ b/docs/navigation.html @@ -198,6 +198,7 @@