From c4c1e3c90ba4115cc8ea53e642fc13d029e01c6c Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:22:39 +0200 Subject: [PATCH 1/2] [core] Add PageContainer component (#3713) Signed-off-by: Jan Potoms <2109932+Janpot@users.noreply.github.com> Co-authored-by: Bharat Kashyap --- .../page-container/ActionsPageContainer.js | 55 +++++ .../page-container/ActionsPageContainer.tsx | 55 +++++ .../ActionsPageContainer.tsx.preview | 16 ++ .../page-container/BasicPageContainer.js | 26 +++ .../page-container/BasicPageContainer.tsx | 26 +++ .../BasicPageContainer.tsx.preview | 1 + .../components/page-container/PageContent.js | 36 +++ .../components/page-container/PageContent.tsx | 36 +++ .../TitleBreadcrumbsPageContainer.js | 37 ++++ .../TitleBreadcrumbsPageContainer.tsx | 37 ++++ .../TitleBreadcrumbsPageContainer.tsx.preview | 3 + .../page-container/page-container.md | 55 +++++ .../core/introduction/TutorialDefault.js | 41 ++-- .../core/introduction/TutorialDefault.tsx | 37 ++-- .../introduction/TutorialDefault.tsx.preview | 2 +- .../core/introduction/TutorialPages.js | 45 ++-- .../core/introduction/TutorialPages.tsx | 46 ++-- .../introduction/TutorialPages.tsx.preview | 2 +- .../toolpad/core/introduction/tutorial.md | 14 +- docs/data/toolpad/core/pages.ts | 4 + docs/data/toolpad/core/pagesApi.js | 2 + docs/package.json | 1 + .../core/api/page-container-toolbar.js | 23 ++ .../core/api/page-container-toolbar.json | 13 ++ docs/pages/toolpad/core/api/page-container.js | 23 ++ .../toolpad/core/api/page-container.json | 73 ++++++ .../core/react-page-container/index.js | 7 + docs/src/components/landing-core/Features.js | 3 +- .../landing-core/ToolpadDashboardLayout.tsx | 26 ++- .../landing-core/ToolpadPageContainerDemo.tsx | 58 +++++ .../page-container-toolbar.json | 1 + .../page-container/page-container.json | 43 ++++ .../create-toolpad-app/src/generateProject.ts | 32 ++- .../src/DashboardLayout/DashboardLayout.tsx | 8 +- .../src/PageContainer/PageContainer.test.tsx | 48 ++++ .../src/PageContainer/PageContainer.tsx | 209 ++++++++++++++++++ .../PageContainerToolbar.test.tsx | 16 ++ .../PageContainer/PageContainerToolbar.tsx | 31 +++ .../toolpad-core/src/PageContainer/index.ts | 2 + packages/toolpad-core/src/index.ts | 2 + packages/toolpad-core/src/shared/branding.ts | 7 + .../nextjs/src/app/(dashboard)/layout.tsx | 7 +- .../src/app/(dashboard)/orders/page.tsx | 4 +- .../nextjs/src/app/(dashboard)/page.tsx | 4 +- pnpm-lock.yaml | 134 +++++++++++ 45 files changed, 1229 insertions(+), 122 deletions(-) create mode 100644 docs/data/toolpad/core/components/page-container/ActionsPageContainer.js create mode 100644 docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx create mode 100644 docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview create mode 100644 docs/data/toolpad/core/components/page-container/BasicPageContainer.js create mode 100644 docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx create mode 100644 docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx.preview create mode 100644 docs/data/toolpad/core/components/page-container/PageContent.js create mode 100644 docs/data/toolpad/core/components/page-container/PageContent.tsx create mode 100644 docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.js create mode 100644 docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx create mode 100644 docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx.preview create mode 100644 docs/data/toolpad/core/components/page-container/page-container.md create mode 100644 docs/pages/toolpad/core/api/page-container-toolbar.js create mode 100644 docs/pages/toolpad/core/api/page-container-toolbar.json create mode 100644 docs/pages/toolpad/core/api/page-container.js create mode 100644 docs/pages/toolpad/core/api/page-container.json create mode 100644 docs/pages/toolpad/core/react-page-container/index.js create mode 100644 docs/src/components/landing-core/ToolpadPageContainerDemo.tsx create mode 100644 docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json create mode 100644 docs/translations/api-docs/page-container/page-container.json create mode 100644 packages/toolpad-core/src/PageContainer/PageContainer.test.tsx create mode 100644 packages/toolpad-core/src/PageContainer/PageContainer.tsx create mode 100644 packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx create mode 100644 packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx create mode 100644 packages/toolpad-core/src/PageContainer/index.ts create mode 100644 packages/toolpad-core/src/shared/branding.ts diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js new file mode 100644 index 00000000000..bd038582dc5 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.js @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { PageContainer, PageContainerToolbar } 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'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import Button from '@mui/material/Button'; +import FileDownloadIcon from '@mui/icons-material/FileDownload'; +import dayjs from 'dayjs'; +import { Paper, useTheme } from '@mui/material'; +import PageContent from './PageContent'; + +const NAVIGATION = [ + { segment: '', title: 'Weather' }, + { segment: 'orders', title: 'Orders' }, +]; + +// preview-start +function PageToolbar() { + return ( + + + + + ); +} +// preview-end + +export default function ActionsPageContainer() { + const router = useDemoRouter(); + + const theme = useTheme(); + + return ( + + + + + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx new file mode 100644 index 00000000000..bcc66b0a839 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { PageContainer, PageContainerToolbar } 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'; +import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; +import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; +import Button from '@mui/material/Button'; +import FileDownloadIcon from '@mui/icons-material/FileDownload'; +import dayjs from 'dayjs'; +import { Paper, useTheme } from '@mui/material'; +import PageContent from './PageContent'; + +const NAVIGATION = [ + { segment: '', title: 'Weather' }, + { segment: 'orders', title: 'Orders' }, +]; + +// preview-start +function PageToolbar() { + return ( + + + + + ); +} +// preview-end + +export default function ActionsPageContainer() { + const router = useDemoRouter(); + + const theme = useTheme(); + + return ( + + + + + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview new file mode 100644 index 00000000000..99d697f9bbb --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/ActionsPageContainer.tsx.preview @@ -0,0 +1,16 @@ +function PageToolbar() { + return ( + + + + + ); +} \ No newline at end of file diff --git a/docs/data/toolpad/core/components/page-container/BasicPageContainer.js b/docs/data/toolpad/core/components/page-container/BasicPageContainer.js new file mode 100644 index 00000000000..64ce4a613e4 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/BasicPageContainer.js @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { Paper, useTheme } from '@mui/material'; + +const NAVIGATION = [ + { segment: '', title: 'Home' }, + { segment: 'orders', title: 'Orders' }, +]; + +export default function BasicPageContainer() { + const router = useDemoRouter('/orders'); + + const theme = useTheme(); + + return ( + + + {/* preview-start */} + Page content + {/* preview-end */} + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx b/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx new file mode 100644 index 00000000000..64ce4a613e4 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { Paper, useTheme } from '@mui/material'; + +const NAVIGATION = [ + { segment: '', title: 'Home' }, + { segment: 'orders', title: 'Orders' }, +]; + +export default function BasicPageContainer() { + const router = useDemoRouter('/orders'); + + const theme = useTheme(); + + return ( + + + {/* preview-start */} + Page content + {/* preview-end */} + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx.preview b/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx.preview new file mode 100644 index 00000000000..253e0161496 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/BasicPageContainer.tsx.preview @@ -0,0 +1 @@ +Page content \ No newline at end of file diff --git a/docs/data/toolpad/core/components/page-container/PageContent.js b/docs/data/toolpad/core/components/page-container/PageContent.js new file mode 100644 index 00000000000..808c4242497 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/PageContent.js @@ -0,0 +1,36 @@ +import * as React from 'react'; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +import Typography from '@mui/material/Typography'; +import Grid from '@mui/material/Unstable_Grid2'; + +export default function PageContent() { + return ( + + + + + Temperature + 24°C + + + + + + + Precipitation + 5% + + + + + + + Wind + 18km/h + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/PageContent.tsx b/docs/data/toolpad/core/components/page-container/PageContent.tsx new file mode 100644 index 00000000000..808c4242497 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/PageContent.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +import Typography from '@mui/material/Typography'; +import Grid from '@mui/material/Unstable_Grid2'; + +export default function PageContent() { + return ( + + + + + Temperature + 24°C + + + + + + + Precipitation + 5% + + + + + + + Wind + 18km/h + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.js b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.js new file mode 100644 index 00000000000..823139b1ad9 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.js @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { Paper, useTheme } from '@mui/material'; + +const NAVIGATION = [ + { + segment: 'home', + title: 'Home', + children: [ + { + segment: 'orders', + title: 'Orders', + }, + ], + }, +]; + +export default function TitleBreadcrumbsPageContainer() { + const router = useDemoRouter('/home/orders'); + + const theme = useTheme(); + + return ( + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx new file mode 100644 index 00000000000..823139b1ad9 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { Paper, useTheme } from '@mui/material'; + +const NAVIGATION = [ + { + segment: 'home', + title: 'Home', + children: [ + { + segment: 'orders', + title: 'Orders', + }, + ], + }, +]; + +export default function TitleBreadcrumbsPageContainer() { + const router = useDemoRouter('/home/orders'); + + const theme = useTheme(); + + return ( + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx.preview b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx.preview new file mode 100644 index 00000000000..38c2ca55767 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/TitleBreadcrumbsPageContainer.tsx.preview @@ -0,0 +1,3 @@ + + + \ 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 new file mode 100644 index 00000000000..aab6e754c46 --- /dev/null +++ b/docs/data/toolpad/core/components/page-container/page-container.md @@ -0,0 +1,55 @@ +--- +productId: toolpad-core +title: Page Container +components: PageContainer, PageContainerToolbar +--- + +# Page Container + +

A component that wraps page content and provides a title, breadcrumbs, and page actions.

+ +`PageContent` is the ideal wrapper for the content of your dashboard. It shows the current page title, and provides breadcrumbs to navigate back into the current hierarchy. It makes your page responsive through the use of the Material UI Container component under the hood. + +Just like [`DashboardLayout`](/toolpad/core/react-dashboard-layout/), `PageContainer` uses the navigation structure that is defined in the [`AppProvider`](/toolpad/core/react-app-provider/) to build up its breadcrumbs and title. + +{{"demo": "BasicPageContainer.js", "height": 300}} + +## Title and Breadcrumbs + +The breacrumbs are formed by matching the current pathname with the navigation structure defined in the [`AppProvider`](/toolpad/core/react-app-provider/). The title of the matched segment is used as the page title. You can override the page title with the `title` property. + +For example, under the following navigation structure: + +```tsx + + ... + +``` + +The breadcrumbs contains **ACME / Home / Orders** when you visit the path **/home/orders**, and the page has a title of **Orders**. + +{{"demo": "TitleBreadcrumbsPageContainer.js", "height": 300, "hideToolbar": true}} + +## 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: + +{{"demo": "ActionsPageContainer.js", "height": 300}} + +## 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` and `fixed` properties to control the bounds of the page. diff --git a/docs/data/toolpad/core/introduction/TutorialDefault.js b/docs/data/toolpad/core/introduction/TutorialDefault.js index 3329764f906..24e07c47e45 100644 --- a/docs/data/toolpad/core/introduction/TutorialDefault.js +++ b/docs/data/toolpad/core/introduction/TutorialDefault.js @@ -1,14 +1,15 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; import { extendTheme } from '@mui/material/styles'; import DashboardIcon from '@mui/icons-material/Dashboard'; 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'; const NAVIGATION = [ { + segment: 'page', title: 'Page', icon: , }, @@ -26,32 +27,36 @@ const demoTheme = extendTheme({ }, }); -function DemoPageContent() { - return ( - - Dashboard content - - ); +function DemoPageContent({ pathname }) { + switch (pathname) { + case '/page': + return Hello world!; + default: + return null; + } } +DemoPageContent.propTypes = { + pathname: PropTypes.string.isRequired, +}; + function TutorialDefault(props) { const { window } = props; // Remove this const when copying and pasting into your project. const demoWindow = window !== undefined ? window() : undefined; + const demoRouter = useDemoRouter('/page'); + return ( - + - + ); diff --git a/docs/data/toolpad/core/introduction/TutorialDefault.tsx b/docs/data/toolpad/core/introduction/TutorialDefault.tsx index b9240242191..671c1574944 100644 --- a/docs/data/toolpad/core/introduction/TutorialDefault.tsx +++ b/docs/data/toolpad/core/introduction/TutorialDefault.tsx @@ -1,13 +1,14 @@ import * as React from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; import { extendTheme } from '@mui/material/styles'; import DashboardIcon from '@mui/icons-material/Dashboard'; import { AppProvider, Navigation } from '@toolpad/core/AppProvider'; import { DashboardLayout } from '@toolpad/core/DashboardLayout'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; const NAVIGATION: Navigation = [ { + segment: 'page', title: 'Page', icon: , }, @@ -25,20 +26,13 @@ const demoTheme = extendTheme({ }, }); -function DemoPageContent() { - return ( - - Dashboard content - - ); +function DemoPageContent({ pathname }: { pathname: string }) { + switch (pathname) { + case '/page': + return Hello world!; + default: + return null; + } } interface DemoProps { @@ -55,10 +49,17 @@ export default function TutorialDefault(props: DemoProps) { // Remove this const when copying and pasting into your project. const demoWindow = window !== undefined ? window() : undefined; + const demoRouter = useDemoRouter('/page'); + return ( - + - + ); diff --git a/docs/data/toolpad/core/introduction/TutorialDefault.tsx.preview b/docs/data/toolpad/core/introduction/TutorialDefault.tsx.preview index 3e244843ec9..934392cc699 100644 --- a/docs/data/toolpad/core/introduction/TutorialDefault.tsx.preview +++ b/docs/data/toolpad/core/introduction/TutorialDefault.tsx.preview @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/docs/data/toolpad/core/introduction/TutorialPages.js b/docs/data/toolpad/core/introduction/TutorialPages.js index c9d06a98633..632c8c489b1 100644 --- a/docs/data/toolpad/core/introduction/TutorialPages.js +++ b/docs/data/toolpad/core/introduction/TutorialPages.js @@ -1,12 +1,13 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; import { extendTheme } from '@mui/material/styles'; import DashboardIcon from '@mui/icons-material/Dashboard'; import TimelineIcon from '@mui/icons-material/Timeline'; 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 { Typography } from '@mui/material'; const NAVIGATION = [ { @@ -39,19 +40,19 @@ const demoTheme = extendTheme({ }); function DemoPageContent({ pathname }) { - return ( - - Dashboard content for {pathname} - - ); + switch (pathname) { + case '/page': + return Hello world!; + case '/page-2': + return ( + + This is Page 2 + + ); + + default: + return null; + } } DemoPageContent.propTypes = { @@ -64,25 +65,17 @@ function TutorialPages(props) { // Remove this const when copying and pasting into your project. const demoWindow = window !== undefined ? window() : undefined; - const [pathname, setPathname] = React.useState('page'); - - const router = React.useMemo(() => { - return { - pathname, - searchParams: new URLSearchParams(), - navigate: (path) => setPathname(String(path)), - }; - }, [pathname]); + const demoRouter = useDemoRouter('/page-2'); return ( - + ); diff --git a/docs/data/toolpad/core/introduction/TutorialPages.tsx b/docs/data/toolpad/core/introduction/TutorialPages.tsx index 2961b113d13..ab1e1daa7f8 100644 --- a/docs/data/toolpad/core/introduction/TutorialPages.tsx +++ b/docs/data/toolpad/core/introduction/TutorialPages.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; import { extendTheme } from '@mui/material/styles'; import DashboardIcon from '@mui/icons-material/Dashboard'; import TimelineIcon from '@mui/icons-material/Timeline'; -import { AppProvider, Navigation, Router } from '@toolpad/core/AppProvider'; +import { AppProvider, Navigation } from '@toolpad/core/AppProvider'; import { DashboardLayout } from '@toolpad/core/DashboardLayout'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { Typography } from '@mui/material'; const NAVIGATION: Navigation = [ { @@ -38,19 +39,18 @@ const demoTheme = extendTheme({ }); function DemoPageContent({ pathname }: { pathname: string }) { - return ( - - Dashboard content for {pathname} - - ); + switch (pathname) { + case '/page': + return Hello world!; + case '/page-2': + return ( + + This is Page 2 + + ); + default: + return null; + } } interface DemoProps { @@ -67,25 +67,17 @@ export default function TutorialPages(props: DemoProps) { // Remove this const when copying and pasting into your project. const demoWindow = window !== undefined ? window() : undefined; - const [pathname, setPathname] = React.useState('page'); - - const router = React.useMemo(() => { - return { - pathname, - searchParams: new URLSearchParams(), - navigate: (path) => setPathname(String(path)), - }; - }, [pathname]); + const demoRouter = useDemoRouter('/page-2'); return ( - + ); diff --git a/docs/data/toolpad/core/introduction/TutorialPages.tsx.preview b/docs/data/toolpad/core/introduction/TutorialPages.tsx.preview index 96d68868d23..934392cc699 100644 --- a/docs/data/toolpad/core/introduction/TutorialPages.tsx.preview +++ b/docs/data/toolpad/core/introduction/TutorialPages.tsx.preview @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/docs/data/toolpad/core/introduction/tutorial.md b/docs/data/toolpad/core/introduction/tutorial.md index 04d02c6ba74..d2100fd83b1 100644 --- a/docs/data/toolpad/core/introduction/tutorial.md +++ b/docs/data/toolpad/core/introduction/tutorial.md @@ -65,15 +65,15 @@ yarn && yarn dev ```tsx import { Typography, Container } from '@mui/material'; +import { PageContainer } from '@toolpad/core/'; + export default function Home() { return ( -
- - - This is page 2! - - -
+ + + This is page 2! + + ); } ``` diff --git a/docs/data/toolpad/core/pages.ts b/docs/data/toolpad/core/pages.ts index 1c6b3d68394..c09a175f764 100644 --- a/docs/data/toolpad/core/pages.ts +++ b/docs/data/toolpad/core/pages.ts @@ -61,6 +61,10 @@ const pages: MuiPage[] = [ pathname: '/toolpad/core/react-dashboard-layout', title: 'Dashboard Layout', }, + { + pathname: '/toolpad/core/react-page-container', + title: 'Page Container', + }, ], }, { diff --git a/docs/data/toolpad/core/pagesApi.js b/docs/data/toolpad/core/pagesApi.js index 3b1a64b542a..ada34884ebe 100644 --- a/docs/data/toolpad/core/pagesApi.js +++ b/docs/data/toolpad/core/pagesApi.js @@ -3,4 +3,6 @@ module.exports = [ { pathname: '/toolpad/core/api/dashboard-layout' }, { 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' }, ]; diff --git a/docs/package.json b/docs/package.json index 6b75bb10e6b..9c074563052 100644 --- a/docs/package.json +++ b/docs/package.json @@ -36,6 +36,7 @@ "@mui/system": "next", "@mui/utils": "next", "@mui/x-date-pickers": "7.11.0", + "@mui/x-date-pickers-pro": "7.10.0", "@mui/x-license": "7.11.0", "@toolpad/core": "workspace:*", "@toolpad/studio": "workspace:*", diff --git a/docs/pages/toolpad/core/api/page-container-toolbar.js b/docs/pages/toolpad/core/api/page-container-toolbar.js new file mode 100644 index 00000000000..c34ccdc8262 --- /dev/null +++ b/docs/pages/toolpad/core/api/page-container-toolbar.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-container-toolbar.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docs-toolpad/translations/api-docs/page-container-toolbar', + false, + /\.\/page-container-toolbar.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/toolpad/core/api/page-container-toolbar.json b/docs/pages/toolpad/core/api/page-container-toolbar.json new file mode 100644 index 00000000000..fce831943e9 --- /dev/null +++ b/docs/pages/toolpad/core/api/page-container-toolbar.json @@ -0,0 +1,13 @@ +{ + "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.js b/docs/pages/toolpad/core/api/page-container.js new file mode 100644 index 00000000000..e49a8b27450 --- /dev/null +++ b/docs/pages/toolpad/core/api/page-container.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-container.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docs-toolpad/translations/api-docs/page-container', + false, + /\.\/page-container.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/toolpad/core/api/page-container.json b/docs/pages/toolpad/core/api/page-container.json new file mode 100644 index 00000000000..63cbe300d3a --- /dev/null +++ b/docs/pages/toolpad/core/api/page-container.json @@ -0,0 +1,73 @@ +{ + "props": {}, + "name": "PageContainer", + "imports": [ + "import { PageContainer } from '@toolpad-core/PageContainer';", + "import { PageContainer } from '@toolpad-core';" + ], + "slots": [ + { + "name": "toolbar", + "description": "The component that renders the actions toolbar.", + "default": "Snackbar", + "class": null + } + ], + "classes": [ + { + "key": "disableGutters", + "className": "", + "description": "Styles applied to the root element if `disableGutters={true}`.", + "isGlobal": false + }, + { + "key": "fixed", + "className": "", + "description": "Styles applied to the root element if `fixed={true}`.", + "isGlobal": false + }, + { + "key": "maxWidthLg", + "className": "", + "description": "Styles applied to the root element if `maxWidth=\"lg\"`.", + "isGlobal": false + }, + { + "key": "maxWidthMd", + "className": "", + "description": "Styles applied to the root element if `maxWidth=\"md\"`.", + "isGlobal": false + }, + { + "key": "maxWidthSm", + "className": "", + "description": "Styles applied to the root element if `maxWidth=\"sm\"`.", + "isGlobal": false + }, + { + "key": "maxWidthXl", + "className": "", + "description": "Styles applied to the root element if `maxWidth=\"xl\"`.", + "isGlobal": false + }, + { + "key": "maxWidthXs", + "className": "", + "description": "Styles applied to the root element if `maxWidth=\"xs\"`.", + "isGlobal": false + }, + { + "key": "root", + "className": "", + "description": "Styles applied to the root element.", + "isGlobal": false + } + ], + "spread": true, + "themeDefaultProps": false, + "muiName": "PageContainer", + "filename": "/packages/toolpad-core/src/PageContainer/PageContainer.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/toolpad/core/react-page-container/index.js b/docs/pages/toolpad/core/react-page-container/index.js new file mode 100644 index 00000000000..ad37c63c210 --- /dev/null +++ b/docs/pages/toolpad/core/react-page-container/index.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from '../../../../data/toolpad/core/components/page-container/page-container.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/src/components/landing-core/Features.js b/docs/src/components/landing-core/Features.js index 5ffce141610..a4341f880b2 100644 --- a/docs/src/components/landing-core/Features.js +++ b/docs/src/components/landing-core/Features.js @@ -8,6 +8,7 @@ import ToolpadFeaturesSwitcher from './ToolpadFeaturesSwitcher'; import ToolpadDialogDemo from './ToolpadDialogDemo'; import ToolpadDashboardLayout from './ToolpadDashboardLayout'; import ToolpadNotificationDemo from './ToolpadNotificationDemo'; +import ToolpadPageContainerDemo from './ToolpadPageContainerDemo'; export default function ToolpadComponents() { const [tab, setTab] = React.useState('navigation'); @@ -35,7 +36,7 @@ export default function ToolpadComponents() { {tab === 'auth' &&
To Do
} {tab === 'dialogs' && } {tab === 'notifications' && } - {tab === 'page' &&
To Do
} + {tab === 'page' && } diff --git a/docs/src/components/landing-core/ToolpadDashboardLayout.tsx b/docs/src/components/landing-core/ToolpadDashboardLayout.tsx index c214fec2aa2..59c9a9fce6a 100644 --- a/docs/src/components/landing-core/ToolpadDashboardLayout.tsx +++ b/docs/src/components/landing-core/ToolpadDashboardLayout.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import Paper from '@mui/material/Paper'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; + import DashboardIcon from '@mui/icons-material/Dashboard'; import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; import BarChartIcon from '@mui/icons-material/BarChart'; @@ -10,8 +10,10 @@ import DescriptionIcon from '@mui/icons-material/Description'; import LayersIcon from '@mui/icons-material/Layers'; import { AppProvider, Router } from '@toolpad/core/AppProvider'; import { DashboardLayout } from '@toolpad/core/DashboardLayout'; -import type { Navigation } from '@toolpad/core'; +import { PageContainer, type Navigation } from '@toolpad/core'; import DemoSandbox from 'docs/src/modules/components/DemoSandbox'; +import Grid from '@mui/material/Unstable_Grid2'; +import { styled } from '@mui/material'; import Frame from '../../modules/components/Frame'; const code = ` @@ -142,6 +144,12 @@ interface DemoProps { const NOOP = () => {}; +const PlaceHolder = styled('div')<{ height: number }>(({ theme, height }) => ({ + border: `1px solid ${theme.palette.divider}`, + height, + borderRadius: theme.shape.borderRadius, +})); + function DashboardLayoutBasic(props: DemoProps) { const { window } = props; @@ -168,7 +176,19 @@ function DashboardLayoutBasic(props: DemoProps) { alignItems: 'center', }} > - Dashboard content for {pathname} + + + + + + + + + + + + +
diff --git a/docs/src/components/landing-core/ToolpadPageContainerDemo.tsx b/docs/src/components/landing-core/ToolpadPageContainerDemo.tsx new file mode 100644 index 00000000000..e312ed2f9f8 --- /dev/null +++ b/docs/src/components/landing-core/ToolpadPageContainerDemo.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import Frame from 'docs/src/components/action/Frame'; +import Paper from '@mui/material/Paper'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { PageContainer } from '@toolpad/core/PageContainer'; +import { useDemoRouter } from '@toolpad/core/internals/demo'; + +const code = ` + + Page content + +`; + +const NAVIGATION = [ + { segment: '', title: 'Home' }, + { segment: 'orders', title: 'Orders' }, +]; + +function PageContainerDemp() { + const router = useDemoRouter('/orders'); + return ( + + + Page content + + + ); +} + +export default function ToolpadPageContainerDemo() { + return ( + + + ({ + p: 2, + display: 'flex', + alignItems: 'center', + maxWidth: '100%', + mx: 'auto', + bgcolor: '#FFF', + borderRadius: '8px', + ...theme.applyDarkStyles({ + bgcolor: 'primaryDark.900', + }), + })} + > + + + + + + + + ); +} diff --git a/docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json b/docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json new file mode 100644 index 00000000000..f93d4cbd8c7 --- /dev/null +++ b/docs/translations/api-docs/page-container-toolbar/page-container-toolbar.json @@ -0,0 +1 @@ +{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} } diff --git a/docs/translations/api-docs/page-container/page-container.json b/docs/translations/api-docs/page-container/page-container.json new file mode 100644 index 00000000000..643fe8e0f28 --- /dev/null +++ b/docs/translations/api-docs/page-container/page-container.json @@ -0,0 +1,43 @@ +{ + "componentDescription": "", + "propDescriptions": {}, + "classDescriptions": { + "disableGutters": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "disableGutters={true}" + }, + "fixed": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "fixed={true}" + }, + "maxWidthLg": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "maxWidth=\"lg\"" + }, + "maxWidthMd": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "maxWidth=\"md\"" + }, + "maxWidthSm": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "maxWidth=\"sm\"" + }, + "maxWidthXl": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "maxWidth=\"xl\"" + }, + "maxWidthXs": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "maxWidth=\"xs\"" + }, + "root": { "description": "Styles applied to the root element." } + }, + "slotDescriptions": { "toolbar": "The component that renders the actions toolbar." } +} diff --git a/packages/create-toolpad-app/src/generateProject.ts b/packages/create-toolpad-app/src/generateProject.ts index b2cb8a193b8..30c1345060a 100644 --- a/packages/create-toolpad-app/src/generateProject.ts +++ b/packages/create-toolpad-app/src/generateProject.ts @@ -54,7 +54,19 @@ export default function generateProject( } `; - const rootPageContent = ` + const dashboardPageLayout = ` + import { PageContainer } from '@toolpad/core/PageContainer'; + + export default function Layout({ + children, + }: Readonly<{ children: React.ReactNode }>) { + return ( + {children} + ); + } + `; + + const rootPageContainer = ` import Link from "next/link"; import { Button, Container, Typography, Box } from "@mui/material"; @@ -86,16 +98,15 @@ export default function generateProject( } `; - const dashboardPageContent = ` - import { Typography, Container } from "@mui/material"; + const dashboardPage = ` + import { Typography } from "@mui/material"; + export default function Home() { return (
- - - Dashboard content! - - + + Hello world! +
); } @@ -347,10 +358,11 @@ export default function generateProject( return new Map([ ['app/api/auth/[...nextAuth]/route.ts', { content: '' }], ['app/auth/[...path]/page.tsx', { content: '' }], - ['app/(dashboard)/page/page.tsx', { content: dashboardPageContent }], + ['app/(dashboard)/page/page.tsx', { content: dashboardPage }], + ['app/(dashboard)/page/layout.tsx', { content: dashboardPageLayout }], ['app/(dashboard)/layout.tsx', { content: dashboardLayoutContent }], ['app/layout.tsx', { content: rootLayoutContent }], - ['app/page.tsx', { content: rootPageContent }], + ['app/page.tsx', { content: rootPageContainer }], ['theme.ts', { content: themeContent }], ['next-env.d.ts', { content: nextTypesContent }], ['next.config.mjs', { content: nextConfigContent }], diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index dfdfb23c422..61d1d032ead 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -37,6 +37,7 @@ import { import type { Navigation, NavigationPageItem } from '../AppProvider'; import { ToolpadLogo } from './ToolpadLogo'; import { getItemTitle, isPageItem } from '../shared/navigation'; +import { useApplicationTitle } from '../shared/branding'; const DRAWER_WIDTH = 320; // px @@ -320,6 +321,7 @@ function DashboardLayout(props: DashboardLayoutProps) { const branding = React.useContext(BrandingContext); const navigation = React.useContext(NavigationContext); const appWindow = React.useContext(WindowContext); + const applicationTitle = useApplicationTitle(); const [isMobileNavigationOpen, setIsMobileNavigationOpen] = React.useState(false); @@ -381,7 +383,7 @@ function DashboardLayout(props: DashboardLayoutProps) { transform: { xs: 'translateX(-50%)', md: 'none' }, }} > - + {branding?.logo ?? } - {branding?.title ?? 'Toolpad'} + {applicationTitle} - + diff --git a/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx b/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx new file mode 100644 index 00000000000..3a27be71ecf --- /dev/null +++ b/packages/toolpad-core/src/PageContainer/PageContainer.test.tsx @@ -0,0 +1,48 @@ +/** + * @vitest-environment jsdom + */ + +import * as React from 'react'; +import { expect, describe, test, vi } from 'vitest'; +import describeConformance from '@toolpad/utils/describeConformance'; +import { render, within, screen } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { PageContainer } from './PageContainer'; +import { AppProvider } from '../AppProvider'; + +describe('PageContainer', () => { + describeConformance(, () => ({ + skip: ['themeDefaultProps'], + slots: { + toolbar: {}, + }, + })); + + test('renders page container correctly', async () => { + const user = await userEvent.setup(); + const router = { pathname: '/orders', searchParams: new URLSearchParams(), navigate: vi.fn() }; + render( + + + , + ); + + const breadCrumbs = screen.getByRole('navigation', { name: 'breadcrumb' }); + + const homeLink = within(breadCrumbs).getByRole('link', { name: 'Home' }); + await user.click(homeLink); + + expect(router.navigate).toHaveBeenCalledWith('/', expect.objectContaining({})); + router.navigate.mockClear(); + + expect(within(breadCrumbs).getByText('Orders')).toBeTruthy(); + + expect(screen.getByText('Orders', { ignore: 'nav *' })); + }); +}); diff --git a/packages/toolpad-core/src/PageContainer/PageContainer.tsx b/packages/toolpad-core/src/PageContainer/PageContainer.tsx new file mode 100644 index 00000000000..9646cfbd352 --- /dev/null +++ b/packages/toolpad-core/src/PageContainer/PageContainer.tsx @@ -0,0 +1,209 @@ +'use client'; +import * as React from 'react'; +import PropTypes from 'prop-types'; +import Breadcrumbs from '@mui/material/Breadcrumbs'; +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/base/utils'; +import { styled } from '@mui/material'; +import { Link as ToolpadLink } from '../shared/Link'; +import { PageContainerToolbar, PageContainerToolbarProps } from './PageContainerToolbar'; +import { NavigationContext, RouterContext } from '../shared/context'; +import { getItemTitle, isPageItem } from '../shared/navigation'; +import { NavigationItem, NavigationPageItem, Navigation } from '../AppProvider'; +import { useApplicationTitle } from '../shared/branding'; + +const PageContentHeader = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + jusifyCOntent: 'space-between', + gap: theme.spacing(2), +})); + +const isRootPage = (item: NavigationItem) => isPageItem(item) && !item.segment; + +interface BreadCrumbItem extends NavigationPageItem { + path: string; +} + +function createPageLookup( + navigation: Navigation, + segments: BreadCrumbItem[] = [], + base = '', +): Map { + const result = new Map(); + + const resolveSegment = (segment: string) => `${base}${segment ? `/${segment}` : ''}` || '/'; + + const root = navigation.find((item) => isRootPage(item)) as NavigationPageItem | undefined; + const rootCrumb = root ? { path: resolveSegment(''), ...root } : undefined; + + for (const item of navigation) { + if (!isPageItem(item)) { + continue; + } + + const path = resolveSegment(item.segment); + if (result.has(path)) { + throw new Error(`Duplicate path in navigation: ${path}`); + } + + const itemCrumb: BreadCrumbItem = { path, ...item }; + + const navigationSegments: BreadCrumbItem[] = [ + ...segments, + ...(rootCrumb && !isRootPage(item) ? [rootCrumb] : []), + itemCrumb, + ]; + + result.set(path, navigationSegments); + + if (item.children) { + const childrenLookup = createPageLookup(item.children, navigationSegments, path); + for (const [childPath, childItems] of childrenLookup) { + if (result.has(childPath)) { + throw new Error(`Duplicate path in navigation: ${childPath}`); + } + result.set(childPath, childItems); + } + } + } + + return result; +} + +function matchPath(navigation: Navigation, path: string): BreadCrumbItem[] | null { + const lookup = createPageLookup(navigation); + return lookup.get(path) ?? null; +} + +export interface PageContainerSlotProps { + toolbar: PageContainerToolbarProps; +} + +export interface PageContainerSlots { + /** + * The component that renders the actions toolbar. + * @default Snackbar + */ + toolbar: React.ElementType; +} + +export interface PageContainerProps extends ContainerProps { + children?: React.ReactNode; + title?: string; + slots?: PageContainerSlots; + slotProps?: PageContainerSlotProps; +} +/** + * + * Demos: + * + * - [Page Container](https://mui.com/toolpad/core/react-page-container/) + * + * API: + * + * - [PageContainer API](https://mui.com/toolpad/core/api/page-container) + */ +function PageContainer(props: PageContainerProps) { + const { children, slots, slotProps, ...rest } = props; + const routerContext = React.useContext(RouterContext); + const navigationContext = React.useContext(NavigationContext); + const pathname = routerContext?.pathname ?? '/'; + const applicationTitle = useApplicationTitle(); + const breadCrumbs = React.useMemo(() => { + let crumbs = matchPath(navigationContext, pathname) ?? []; + + if (crumbs.length <= 0 || crumbs[0].path !== '/') { + crumbs = [ + { + segment: '', + path: '/', + title: applicationTitle, + }, + ...crumbs, + ]; + } + return crumbs; + }, [navigationContext, pathname, applicationTitle]); + + const title = + (breadCrumbs ? getItemTitle(breadCrumbs[breadCrumbs.length - 1]) : '') ?? props.title; + + const ToolbarComponent = props?.slots?.toolbar ?? PageContainerToolbar; + const toolbarSlotProps = useSlotProps({ + elementType: ToolbarComponent, + ownerState: props, + externalSlotProps: props?.slotProps?.toolbar, + additionalProps: {}, + }); + + return ( + + + + + {breadCrumbs + ? breadCrumbs.map((item, index) => { + return index < breadCrumbs.length - 1 ? ( + + {getItemTitle(item)} + + ) : ( + + {getItemTitle(item)} + + ); + }) + : null} + + + + {title ? {title} : null} + + + +
{children}
+
+
+ ); +} + +PageContainer.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, + /** + * @ignore + */ + slotProps: PropTypes.shape({ + toolbar: PropTypes.shape({ + children: PropTypes.node, + }).isRequired, + }), + /** + * @ignore + */ + slots: PropTypes.shape({ + toolbar: PropTypes.elementType, + }), + /** + * @ignore + */ + title: PropTypes.string, +} as any; + +export { PageContainer }; diff --git a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx b/packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx new file mode 100644 index 00000000000..2cd4d9d5c03 --- /dev/null +++ b/packages/toolpad-core/src/PageContainer/PageContainerToolbar.test.tsx @@ -0,0 +1,16 @@ +/** + * @vitest-environment jsdom + */ + +import * as React from 'react'; +import { describe, test } from 'vitest'; +import describeConformance from '@toolpad/utils/describeConformance'; +import { PageContainerToolbar } from './PageContainerToolbar'; + +describe('PageContainerToolbar', () => { + describeConformance(, () => ({ + skip: ['themeDefaultProps'], + })); + + test('dummy test', () => {}); +}); diff --git a/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx b/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx new file mode 100644 index 00000000000..3eef00c9a8d --- /dev/null +++ b/packages/toolpad-core/src/PageContainer/PageContainerToolbar.tsx @@ -0,0 +1,31 @@ +'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/index.ts b/packages/toolpad-core/src/PageContainer/index.ts new file mode 100644 index 00000000000..c12250743e1 --- /dev/null +++ b/packages/toolpad-core/src/PageContainer/index.ts @@ -0,0 +1,2 @@ +export * from './PageContainer'; +export * from './PageContainerToolbar'; diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts index de4af47c8a6..4134752e384 100644 --- a/packages/toolpad-core/src/index.ts +++ b/packages/toolpad-core/src/index.ts @@ -2,6 +2,8 @@ export * from './AppProvider'; export * from './DashboardLayout'; +export * from './PageContainer'; + export * from './useDialogs'; export * from './useNotifications'; diff --git a/packages/toolpad-core/src/shared/branding.ts b/packages/toolpad-core/src/shared/branding.ts new file mode 100644 index 00000000000..316f85c481f --- /dev/null +++ b/packages/toolpad-core/src/shared/branding.ts @@ -0,0 +1,7 @@ +import * as React from 'react'; +import { BrandingContext } from './context'; + +export function useApplicationTitle() { + const branding = React.useContext(BrandingContext); + return branding?.title ?? 'Toolpad'; +} diff --git a/playground/nextjs/src/app/(dashboard)/layout.tsx b/playground/nextjs/src/app/(dashboard)/layout.tsx index cf4e6b4dd8f..e481f628f1c 100644 --- a/playground/nextjs/src/app/(dashboard)/layout.tsx +++ b/playground/nextjs/src/app/(dashboard)/layout.tsx @@ -1,6 +1,11 @@ import * as React from 'react'; import { DashboardLayout } from '@toolpad/core/DashboardLayout'; +import { PageContainer } from '@toolpad/core/PageContainer'; export default function DashboardPagesLayout(props: { children: React.ReactNode }) { - return {props.children}; + return ( + + {props.children} + + ); } diff --git a/playground/nextjs/src/app/(dashboard)/orders/page.tsx b/playground/nextjs/src/app/(dashboard)/orders/page.tsx index c63eb5844df..4da73e5200c 100644 --- a/playground/nextjs/src/app/(dashboard)/orders/page.tsx +++ b/playground/nextjs/src/app/(dashboard)/orders/page.tsx @@ -14,9 +14,7 @@ export default function OrdersPage() { textAlign: 'center', }} > - - Welcome to the Toolpad orders! - + Welcome to the Toolpad orders!
); } diff --git a/playground/nextjs/src/app/(dashboard)/page.tsx b/playground/nextjs/src/app/(dashboard)/page.tsx index ff57b97d844..3e404ef074a 100644 --- a/playground/nextjs/src/app/(dashboard)/page.tsx +++ b/playground/nextjs/src/app/(dashboard)/page.tsx @@ -14,9 +14,7 @@ export default function HomePage() { textAlign: 'center', }} > - - Welcome to Toolpad! - + Welcome to Toolpad! ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c46803d400..5c6ee40f3ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -324,6 +324,9 @@ importers: '@mui/x-date-pickers': specifier: 7.11.0 version: 7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/x-date-pickers-pro': + specifier: 7.10.0 + version: 7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-license': specifier: 7.11.0 version: 7.11.0(@types/react@18.3.3)(react@18.3.1) @@ -2997,6 +3000,42 @@ packages: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 + '@mui/x-date-pickers-pro@7.10.0': + resolution: {integrity: sha512-imBg/WclPP5F/BosvI665iQ/MyaDTjjPySbU4dl0zhPLZIFCmabtltd+RcxSGKGsgr0kF4UGA1WMRAzpiB/VIA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.15.14 + date-fns: ^2.25.0 || ^3.2.0 + date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + '@mui/x-date-pickers-pro@7.11.0': resolution: {integrity: sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==} engines: {node: '>=14.0.0'} @@ -3033,6 +3072,42 @@ packages: moment-jalaali: optional: true + '@mui/x-date-pickers@7.10.0': + resolution: {integrity: sha512-mfJuKOdrrdlH5FskXl0aypRmZuVctNRwn5Xw0aMgE3n1ORCpzDSGCXd5El1/PdH3/3olT+vPFmxXKMQju5UMow==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.15.14 + date-fns: ^2.25.0 || ^3.2.0 + date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + '@mui/x-date-pickers@7.11.0': resolution: {integrity: sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==} engines: {node: '>=14.0.0'} @@ -3075,6 +3150,12 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 + '@mui/x-license@7.10.0': + resolution: {integrity: sha512-LliJ/A1VWGC8CKDGmGpCd3tYW+3DPPEk3FkyMrWyR9fzxFUKk3wc9+uE6d6mzYgeBUnfttdubO6d9Yf+eOyw5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + '@mui/x-license@7.11.0': resolution: {integrity: sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==} engines: {node: '>=14.0.0'} @@ -12051,6 +12132,29 @@ snapshots: - '@emotion/styled' - '@types/react' + '@mui/x-date-pickers-pro@7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.8 + '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) + '@mui/x-date-pickers': 7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/x-license': 7.10.0(@types/react@18.3.3)(react@18.3.1) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + date-fns: 2.30.0 + date-fns-jalali: 2.29.3-0 + dayjs: 1.11.11 + transitivePeerDependencies: + - '@types/react' + '@mui/x-date-pickers-pro@7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns@2.30.0)(dayjs@1.11.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 @@ -12073,6 +12177,28 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@mui/x-date-pickers@7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.8 + '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) + '@types/react-transition-group': 4.4.10 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + date-fns: 2.30.0 + date-fns-jalali: 2.29.3-0 + dayjs: 1.11.11 + transitivePeerDependencies: + - '@types/react' + '@mui/x-date-pickers@7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns@2.30.0)(dayjs@1.11.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 @@ -12124,6 +12250,14 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@mui/x-license@7.10.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.8 + '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + transitivePeerDependencies: + - '@types/react' + '@mui/x-license@7.11.0(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 From a8d3674b20ffef18cbdb782c1d65ab823865398f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:43:59 +0100 Subject: [PATCH 2/2] Bump @mui/x-date-pickers-pro to 7.11.0 (#3839) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docs/package.json | 2 +- pnpm-lock.yaml | 118 ++-------------------------------------------- 2 files changed, 6 insertions(+), 114 deletions(-) diff --git a/docs/package.json b/docs/package.json index 9c074563052..94b709e4726 100644 --- a/docs/package.json +++ b/docs/package.json @@ -36,7 +36,7 @@ "@mui/system": "next", "@mui/utils": "next", "@mui/x-date-pickers": "7.11.0", - "@mui/x-date-pickers-pro": "7.10.0", + "@mui/x-date-pickers-pro": "7.11.0", "@mui/x-license": "7.11.0", "@toolpad/core": "workspace:*", "@toolpad/studio": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c6ee40f3ff..fc425d01ff1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -325,8 +325,8 @@ importers: specifier: 7.11.0 version: 7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-date-pickers-pro': - specifier: 7.10.0 - version: 7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.11.0 + version: 7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-license': specifier: 7.11.0 version: 7.11.0(@types/react@18.3.3)(react@18.3.1) @@ -3000,42 +3000,6 @@ packages: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - '@mui/x-date-pickers-pro@7.10.0': - resolution: {integrity: sha512-imBg/WclPP5F/BosvI665iQ/MyaDTjjPySbU4dl0zhPLZIFCmabtltd+RcxSGKGsgr0kF4UGA1WMRAzpiB/VIA==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@emotion/react': ^11.9.0 - '@emotion/styled': ^11.8.1 - '@mui/material': ^5.15.14 - date-fns: ^2.25.0 || ^3.2.0 - date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 - dayjs: ^1.10.7 - luxon: ^3.0.2 - moment: ^2.29.4 - moment-hijri: ^2.1.2 - moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - date-fns: - optional: true - date-fns-jalali: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - moment-hijri: - optional: true - moment-jalaali: - optional: true - '@mui/x-date-pickers-pro@7.11.0': resolution: {integrity: sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==} engines: {node: '>=14.0.0'} @@ -3072,42 +3036,6 @@ packages: moment-jalaali: optional: true - '@mui/x-date-pickers@7.10.0': - resolution: {integrity: sha512-mfJuKOdrrdlH5FskXl0aypRmZuVctNRwn5Xw0aMgE3n1ORCpzDSGCXd5El1/PdH3/3olT+vPFmxXKMQju5UMow==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@emotion/react': ^11.9.0 - '@emotion/styled': ^11.8.1 - '@mui/material': ^5.15.14 - date-fns: ^2.25.0 || ^3.2.0 - date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 - dayjs: ^1.10.7 - luxon: ^3.0.2 - moment: ^2.29.4 - moment-hijri: ^2.1.2 - moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - date-fns: - optional: true - date-fns-jalali: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - moment-hijri: - optional: true - moment-jalaali: - optional: true - '@mui/x-date-pickers@7.11.0': resolution: {integrity: sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==} engines: {node: '>=14.0.0'} @@ -3150,12 +3078,6 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 - '@mui/x-license@7.10.0': - resolution: {integrity: sha512-LliJ/A1VWGC8CKDGmGpCd3tYW+3DPPEk3FkyMrWyR9fzxFUKk3wc9+uE6d6mzYgeBUnfttdubO6d9Yf+eOyw5A==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: ^17.0.0 || ^18.0.0 - '@mui/x-license@7.11.0': resolution: {integrity: sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==} engines: {node: '>=14.0.0'} @@ -12132,29 +12054,6 @@ snapshots: - '@emotion/styled' - '@types/react' - '@mui/x-date-pickers-pro@7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.8 - '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/material': 6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) - '@mui/x-date-pickers': 7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/x-license': 7.10.0(@types/react@18.3.3)(react@18.3.1) - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - optionalDependencies: - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - date-fns: 2.30.0 - date-fns-jalali: 2.29.3-0 - dayjs: 1.11.11 - transitivePeerDependencies: - - '@types/react' - '@mui/x-date-pickers-pro@7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns@2.30.0)(dayjs@1.11.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 @@ -12177,14 +12076,15 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@mui/x-date-pickers@7.10.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/x-date-pickers-pro@7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8 '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material': 6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/system': 5.16.4(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) - '@types/react-transition-group': 4.4.10 + '@mui/x-date-pickers': 7.11.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-beta.2(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(date-fns-jalali@2.29.3-0)(date-fns@2.30.0)(dayjs@1.11.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/x-license': 7.11.0(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -12250,14 +12150,6 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@mui/x-license@7.10.0(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.8 - '@mui/utils': 5.16.4(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - transitivePeerDependencies: - - '@types/react' - '@mui/x-license@7.11.0(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.8