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

[Doc] Update docs for <Breadcrumb> #9640

Merged
merged 3 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
100 changes: 78 additions & 22 deletions docs/Breadcrumb.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "The Breadcrumb Component"

# `<Breadcrumb>`

This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" src="./img/premium.svg" /> component renders a breadcrumb path that automatically adapts to the page location. It helps users navigate large web applications.
This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" src="./img/premium.svg" /> component renders a breadcrumb path that automatically adapts to the page location. It helps users navigate large web applications.

<video controls autoplay playsinline muted loop width="100%">
<source src="https://marmelab.com/ra-enterprise/modules/assets/ra-navigation/latest/breadcumb-nested-resource.webm" type="video/webm" />
Expand Down Expand Up @@ -38,10 +38,12 @@ export const MyLayout = ({ children, ...rest }) => (
);
```

**Tip**: The layout must be wrapped with `<AppLocationContext>`, as `<Breadcrumb>` reads the app location from this context and not the URL. Layout components from `ra-navigation` ([`<ContainerLayout>`](./ContainerLayout.md) or `<SolarLayout>`) already include that context, so it's not necessary to include it in the custom layout.

**Tip**: The layout must be wrapped with `<AppLocationContext>`, as `<Breadcrumb>` reads the app location from this context and not the URL. Layout components from `ra-navigation` ([`<ContainerLayout>`](./ContainerLayout.md) or `<SolarLayout>`) already include that context, so it's not necessary to include it in the custom layout.

**Tip:** The `ra-enterprise` package exports an alternative `<Layout>`, which contains a pre-configured `<Breadcrumb>` that renders breadcrumb paths for all resources.

Next, set this custom layout as the [`<Admin layout>`](./Admin.md#layout) component:

```jsx
import { Admin } from 'react-admin';
import { DataProvider } from './dataProvider';
Expand Down Expand Up @@ -105,10 +107,10 @@ export const MyLayout = ({ children, ...rest }) => (

With this setup, the breadcrumb on the post pages now renders as:

- "Dashboard / Posts" on the Post List page
- "Dashboard / Posts / Lorem ipsum" on the Post Edition page with id = 1
- "Dashboard / Posts / Lorem ipsum" on the Post Show page with id = 1
- "Dashboard / Posts / Create" on the Post Creation page
- "🏠️ / Posts" on the Post List page
- "🏠️ / Posts / Lorem ipsum" on the Post Edition page with id = 1
- "🏠️ / Posts / Lorem ipsum" on the Post Show page with id = 1
- "🏠️ / Posts / Create" on the Post Creation page

You can customize the breadcrumb path of each page, as well as add custom pages to the breadcrumb, by adding `children` to the `<Breadcrumb>` component. See [the `children` section](#children) below for more information.

Expand All @@ -125,15 +127,23 @@ You don't need to define the app location for CRUD pages as react-admin does it
- Edit: `[resource].edit`. The location also contains the current `record`
- Show: `[resource].show`. The location also contains the current `record`

However, you can customize these default app locations in your CRUD pages, and you must [define the location for custom pages](#adding-custom-pages).
However, you can customize these default app locations in your CRUD pages, and you must [define the location for custom pages](#adding-custom-pages).

To leverage the provided components such as the [`<Breadcrumb>`](#breadcrumb) or [`<MultiLevelMenu>`](./MultiLevelMenu), the layout must be wrapped with `<AppLocationContext>`.

Layout components from `ra-navigation` ([`<ContainerLayout>`](./ContainerLayout) or [`<SolarLayout>`](./SolarLayout)) already include that context, so you can skip that step if you are using one of these layouts.

If, however, you are using the default `<Layout>` component from `react-admin`, or a custom layout, you must wrap it with `<AppLocationContext>`:

## Props

| Prop | Required | Type | Default | Description |
| ----------- | -------- | ------------------- | -------- | -------------------------------------- |
| `children` | Optional | `ReactNode` | - | The Breadcrumb Items to be rendered. |
| `separator` | Optional | `string | function` | ' / ' | The character user as separator |
| `sx` | Optional | `SxProps` | - | Style overrides, powered by MUI System |
| Prop | Required | Type | Default | Description |
| -------------- | -------- | ------------------ | ------- | ------------------------------------------------------------------------------------ |
| `children` | Optional | `ReactNode` | - | The Breadcrumb Items to be rendered. |
| `dashboard` | Optional | `ReactNode` | - | The dashboard component, used to determine if the Admin has a dashboard. |
| `hasDashboard` | Optional | boolean | - | Alternative to `dashboard`. Set to `true` to add a dashboard item to the breadcrumb. |
| `separator` | Optional | string or function | ' / ' | The character user as separator |
| `sx` | Optional | `SxProps` | - | Style overrides, powered by MUI System |

Additional props are passed down to the root `<nav>` component.

Expand Down Expand Up @@ -451,7 +461,51 @@ const MyBreadcrumb = () => (
);
```

Check the [`<Breadcrumb.ResourceItem>`](#breadcrumbresourceitem) section for more information.
Check the [`<Breadcrumb.ResourceItem>`](#breadcrumbresourceitem) section for more information.

## `<Breadcrumb.DashboardItem>`

A version of the `<Breadcrumb.Item>` dedicated to the dashboard.

It is convenient for customizing the dashboard item label.

```tsx
const MyBreadcrumbCustomHome = () => (
<Breadcrumb hasDashboard>
<Breadcrumb.DashboardItem label="My Home">
<Breadcrumb.ResourceItem resource="posts" />
<Breadcrumb.ResourceItem resource="comments" />
</Breadcrumb.DashboardItem>
</Breadcrumb>
);
```

Just like with `<Breadcrumb.Item>`, you can also use a React component as label:

```tsx
import { Breadcrumb } from '@react-admin/ra-navigation';
import { Box, Stack } from '@mui/material';
import { visuallyHidden } from '@mui/utils';
import CabinIcon from '@mui/icons-material/Cabin';

const MyBreadcrumbCustomHome = () => (
<Breadcrumb hasDashboard>
<Breadcrumb.DashboardItem
label={
<Stack direction="row" alignItems="center" spacing={1}>
<CabinIcon />
<Box sx={visuallyHidden}>Dashboard</Box>
</Stack>
}
>
<Breadcrumb.ResourceItem resource="posts" />
<Breadcrumb.ResourceItem resource="comments" />
</Breadcrumb.DashboardItem>
</Breadcrumb>
);
```

**Tip:** It's a good practice to include a visually hidden placeholder ('Dashboard' in this example) for screen readers when using an icon as label.

## Using A Dashboard As The Root

Expand All @@ -474,12 +528,14 @@ export const MyLayout = ({ children, ...rest }) => (

By doing this, the breadcrumb will now show respectively:

- "Dashboard / Posts" on the Post List page
- "Dashboard / Posts / Show #1" on the Post Show page with id = 1
- "Dashboard / Posts / Edit #1" on the Post Edition page with id = 1
- "Dashboard / Posts / Create" on the Post Creation page
- "🏠️ / Posts" on the Post List page
- "🏠️ / Posts / Show #1" on the Post Show page with id = 1
- "🏠️ / Posts / Edit #1" on the Post Edition page with id = 1
- "🏠️ / Posts / Create" on the Post Creation page

**Tip:** Even though it is rendered as a 'home' icon (🏠️), the dashboard breadcrumb item also contains the hidden placeholder text 'Dashboard', for screen readers. If you want to customize this text, e.g. to rename "Dashboard" to "Home", provide a [custom translation](https://marmelab.com/react-admin/Translation.html) for the `ra.page.dashboard` message.

If you want to customize the dashboard breadcrumb item label, e.g. to rename "Dashboard" to "Home", provide a [custom translation](./Translation.md) for the `ra.page.dashboard` message.
If you want to customize the dashboard breadcrumb item label, e.g. to rename "Dashboard" to "Home", provide a [custom translation](./Translation.md) for the `ra.page.dashboard` message.

## Adding Custom Pages

Expand Down Expand Up @@ -604,7 +660,7 @@ const App = () => (

## Nested Resources

When using [nested resources](./Resource.md#nested-resources), you should create breadcrumb items for the sub-resources.
When using [nested resources](./Resource.md#nested-resources), you should create breadcrumb items for the sub-resources.

For instance, the screencast at the top of this page shows a `songs` resource nested in an `artists` resource, using the following routes:

Expand Down Expand Up @@ -838,4 +894,4 @@ const MyBreadcrumb = () => (
);
```

As you see, you can compose Breadcrumb item elements at will.
As you see, you can compose Breadcrumb item elements at will.
37 changes: 32 additions & 5 deletions docs/IconMenu.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" s
Your browser does not support the video tag.
</video>

Sometimes, even menus with sub-menus are not enough to organize the navigation. `ra-navigation` offers an alternative UI for that case: a vertical bar with small items, where the menu label renders underneath the icon. Clicking on any of those items opens a panel containing as many navigation links as you like, laid out as you wish.

Test it live on [the Enterprise Edition Storybook](https://storybook.ra-enterprise.marmelab.com/?path=/story/ra-navigation-iconmenu--basic).

## Usage


Create a custom menu component using the `<IconMenu>` and `<IconMenu.Item>` components from the `ra-navigation` package:

```jsx
Expand All @@ -28,15 +31,16 @@ import MusicIcon from '@mui/icons-material/MusicNote';
import PeopleIcon from '@mui/icons-material/People';

const MyMenu = () => (
<IconMenu>
<IconMenu variant="categories">
<IconMenu.Item name="dashboard" to="/" label="Dashboard" icon={<DashboardIcon />} />
<IconMenu.Item name="songs" to="/songs" label="Songs" icon={<MusicIcon />} />
{/* The empty filter is required to avoid falling back to the previously set filter */}
<IconMenu.Item name="artists" to="/artists" label="Artists" icon={<PeopleIcon />} />
</IconMenu>
);
```

Then, create a custom layout using [the `<Layout>` component](./Layout.md) and pass your custom menu component to it. Make sure you wrap the layout with the `<AppLocationContext>` component.
Then, create a custom layout using [the `<Layout>` component](./Layout.md) and pass your custom menu component to it. Make sure you wrap the layout with the `<AppLocationContext>` component.

```jsx
// in src/MyLayout.js
Expand All @@ -52,7 +56,7 @@ export const MyLayout = (props) => (
);
```

`<AppLocationContext>` 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. Check [the ra-navigation documentation](https://marmelab.com/ra-enterprise/modules/ra-navigation) to learn more about App Location.
`<AppLocationContext>` 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. 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 `<Admin>` component. You should apply the theme provided by ra-navigation:

Expand All @@ -74,6 +78,29 @@ const App = () => (
);
```

In order to adjust the size of the React-Admin `<Sidebar>` component according to the categories, you should either apply the `theme` provided by the `@react-admin/ra-navigation` package (as above), or merge it in your own custom theme.

```tsx
import merge from 'lodash/merge';
import { defaultTheme } from 'react-admin';
import { ThemeOptions } from '@react-admin/ra-navigation';
export const theme: ThemeOptions = merge({}, defaultTheme, {
djhi marked this conversation as resolved.
Show resolved Hide resolved
sidebar: {
width: 96,
closedWidth: 48,
},
overrides: {
RaSidebar: {
fixed: {
zIndex: 1200,
},
},
},
});
```

**Tip**: With `<IconMenu />`, labels may disappear when the sidebar is in reduced mode. This is because of the internal workings of react-admin. That's why we recommend implementing your own `<AppBar />`, and hiding the Hamburger Button. `<IconMenu />` is thin enough not to interfere with the navigation anyway.

## Props

| Prop | Required | Type | Default | Description |
Expand Down Expand Up @@ -127,7 +154,7 @@ To override the style of `<IconMenu>` using the [application-wide style override
The `<IconMenu.Item>` component displays a menu item with a label and an icon.

```jsx
<IconMenu.Item
<IconMenu.Item
name="dashboard"
to="/"
label="Dashboard"
Expand Down Expand Up @@ -212,7 +239,7 @@ import LabelIcon from '@mui/icons-material/Label';

export const MyMenu = () => {
const resources = useResourceDefinitions();

return (
<IconMenu>
{Object.keys(resources).map(name => (
Expand Down
27 changes: 16 additions & 11 deletions docs/MultiLevelMenu.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ title: "The MultiLevelMenu Component"

# `<MultiLevelMenu>`

This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" src="./img/premium.svg" /> component adds support for nested sub menus in the left navigation bar.
This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" src="./img/premium.svg" /> component adds support for nested sub menus in the left navigation bar.

![MultiLevelMenu](./img/multilevelmenu.png)

When a React-admin application grows significantly, the default menu might not be the best solution. The `<MultiLevelMenu>` 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.

<video controls autoplay playsinline muted loop>
<source src="https://marmelab.com/ra-enterprise/modules/assets/ra-multilevelmenu-item.webm" type="video/webm" />
Expand Down Expand Up @@ -50,7 +54,7 @@ const MyMenu = () => (

Note that each `<MultiLevelMenu.Item>` requires a unique `name` attribute.

Then, create a custom layout using [the `<Layout>` component](./Layout.md) and pass your custom menu component to it. Make sure you wrap the layout with the `<AppLocationContext>` component.
Then, create a custom layout using [the `<Layout>` component](./Layout.md) and pass your custom menu component to it. Make sure you wrap the layout with the `<AppLocationContext>` component.

```jsx
// in src/MyLayout.js
Expand All @@ -66,7 +70,7 @@ export const MyLayout = (props) => (
);
```

`<AppLocationContext>` 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 `<MultiLevelMenu.Item>` requires a unique `name`, that matches a particular page location.
`<AppLocationContext>` 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 `<MultiLevelMenu.Item>` requires a unique `name`, that matches a particular page location.

You can set the `AppLocation` for a given page like so:

Expand All @@ -89,7 +93,7 @@ And then use this `AppLocation` as `name` for `<MultiLevelMenu.Item>`:
>
```

Check [the ra-navigation documentation](https://marmelab.com/ra-enterprise/modules/ra-navigation) to learn more about App 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 `<Admin>` component

Expand All @@ -111,11 +115,12 @@ 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 |
| Prop | Required | Type | Default | Description |
| -------------- | -------- | ----------- | -------- | ------------------------------------------------------------- |
| `children` | Optional | `ReactNode` | - | The Menu Items to be rendered. |
| `initialOpen` | Optional | `boolean` | `false` | Whether the menu is initially open. |
| `openItemList` | Optional | `Array` | - | List of names of menu items that should be opened by default. |
| `sx` | Optional | `SxProps` | - | Style overrides, powered by MUI System |

Additional props are passed down to the root `<div>` component.

Expand Down Expand Up @@ -175,7 +180,7 @@ To override the style of `<MultiLevelMenu>` using the [application-wide style ov
The `<MultiLevelMenu.Item>` component displays a menu item with a label and an icon.

```jsx
<MultiLevelMenu.Item
<MultiLevelMenu.Item
name="dashboard"
to="/"
label="Dashboard"
Expand Down Expand Up @@ -210,7 +215,7 @@ import LabelIcon from '@mui/icons-material/Label';

export const MyMenu = () => {
const resources = useResourceDefinitions();

return (
<MultiLevelMenu>
{Object.keys(resources).map(name => (
Expand Down
Binary file added docs/img/multilevelmenu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading