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

Remove injected props in Admin and Layout components #9591

Merged
merged 10 commits into from
Jan 24, 2024
42 changes: 40 additions & 2 deletions docs/Admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,11 @@ Layout components can be customized via props. For instance, you can pass a cust
import { Layout } from 'react-admin';
import MyMenu from './MyMenu';

export const MyLayout = (props) => <Layout {...props} menu={MyMenu} />;
export const MyLayout = ({ children }) => (
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
<Layout menu={MyMenu}>
{children}
</Layout>
);
```

Then, pass it to the `<Admin>` component as the `layout` prop:
Expand All @@ -617,7 +621,30 @@ const App = () => (

Refer to each layout component documentation to understand the props it accepts.

Finally, you can also pass a custom component as the `layout` prop. It must contain a `{children}` placeholder, where react-admin will render the page content. Check [the custom layout documentation](./Layout.md#writing-a-layout-from-scratch) for examples, and use the [default `<Layout>`](https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/layout/Layout.tsx) as a starting point.
Finally, you can also pass a custom component as the `layout` prop. Your custom layout will receive the page content as `children`, so it should render it somewhere.

```tsx
// in src/MyLayout.js
export const MyLayout = ({ children }) => (
<div>
<h1>My App</h1>
<main>{children}</main>
</div>
);

// in src/App.js
import { Admin } from 'react-admin';
import { dataProvider } from './dataProvider';
import { MyLayout } from './MyLayout';

const App = () => (
<Admin dataProvider={dataProvider} layout={MyLayout}>
// ...
</Admin>
);
```

Check [the custom layout documentation](./Layout.md#writing-a-layout-from-scratch) for examples, and use the [default `<Layout>`](https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/layout/Layout.tsx) as a starting point.

## `loginPage`

Expand Down Expand Up @@ -878,6 +905,17 @@ const App = () => (
);
```

If you need to display this application title somewhere in your app, use the `useDefaultTitle` hook:

```tsx
import { useDefaultTitle } from 'react-admin';

const MyTitle = () => {
const defaultTitle = useDefaultTitle();
return <span>{defaultTitle}</span>; // My Custom Admin
};
```

## Adding Custom Pages

The [`children`](#children) prop of the `<Admin>` component define the routes of the application.
Expand Down
14 changes: 9 additions & 5 deletions docs/AppBar.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ Then, create a custom layout based on react-admin's `<Layout>`:
```jsx
// in src/MyLayout.js
import { Layout } from 'react-admin';

import { MyAppBar } from './MyAppBar';

export const MyLayout = props => <Layout {...props} appBar={MyAppBar} />;
export const MyLayout = ({ children }) => (
<Layout appBar={MyAppBar}>
{children}
</Layout>
);
```

Then pass this custom layout to the `<Admin>` component:
Expand Down Expand Up @@ -463,11 +466,12 @@ Then, use your custom app bar in a custom `<Layout>` component:
```jsx
// in src/MyLayout.js
import { Layout } from 'react-admin';

import { MyAppBar } from './MyAppBar';

export const MyLayout = (props) => (
<Layout {...props} appBar={MyAppBar} />
export const MyLayout = ({ children }) => (
<Layout appBar={MyAppBar}>
{children}
</Layout>
);
```

Expand Down
6 changes: 5 additions & 1 deletion docs/AppTheme.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,11 @@ const MySidebar = (props) => (
/>
);

const MyLayout = props => <Layout {...props} sidebar={MySidebar} />
const MyLayout = ({ children }) => (
<Layout sidebar={MySidebar}>
{children}
</Layout>
);
```
{% endraw %}

Expand Down
6 changes: 5 additions & 1 deletion docs/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ The trade-off with this approach is that sometimes react-admin may require you t
import { Layout } from 'react-admin';
import { Menu } from './Menu';

export const Layout = (props) => <Layout {...props} menu={Menu} />;
export const Layout = ({ children }) => (
<Layout menu={Menu}>
{children}
</Layout>
);

// in src/App.js
import { Layout } from './Layout';
Expand Down
6 changes: 5 additions & 1 deletion docs/AuthRBAC.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,11 @@ const authProvider= {
}),
};

const CustomLayout = props => <Layout {...props} menu={Menu} />;
const CustomLayout = ({ children }) => (
<Layout menu={Menu}>
{children}
</Layout>
);

const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider} layout={CustomLayout}>
Expand Down
6 changes: 5 additions & 1 deletion docs/Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,11 @@ const MyUserMenu = () => <UserMenu><MyLogoutButton /></UserMenu>;

const MyAppBar = () => <AppBar userMenu={<MyUserMenu />} />;

const MyLayout = (props) => <Layout {...props} appBar={MyAppBar} />;
const MyLayout = ({ children }) => (
<Layout appBar={MyAppBar}>
{children}
</Layout>
);

const App = () => (
<Admin layout={MyLayout}>
Expand Down
6 changes: 5 additions & 1 deletion docs/Buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,11 @@ To use this custom menu component, pass it to a custom Layout:
import { Layout } from 'react-admin';
import { Menu } from './Menu';

export const Layout = (props) => <Layout {...props} menu={Menu} />;
export const Layout = ({ children }) => (
<Layout menu={Menu}>
{children}
</Layout>
);
```

Then, use this layout in the `<Admin>` `layout` prop:
Expand Down
34 changes: 19 additions & 15 deletions docs/CheckForApplicationUpdate.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ Include this component in a custom layout:

```tsx
// in src/MyLayout.tsx
import { CheckForApplicationUpdate, Layout, LayoutProps } from 'react-admin';
import type { ReactNode } from 'react';
import { CheckForApplicationUpdate, Layout } from 'react-admin';

export const MyLayout = ({ children, ...props }: LayoutProps) => (
<Layout {...props}>
export const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate />
</Layout>
Expand Down Expand Up @@ -56,12 +57,13 @@ You can customize the interval between each check by providing the `interval` pr

```tsx
// in src/MyLayout.tsx
import { CheckForApplicationUpdate, Layout, LayoutProps } from 'react-admin';
import type { ReactNode } from 'react';
import { CheckForApplicationUpdate, Layout } from 'react-admin';

const HALF_HOUR = 30 * 60 * 1000;

export const MyLayout = ({ children, ...props }: LayoutProps) => (
<Layout {...props}>
export const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate interval={HALF_HOUR} />
</Layout>
Expand All @@ -74,10 +76,11 @@ You can dynamically disable the automatic application update detection by provid

```tsx
// in src/MyLayout.tsx
import { CheckForApplicationUpdate, Layout, LayoutProps } from 'react-admin';
import type { ReactNode } from 'react';
import { CheckForApplicationUpdate, Layout } from 'react-admin';

export const MyLayout = ({ children, ...props }: LayoutProps) => (
<Layout {...props}>
export const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate disabled={process.env.NODE_ENV !== 'production'} />
</Layout>
Expand All @@ -91,7 +94,7 @@ Note that you must wrap your component with `forwardRef`.

```tsx
// in src/MyLayout.tsx
import { forwardRef } from 'react';
import { forwardRef, ReactNode } from 'react';
import { Layout, CheckForApplicationUpdate } from 'react-admin';

const CustomAppUpdatedNotification = forwardRef((props, ref) => (
Expand All @@ -112,8 +115,8 @@ const CustomAppUpdatedNotification = forwardRef((props, ref) => (
</Alert>
));

const MyLayout = ({ children, ...props }) => (
<Layout {...props}>
const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate notification={<CustomAppUpdatedNotification />}/>
</Layout>
Expand Down Expand Up @@ -163,12 +166,13 @@ You can customize the URL fetched to detect updates by providing the `url` prop.

```tsx
// in src/MyLayout.tsx
import { CheckForApplicationUpdate, Layout, LayoutProps } from 'react-admin';
import type { ReactNode } from 'react';
import { CheckForApplicationUpdate, Layout } from 'react-admin';

const MY_APP_ROOT_URL = 'https://admin.mycompany.com';

export const MyLayout = ({ children, ...props }: LayoutProps) => (
<Layout {...props}>
export const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate url={MY_APP_ROOT_URL} />
</Layout>
Expand Down
7 changes: 4 additions & 3 deletions docs/CreateReactApp.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ To enable it, start by creating a custom layout:

```tsx
// in src/admin/MyLayout.tsx
import { CheckForApplicationUpdate, Layout, LayoutProps } from 'react-admin';
import type { ReactNode } from 'react';
import { CheckForApplicationUpdate, Layout } from 'react-admin';

export const MyLayout = ({ children, ...props }: LayoutProps) => (
<Layout {...props}>
export const MyLayout = ({ children }: { children: ReactNode}) => (
<Layout>
{children}
<CheckForApplicationUpdate />
</Layout>
Expand Down
6 changes: 5 additions & 1 deletion docs/CustomRoutes.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,11 @@ Next, pass the custom menu to a custom `<Layout>` component:
import { Layout } from 'react-admin';
import { MyMenu } from './MyMenu';

export const MyLayout = (props) => <Layout {...props} menu={MyMenu} />;
export const MyLayout = ({ children }) => (
<Layout menu={MyMenu}>
{children}
</Layout>
);
```

Finally, pass the custom `<Layout>` component to `<Admin>`:
Expand Down
8 changes: 4 additions & 4 deletions docs/DataProviders.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ To enable these devtools, add the `<ReactQueryDevtools>` component to a custom L
import { Layout } from 'react-admin';
import { ReactQueryDevtools } from 'react-query/devtools';

export const MyLayout = props => (
<>
<Layout {...props} />
export const MyLayout = ({ children }) => (
<Layout>
{children}
<ReactQueryDevtools initialIsOpen={false} />
</>
</Layout>
);
```

Expand Down
6 changes: 4 additions & 2 deletions docs/Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -1191,8 +1191,10 @@ import { MenuLive } from '@react-admin/ra-realtime';

import { PostList, PostShow, PostEdit, realTimeDataProvider } from '.';

const CustomLayout = (props) => (
<Layout {...props} menu={MenuLive} />
const CustomLayout = ({ children }) => (
<Layout menu={MenuLive}>
{children}
</Layout>
);

const MyReactAdmin = () => (
Expand Down
6 changes: 4 additions & 2 deletions docs/IconMenu.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ import { AppLocationContext } from '@react-admin/ra-navigation';

import { MyMenu } from './MyMenu';

export const MyLayout = (props) => (
export const MyLayout = ({ children }) => (
<AppLocationContext>
<Layout {...props} menu={MyMenu} />
<Layout menu={MyMenu}>
{children}
</Layout>
</AppLocationContext>
);
```
Expand Down
Loading
Loading