diff --git a/docs/data/toolpad/core/introduction/examples.md b/docs/data/toolpad/core/introduction/examples.md index 40cdc04abb8..36dd4d14471 100644 --- a/docs/data/toolpad/core/introduction/examples.md +++ b/docs/data/toolpad/core/introduction/examples.md @@ -9,4 +9,10 @@ title: Examples -{{"component": "modules/components/ExamplesGrid/ExamplesGrid.tsx", "examplesFile": "core-examples.ts"}} +## Featured Examples + +{{"component": "modules/components/Examples/FeaturedExamples.tsx", "examplesFile": "core-examples.ts"}} + +## Other Examples + +{{"component": "modules/components/Examples/ExamplesGrid.tsx", "examplesFile": "core-examples.ts", "reverse": true}} diff --git a/docs/data/toolpad/studio/getting-started/examples-overview.md b/docs/data/toolpad/studio/getting-started/examples-overview.md index 95335641cf4..4f071102e2f 100644 --- a/docs/data/toolpad/studio/getting-started/examples-overview.md +++ b/docs/data/toolpad/studio/getting-started/examples-overview.md @@ -13,4 +13,4 @@ This collection includes apps that showcase connecting to APIs, adding custom co If you're interested in how we, at MUI, use Toolpad Studio to build internal apps, check out the [blog post](https://mui.com/blog/toolpad-use-cases/). -{{"component": "modules/components/ExamplesGrid/ExamplesGrid.tsx", "examplesFile": "studio-examples.ts"}} +{{"component": "modules/components/Examples/ExamplesGrid.tsx", "examplesFile": "studio-examples.ts"}} diff --git a/docs/public/static/toolpad/docs/core/functional-dashboard-dark.png b/docs/public/static/toolpad/docs/core/functional-dashboard-dark.png new file mode 100644 index 00000000000..eed997b7c8c Binary files /dev/null and b/docs/public/static/toolpad/docs/core/functional-dashboard-dark.png differ diff --git a/docs/public/static/toolpad/docs/core/functional-dashboard.png b/docs/public/static/toolpad/docs/core/functional-dashboard.png new file mode 100644 index 00000000000..e3e781c8850 Binary files /dev/null and b/docs/public/static/toolpad/docs/core/functional-dashboard.png differ diff --git a/docs/src/modules/components/ExamplesGrid/ExamplesGrid.tsx b/docs/src/modules/components/Examples/ExamplesGrid.tsx similarity index 87% rename from docs/src/modules/components/ExamplesGrid/ExamplesGrid.tsx rename to docs/src/modules/components/Examples/ExamplesGrid.tsx index b3bf9c6fb98..17e08d0387f 100644 --- a/docs/src/modules/components/ExamplesGrid/ExamplesGrid.tsx +++ b/docs/src/modules/components/Examples/ExamplesGrid.tsx @@ -11,20 +11,11 @@ import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import Stack from '@mui/material/Stack'; import SvgIcon from '@mui/material/SvgIcon'; +import type { Example } from './types'; -interface Example { - title: string; - description: string; - src: string; - srcDark?: string; - href: string; - source: string; - codesandbox?: string; - stackblitz?: string; -} - -interface TemplatesProps { +interface ExamplesGridProps { examplesFile: string; + reverse?: boolean; } function StackBlitzIcon() { @@ -43,16 +34,23 @@ function CodeSandboxIcon() { ); } -function Templates({ examplesFile }: TemplatesProps) { +function ExamplesGrid(props: ExamplesGridProps) { const [examples, setExamples] = React.useState([]); React.useEffect(() => { const importExamples = async () => { - const exampleContent = await import(`./${examplesFile}`); - setExamples(exampleContent.default); + let exampleContent = await import(`./${props.examplesFile}`); + + exampleContent = exampleContent + .default() + .filter((example: Example) => example.featured !== true); + if (props.reverse) { + setExamples(exampleContent.reverse()); + } + setExamples(exampleContent); }; importExamples(); - }, [examplesFile]); + }, [props.examplesFile, props.reverse]); const docsTheme = useTheme(); return ( @@ -121,11 +119,11 @@ function Templates({ examplesFile }: TemplatesProps) { Source - {example.codesandbox && ( + {example.codeSandbox && ( )} - {example.stackblitz && ( + {example.stackBlitz && ( ([]); + const [loading, setLoading] = React.useState(true); + + React.useEffect(() => { + const importExamples = async () => { + setLoading(true); + let exampleContent = await import(`./${props.examplesFile}`); + exampleContent = exampleContent + .default() + .filter((example: Example) => example.featured === true); + setExamples(exampleContent); + setLoading(false); + }; + importExamples(); + }, [props.examplesFile]); + const docsTheme = useTheme(); + if (loading) { + return ( + + {[1].map((key) => ( + + + + + + ))} + + ); + } + + return ( + + {examples.map((example: Example) => { + const computedSrc = + docsTheme?.palette?.mode === 'dark' && example.srcDark ? example.srcDark : example.src; + return ( + + + {example.title} + {example.new && } + + + {example.description} + + + .MuiCardMedia-root': { + filter: 'blur(4px)', + }, + '&:hover > .MuiButtonBase-root': { + opacity: 1, + }, + }} + > + + + + + + {example.stackBlitz ? ( + + { + window.open(example.stackBlitz, '_blank', 'noopener,noreferrer'); + }} + > + + + + + + ) : null} + {example.codeSandbox ? ( + + { + window.open(example.codeSandbox, '_blank', 'noopener,noreferrer'); + }} + > + + + + + + ) : null} + + + + + + + + + + + ); + })} + + ); +} diff --git a/docs/src/modules/components/ExamplesGrid/core-examples.ts b/docs/src/modules/components/Examples/core-examples.ts similarity index 90% rename from docs/src/modules/components/ExamplesGrid/core-examples.ts rename to docs/src/modules/components/Examples/core-examples.ts index de67bda126c..d8b97f1231b 100644 --- a/docs/src/modules/components/ExamplesGrid/core-examples.ts +++ b/docs/src/modules/components/Examples/core-examples.ts @@ -84,12 +84,15 @@ export default function examples() { 'https://codesandbox.io/s/github/mui/toolpad/tree/master/examples/core/auth-vite', }, { - title: 'Custom theme with Auth.js and Next.js App router', + title: 'Functional Dashboard', description: - 'This app shows you how to get started using Toolpad Core with Next.js, Auth.js and customize the Material UI theme', - src: '/static/toolpad/docs/core/auth-next-themed.png', - srcDark: '/static/toolpad/docs/core/auth-next-themed-dark.png', + 'This example shows you how to get started building a dashboard with Toolpad Core, Next.js app router, Auth.js and Material UI components in a customized theme', + src: '/static/toolpad/docs/core/functional-dashboard.png', + href: 'https://deploy-preview-4415--mui-toolpad-docs.netlify.app/toolpad/core/templates/nextjs-dashboard', + srcDark: '/static/toolpad/docs/core/functional-dashboard-dark.png', source: 'https://github.com/mui/toolpad/tree/master/examples/core/auth-nextjs-themed', + featured: true, + new: true, codesandbox: 'https://codesandbox.io/s/github/mui/toolpad/tree/master/examples/core/auth-nextjs-themed', }, diff --git a/docs/src/modules/components/ExamplesGrid/studio-examples.ts b/docs/src/modules/components/Examples/studio-examples.ts similarity index 100% rename from docs/src/modules/components/ExamplesGrid/studio-examples.ts rename to docs/src/modules/components/Examples/studio-examples.ts diff --git a/docs/src/modules/components/Examples/types.ts b/docs/src/modules/components/Examples/types.ts new file mode 100644 index 00000000000..96508d22704 --- /dev/null +++ b/docs/src/modules/components/Examples/types.ts @@ -0,0 +1,12 @@ +export interface Example { + title: string; + description: string; + src: string; + srcDark?: string; + href: string; + source: string; + codeSandbox?: string; + stackBlitz?: string; + new?: boolean; + featured?: boolean; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8de7e5acbda..6f6c12834ea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2061,7 +2061,7 @@ packages: resolution: {integrity: sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.26.0 '@babel/preset-typescript@7.26.0': resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} @@ -2131,7 +2131,7 @@ packages: '@docsearch/react@3.8.0': resolution: {integrity: sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==} peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' + '@types/react': ^18.3.12 react: '>= 16.8.0 < 19.0.0' react-dom: '>= 16.8.0 < 19.0.0' search-insights: '>= 1 < 3' @@ -4036,8 +4036,8 @@ packages: engines: {node: '>=18'} peerDependencies: '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 - '@types/react-dom': ^18.0.0 + '@types/react': ^18.3.12 + '@types/react-dom': 18.3.1 react: ^18.0.0 react-dom: ^18.0.0 peerDependenciesMeta: