diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js
index 514612d1ecd..4a8fa95bca4 100644
--- a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js
+++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js
@@ -1,7 +1,11 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { useDemoRouter } from '@toolpad/core/internal';
-import { PageContainer, PageContainerToolbar } from '@toolpad/core/PageContainer';
+import {
+ PageContainer,
+ PageHeader,
+ PageHeaderToolbar,
+} from '@toolpad/core/PageContainer';
import { AppProvider } from '@toolpad/core/AppProvider';
import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs';
@@ -20,9 +24,9 @@ const NAVIGATION = [
];
// preview-start
-function PageToolbar({ status }) {
+function CustomPageToolbar({ status }) {
return (
-
+
Current status: {status}
} color="inherit">
Export
@@ -35,21 +39,34 @@ function PageToolbar({ status }) {
slotProps={{ field: { size: 'small' } }}
label="Period"
/>
-
+
);
}
+
+CustomPageToolbar.propTypes = {
+ status: PropTypes.string.isRequired,
+};
+
+function CustomPageHeader({ status }) {
+ const CustomPageToolbarComponent = React.useCallback(
+ () => ,
+ [status],
+ );
+
+ return ;
+}
// preview-end
-PageToolbar.propTypes = {
+CustomPageHeader.propTypes = {
status: PropTypes.string.isRequired,
};
export default function ActionsPageContainer() {
const router = useDemoRouter();
- const status = 'supesh';
+ const status = 'Active';
- const PageToolbarComponent = React.useCallback(
- () => ,
+ const CustomPageHeaderComponent = React.useCallback(
+ () => ,
[status],
);
const theme = useTheme();
@@ -58,7 +75,7 @@ export default function ActionsPageContainer() {
-
+
diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx
index c14ae6cbe40..2345e1cf2a7 100644
--- a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx
+++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx
@@ -1,6 +1,10 @@
import * as React from 'react';
import { useDemoRouter } from '@toolpad/core/internal';
-import { PageContainer, PageContainerToolbar } from '@toolpad/core/PageContainer';
+import {
+ PageContainer,
+ PageHeader,
+ PageHeaderToolbar,
+} from '@toolpad/core/PageContainer';
import { AppProvider } from '@toolpad/core/AppProvider';
import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs';
@@ -19,9 +23,9 @@ const NAVIGATION = [
];
// preview-start
-function PageToolbar({ status }: { status: string }) {
+function CustomPageToolbar({ status }: { status: string }) {
return (
-
+
Current status: {status}
} color="inherit">
Export
@@ -34,17 +38,26 @@ function PageToolbar({ status }: { status: string }) {
slotProps={{ field: { size: 'small' } as any }}
label="Period"
/>
-
+
);
}
+
+function CustomPageHeader({ status }: { status: string }) {
+ const CustomPageToolbarComponent = React.useCallback(
+ () => ,
+ [status],
+ );
+
+ return ;
+}
// preview-end
export default function ActionsPageContainer() {
const router = useDemoRouter();
- const status = 'supesh';
+ const status = 'Active';
- const PageToolbarComponent = React.useCallback(
- () => ,
+ const CustomPageHeaderComponent = React.useCallback(
+ () => ,
[status],
);
const theme = useTheme();
@@ -53,7 +66,7 @@ export default function ActionsPageContainer() {
-
+
diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview
index 1c0ac87de1e..965e05f829a 100644
--- a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview
+++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview
@@ -1,6 +1,6 @@
-function PageToolbar({ status }: { status: string }) {
+function CustomPageToolbar({ status }: { status: string }) {
return (
-
+
Current status: {status}
} color="inherit">
Export
@@ -13,6 +13,15 @@ function PageToolbar({ status }: { status: string }) {
slotProps={{ field: { size: 'small' } as any }}
label="Period"
/>
-
+
);
+}
+
+function CustomPageHeader({ status }: { status: string }) {
+ const CustomPageToolbarComponent = React.useCallback(
+ () => ,
+ [status],
+ );
+
+ return ;
}
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.js b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.js
new file mode 100644
index 00000000000..43d867e76ce
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.js
@@ -0,0 +1,72 @@
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import { createTheme } from '@mui/material/styles';
+import MapIcon from '@mui/icons-material/Map';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { DashboardLayout } from '@toolpad/core/DashboardLayout';
+import { PageContainer } from '@toolpad/core/PageContainer';
+import { useDemoRouter } from '@toolpad/core/internal';
+
+const NAVIGATION = [
+ {
+ segment: 'map',
+ title: 'Map',
+ icon: ,
+ },
+];
+
+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 PageContainerFullScreen(props) {
+ const { window } = props;
+
+ const router = useDemoRouter('/map');
+
+ // Remove this const when copying and pasting into your project.
+ const demoWindow = window !== undefined ? window() : undefined;
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+PageContainerFullScreen.propTypes = {
+ /**
+ * Injected by the documentation to work in an iframe.
+ * Remove this when copying and pasting into your project.
+ */
+ window: PropTypes.func,
+};
+
+export default PageContainerFullScreen;
diff --git a/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.tsx b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.tsx
new file mode 100644
index 00000000000..4b3ff0fdb3c
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.tsx
@@ -0,0 +1,69 @@
+import * as React from 'react';
+import { createTheme } from '@mui/material/styles';
+import MapIcon from '@mui/icons-material/Map';
+import { AppProvider, type Navigation } from '@toolpad/core/AppProvider';
+import { DashboardLayout } from '@toolpad/core/DashboardLayout';
+import { PageContainer } from '@toolpad/core/PageContainer';
+import { useDemoRouter } from '@toolpad/core/internal';
+
+const NAVIGATION: Navigation = [
+ {
+ segment: 'map',
+ title: 'Map',
+ icon: ,
+ },
+];
+
+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,
+ },
+ },
+});
+
+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 PageContainerFullScreen(props: DemoProps) {
+ const { window } = props;
+
+ const router = useDemoRouter('/map');
+
+ // 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/page-container/PageContainerFullScreen.tsx.preview b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.tsx.preview
new file mode 100644
index 00000000000..973c30fdb99
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerFullScreen.tsx.preview
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/page-container/PageContainerHeader.js b/docs/data/toolpad/core/components/page-container/PageContainerHeader.js
new file mode 100644
index 00000000000..d68aaf521ea
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerHeader.js
@@ -0,0 +1,34 @@
+import * as React from 'react';
+// preview-start
+import { PageHeader } from '@toolpad/core/PageContainer';
+// preview-end
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { useDemoRouter } from '@toolpad/core/internal';
+import { useTheme } from '@mui/material/styles';
+import Box from '@mui/material/Box';
+import Container from '@mui/material/Container';
+import Paper from '@mui/material/Paper';
+
+const NAVIGATION = [
+ { segment: '', title: 'Home' },
+ { segment: 'orders', title: 'Orders' },
+];
+
+export default function PageContainerHeader() {
+ const router = useDemoRouter('/orders');
+
+ const theme = useTheme();
+
+ return (
+
+
+ {/* preview-start */}
+
+
+ Page content
+
+ {/* preview-end */}
+
+
+ );
+}
diff --git a/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx b/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx
new file mode 100644
index 00000000000..d68aaf521ea
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx
@@ -0,0 +1,34 @@
+import * as React from 'react';
+// preview-start
+import { PageHeader } from '@toolpad/core/PageContainer';
+// preview-end
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { useDemoRouter } from '@toolpad/core/internal';
+import { useTheme } from '@mui/material/styles';
+import Box from '@mui/material/Box';
+import Container from '@mui/material/Container';
+import Paper from '@mui/material/Paper';
+
+const NAVIGATION = [
+ { segment: '', title: 'Home' },
+ { segment: 'orders', title: 'Orders' },
+];
+
+export default function PageContainerHeader() {
+ const router = useDemoRouter('/orders');
+
+ const theme = useTheme();
+
+ return (
+
+
+ {/* preview-start */}
+
+
+ Page content
+
+ {/* preview-end */}
+
+
+ );
+}
diff --git a/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx.preview b/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx.preview
new file mode 100644
index 00000000000..ae1ce4bd1f4
--- /dev/null
+++ b/docs/data/toolpad/core/components/page-container/PageContainerHeader.tsx.preview
@@ -0,0 +1,8 @@
+import { PageHeader } from '@toolpad/core/PageContainer';
+
+// ...
+
+
+
+ Page content
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/page-container/page-container.md b/docs/data/toolpad/core/components/page-container/page-container.md
index e8b37a36f8b..70f3c2a2cf2 100644
--- a/docs/data/toolpad/core/components/page-container/page-container.md
+++ b/docs/data/toolpad/core/components/page-container/page-container.md
@@ -1,7 +1,7 @@
---
productId: toolpad-core
title: Page Container
-components: PageContainer, PageContainerToolbar
+components: PageContainer, PageHeader, PageHeaderToolbar
---
# Page Container
@@ -100,12 +100,24 @@ export default function Example() {
}
```
+## Responsiveness
+
+The Page Container component inherits the properties of the Material UI [Container](https://mui.com/material-ui/react-container/) component. You can use its [`maxWidth`](https://mui.com/material-ui/api/container/#container-prop-maxWidth) and [`fixed`](https://mui.com/material-ui/api/container/#container-prop-fixed) properties to control the bounds of the page. Set `maxWidth` to `false` to disable the container altogether and have the content bleed right up to the edges of the page.
+
+## Standalone page header
+
+The `PageHeader` component included in `PageContainer` can be imported and used by itself if you wish to do so, for more freedom of customization.
+
+{{"demo": "PageContainerHeader.js", "height": 300}}
+
## Actions
-You can configure additional actions in the area that is reserved on the right. To do so provide the `toolbar` slot to the `PageContainer` component. You can wrap the `PageContainerToolbar` component to create a custom toolbar component, as shown here:
+You can configure additional actions in the area that is reserved on the right. To do so provide a custom `header` slot to the `PageContainer` component, where you can provide a custom `toolbar` slot to a `PageHeader`. You can wrap the `PageHeaderToolbar` component to create a custom toolbar component, as shown here:
{{"demo": "ActionsPageContainer.js", "height": 300}}
-## Responsiveness
+## Full-size content
-The Page Container component inherits the properties of the Material UI [Container](https://mui.com/material-ui/react-container/) component. You can use its [`maxWidth`](https://mui.com/material-ui/api/container/#container-prop-maxWidth) and [`fixed`](https://mui.com/material-ui/api/container/#container-prop-fixed) properties to control the bounds of the page. Set `maxWidth` to `false` to disable the container altogether and have the content bleed right up to the edges of the page.
+The content inside the container can take up the full remaining available area with styles such as `flex: 1` or `height: 100%`.
+
+{{"demo": "PageContainerFullScreen.js", "height": 400, "iframe": true}}
diff --git a/docs/data/toolpad/core/pagesApi.js b/docs/data/toolpad/core/pagesApi.js
index 8a3bc6d2b60..c36b8e189db 100644
--- a/docs/data/toolpad/core/pagesApi.js
+++ b/docs/data/toolpad/core/pagesApi.js
@@ -8,7 +8,8 @@ module.exports = [
{ pathname: '/toolpad/core/api/dialogs-provider' },
{ pathname: '/toolpad/core/api/notifications-provider' },
{ pathname: '/toolpad/core/api/page-container' },
- { pathname: '/toolpad/core/api/page-container-toolbar' },
+ { pathname: '/toolpad/core/api/page-header' },
+ { pathname: '/toolpad/core/api/page-header-toolbar' },
{ pathname: '/toolpad/core/api/sign-in-button' },
{ pathname: '/toolpad/core/api/sign-in-page' },
{ pathname: '/toolpad/core/api/sign-out-button' },
diff --git a/docs/pages/toolpad/core/api/account-popover-footer.json b/docs/pages/toolpad/core/api/account-popover-footer.json
index 4d4b4d99d00..a10949e29d7 100644
--- a/docs/pages/toolpad/core/api/account-popover-footer.json
+++ b/docs/pages/toolpad/core/api/account-popover-footer.json
@@ -1,5 +1,13 @@
{
- "props": {},
+ "props": {
+ "sx": {
+ "type": {
+ "name": "union",
+ "description": "Array<func
| object
| bool>
| func
| object"
+ },
+ "additionalInfo": { "sx": true }
+ }
+ },
"name": "AccountPopoverFooter",
"imports": ["import { AccountPopoverFooter } from '@toolpad/core/Account';"],
"classes": [],
diff --git a/docs/pages/toolpad/core/api/account-popover-header.json b/docs/pages/toolpad/core/api/account-popover-header.json
index e2ec37ec671..1289db98b2e 100644
--- a/docs/pages/toolpad/core/api/account-popover-header.json
+++ b/docs/pages/toolpad/core/api/account-popover-header.json
@@ -1,5 +1,5 @@
{
- "props": {},
+ "props": { "children": { "type": { "name": "node" } } },
"name": "AccountPopoverHeader",
"imports": ["import { AccountPopoverHeader } from '@toolpad/core/Account';"],
"classes": [],
diff --git a/docs/pages/toolpad/core/api/page-container-toolbar.json b/docs/pages/toolpad/core/api/page-container-toolbar.json
deleted file mode 100644
index 4d789399e61..00000000000
--- a/docs/pages/toolpad/core/api/page-container-toolbar.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "props": {},
- "name": "PageContainerToolbar",
- "imports": ["import { PageContainerToolbar } from '@toolpad/core/PageContainer';"],
- "classes": [],
- "spread": true,
- "themeDefaultProps": false,
- "muiName": "PageContainerToolbar",
- "filename": "/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx",
- "inheritance": null,
- "demos": "",
- "cssComponent": false
-}
diff --git a/docs/pages/toolpad/core/api/page-container.json b/docs/pages/toolpad/core/api/page-container.json
index e7a4835c201..95ddd5e232d 100644
--- a/docs/pages/toolpad/core/api/page-container.json
+++ b/docs/pages/toolpad/core/api/page-container.json
@@ -3,11 +3,23 @@
"breadcrumbs": {
"type": { "name": "arrayOf", "description": "Array<{ path: string, title: string }>" }
},
- "slotProps": { "type": { "name": "shape", "description": "{ toolbar: { children?: node } }" } },
+ "slotProps": {
+ "type": {
+ "name": "shape",
+ "description": "{ header: { breadcrumbs?: Array<{ path: string, title: string }>, slotProps?: { toolbar: object }, slots?: { toolbar?: elementType }, title?: string } }"
+ }
+ },
"slots": {
- "type": { "name": "shape", "description": "{ toolbar?: elementType }" },
+ "type": { "name": "shape", "description": "{ header?: elementType }" },
"additionalInfo": { "slotsApi": true }
},
+ "sx": {
+ "type": {
+ "name": "union",
+ "description": "Array<func
| object
| bool>
| func
| object"
+ },
+ "additionalInfo": { "sx": true }
+ },
"title": { "type": { "name": "string" } }
},
"name": "PageContainer",
@@ -17,9 +29,9 @@
],
"slots": [
{
- "name": "toolbar",
- "description": "The component that renders the actions toolbar.",
- "default": "Snackbar",
+ "name": "header",
+ "description": "The component that renders the page header.",
+ "default": "PageHeader",
"class": null
}
],
diff --git a/docs/pages/toolpad/core/api/page-container-toolbar.js b/docs/pages/toolpad/core/api/page-header-toolbar.js
similarity index 76%
rename from docs/pages/toolpad/core/api/page-container-toolbar.js
rename to docs/pages/toolpad/core/api/page-header-toolbar.js
index c34ccdc8262..01adee5b6bd 100644
--- a/docs/pages/toolpad/core/api/page-container-toolbar.js
+++ b/docs/pages/toolpad/core/api/page-header-toolbar.js
@@ -1,7 +1,7 @@
import * as React from 'react';
import ApiPage from 'docs/src/modules/components/ApiPage';
import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
-import jsonPageContent from './page-container-toolbar.json';
+import jsonPageContent from './page-header-toolbar.json';
export default function Page(props) {
const { descriptions, pageContent } = props;
@@ -10,9 +10,9 @@ export default function Page(props) {
Page.getInitialProps = () => {
const req = require.context(
- 'docs-toolpad/translations/api-docs/page-container-toolbar',
+ 'docs-toolpad/translations/api-docs/page-header-toolbar',
false,
- /\.\/page-container-toolbar.*.json$/,
+ /\.\/page-header-toolbar.*.json$/,
);
const descriptions = mapApiPageTranslations(req);
diff --git a/docs/pages/toolpad/core/api/page-header-toolbar.json b/docs/pages/toolpad/core/api/page-header-toolbar.json
new file mode 100644
index 00000000000..6824539c9d3
--- /dev/null
+++ b/docs/pages/toolpad/core/api/page-header-toolbar.json
@@ -0,0 +1,13 @@
+{
+ "props": {},
+ "name": "PageHeaderToolbar",
+ "imports": ["import { PageHeaderToolbar } from '@toolpad/core/PageContainer';"],
+ "classes": [],
+ "spread": true,
+ "themeDefaultProps": false,
+ "muiName": "PageHeaderToolbar",
+ "filename": "/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.tsx",
+ "inheritance": null,
+ "demos": "",
+ "cssComponent": false
+}
diff --git a/docs/pages/toolpad/core/api/page-header.js b/docs/pages/toolpad/core/api/page-header.js
new file mode 100644
index 00000000000..0ed0e513800
--- /dev/null
+++ b/docs/pages/toolpad/core/api/page-header.js
@@ -0,0 +1,23 @@
+import * as React from 'react';
+import ApiPage from 'docs/src/modules/components/ApiPage';
+import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
+import jsonPageContent from './page-header.json';
+
+export default function Page(props) {
+ const { descriptions, pageContent } = props;
+ return ;
+}
+
+Page.getInitialProps = () => {
+ const req = require.context(
+ 'docs-toolpad/translations/api-docs/page-header',
+ false,
+ /\.\/page-header.*.json$/,
+ );
+ const descriptions = mapApiPageTranslations(req);
+
+ return {
+ descriptions,
+ pageContent: jsonPageContent,
+ };
+};
diff --git a/docs/pages/toolpad/core/api/page-header.json b/docs/pages/toolpad/core/api/page-header.json
new file mode 100644
index 00000000000..68523c20a64
--- /dev/null
+++ b/docs/pages/toolpad/core/api/page-header.json
@@ -0,0 +1,29 @@
+{
+ "props": {
+ "breadcrumbs": {
+ "type": { "name": "arrayOf", "description": "Array<{ path: string, title: string }>" }
+ },
+ "slotProps": { "type": { "name": "shape", "description": "{ toolbar: { children?: node } }" } },
+ "slots": {
+ "type": { "name": "shape", "description": "{ toolbar?: elementType }" },
+ "additionalInfo": { "slotsApi": true }
+ },
+ "title": { "type": { "name": "string" } }
+ },
+ "name": "PageHeader",
+ "imports": ["import { PageHeader } from '@toolpad/core/PageContainer';"],
+ "slots": [
+ {
+ "name": "toolbar",
+ "description": "The component that renders the actions toolbar.",
+ "default": "PageHeaderToolbar",
+ "class": null
+ }
+ ],
+ "classes": [],
+ "muiName": "PageHeader",
+ "filename": "/packages/toolpad-core/src/PageContainer/PageHeader.tsx",
+ "inheritance": null,
+ "demos": "",
+ "cssComponent": false
+}
diff --git a/docs/pages/toolpad/core/api/sign-in-button.json b/docs/pages/toolpad/core/api/sign-in-button.json
index 72ccc67fc4a..0d34a3b5cf4 100644
--- a/docs/pages/toolpad/core/api/sign-in-button.json
+++ b/docs/pages/toolpad/core/api/sign-in-button.json
@@ -1,5 +1,5 @@
{
- "props": {},
+ "props": { "children": { "type": { "name": "node" } } },
"name": "SignInButton",
"imports": ["import { SignInButton } from '@toolpad/core/Account';"],
"classes": [
diff --git a/docs/pages/toolpad/core/api/sign-out-button.json b/docs/pages/toolpad/core/api/sign-out-button.json
index 9305dc4de49..66fd2b0b73d 100644
--- a/docs/pages/toolpad/core/api/sign-out-button.json
+++ b/docs/pages/toolpad/core/api/sign-out-button.json
@@ -1,5 +1,5 @@
{
- "props": {},
+ "props": { "children": { "type": { "name": "node" } } },
"name": "SignOutButton",
"imports": ["import { SignOutButton } from '@toolpad/core/Account';"],
"classes": [
diff --git a/docs/translations/api-docs/account-popover-footer/account-popover-footer.json b/docs/translations/api-docs/account-popover-footer/account-popover-footer.json
index f93d4cbd8c7..6302728c133 100644
--- a/docs/translations/api-docs/account-popover-footer/account-popover-footer.json
+++ b/docs/translations/api-docs/account-popover-footer/account-popover-footer.json
@@ -1 +1,9 @@
-{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} }
+{
+ "componentDescription": "",
+ "propDescriptions": {
+ "sx": {
+ "description": "The system prop that allows defining system overrides as well as additional CSS styles."
+ }
+ },
+ "classDescriptions": {}
+}
diff --git a/docs/translations/api-docs/account-popover-header/account-popover-header.json b/docs/translations/api-docs/account-popover-header/account-popover-header.json
index f93d4cbd8c7..6d480ad874c 100644
--- a/docs/translations/api-docs/account-popover-header/account-popover-header.json
+++ b/docs/translations/api-docs/account-popover-header/account-popover-header.json
@@ -1 +1,5 @@
-{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} }
+{
+ "componentDescription": "",
+ "propDescriptions": { "children": { "description": "The content of the component." } },
+ "classDescriptions": {}
+}
diff --git a/docs/translations/api-docs/page-container/page-container.json b/docs/translations/api-docs/page-container/page-container.json
index 3ff8ccbdbd2..80156f5a92c 100644
--- a/docs/translations/api-docs/page-container/page-container.json
+++ b/docs/translations/api-docs/page-container/page-container.json
@@ -6,6 +6,9 @@
},
"slotProps": { "description": "The props used for each slot inside." },
"slots": { "description": "The components used for each slot inside." },
+ "sx": {
+ "description": "The system prop that allows defining system overrides as well as additional CSS styles."
+ },
"title": { "description": "The title of the page. Leave blank to use the active page title." }
},
"classDescriptions": {
@@ -46,5 +49,5 @@
},
"root": { "description": "Styles applied to the root element." }
},
- "slotDescriptions": { "toolbar": "The component that renders the actions toolbar." }
+ "slotDescriptions": { "header": "The component that renders the page header." }
}
diff --git a/docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json b/docs/translations/api-docs/page-header-toolbar/page-header-toolbar.json
similarity index 100%
rename from docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json
rename to docs/translations/api-docs/page-header-toolbar/page-header-toolbar.json
diff --git a/docs/translations/api-docs/page-header/page-header.json b/docs/translations/api-docs/page-header/page-header.json
new file mode 100644
index 00000000000..0e7d13e55a2
--- /dev/null
+++ b/docs/translations/api-docs/page-header/page-header.json
@@ -0,0 +1,13 @@
+{
+ "componentDescription": "A header component to provide a title and breadcrumbs for your pages.",
+ "propDescriptions": {
+ "breadcrumbs": {
+ "description": "The breadcrumbs of the page. Leave blank to use the active page breadcrumbs."
+ },
+ "slotProps": { "description": "The props used for each slot inside." },
+ "slots": { "description": "The components used for each slot inside." },
+ "title": { "description": "The title of the page. Leave blank to use the active page title." }
+ },
+ "classDescriptions": {},
+ "slotDescriptions": { "toolbar": "The component that renders the actions toolbar." }
+}
diff --git a/docs/translations/api-docs/sign-in-button/sign-in-button.json b/docs/translations/api-docs/sign-in-button/sign-in-button.json
index 18077dbb50a..77a6eff5224 100644
--- a/docs/translations/api-docs/sign-in-button/sign-in-button.json
+++ b/docs/translations/api-docs/sign-in-button/sign-in-button.json
@@ -1,6 +1,6 @@
{
"componentDescription": "",
- "propDescriptions": {},
+ "propDescriptions": { "children": { "description": "The content of the component." } },
"classDescriptions": {
"colorError": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
diff --git a/docs/translations/api-docs/sign-out-button/sign-out-button.json b/docs/translations/api-docs/sign-out-button/sign-out-button.json
index 18077dbb50a..77a6eff5224 100644
--- a/docs/translations/api-docs/sign-out-button/sign-out-button.json
+++ b/docs/translations/api-docs/sign-out-button/sign-out-button.json
@@ -1,6 +1,6 @@
{
"componentDescription": "",
- "propDescriptions": {},
+ "propDescriptions": { "children": { "description": "The content of the component." } },
"classDescriptions": {
"colorError": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
diff --git a/packages/toolpad-core/src/Account/AccountPopoverFooter.tsx b/packages/toolpad-core/src/Account/AccountPopoverFooter.tsx
index 62696b0b449..01699d5a0a3 100644
--- a/packages/toolpad-core/src/Account/AccountPopoverFooter.tsx
+++ b/packages/toolpad-core/src/Account/AccountPopoverFooter.tsx
@@ -1,11 +1,12 @@
import * as React from 'react';
+import PropTypes from 'prop-types';
import Box, { BoxProps } from '@mui/material/Box';
export interface AccountPopoverFooterProps extends BoxProps {
children?: React.ReactNode;
}
-export /**
+/**
*
* Demos:
*
@@ -14,7 +15,8 @@ export /**
* API:
*
* - [AccountPopoverFooter API](https://mui.com/toolpad/core/api/account-popover-footer)
- */ function AccountPopoverFooter(props: AccountPopoverFooterProps) {
+ */
+function AccountPopoverFooter(props: AccountPopoverFooterProps) {
const { children, ...rest } = props;
return (
);
}
+
+AccountPopoverFooter.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * @ignore
+ */
+ children: PropTypes.node,
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),
+ PropTypes.func,
+ PropTypes.object,
+ ]),
+} as any;
+
+export { AccountPopoverFooter };
diff --git a/packages/toolpad-core/src/Account/AccountPopoverHeader.tsx b/packages/toolpad-core/src/Account/AccountPopoverHeader.tsx
index f22591550d3..10de9d409f6 100644
--- a/packages/toolpad-core/src/Account/AccountPopoverHeader.tsx
+++ b/packages/toolpad-core/src/Account/AccountPopoverHeader.tsx
@@ -1,11 +1,12 @@
import * as React from 'react';
+import PropTypes from 'prop-types';
import Stack, { StackProps } from '@mui/material/Stack';
export interface AccountPopoverHeaderProps extends StackProps {
children?: React.ReactNode;
}
-export /**
+/**
*
* Demos:
*
@@ -14,7 +15,21 @@ export /**
* API:
*
* - [AccountPopoverHeader API](https://mui.com/toolpad/core/api/account-popover-header)
- */ function AccountPopoverHeader(props: AccountPopoverHeaderProps) {
+ */
+function AccountPopoverHeader(props: AccountPopoverHeaderProps) {
const { children, ...rest } = props;
return {children};
}
+
+AccountPopoverHeader.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The content of the component.
+ */
+ children: PropTypes.node,
+} as any;
+
+export { AccountPopoverHeader };
diff --git a/packages/toolpad-core/src/Account/SignInButton.tsx b/packages/toolpad-core/src/Account/SignInButton.tsx
index 13d79b6ccde..92b16e8fa12 100644
--- a/packages/toolpad-core/src/Account/SignInButton.tsx
+++ b/packages/toolpad-core/src/Account/SignInButton.tsx
@@ -1,9 +1,10 @@
import * as React from 'react';
+import PropTypes from 'prop-types';
import Button, { ButtonProps } from '@mui/material/Button';
import { AuthenticationContext } from '../AppProvider/AppProvider';
import { useLocaleText } from '../shared/locales/LocaleContext';
-export /**
+/**
*
* Demos:
*
@@ -12,7 +13,8 @@ export /**
* API:
*
* - [SignInButton API](https://mui.com/toolpad/core/api/sign-in-button)
- */ function SignInButton(props: ButtonProps) {
+ */
+function SignInButton(props: ButtonProps) {
const authentication = React.useContext(AuthenticationContext);
const localeText = useLocaleText();
@@ -38,3 +40,16 @@ export /**
);
}
+
+SignInButton.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The content of the component.
+ */
+ children: PropTypes.node,
+} as any;
+
+export { SignInButton };
diff --git a/packages/toolpad-core/src/Account/SignOutButton.tsx b/packages/toolpad-core/src/Account/SignOutButton.tsx
index 03d87b1fcaf..e9d8e1701b8 100644
--- a/packages/toolpad-core/src/Account/SignOutButton.tsx
+++ b/packages/toolpad-core/src/Account/SignOutButton.tsx
@@ -1,4 +1,5 @@
import * as React from 'react';
+import PropTypes from 'prop-types';
import Button, { ButtonProps } from '@mui/material/Button';
import LogoutIcon from '@mui/icons-material/Logout';
import { AuthenticationContext } from '../AppProvider/AppProvider';
@@ -6,7 +7,7 @@ import { useLocaleText } from '../shared/locales/LocaleContext';
export type SignOutButtonProps = ButtonProps;
-export /**
+/**
*
* Demos:
*
@@ -15,7 +16,8 @@ export /**
* API:
*
* - [SignOutButton API](https://mui.com/toolpad/core/api/sign-out-button)
- */ function SignOutButton(props: SignOutButtonProps) {
+ */
+function SignOutButton(props: SignOutButtonProps) {
const authentication = React.useContext(AuthenticationContext);
const localeText = useLocaleText();
@@ -42,3 +44,16 @@ export /**
);
}
+
+SignOutButton.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The content of the component.
+ */
+ children: PropTypes.node,
+} as any;
+
+export { SignOutButton };
diff --git a/packages/toolpad-core/src/DashboardLayout/ThemeSwitcher.tsx b/packages/toolpad-core/src/DashboardLayout/ThemeSwitcher.tsx
index 23fa68d0fd7..927b8695a61 100644
--- a/packages/toolpad-core/src/DashboardLayout/ThemeSwitcher.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/ThemeSwitcher.tsx
@@ -7,6 +7,7 @@ import DarkModeIcon from '@mui/icons-material/DarkMode';
import LightModeIcon from '@mui/icons-material/LightMode';
import useSsr from '@toolpad/utils/hooks/useSsr';
import { PaletteModeContext } from '../shared/context';
+
/**
*
* Demos:
diff --git a/packages/toolpad-core/src/DashboardLayout/ToolbarActions.tsx b/packages/toolpad-core/src/DashboardLayout/ToolbarActions.tsx
index ca25ff54493..19a2717870f 100644
--- a/packages/toolpad-core/src/DashboardLayout/ToolbarActions.tsx
+++ b/packages/toolpad-core/src/DashboardLayout/ToolbarActions.tsx
@@ -2,6 +2,7 @@
import * as React from 'react';
import Stack from '@mui/material/Stack';
import { ThemeSwitcher } from './ThemeSwitcher';
+
/**
*
* Demos:
diff --git a/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx b/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx
index 1eee03441a4..19ee4085eeb 100644
--- a/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx
+++ b/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx
@@ -14,7 +14,7 @@ describe('PageContainer', () => {
describeConformance(, () => ({
skip: ['themeDefaultProps'],
slots: {
- toolbar: {},
+ header: {},
},
}));
@@ -158,29 +158,6 @@ describe('PageContainer', () => {
expect(within(breadcrumbs).getByText('World')).toBeTruthy();
});
- // TODO: Remove in the next major version
- test('renders legacy breadcrumbs prop', async () => {
- vi.spyOn(console, 'warn').mockImplementation(() => {});
- render(
- ,
- );
-
- const breadcrumbs = screen.getByRole('navigation', { name: 'breadcrumb' });
-
- const helloLink = within(breadcrumbs).getByRole('link', { name: 'Hello' });
- expect(helloLink.getAttribute('href')).toBe('/hello');
- expect(within(breadcrumbs).getByText('World')).toBeTruthy();
- expect(console.warn).toHaveBeenCalledOnce();
- expect(console.warn).toHaveBeenCalledWith(
- 'The PageContainer `breadCrumbs` prop is deprecated. Use `breadcrumbs` instead.',
- );
- });
-
test("doesn't spread title to child", async () => {
render();
diff --git a/packages/toolpad-core/src/PageContainer/PageContainer.tsx b/packages/toolpad-core/src/PageContainer/PageContainer.tsx
index 6e7235684f0..011794841f9 100644
--- a/packages/toolpad-core/src/PageContainer/PageContainer.tsx
+++ b/packages/toolpad-core/src/PageContainer/PageContainer.tsx
@@ -1,37 +1,11 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import warnOnce from '@toolpad/utils/warnOnce';
-import Breadcrumbs from '@mui/material/Breadcrumbs';
+import Box from '@mui/material/Box';
import Container, { ContainerProps } from '@mui/material/Container';
-import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
-import Typography from '@mui/material/Typography';
-import useSlotProps from '@mui/utils/useSlotProps';
-import { styled } from '@mui/material';
-import { Link as ToolpadLink } from '../shared/Link';
-import { PageContainerToolbar, PageContainerToolbarProps } from './PageContainerToolbar';
-import { getItemTitle } from '../shared/navigation';
-import { useActivePage } from '../useActivePage';
-
-const PageContentHeader = styled('div')(({ theme }) => ({
- display: 'flex',
- flexDirection: 'row',
- justifyContent: 'space-between',
- gap: theme.spacing(2),
-}));
-
-export interface PageContainerSlotProps {
- toolbar: PageContainerToolbarProps;
-}
-
-export interface PageContainerSlots {
- /**
- * The component that renders the actions toolbar.
- * @default Snackbar
- */
- toolbar: React.ElementType;
-}
+import { SxProps } from '@mui/material';
+import { PageHeader, PageHeaderProps } from './PageHeader';
export interface Breadcrumb {
/**
@@ -43,12 +17,17 @@ export interface Breadcrumb {
*/
path: string;
}
+export interface PageContainerSlotProps {
+ header: PageHeaderProps;
+}
-// TODO: Remove in the next major version
-/**
- * @deprecated Use `Breadcrumb` instead.
- */
-export type BreadCrumb = Breadcrumb;
+export interface PageContainerSlots {
+ /**
+ * The component that renders the page header.
+ * @default PageHeader
+ */
+ header: React.ElementType;
+}
export interface PageContainerProps extends ContainerProps {
children?: React.ReactNode;
@@ -60,11 +39,6 @@ export interface PageContainerProps extends ContainerProps {
* The breadcrumbs of the page. Leave blank to use the active page breadcrumbs.
*/
breadcrumbs?: Breadcrumb[];
- // TODO: Remove in the next major version
- /**
- * @deprecated Use `breadcrumbs` instead.
- */
- breadCrumbs?: Breadcrumb[];
/**
* The components used for each slot inside.
*/
@@ -73,6 +47,10 @@ export interface PageContainerProps extends ContainerProps {
* The props used for each slot inside.
*/
slotProps?: PageContainerSlotProps;
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx?: SxProps;
}
/**
@@ -87,58 +65,15 @@ export interface PageContainerProps extends ContainerProps {
* - [PageContainer API](https://mui.com/toolpad/core/api/page-container)
*/
function PageContainer(props: PageContainerProps) {
- const { children, slots, slotProps, breadcrumbs, breadCrumbs, title, ...rest } = props;
-
- if (process.env.NODE_ENV !== 'production' && breadCrumbs) {
- warnOnce('The PageContainer `breadCrumbs` prop is deprecated. Use `breadcrumbs` instead.');
- }
+ const { children, breadcrumbs, slots, slotProps, title, ...rest } = props;
- const activePage = useActivePage();
-
- // TODO: Remove `props.breadCrumbs` in the next major version
- const resolvedBreadcrumbs = breadcrumbs ?? breadCrumbs ?? activePage?.breadcrumbs ?? [];
- const resolvedTitle = title ?? activePage?.title ?? '';
-
- const ToolbarComponent = props?.slots?.toolbar ?? PageContainerToolbar;
- const toolbarSlotProps = useSlotProps({
- elementType: ToolbarComponent,
- ownerState: props,
- externalSlotProps: props?.slotProps?.toolbar,
- additionalProps: {},
- });
+ const PageHeaderSlot = slots?.header ?? PageHeader;
return (
-
-
-
-
- {resolvedBreadcrumbs
- ? resolvedBreadcrumbs.map((item, index) => {
- return index < resolvedBreadcrumbs.length - 1 ? (
-
- {getItemTitle(item)}
-
- ) : (
-
- {getItemTitle(item)}
-
- );
- })
- : null}
-
-
-
- {resolvedTitle ? {resolvedTitle} : null}
-
-
-
- {children}
+
+
+
+ {children}
);
@@ -158,15 +93,6 @@ PageContainer.propTypes /* remove-proptypes */ = {
title: PropTypes.string.isRequired,
}),
),
- /**
- * @deprecated Use `breadcrumbs` instead.
- */
- breadCrumbs: PropTypes.arrayOf(
- PropTypes.shape({
- path: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- }),
- ),
/**
* @ignore
*/
@@ -175,16 +101,36 @@ PageContainer.propTypes /* remove-proptypes */ = {
* The props used for each slot inside.
*/
slotProps: PropTypes.shape({
- toolbar: PropTypes.shape({
- children: PropTypes.node,
+ header: PropTypes.shape({
+ breadcrumbs: PropTypes.arrayOf(
+ PropTypes.shape({
+ path: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ }),
+ ),
+ slotProps: PropTypes.shape({
+ toolbar: PropTypes.object.isRequired,
+ }),
+ slots: PropTypes.shape({
+ toolbar: PropTypes.elementType,
+ }),
+ title: PropTypes.string,
}).isRequired,
}),
/**
* The components used for each slot inside.
*/
slots: PropTypes.shape({
- toolbar: PropTypes.elementType,
+ header: PropTypes.elementType,
}),
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),
+ PropTypes.func,
+ PropTypes.object,
+ ]),
/**
* The title of the page. Leave blank to use the active page title.
*/
diff --git a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx b/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx
deleted file mode 100644
index 3eef00c9a8d..00000000000
--- a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-'use client';
-import * as React from 'react';
-import { styled } from '@mui/material';
-
-const PageContainerToolbarRoot = styled('div')(({ theme }) => ({
- display: 'flex',
- flexDirection: 'row',
- gap: theme.spacing(1),
- // Ensure the toolbar is always on the right side, even after wrapping
- marginLeft: 'auto',
-}));
-
-export interface PageContainerToolbarProps {
- children?: React.ReactNode;
-}
-
-/**
- *
- * Demos:
- *
- * - [Page Container](https://mui.com/toolpad/core/react-page-container/)
- *
- * API:
- *
- * - [PageContainerToolbar API](https://mui.com/toolpad/core/api/page-container-toolbar)
- */
-function PageContainerToolbar(props: PageContainerToolbarProps) {
- return ;
-}
-
-export { PageContainerToolbar };
diff --git a/packages/toolpad-core/src/PageContainer/PageHeader.tsx b/packages/toolpad-core/src/PageContainer/PageHeader.tsx
new file mode 100644
index 00000000000..d72921abefa
--- /dev/null
+++ b/packages/toolpad-core/src/PageContainer/PageHeader.tsx
@@ -0,0 +1,147 @@
+'use client';
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import Breadcrumbs from '@mui/material/Breadcrumbs';
+import Link from '@mui/material/Link';
+import Stack from '@mui/material/Stack';
+import Typography from '@mui/material/Typography';
+import useSlotProps from '@mui/utils/useSlotProps';
+import { styled } from '@mui/material';
+import { Link as ToolpadLink } from '../shared/Link';
+import { getItemTitle } from '../shared/navigation';
+import { useActivePage } from '../useActivePage';
+import { PageHeaderToolbar, PageHeaderToolbarProps } from './PageHeaderToolbar';
+import type { Breadcrumb } from './PageContainer';
+
+const PageContentHeader = styled('div')(({ theme }) => ({
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ gap: theme.spacing(2),
+}));
+
+export interface PageHeaderSlotProps {
+ toolbar: PageHeaderToolbarProps;
+}
+
+export interface PageHeaderSlots {
+ /**
+ * The component that renders the actions toolbar.
+ * @default PageHeaderToolbar
+ */
+ toolbar: React.ElementType;
+}
+
+export interface PageHeaderProps {
+ /**
+ * The title of the page. Leave blank to use the active page title.
+ */
+ title?: string;
+ /**
+ * The breadcrumbs of the page. Leave blank to use the active page breadcrumbs.
+ */
+ breadcrumbs?: Breadcrumb[];
+ /**
+ * The components used for each slot inside.
+ */
+ slots?: PageHeaderSlots;
+ /**
+ * The props used for each slot inside.
+ */
+ slotProps?: PageHeaderSlotProps;
+}
+
+/**
+ * A header component to provide a title and breadcrumbs for your pages.
+ *
+ * Demos:
+ *
+ * - [Page Container](https://mui.com/toolpad/core/react-page-container/)
+ *
+ * API:
+ *
+ * - [PageHeader API](https://mui.com/toolpad/core/api/page-header)
+ */
+function PageHeader(props: PageHeaderProps) {
+ const { breadcrumbs, title } = props;
+
+ const activePage = useActivePage();
+
+ const resolvedBreadcrumbs = breadcrumbs ?? activePage?.breadcrumbs ?? [];
+ const resolvedTitle = title ?? activePage?.title ?? '';
+
+ const ToolbarComponent = props?.slots?.toolbar ?? PageHeaderToolbar;
+ const toolbarSlotProps = useSlotProps({
+ elementType: ToolbarComponent,
+ ownerState: props,
+ externalSlotProps: props?.slotProps?.toolbar,
+ additionalProps: {},
+ });
+
+ return (
+
+
+ {resolvedBreadcrumbs
+ ? resolvedBreadcrumbs.map((item, index) => {
+ return index < resolvedBreadcrumbs.length - 1 ? (
+
+ {getItemTitle(item)}
+
+ ) : (
+
+ {getItemTitle(item)}
+
+ );
+ })
+ : null}
+
+
+
+ {resolvedTitle ? {resolvedTitle} : null}
+
+
+
+ );
+}
+
+PageHeader.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The breadcrumbs of the page. Leave blank to use the active page breadcrumbs.
+ */
+ breadcrumbs: PropTypes.arrayOf(
+ PropTypes.shape({
+ path: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ }),
+ ),
+ /**
+ * The props used for each slot inside.
+ */
+ slotProps: PropTypes.shape({
+ toolbar: PropTypes.shape({
+ children: PropTypes.node,
+ }).isRequired,
+ }),
+ /**
+ * The components used for each slot inside.
+ */
+ slots: PropTypes.shape({
+ toolbar: PropTypes.elementType,
+ }),
+ /**
+ * The title of the page. Leave blank to use the active page title.
+ */
+ title: PropTypes.string,
+} as any;
+
+export { PageHeader };
diff --git a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx b/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.test.tsx
similarity index 61%
rename from packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx
rename to packages/toolpad-core/src/PageContainer/PageHeaderToolbar.test.tsx
index 2cd4d9d5c03..58b8c335b6c 100644
--- a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx
+++ b/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.test.tsx
@@ -5,10 +5,10 @@
import * as React from 'react';
import { describe, test } from 'vitest';
import describeConformance from '@toolpad/utils/describeConformance';
-import { PageContainerToolbar } from './PageContainerToolbar';
+import { PageHeaderToolbar } from './PageHeaderToolbar';
-describe('PageContainerToolbar', () => {
- describeConformance(, () => ({
+describe('PageHeaderToolbar', () => {
+ describeConformance(, () => ({
skip: ['themeDefaultProps'],
}));
diff --git a/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.tsx b/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.tsx
new file mode 100644
index 00000000000..49944454b14
--- /dev/null
+++ b/packages/toolpad-core/src/PageContainer/PageHeaderToolbar.tsx
@@ -0,0 +1,43 @@
+'use client';
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import { styled } from '@mui/material';
+
+const PageHeaderToolbarRoot = styled('div')(({ theme }) => ({
+ display: 'flex',
+ flexDirection: 'row',
+ gap: theme.spacing(1),
+ // Ensure the toolbar is always on the right side, even after wrapping
+ marginLeft: 'auto',
+}));
+
+export interface PageHeaderToolbarProps {
+ children?: React.ReactNode;
+}
+
+/**
+ *
+ * Demos:
+ *
+ * - [Page Container](https://mui.com/toolpad/core/react-page-container/)
+ *
+ * API:
+ *
+ * - [PageHeaderToolbar API](https://mui.com/toolpad/core/api/page-header-toolbar)
+ */
+function PageHeaderToolbar(props: PageHeaderToolbarProps) {
+ return ;
+}
+
+PageHeaderToolbar.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * @ignore
+ */
+ children: PropTypes.node,
+} as any;
+
+export { PageHeaderToolbar };
diff --git a/packages/toolpad-core/src/PageContainer/index.ts b/packages/toolpad-core/src/PageContainer/index.ts
index c12250743e1..c72edd9b0e2 100644
--- a/packages/toolpad-core/src/PageContainer/index.ts
+++ b/packages/toolpad-core/src/PageContainer/index.ts
@@ -1,2 +1,3 @@
export * from './PageContainer';
-export * from './PageContainerToolbar';
+export * from './PageHeader';
+export * from './PageHeaderToolbar';
diff --git a/packages/toolpad-core/src/useActivePage/useActivePage.ts b/packages/toolpad-core/src/useActivePage/useActivePage.ts
index 3c7b03ada00..74665f7a518 100644
--- a/packages/toolpad-core/src/useActivePage/useActivePage.ts
+++ b/packages/toolpad-core/src/useActivePage/useActivePage.ts
@@ -7,10 +7,6 @@ import type { Breadcrumb } from '../PageContainer';
export interface ActivePage {
title: string;
path: string;
- /**
- * @deprecated Use `breadcrumbs` instead.
- */
- breadCrumbs: Breadcrumb[];
breadcrumbs: Breadcrumb[];
}
@@ -59,8 +55,6 @@ export function useActivePage(): ActivePage | null {
title: getItemTitle(activeItem),
path: getItemPath(navigationContext, activeItem),
breadcrumbs,
- // TODO: Remove in the next major version
- breadCrumbs: breadcrumbs,
};
}, [activeItem, rootItem, pathname, navigationContext]);
}
diff --git a/scripts/generateProptypes.ts b/scripts/generateProptypes.ts
index b0e80ecefad..ad49871579a 100644
--- a/scripts/generateProptypes.ts
+++ b/scripts/generateProptypes.ts
@@ -41,6 +41,16 @@ async function generateProptypes(
sourceFile: string,
tsFile: string,
): Promise {
+ const sourceContent = await fse.readFile(sourceFile, 'utf8');
+
+ if (
+ sourceContent.match(/@ignore - internal component\./) ||
+ sourceContent.match(/@ignore - internal hook\./) ||
+ sourceContent.match(/@ignore - do not document\./)
+ ) {
+ return;
+ }
+
const components = getPropTypesFromFile({
filePath: tsFile,
project,
@@ -82,7 +92,6 @@ async function generateProptypes(
});
});
- const sourceContent = await fse.readFile(sourceFile, 'utf8');
const isTsFile = /(\.(ts|tsx))/.test(sourceFile);
// TODO remove, should only have .types.ts
@@ -204,7 +213,7 @@ async function run(argv: HandlerArgv) {
folderName = folderName.slice(9);
}
- return fileName === folderName;
+ return !fileName.endsWith('.test');
})
.filter((filePath) => filePattern.test(filePath));