diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.js b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.js new file mode 100644 index 00000000000..b805aea99c9 --- /dev/null +++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.js @@ -0,0 +1,78 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { createTheme } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { DashboardLayout } from '@toolpad/core/DashboardLayout'; + +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 DemoPageContent({ pathname }) { + return ( + + Dashboard content for {pathname} + + ); +} + +DemoPageContent.propTypes = { + pathname: PropTypes.string.isRequired, +}; + +function DashboardLayoutSidebarHidden(props) { + 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 ( + + + + + + ); +} + +DashboardLayoutSidebarHidden.propTypes = { + /** + * Injected by the documentation to work in an iframe. + * Remove this when copying and pasting into your project. + */ + window: PropTypes.func, +}; + +export default DashboardLayoutSidebarHidden; diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx new file mode 100644 index 00000000000..152f03f6cf2 --- /dev/null +++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; +import { createTheme } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { DashboardLayout } from '@toolpad/core/DashboardLayout'; +import type { Router } from '@toolpad/core'; + +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 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 DashboardLayoutSidebarHidden(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 ( + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx.preview b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx.preview new file mode 100644 index 00000000000..aff732ec858 --- /dev/null +++ b/docs/data/toolpad/core/components/dashboard-layout/DashboardLayoutSidebarHidden.tsx.preview @@ -0,0 +1,3 @@ + + + \ No newline at end of file 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 4f497ad90e9..59e061e5309 100644 --- a/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md +++ b/docs/data/toolpad/core/components/dashboard-layout/dashboard-layout.md @@ -109,6 +109,12 @@ The layout sidebar is collapsible to a mini-drawer (with icons only) in desktop {{"demo": "DashboardLayoutNoMiniSidebar.js", "height": 400, "iframe": true}} +### Hiding the sidebar + +The layout sidebar can be hidden if needed with the `hideNavigation` prop. + +{{"demo": "DashboardLayoutSidebarHidden.js", "height": 400, "iframe": true}} + ## Account The `DashboardLayout` comes integrated with the [``](/toolpad/core/react-account/) component. It renders as an account management menu when a user is signed in – a `session` object is present – and a button when not. diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json index 8e5707511f8..582c78a5088 100644 --- a/docs/pages/toolpad/core/api/dashboard-layout.json +++ b/docs/pages/toolpad/core/api/dashboard-layout.json @@ -2,6 +2,7 @@ "props": { "children": { "type": { "name": "node" }, "required": true }, "disableCollapsibleSidebar": { "type": { "name": "bool" }, "default": "false" }, + "hideNavigation": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { "type": { "name": "shape", diff --git a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json index 450933674b6..d84ffaffa4a 100644 --- a/docs/translations/api-docs/dashboard-layout/dashboard-layout.json +++ b/docs/translations/api-docs/dashboard-layout/dashboard-layout.json @@ -5,6 +5,9 @@ "disableCollapsibleSidebar": { "description": "Whether the sidebar should not be collapsible to a mini variant in desktop and tablet viewports." }, + "hideNavigation": { + "description": "Whether the navigation bar and menu icon should be hidden" + }, "slotProps": { "description": "The props used for each slot inside." }, "slots": { "description": "The components used for each slot inside." } }, diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.test.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.test.tsx index 8811952cba3..1dcf8365ce8 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.test.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.test.tsx @@ -340,4 +340,35 @@ describe('DashboardLayout', () => { expect(within(desktopNavigation).getByText('Action 1')).toBeTruthy(); expect(within(desktopNavigation).getByText('Action 2')).toBeTruthy(); }); + + test('renders without the navigation and toggle button', async () => { + const NAVIGATION: Navigation = [ + { + title: 'Dashboard', + segment: 'dashboard', + icon: , + }, + { + title: 'Orders', + segment: 'orders', + icon: , + }, + ]; + + render( + + Hello world + , + ); + + const desktopNavigation = screen.queryByRole('navigation', { name: 'Desktop' }); + const navigationToggle = screen.queryByLabelText('Collapse menu'); + + // Expect that the navigation and toggle button are not rendered + expect(desktopNavigation).toBeNull(); + expect(navigationToggle).toBeNull(); + + // Ensure the main content is still rendered + expect(screen.getByText('Hello world')).toBeTruthy(); + }); }); diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index b21df1beee3..f117e2af6c3 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -360,6 +360,11 @@ export interface DashboardLayoutProps { toolbarActions?: {}; toolbarAccount?: AccountProps; }; + /** + * Whether the navigation bar and menu icon should be hidden + * @default false + */ + hideNavigation?: boolean; } /** @@ -373,7 +378,13 @@ export interface DashboardLayoutProps { * - [DashboardLayout API](https://mui.com/toolpad/core/api/dashboard-layout) */ function DashboardLayout(props: DashboardLayoutProps) { - const { children, disableCollapsibleSidebar = false, slots, slotProps } = props; + const { + children, + disableCollapsibleSidebar = false, + slots, + slotProps, + hideNavigation = false, + } = props; const theme = useTheme(); @@ -545,22 +556,26 @@ function DashboardLayout(props: DashboardLayoutProps) { - - {getMenuIcon(isMobileNavigationExpanded)} - - - {getMenuIcon(isDesktopNavigationExpanded)} - + {!hideNavigation ? ( + + + {getMenuIcon(isMobileNavigationExpanded)} + + + {getMenuIcon(isDesktopNavigationExpanded)} + + + ) : null} - - {getDrawerContent(false, 'Phone')} - - - {getDrawerContent(isMobileMini, 'Tablet')} - - - {getDrawerContent(isDesktopMini, 'Desktop')} - + {!hideNavigation ? ( + + + {getDrawerContent(false, 'Phone')} + + + {getDrawerContent(isMobileMini, 'Tablet')} + + + {getDrawerContent(isDesktopMini, 'Desktop')} + + + ) : null}