Skip to content

Commit

Permalink
[docs] Full documentation for React Router integration (#4185)
Browse files Browse the repository at this point in the history
  • Loading branch information
apedroferreira authored Oct 16, 2024
1 parent 8beaef2 commit b0132c4
Show file tree
Hide file tree
Showing 43 changed files with 1,005 additions and 6 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pnpm-lock.yaml
/packages/toolpad-studio/public

build
dist

/examples/*/toolpad.yml

Expand Down
6 changes: 5 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ You can also test the example apps to make sure they work as expected.
pnpm --filter @toolpad/core dev
```

3. Run the example app
3. Install then run the example app

```bash
pnpm --filter core-nextjs install
```

```bash
pnpm --filter core-nextjs dev
Expand Down
130 changes: 130 additions & 0 deletions docs/data/toolpad/core/introduction/ReactRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { createTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import DashboardIcon from '@mui/icons-material/Dashboard';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import { createMemoryRouter, RouterProvider, Outlet } from 'react-router-dom';
import { AppProvider } from '@toolpad/core/react-router-dom';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { PageContainer } from '@toolpad/core/PageContainer';

function Layout() {
return (
<DashboardLayout>
<PageContainer>
<Outlet />
</PageContainer>
</DashboardLayout>
);
}

function DashboardPage() {
return <Typography>Welcome to Toolpad!</Typography>;
}

function OrdersPage() {
return <Typography>Welcome to the orders page!</Typography>;
}

const NAVIGATION = [
{
kind: 'header',
title: 'Main items',
},
{
title: 'Dashboard',
icon: <DashboardIcon />,
},
{
segment: 'orders',
title: 'Orders',
icon: <ShoppingCartIcon />,
},
];

const BRANDING = {
title: 'My Toolpad Core App',
};

const demoTheme = createTheme({
cssVariables: {
colorSchemeSelector: 'data-toolpad-color-scheme',
},
colorSchemes: { light: true, dark: true },
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 600,
lg: 1200,
xl: 1536,
},
},
});

function App(props) {
const { window } = props;

return (
<AppProvider
navigation={NAVIGATION}
branding={BRANDING}
theme={demoTheme}
window={window}
>
<Outlet />
</AppProvider>
);
}

App.propTypes = {
window: PropTypes.object,
};

function ReactRouter(props) {
const { window } = props;

// Remove this const when copying and pasting into your project.
const demoWindow = window !== undefined ? window() : undefined;

// preview-start
const router = React.useMemo(
() =>
createMemoryRouter([
{
element: <App window={demoWindow} />, // root layout route
children: [
{
path: '/',
Component: Layout,
children: [
{
path: '/',
Component: DashboardPage,
},
{
path: '/orders',
Component: OrdersPage,
},
],
},
],
},
]),
[demoWindow],
);

return <RouterProvider router={router} />;
// preview-end
}

ReactRouter.propTypes = {
/**
* Injected by the documentation to work in an iframe.
* Remove this when copying and pasting into your project.
*/
window: PropTypes.func.isRequired,
};

export default ReactRouter;
124 changes: 124 additions & 0 deletions docs/data/toolpad/core/introduction/ReactRouter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import * as React from 'react';
import { createTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import DashboardIcon from '@mui/icons-material/Dashboard';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import { createMemoryRouter, RouterProvider, Outlet } from 'react-router-dom';
import { AppProvider } from '@toolpad/core/react-router-dom';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { PageContainer } from '@toolpad/core/PageContainer';
import type { Navigation } from '@toolpad/core';

function Layout() {
return (
<DashboardLayout>
<PageContainer>
<Outlet />
</PageContainer>
</DashboardLayout>
);
}

function DashboardPage() {
return <Typography>Welcome to Toolpad!</Typography>;
}

function OrdersPage() {
return <Typography>Welcome to the orders page!</Typography>;
}

const NAVIGATION: Navigation = [
{
kind: 'header',
title: 'Main items',
},
{
title: 'Dashboard',
icon: <DashboardIcon />,
},
{
segment: 'orders',
title: 'Orders',
icon: <ShoppingCartIcon />,
},
];

const BRANDING = {
title: 'My Toolpad Core App',
};

const demoTheme = createTheme({
cssVariables: {
colorSchemeSelector: 'data-toolpad-color-scheme',
},
colorSchemes: { light: true, dark: true },
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 600,
lg: 1200,
xl: 1536,
},
},
});

function App(props: { window?: Window }) {
const { window } = props;

return (
<AppProvider
navigation={NAVIGATION}
branding={BRANDING}
theme={demoTheme}
window={window}
>
<Outlet />
</AppProvider>
);
}

interface DemoProps {
/**
* Injected by the documentation to work in an iframe.
* Remove this when copying and pasting into your project.
*/
window: () => Window;
}

export default function ReactRouter(props: DemoProps) {
const { window } = props;

// Remove this const when copying and pasting into your project.
const demoWindow = window !== undefined ? window() : undefined;

// preview-start
const router = React.useMemo(
() =>
createMemoryRouter([
{
element: <App window={demoWindow} />, // root layout route
children: [
{
path: '/',
Component: Layout,
children: [
{
path: '/',
Component: DashboardPage,
},
{
path: '/orders',
Component: OrdersPage,
},
],
},
],
},
]),
[demoWindow],
);

return <RouterProvider router={router} />;
// preview-end
}
27 changes: 27 additions & 0 deletions docs/data/toolpad/core/introduction/ReactRouter.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const router = React.useMemo(
() =>
createMemoryRouter([
{
element: <App window={demoWindow} />, // root layout route
children: [
{
path: '/',
Component: Layout,
children: [
{
path: '/',
Component: DashboardPage,
},
{
path: '/orders',
Component: OrdersPage,
},
],
},
],
},
]),
[demoWindow],
);

return <RouterProvider router={router} />;
2 changes: 1 addition & 1 deletion docs/data/toolpad/core/introduction/base-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ You can pass the router implementation to the `AppProvider` component using the
:::success
If you are using Next.js, use the `AppProvider` exported from `@toolpad/core/nextjs`.

If you are building a single-page application with React Router for routing, use the `AppProvider` exported from `@toolpad/core/react-router-dom`.
If you are building a single-page application (with [Vite](https://vite.dev/), for example) using React Router for routing, use the `AppProvider` exported from `@toolpad/core/react-router-dom`.

This automatically sets up the router for you, so that you don't need to pass the `router` prop.
:::
Expand Down
Loading

0 comments on commit b0132c4

Please sign in to comment.