From e6908fd2a72f20321773f858c46ae1e8757563f8 Mon Sep 17 00:00:00 2001
From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com>
Date: Tue, 23 Jul 2024 17:07:37 +0100
Subject: [PATCH 1/5] Agnostic DashboardLayout with props for overrides
---
.../toolpad/core/api/dashboard-layout.json | 14 ++-
.../dashboard-layout/dashboard-layout.json | 8 +-
.../src/DashboardLayout/DashboardLayout.tsx | 117 ++++++++++++++++--
playground/nextjs/src/app/layout.tsx | 4 +-
4 files changed, 129 insertions(+), 14 deletions(-)
diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json
index af4c4e66fda..0d1550e1def 100644
--- a/docs/pages/toolpad/core/api/dashboard-layout.json
+++ b/docs/pages/toolpad/core/api/dashboard-layout.json
@@ -1,5 +1,17 @@
{
- "props": { "children": { "type": { "name": "node" }, "required": true } },
+ "props": {
+ "children": { "type": { "name": "node" }, "required": true },
+ "navigation": {
+ "type": {
+ "name": "arrayOf",
+ "description": "Array<{ children?: Array<object
| { kind: 'header', title: string }
| { kind: 'divider' }>, icon?: node, kind?: 'page', segment: string, title?: string }
| { kind: 'header', title: string }
| { kind: 'divider' }>"
+ },
+ "default": "[]"
+ },
+ "paletteMode": { "type": { "name": "enum", "description": "'dark'
| 'light'" } },
+ "setPaletteMode": { "type": { "name": "func" } },
+ "window": { "type": { "name": "object" }, "default": "null" }
+ },
"name": "DashboardLayout",
"imports": [
"import { DashboardLayout } from '@toolpad-core/DashboardLayout';",
diff --git a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
index 8e461ca2aaa..6f73a05bb86 100644
--- a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
+++ b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
@@ -1,5 +1,11 @@
{
"componentDescription": "",
- "propDescriptions": { "children": { "description": "The content of the dashboard." } },
+ "propDescriptions": {
+ "children": { "description": "The content of the dashboard." },
+ "navigation": { "description": "Navigation definition for the layout." },
+ "paletteMode": { "description": "Active palette mode in theme." },
+ "setPaletteMode": { "description": "Function to run when the theme switcher is toggled." },
+ "window": { "description": "Branding options for the layout." }
+ },
"classDescriptions": {}
}
diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
index ffe4f654d3e..031e6fa74db 100644
--- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
@@ -1,7 +1,7 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import { styled, useTheme } from '@mui/material';
+import { PaletteMode, styled, useTheme } from '@mui/material';
import MuiAppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Collapse from '@mui/material/Collapse';
@@ -34,7 +34,7 @@ import {
RouterContext,
WindowContext,
} from '../shared/context';
-import type { Navigation, NavigationPageItem } from '../AppProvider';
+import type { AppProviderProps, Navigation, NavigationPageItem } from '../AppProvider';
import { ToolpadLogo } from './ToolpadLogo';
import { getItemTitle, isPageItem } from '../shared/navigation';
@@ -78,11 +78,20 @@ const NavigationListItemButton = styled(ListItemButton)(({ theme }) => ({
},
}));
-function ThemeSwitcher() {
+interface ThemeSwitcherProps {
+ value?: PaletteMode;
+ onChange?: (mode: PaletteMode) => void;
+}
+
+function ThemeSwitcher({ value, onChange }: ThemeSwitcherProps) {
const isSsr = useSsr();
const theme = useTheme();
- const { paletteMode, setPaletteMode, isDualTheme } = React.useContext(PaletteModeContext);
+ const paletteModeContext = React.useContext(PaletteModeContext);
+
+ const paletteMode = value ?? paletteModeContext.paletteMode;
+ const setPaletteMode = onChange ?? paletteModeContext.setPaletteMode;
+ const isDualTheme = !!onChange ?? paletteModeContext.isDualTheme;
const toggleMode = React.useCallback(() => {
setPaletteMode(paletteMode === 'dark' ? 'light' : 'dark');
@@ -301,6 +310,30 @@ export interface DashboardLayoutProps {
* The content of the dashboard.
*/
children: React.ReactNode;
+ branding?: AppProviderProps['branding'];
+ /**
+ * Navigation definition for the layout.
+ * @default []
+ */
+ navigation?: AppProviderProps['navigation'];
+ /**
+ * The window where the layout is rendered.
+ * This is needed when rendering the layout inside an iframe, for example.
+ * @default window
+ */
+ /**
+ * Active palette mode in theme.
+ */
+ paletteMode?: PaletteMode;
+ /**
+ * Function to run when the theme switcher is toggled.
+ */
+ setPaletteMode?: (theme: PaletteMode) => void;
+ /**
+ * Branding options for the layout.
+ * @default null
+ */
+ window?: AppProviderProps['window'];
}
/**
@@ -314,11 +347,22 @@ export interface DashboardLayoutProps {
* - [DashboardLayout API](https://mui.com/toolpad/core/api/dashboard-layout)
*/
function DashboardLayout(props: DashboardLayoutProps) {
- const { children } = props;
-
- const branding = React.useContext(BrandingContext);
- const navigation = React.useContext(NavigationContext);
- const appWindow = React.useContext(WindowContext);
+ const {
+ children,
+ paletteMode,
+ setPaletteMode,
+ branding: brandingProp,
+ navigation: navigationProp,
+ window: windowProp,
+ } = props;
+
+ const brandingContext = React.useContext(BrandingContext);
+ const navigationContext = React.useContext(NavigationContext);
+ const windowContext = React.useContext(WindowContext);
+
+ const branding = brandingProp ?? brandingContext;
+ const navigation = navigationProp ?? navigationContext;
+ const appWindow = windowProp ?? windowContext;
const [isMobileNavigationOpen, setIsMobileNavigationOpen] = React.useState(false);
@@ -396,7 +440,7 @@ function DashboardLayout(props: DashboardLayoutProps) {
-
+
,
},
{
- slug: 'orders',
+ segment: 'orders',
title: 'Orders',
icon: ,
},
From 125cf5e7c66e3aff08010de92b8699f84fb91ed5 Mon Sep 17 00:00:00 2001
From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com>
Date: Tue, 23 Jul 2024 17:11:19 +0100
Subject: [PATCH 2/5] what the
---
.../toolpad/core/api/dashboard-layout.json | 6 ++++-
.../dashboard-layout/dashboard-layout.json | 5 ++++-
.../src/DashboardLayout/DashboardLayout.tsx | 22 ++++++++++---------
3 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json
index 0d1550e1def..c1032fb5815 100644
--- a/docs/pages/toolpad/core/api/dashboard-layout.json
+++ b/docs/pages/toolpad/core/api/dashboard-layout.json
@@ -1,6 +1,10 @@
{
"props": {
"children": { "type": { "name": "node" }, "required": true },
+ "branding": {
+ "type": { "name": "shape", "description": "{ logo?: node, title?: string }" },
+ "default": "null"
+ },
"navigation": {
"type": {
"name": "arrayOf",
@@ -10,7 +14,7 @@
},
"paletteMode": { "type": { "name": "enum", "description": "'dark'
| 'light'" } },
"setPaletteMode": { "type": { "name": "func" } },
- "window": { "type": { "name": "object" }, "default": "null" }
+ "window": { "type": { "name": "object" }, "default": "window" }
},
"name": "DashboardLayout",
"imports": [
diff --git a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
index 6f73a05bb86..00c6a39be1a 100644
--- a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
+++ b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
@@ -1,11 +1,14 @@
{
"componentDescription": "",
"propDescriptions": {
+ "branding": { "description": "Branding options for the layout." },
"children": { "description": "The content of the dashboard." },
"navigation": { "description": "Navigation definition for the layout." },
"paletteMode": { "description": "Active palette mode in theme." },
"setPaletteMode": { "description": "Function to run when the theme switcher is toggled." },
- "window": { "description": "Branding options for the layout." }
+ "window": {
+ "description": "The window where the layout is rendered. This is needed when rendering the layout inside an iframe, for example."
+ }
},
"classDescriptions": {}
}
diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
index 031e6fa74db..979ca408b26 100644
--- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
@@ -310,17 +310,16 @@ export interface DashboardLayoutProps {
* The content of the dashboard.
*/
children: React.ReactNode;
+ /**
+ * Branding options for the layout.
+ * @default null
+ */
branding?: AppProviderProps['branding'];
/**
* Navigation definition for the layout.
* @default []
*/
navigation?: AppProviderProps['navigation'];
- /**
- * The window where the layout is rendered.
- * This is needed when rendering the layout inside an iframe, for example.
- * @default window
- */
/**
* Active palette mode in theme.
*/
@@ -330,8 +329,9 @@ export interface DashboardLayoutProps {
*/
setPaletteMode?: (theme: PaletteMode) => void;
/**
- * Branding options for the layout.
- * @default null
+ * The window where the layout is rendered.
+ * This is needed when rendering the layout inside an iframe, for example.
+ * @default window
*/
window?: AppProviderProps['window'];
}
@@ -494,7 +494,8 @@ DashboardLayout.propTypes /* remove-proptypes */ = {
// │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
// └─────────────────────────────────────────────────────────────────────┘
/**
- * @ignore
+ * Branding options for the layout.
+ * @default null
*/
branding: PropTypes.shape({
logo: PropTypes.node,
@@ -546,8 +547,9 @@ DashboardLayout.propTypes /* remove-proptypes */ = {
*/
setPaletteMode: PropTypes.func,
/**
- * Branding options for the layout.
- * @default null
+ * The window where the layout is rendered.
+ * This is needed when rendering the layout inside an iframe, for example.
+ * @default window
*/
window: PropTypes.object,
} as any;
From 3e449b63a1721650cdeb87acf533ca4bedd80310 Mon Sep 17 00:00:00 2001
From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com>
Date: Fri, 26 Jul 2024 15:26:42 +0100
Subject: [PATCH 3/5] Fix merge
---
.../src/DashboardLayout/DashboardLayout.tsx | 19 ++-----------------
.../toolpad-core/src/useColorScheme/index.ts | 1 -
.../src/useColorScheme/useColorScheme.ts | 0
3 files changed, 2 insertions(+), 18 deletions(-)
delete mode 100644 packages/toolpad-core/src/useColorScheme/index.ts
delete mode 100644 packages/toolpad-core/src/useColorScheme/useColorScheme.ts
diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
index 45a7b654479..b24a07017a8 100644
--- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
@@ -79,12 +79,7 @@ const NavigationListItemButton = styled(ListItemButton)(({ theme }) => ({
},
}));
-interface ThemeSwitcherProps {
- value?: PaletteMode;
- onChange?: (mode: PaletteMode) => void;
-}
-
-function ThemeSwitcher({ value, onChange }: ThemeSwitcherProps) {
+function ThemeSwitcher() {
const isSsr = useSsr();
const theme = useTheme();
@@ -322,14 +317,6 @@ export interface DashboardLayoutProps {
* @default []
*/
navigation?: AppProviderProps['navigation'];
- /**
- * Active palette mode in theme.
- */
- paletteMode?: PaletteMode;
- /**
- * Function to run when the theme switcher is toggled.
- */
- setPaletteMode?: (theme: PaletteMode) => void;
/**
* The window where the layout is rendered.
* This is needed when rendering the layout inside an iframe, for example.
@@ -351,8 +338,6 @@ export interface DashboardLayoutProps {
function DashboardLayout(props: DashboardLayoutProps) {
const {
children,
- paletteMode,
- setPaletteMode,
branding: brandingProp,
navigation: navigationProp,
window: windowProp,
@@ -444,7 +429,7 @@ function DashboardLayout(props: DashboardLayoutProps) {
-
+
Date: Fri, 26 Jul 2024 16:02:37 +0100
Subject: [PATCH 4/5] Rename props as per review
---
.../src/DashboardLayout/DashboardLayout.tsx | 25 +++++++++++++++----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
index b24a07017a8..160f18decf3 100644
--- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
@@ -79,15 +79,20 @@ const NavigationListItemButton = styled(ListItemButton)(({ theme }) => ({
},
}));
-function ThemeSwitcher() {
+interface ThemeSwitcherProps {
+ colorScheme?: PaletteMode;
+ onColorSchemeChange?: (mode: PaletteMode) => void;
+}
+
+function ThemeSwitcher({ colorScheme, onColorSchemeChange }: ThemeSwitcherProps) {
const isSsr = useSsr();
const theme = useTheme();
const paletteModeContext = React.useContext(PaletteModeContext);
- const paletteMode = value ?? paletteModeContext.paletteMode;
- const setPaletteMode = onChange ?? paletteModeContext.setPaletteMode;
- const isDualTheme = !!onChange ?? paletteModeContext.isDualTheme;
+ const paletteMode = colorScheme ?? paletteModeContext.paletteMode;
+ const setPaletteMode = onColorSchemeChange ?? paletteModeContext.setPaletteMode;
+ const isDualTheme = !!onColorSchemeChange || paletteModeContext.isDualTheme;
const toggleMode = React.useCallback(() => {
setPaletteMode(paletteMode === 'dark' ? 'light' : 'dark');
@@ -317,6 +322,14 @@ export interface DashboardLayoutProps {
* @default []
*/
navigation?: AppProviderProps['navigation'];
+ /**
+ * Active color scheme in theme.
+ */
+ colorScheme?: PaletteMode;
+ /**
+ * Callback to run when the theme color scheme is changed.
+ */
+ onColorSchemeChange?: (theme: PaletteMode) => void;
/**
* The window where the layout is rendered.
* This is needed when rendering the layout inside an iframe, for example.
@@ -338,6 +351,8 @@ export interface DashboardLayoutProps {
function DashboardLayout(props: DashboardLayoutProps) {
const {
children,
+ colorScheme,
+ onColorSchemeChange,
branding: brandingProp,
navigation: navigationProp,
window: windowProp,
@@ -429,7 +444,7 @@ function DashboardLayout(props: DashboardLayoutProps) {
-
+
Date: Fri, 26 Jul 2024 16:55:30 +0100
Subject: [PATCH 5/5] Incomplete work so far
---
.../dashboard-layout/DashboardLayoutBasic.tsx | 4 +-
.../DashboardLayoutBranding.tsx | 4 +-
.../DashboardLayoutNavigationActions.tsx | 3 +-
.../DashboardLayoutNavigationItems.tsx | 3 +-
.../DashboardLayoutStandalone.tsx | 98 +++++++++++++++++++
.../dashboard-layout/dashboard-layout.md | 9 +-
.../core/introduction/TutorialDefault.tsx | 3 +-
.../core/introduction/TutorialPages.tsx | 3 +-
.../toolpad/core/api/dashboard-layout.json | 6 +-
.../dashboard-layout/dashboard-layout.json | 6 +-
.../src/DashboardLayout/DashboardLayout.tsx | 13 +--
11 files changed, 132 insertions(+), 20 deletions(-)
create mode 100644 docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutStandalone.tsx
diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBasic.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBasic.tsx
index fd2b310d2cc..a70fed83e8b 100644
--- a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBasic.tsx
+++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBasic.tsx
@@ -7,9 +7,9 @@ import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import BarChartIcon from '@mui/icons-material/BarChart';
import DescriptionIcon from '@mui/icons-material/Description';
import LayersIcon from '@mui/icons-material/Layers';
-import { AppProvider, Router } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
-import type { Navigation } from '@toolpad/core';
+import type { Navigation, Router } from '@toolpad/core';
const NAVIGATION: Navigation = [
{
diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBranding.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBranding.tsx
index d246ee44077..9ad3d2dbba2 100644
--- a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBranding.tsx
+++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutBranding.tsx
@@ -4,9 +4,9 @@ import Typography from '@mui/material/Typography';
import { extendTheme } from '@mui/material/styles';
import DashboardIcon from '@mui/icons-material/Dashboard';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
-import { AppProvider, Router } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
-import type { Navigation } from '@toolpad/core';
+import type { Navigation, Router } from '@toolpad/core';
const NAVIGATION: Navigation = [
{
diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationActions.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationActions.tsx
index e5623b8c2fc..d890368e9fb 100644
--- a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationActions.tsx
+++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationActions.tsx
@@ -11,8 +11,9 @@ import CallIcon from '@mui/icons-material/Call';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
import CallMadeIcon from '@mui/icons-material/CallMade';
import CallReceivedIcon from '@mui/icons-material/CallReceived';
-import { AppProvider, Router } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
+import type { Router } from '@toolpad/core';
const demoTheme = extendTheme({
breakpoints: {
diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationItems.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationItems.tsx
index 7597bb58ef0..25524047823 100644
--- a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationItems.tsx
+++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutNavigationItems.tsx
@@ -4,8 +4,9 @@ import Typography from '@mui/material/Typography';
import { extendTheme } from '@mui/material/styles';
import DescriptionIcon from '@mui/icons-material/Description';
import FolderIcon from '@mui/icons-material/Folder';
-import { AppProvider, Router } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
+import type { Router } from '@toolpad/core';
const demoTheme = extendTheme({
breakpoints: {
diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutStandalone.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutStandalone.tsx
new file mode 100644
index 00000000000..d662c562142
--- /dev/null
+++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutStandalone.tsx
@@ -0,0 +1,98 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import Typography from '@mui/material/Typography';
+import { CssVarsProvider, extendTheme } from '@mui/material/styles';
+import DashboardIcon from '@mui/icons-material/Dashboard';
+import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
+import { DashboardLayout } from '@toolpad/core/DashboardLayout';
+import type { Navigation, Router } from '@toolpad/core';
+
+const NAVIGATION: Navigation = [
+ {
+ segment: 'dashboard',
+ title: 'Dashboard',
+ icon: ,
+ },
+ {
+ segment: 'orders',
+ title: 'Orders',
+ icon: ,
+ },
+];
+
+const demoTheme = extendTheme({
+ breakpoints: {
+ values: {
+ xs: 0,
+ sm: 600,
+ md: 600,
+ lg: 1200,
+ xl: 1536,
+ },
+ },
+});
+
+function DemoPageContent({ pathname }: { pathname: string }) {
+ return (
+
+ Dashboard content for {pathname}
+
+ );
+}
+
+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 DashboardLayoutStandalone(props: DemoProps) {
+ const { window } = props;
+
+ const [pathname, setPathname] = React.useState('dashboard');
+
+ const router = React.useMemo(() => {
+ return {
+ pathname,
+ searchParams: new URLSearchParams(),
+ navigate: (path) => setPathname(String(path)),
+ };
+ }, [pathname]);
+
+ // Remove this const when copying and pasting into your project.
+ const demoWindow = window !== undefined ? window() : undefined;
+
+ return (
+
+ ,
+ title: 'MUI',
+ }}
+ colorScheme={}
+ onColorSchemeChange={}
+ router={router}
+ window={demoWindow}
+ >
+
+
+
+ );
+}
diff --git a/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md b/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md
index 44f31f12474..9775ad83694 100644
--- a/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md
+++ b/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md
@@ -10,7 +10,8 @@ components: AppProvider, DashboardLayout
The `DashboardLayout` component is a quick, easy way to provide a standard full-screen layout with a header and sidebar to any dashboard page, as well as ready-to-use and easy to customize navigation and branding.
-Many features of this component are configurable through the [AppProvider](https://mui.com/toolpad/core/react-app-provider/) component that should wrap it.
+Many features of this component are configurable through the [AppProvider](https://mui.com/toolpad/core/react-app-provider/) component that should wrap it, which is the recommended approach for a Toolpad app.
+However, it is also possible to use the `DashboardLayout` as a standalone component by setting those configurations with the component props themselves.
## Demo
@@ -50,3 +51,9 @@ The main navigation items that can be used are:
Navigation links have an optional `action` prop that can be used to render any content on the right-side of the respective list item, such as badges with numbers, or buttons to toggle a popover menu.
{{"demo": "DashboardLayoutNavigationActions.js", "height": 500, "iframe": true}}
+
+## Standalone Usage
+
+The component branding, navigation, theme switching and routing can also be set via component props themselves instead of indirectly through an `AppProvider`.
+
+{{"demo": "DashboardLayoutStandalone.js", "height": 500, "iframe": true}}
diff --git a/docs/data/toolpad/core/introduction/TutorialDefault.tsx b/docs/data/toolpad/core/introduction/TutorialDefault.tsx
index 671c1574944..8eca598433d 100644
--- a/docs/data/toolpad/core/introduction/TutorialDefault.tsx
+++ b/docs/data/toolpad/core/introduction/TutorialDefault.tsx
@@ -1,10 +1,11 @@
import * as React from 'react';
import { extendTheme } from '@mui/material/styles';
import DashboardIcon from '@mui/icons-material/Dashboard';
-import { AppProvider, Navigation } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { PageContainer } from '@toolpad/core/PageContainer';
import { useDemoRouter } from '@toolpad/core/internals/demo';
+import type { Navigation } from '@toolpad/core';
const NAVIGATION: Navigation = [
{
diff --git a/docs/data/toolpad/core/introduction/TutorialPages.tsx b/docs/data/toolpad/core/introduction/TutorialPages.tsx
index ab1e1daa7f8..090c4d2e0d6 100644
--- a/docs/data/toolpad/core/introduction/TutorialPages.tsx
+++ b/docs/data/toolpad/core/introduction/TutorialPages.tsx
@@ -2,10 +2,11 @@ import * as React from 'react';
import { extendTheme } from '@mui/material/styles';
import DashboardIcon from '@mui/icons-material/Dashboard';
import TimelineIcon from '@mui/icons-material/Timeline';
-import { AppProvider, Navigation } from '@toolpad/core/AppProvider';
+import { AppProvider } from '@toolpad/core/AppProvider';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { useDemoRouter } from '@toolpad/core/internals/demo';
import { PageContainer } from '@toolpad/core/PageContainer';
+import type { Navigation } from '@toolpad/core';
import { Typography } from '@mui/material';
const NAVIGATION: Navigation = [
diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json
index c1032fb5815..f0e36989a02 100644
--- a/docs/pages/toolpad/core/api/dashboard-layout.json
+++ b/docs/pages/toolpad/core/api/dashboard-layout.json
@@ -5,15 +5,15 @@
"type": { "name": "shape", "description": "{ logo?: node, title?: string }" },
"default": "null"
},
+ "colorScheme": { "type": { "name": "enum", "description": "'dark'
| 'light'" } },
"navigation": {
"type": {
"name": "arrayOf",
- "description": "Array<{ children?: Array<object
| { kind: 'header', title: string }
| { kind: 'divider' }>, icon?: node, kind?: 'page', segment: string, title?: string }
| { kind: 'header', title: string }
| { kind: 'divider' }>"
+ "description": "Array<{ action?: node, children?: Array<object
| { kind: 'header', title: string }
| { kind: 'divider' }>, icon?: node, kind?: 'page', segment: string, title?: string }
| { kind: 'header', title: string }
| { kind: 'divider' }>"
},
"default": "[]"
},
- "paletteMode": { "type": { "name": "enum", "description": "'dark'
| 'light'" } },
- "setPaletteMode": { "type": { "name": "func" } },
+ "onColorSchemeChange": { "type": { "name": "func" } },
"window": { "type": { "name": "object" }, "default": "window" }
},
"name": "DashboardLayout",
diff --git a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
index 00c6a39be1a..fa5e039d84a 100644
--- a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
+++ b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json
@@ -3,9 +3,11 @@
"propDescriptions": {
"branding": { "description": "Branding options for the layout." },
"children": { "description": "The content of the dashboard." },
+ "colorScheme": { "description": "Active color scheme in theme." },
"navigation": { "description": "Navigation definition for the layout." },
- "paletteMode": { "description": "Active palette mode in theme." },
- "setPaletteMode": { "description": "Function to run when the theme switcher is toggled." },
+ "onColorSchemeChange": {
+ "description": "Callback to run when the theme color scheme is changed."
+ },
"window": {
"description": "The window where the layout is rendered. This is needed when rendering the layout inside an iframe, for example."
}
diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
index 160f18decf3..820fd03d3fb 100644
--- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx
@@ -509,6 +509,10 @@ DashboardLayout.propTypes /* remove-proptypes */ = {
* The content of the dashboard.
*/
children: PropTypes.node,
+ /**
+ * Active color scheme in theme.
+ */
+ colorScheme: PropTypes.oneOf(['dark', 'light']),
/**
* Navigation definition for the layout.
* @default []
@@ -516,6 +520,7 @@ DashboardLayout.propTypes /* remove-proptypes */ = {
navigation: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.shape({
+ action: PropTypes.node,
children: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.object,
@@ -543,13 +548,9 @@ DashboardLayout.propTypes /* remove-proptypes */ = {
]).isRequired,
),
/**
- * Active palette mode in theme.
- */
- paletteMode: PropTypes.oneOf(['dark', 'light']),
- /**
- * Function to run when the theme switcher is toggled.
+ * Callback to run when the theme color scheme is changed.
*/
- setPaletteMode: PropTypes.func,
+ onColorSchemeChange: PropTypes.func,
/**
* The window where the layout is rendered.
* This is needed when rendering the layout inside an iframe, for example.