diff --git a/benchmark/browser/scenarios/grid-system/index.js b/benchmark/browser/scenarios/grid-system/index.js index c0c0506cd9d69c..cead80916b8af3 100644 --- a/benchmark/browser/scenarios/grid-system/index.js +++ b/benchmark/browser/scenarios/grid-system/index.js @@ -5,9 +5,7 @@ export default function GridSystem() { return ( {new Array(1000).fill().map(() => ( - - test case - + test case ))} ); diff --git a/docs/data/joy/components/aspect-ratio/VariantsRatio.js b/docs/data/joy/components/aspect-ratio/VariantsRatio.js index 595a48c65270bf..6ef90149ef3274 100644 --- a/docs/data/joy/components/aspect-ratio/VariantsRatio.js +++ b/docs/data/joy/components/aspect-ratio/VariantsRatio.js @@ -6,28 +6,28 @@ import Typography from '@mui/joy/Typography'; export default function VariantsRatio() { return ( - + Solid - + Soft - + Outlined - + Plain diff --git a/docs/data/joy/components/aspect-ratio/VariantsRatio.tsx b/docs/data/joy/components/aspect-ratio/VariantsRatio.tsx index 595a48c65270bf..6ef90149ef3274 100644 --- a/docs/data/joy/components/aspect-ratio/VariantsRatio.tsx +++ b/docs/data/joy/components/aspect-ratio/VariantsRatio.tsx @@ -6,28 +6,28 @@ import Typography from '@mui/joy/Typography'; export default function VariantsRatio() { return ( - + Solid - + Soft - + Outlined - + Plain diff --git a/docs/data/joy/components/grid/AutoGrid.js b/docs/data/joy/components/grid/AutoGrid.js index b1ccef8819a661..a889d3eea7556e 100644 --- a/docs/data/joy/components/grid/AutoGrid.js +++ b/docs/data/joy/components/grid/AutoGrid.js @@ -18,14 +18,14 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function AutoGrid() { return ( - - xs + + size=grow - - xs=6 + + size=6 - - xs + + size=grow ); diff --git a/docs/data/joy/components/grid/AutoGrid.tsx b/docs/data/joy/components/grid/AutoGrid.tsx index b1ccef8819a661..a889d3eea7556e 100644 --- a/docs/data/joy/components/grid/AutoGrid.tsx +++ b/docs/data/joy/components/grid/AutoGrid.tsx @@ -18,14 +18,14 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function AutoGrid() { return ( - - xs + + size=grow - - xs=6 + + size=6 - - xs + + size=grow ); diff --git a/docs/data/joy/components/grid/AutoGrid.tsx.preview b/docs/data/joy/components/grid/AutoGrid.tsx.preview index 712fc60e7985e3..6659ec7ba99118 100644 --- a/docs/data/joy/components/grid/AutoGrid.tsx.preview +++ b/docs/data/joy/components/grid/AutoGrid.tsx.preview @@ -1,11 +1,11 @@ - - xs + + size=grow - - xs=6 + + size=6 - - xs + + size=grow \ No newline at end of file diff --git a/docs/data/joy/components/grid/BasicGrid.js b/docs/data/joy/components/grid/BasicGrid.js index 4ab843fdd64cf4..0a1c0542411ab5 100644 --- a/docs/data/joy/components/grid/BasicGrid.js +++ b/docs/data/joy/components/grid/BasicGrid.js @@ -18,17 +18,17 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function BasicGrid() { return ( - - xs=8 + + size=8 - - xs=4 + + size=4 - - xs=4 + + size=4 - - xs=8 + + size=8 ); diff --git a/docs/data/joy/components/grid/BasicGrid.tsx b/docs/data/joy/components/grid/BasicGrid.tsx index 4ab843fdd64cf4..0a1c0542411ab5 100644 --- a/docs/data/joy/components/grid/BasicGrid.tsx +++ b/docs/data/joy/components/grid/BasicGrid.tsx @@ -18,17 +18,17 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function BasicGrid() { return ( - - xs=8 + + size=8 - - xs=4 + + size=4 - - xs=4 + + size=4 - - xs=8 + + size=8 ); diff --git a/docs/data/joy/components/grid/BasicGrid.tsx.preview b/docs/data/joy/components/grid/BasicGrid.tsx.preview index c068f77d0503d4..162fd81bb8ac5b 100644 --- a/docs/data/joy/components/grid/BasicGrid.tsx.preview +++ b/docs/data/joy/components/grid/BasicGrid.tsx.preview @@ -1,14 +1,14 @@ - - xs=8 + + size=8 - - xs=4 + + size=4 - - xs=4 + + size=4 - - xs=8 + + size=8 \ No newline at end of file diff --git a/docs/data/joy/components/grid/CSSGrid.js b/docs/data/joy/components/grid/CSSGrid.js index 5a40e82099038b..ddee500a868fbc 100644 --- a/docs/data/joy/components/grid/CSSGrid.js +++ b/docs/data/joy/components/grid/CSSGrid.js @@ -20,16 +20,16 @@ export default function CSSGrid() { - xs=8 + size=8 - xs=4 + size=4 - xs=4 + size=4 - xs=8 + size=8 diff --git a/docs/data/joy/components/grid/CSSGrid.tsx b/docs/data/joy/components/grid/CSSGrid.tsx index 5a40e82099038b..ddee500a868fbc 100644 --- a/docs/data/joy/components/grid/CSSGrid.tsx +++ b/docs/data/joy/components/grid/CSSGrid.tsx @@ -20,16 +20,16 @@ export default function CSSGrid() { - xs=8 + size=8 - xs=4 + size=4 - xs=4 + size=4 - xs=8 + size=8 diff --git a/docs/data/joy/components/grid/CSSGrid.tsx.preview b/docs/data/joy/components/grid/CSSGrid.tsx.preview index e0a55118f7e4e4..0911896c8ed831 100644 --- a/docs/data/joy/components/grid/CSSGrid.tsx.preview +++ b/docs/data/joy/components/grid/CSSGrid.tsx.preview @@ -1,14 +1,14 @@ - xs=8 + size=8 - xs=4 + size=4 - xs=4 + size=4 - xs=8 + size=8 \ No newline at end of file diff --git a/docs/data/joy/components/grid/ChildrenCenteredGrid.js b/docs/data/joy/components/grid/ChildrenCenteredGrid.js index 74a9b4fef0a611..46656dc746ba3e 100644 --- a/docs/data/joy/components/grid/ChildrenCenteredGrid.js +++ b/docs/data/joy/components/grid/ChildrenCenteredGrid.js @@ -24,15 +24,13 @@ export default function ChildrenCenteredGrid() { {['Jimmy', 'Michal', 'Jun', 'Marija'].map((name, index) => ( {name} diff --git a/docs/data/joy/components/grid/ChildrenCenteredGrid.tsx b/docs/data/joy/components/grid/ChildrenCenteredGrid.tsx index 74a9b4fef0a611..46656dc746ba3e 100644 --- a/docs/data/joy/components/grid/ChildrenCenteredGrid.tsx +++ b/docs/data/joy/components/grid/ChildrenCenteredGrid.tsx @@ -24,15 +24,13 @@ export default function ChildrenCenteredGrid() { {['Jimmy', 'Michal', 'Jun', 'Marija'].map((name, index) => ( {name} diff --git a/docs/data/joy/components/grid/ColumnsGrid.js b/docs/data/joy/components/grid/ColumnsGrid.js index 6175eaa17cbc0f..53b29dbd53a485 100644 --- a/docs/data/joy/components/grid/ColumnsGrid.js +++ b/docs/data/joy/components/grid/ColumnsGrid.js @@ -18,11 +18,11 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function ColumnsGrid() { return ( - - xs=8 + + size=8 - - xs=8 + + size=8 ); diff --git a/docs/data/joy/components/grid/ColumnsGrid.tsx b/docs/data/joy/components/grid/ColumnsGrid.tsx index 6175eaa17cbc0f..53b29dbd53a485 100644 --- a/docs/data/joy/components/grid/ColumnsGrid.tsx +++ b/docs/data/joy/components/grid/ColumnsGrid.tsx @@ -18,11 +18,11 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function ColumnsGrid() { return ( - - xs=8 + + size=8 - - xs=8 + + size=8 ); diff --git a/docs/data/joy/components/grid/ColumnsGrid.tsx.preview b/docs/data/joy/components/grid/ColumnsGrid.tsx.preview index bf3539f8b90a8e..bcc4b8aedb471d 100644 --- a/docs/data/joy/components/grid/ColumnsGrid.tsx.preview +++ b/docs/data/joy/components/grid/ColumnsGrid.tsx.preview @@ -1,8 +1,8 @@ - - xs=8 + + size=8 - - xs=8 + + size=8 \ No newline at end of file diff --git a/docs/data/joy/components/grid/FullWidthGrid.js b/docs/data/joy/components/grid/FullWidthGrid.js index f6cd1a481d6747..6b45cb80f4c4af 100644 --- a/docs/data/joy/components/grid/FullWidthGrid.js +++ b/docs/data/joy/components/grid/FullWidthGrid.js @@ -18,16 +18,16 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function FullWidthGrid() { return ( - + xs=6 md=8 - + xs=6 md=4 - + xs=6 md=4 - + xs=6 md=8 diff --git a/docs/data/joy/components/grid/FullWidthGrid.tsx b/docs/data/joy/components/grid/FullWidthGrid.tsx index f6cd1a481d6747..6b45cb80f4c4af 100644 --- a/docs/data/joy/components/grid/FullWidthGrid.tsx +++ b/docs/data/joy/components/grid/FullWidthGrid.tsx @@ -18,16 +18,16 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function FullWidthGrid() { return ( - + xs=6 md=8 - + xs=6 md=4 - + xs=6 md=4 - + xs=6 md=8 diff --git a/docs/data/joy/components/grid/FullWidthGrid.tsx.preview b/docs/data/joy/components/grid/FullWidthGrid.tsx.preview index e3cac4aad83f04..a6d886bab7066e 100644 --- a/docs/data/joy/components/grid/FullWidthGrid.tsx.preview +++ b/docs/data/joy/components/grid/FullWidthGrid.tsx.preview @@ -1,14 +1,14 @@ - + xs=6 md=8 - + xs=6 md=4 - + xs=6 md=4 - + xs=6 md=8 \ No newline at end of file diff --git a/docs/data/joy/components/grid/InteractiveGrid.js b/docs/data/joy/components/grid/InteractiveGrid.js index 3a6425ffc583fe..d62eb4194d47d3 100644 --- a/docs/data/joy/components/grid/InteractiveGrid.js +++ b/docs/data/joy/components/grid/InteractiveGrid.js @@ -27,7 +27,7 @@ export default function InteractiveGrid() { return ( - + - + - + direction - + justifyContent - + alignItems - + diff --git a/docs/data/joy/components/grid/InteractiveGrid.tsx b/docs/data/joy/components/grid/InteractiveGrid.tsx index 15017b27815699..325095d7f8fcc6 100644 --- a/docs/data/joy/components/grid/InteractiveGrid.tsx +++ b/docs/data/joy/components/grid/InteractiveGrid.tsx @@ -43,7 +43,7 @@ export default function InteractiveGrid() { return ( - + - + - + direction - + justifyContent - + alignItems - + diff --git a/docs/data/joy/components/grid/ResponsiveGrid.js b/docs/data/joy/components/grid/ResponsiveGrid.js index cd862ace452e12..f099db6c2d71d2 100644 --- a/docs/data/joy/components/grid/ResponsiveGrid.js +++ b/docs/data/joy/components/grid/ResponsiveGrid.js @@ -24,8 +24,8 @@ export default function ResponsiveGrid() { sx={{ flexGrow: 1 }} > {Array.from(Array(6)).map((_, index) => ( - - xs=2 + + {index + 1} ))} diff --git a/docs/data/joy/components/grid/ResponsiveGrid.tsx b/docs/data/joy/components/grid/ResponsiveGrid.tsx index cd862ace452e12..f099db6c2d71d2 100644 --- a/docs/data/joy/components/grid/ResponsiveGrid.tsx +++ b/docs/data/joy/components/grid/ResponsiveGrid.tsx @@ -24,8 +24,8 @@ export default function ResponsiveGrid() { sx={{ flexGrow: 1 }} > {Array.from(Array(6)).map((_, index) => ( - - xs=2 + + {index + 1} ))} diff --git a/docs/data/joy/components/grid/ResponsiveGrid.tsx.preview b/docs/data/joy/components/grid/ResponsiveGrid.tsx.preview index c6395fe5ca4477..bf95bc84b701e1 100644 --- a/docs/data/joy/components/grid/ResponsiveGrid.tsx.preview +++ b/docs/data/joy/components/grid/ResponsiveGrid.tsx.preview @@ -5,8 +5,8 @@ sx={{ flexGrow: 1 }} > {Array.from(Array(6)).map((_, index) => ( - - xs=2 + + {index + 1} ))} \ No newline at end of file diff --git a/docs/data/joy/components/grid/RowAndColumnSpacing.js b/docs/data/joy/components/grid/RowAndColumnSpacing.js index 435f775e4083e6..f8e21087b725e9 100644 --- a/docs/data/joy/components/grid/RowAndColumnSpacing.js +++ b/docs/data/joy/components/grid/RowAndColumnSpacing.js @@ -23,16 +23,16 @@ export default function RowAndColumnSpacing() { columnSpacing={{ xs: 1, sm: 2, md: 3 }} sx={{ width: '100%' }} > - + 1 - + 2 - + 3 - + 4 diff --git a/docs/data/joy/components/grid/RowAndColumnSpacing.tsx b/docs/data/joy/components/grid/RowAndColumnSpacing.tsx index 435f775e4083e6..f8e21087b725e9 100644 --- a/docs/data/joy/components/grid/RowAndColumnSpacing.tsx +++ b/docs/data/joy/components/grid/RowAndColumnSpacing.tsx @@ -23,16 +23,16 @@ export default function RowAndColumnSpacing() { columnSpacing={{ xs: 1, sm: 2, md: 3 }} sx={{ width: '100%' }} > - + 1 - + 2 - + 3 - + 4 diff --git a/docs/data/joy/components/grid/SpacingGrid.js b/docs/data/joy/components/grid/SpacingGrid.js index b23970449d3e57..c14ee7ce14a707 100644 --- a/docs/data/joy/components/grid/SpacingGrid.js +++ b/docs/data/joy/components/grid/SpacingGrid.js @@ -21,7 +21,7 @@ export default function SpacingGrid() { return ( - + {[0, 1, 2].map((value) => ( @@ -30,7 +30,7 @@ export default function SpacingGrid() { ))} - + diff --git a/docs/data/joy/components/grid/SpacingGrid.tsx b/docs/data/joy/components/grid/SpacingGrid.tsx index 47f57585154596..e7c325d68bd22d 100644 --- a/docs/data/joy/components/grid/SpacingGrid.tsx +++ b/docs/data/joy/components/grid/SpacingGrid.tsx @@ -21,7 +21,7 @@ export default function SpacingGrid() { return ( - + {[0, 1, 2].map((value) => ( @@ -30,7 +30,7 @@ export default function SpacingGrid() { ))} - + diff --git a/docs/data/joy/components/grid/VariableWidthGrid.js b/docs/data/joy/components/grid/VariableWidthGrid.js index 659428350eb7e7..056245b0d95abf 100644 --- a/docs/data/joy/components/grid/VariableWidthGrid.js +++ b/docs/data/joy/components/grid/VariableWidthGrid.js @@ -18,14 +18,14 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function VariableWidthGrid() { return ( - - variable width content + + size=auto - - xs=6 + + size=6 - - xs + + size=grow ); diff --git a/docs/data/joy/components/grid/VariableWidthGrid.tsx b/docs/data/joy/components/grid/VariableWidthGrid.tsx index 659428350eb7e7..056245b0d95abf 100644 --- a/docs/data/joy/components/grid/VariableWidthGrid.tsx +++ b/docs/data/joy/components/grid/VariableWidthGrid.tsx @@ -18,14 +18,14 @@ const Item = styled(Sheet)(({ theme }) => ({ export default function VariableWidthGrid() { return ( - - variable width content + + size=auto - - xs=6 + + size=6 - - xs + + size=grow ); diff --git a/docs/data/joy/components/grid/VariableWidthGrid.tsx.preview b/docs/data/joy/components/grid/VariableWidthGrid.tsx.preview index 34fee62a643aed..b1fdd44a57b2e4 100644 --- a/docs/data/joy/components/grid/VariableWidthGrid.tsx.preview +++ b/docs/data/joy/components/grid/VariableWidthGrid.tsx.preview @@ -1,11 +1,11 @@ - - variable width content + + size=auto - - xs=6 + + size=6 - - xs + + size=grow \ No newline at end of file diff --git a/docs/data/joy/components/grid/grid.md b/docs/data/joy/components/grid/grid.md index b8d64c71d8a5ed..9666ed5769ad3e 100644 --- a/docs/data/joy/components/grid/grid.md +++ b/docs/data/joy/components/grid/grid.md @@ -23,11 +23,8 @@ The `Grid` component shouldn't be confused with a data grid; it is closer to a l import Grid from '@mui/joy/Grid'; ``` -Column widths are integer values between 1 and 12. They apply at any breakpoint and indicate how many columns are occupied by the component. - -By default, the value given to a breakpoint is applied to all the other **wider** breakpoints. - -For example, `xs={12}` sizes a component to occupy the whole viewport width regardless of its size, even if you do not pass any value for wider breakpoints like `sm` or `md`. +Column widths are integer values between 1 and 12. +For example, an item with `size={6}` occupies half of the grid container's width. {{"demo": "BasicGrid.js", "bg": true}} @@ -37,7 +34,7 @@ For example, `xs={12}` sizes a component to occupy the whole viewport width rega Components may have multiple widths defined, causing the layout to change at the defined breakpoint. Width values given to larger breakpoints override those given to smaller breakpoints. -For example, `xs={12} sm={6}` sizes a component to occupy half of the viewport width (6 columns) when viewport width is 600 or more pixels. For smaller viewports, the component fills all 12 available columns. +For example, `size={{ xs: 12, sm: 6 }}` sizes a component to occupy half of the viewport width (6 columns) when viewport width is 600 or more pixels. For smaller viewports, the component fills all 12 available columns. {{"demo": "FullWidthGrid.js", "bg": true}} @@ -64,11 +61,13 @@ You can switch the props' value based on the active breakpoint. Responsive values is supported by: +- `size` - `columns` - `columnSpacing` - `direction` - `rowSpacing` - `spacing` +- `offset` - all the [other props](#system-props) of MUI System :::warning @@ -77,7 +76,7 @@ For instance, this is not working. The grid item misses the value for `md`: ```jsx - + ``` @@ -92,7 +91,7 @@ This also means that you can set the width of one grid item, and the others will ### Variable width content -Set one of the size breakpoint props to `"auto"` instead of `true` or a `number` to render a column based on the natural width of its content. +Set one of the size breakpoint props to `"auto"` to render a column based on the natural width of its content. {{"demo": "VariableWidthGrid.js", "bg": true}} @@ -128,7 +127,7 @@ The spacing between items is implemented with a negative margin. This might lead ### direction: column | column-reverse -The `xs`, `sm`, `md`, `lg`, and `xl` props are **not supported** within `direction="column"` and `direction="column-reverse"` containers. +The `size` and `offset` props are **not supported** within `direction="column"` and `direction="column-reverse"` containers. They define the number of grids the component will use for a given breakpoint. They are intended to control **width** using `flex-basis` in `row` containers but they will impact height in `column` containers. If used, these props may have undesirable effects on the height of the `Grid` item elements. diff --git a/docs/data/joy/components/snackbar/PositionedSnackbar.js b/docs/data/joy/components/snackbar/PositionedSnackbar.js index ee272b37adf561..abde01653071d3 100644 --- a/docs/data/joy/components/snackbar/PositionedSnackbar.js +++ b/docs/data/joy/components/snackbar/PositionedSnackbar.js @@ -39,7 +39,7 @@ export default function PositionedSnackbar() { - + - + - + - + - + - + - + - + - + } title="Join the community" @@ -141,7 +141,7 @@ export default function HowToSupport() { - + } title="Support us financially" diff --git a/docs/src/components/about/OurValues.tsx b/docs/src/components/about/OurValues.tsx index e56d7d74cccb6c..b67dcd84172892 100644 --- a/docs/src/components/about/OurValues.tsx +++ b/docs/src/components/about/OurValues.tsx @@ -70,7 +70,7 @@ export default function OurValues() { {values.map(({ title, description, darkIcon, lightIcon, height, width }) => ( - + ({ diff --git a/docs/src/components/about/Team.tsx b/docs/src/components/about/Team.tsx index 60500a97e12e6b..51adddc5596514 100644 --- a/docs/src/components/about/Team.tsx +++ b/docs/src/components/about/Team.tsx @@ -363,7 +363,7 @@ export default function Team() { ...profileJson, }; return ( - + ); @@ -387,7 +387,7 @@ export default function Team() { {contributors.map((profile) => ( - + ))} @@ -406,7 +406,7 @@ export default function Team() { {emeriti.map((profile) => ( - + ))} diff --git a/docs/src/components/careers/CareersFaq.tsx b/docs/src/components/careers/CareersFaq.tsx index 175052f5fd6b2a..b3a385cfc9a4ba 100644 --- a/docs/src/components/careers/CareersFaq.tsx +++ b/docs/src/components/careers/CareersFaq.tsx @@ -106,11 +106,11 @@ export default function CareersFaq() { Frequently asked questions - + {renderFAQItem(0, true)} {renderFAQItem(1)} - + {renderFAQItem(2)} - + diff --git a/docs/src/components/home/CompaniesGrid.tsx b/docs/src/components/home/CompaniesGrid.tsx index 691f9aefc3e043..3165859c29d65f 100644 --- a/docs/src/components/home/CompaniesGrid.tsx +++ b/docs/src/components/home/CompaniesGrid.tsx @@ -189,15 +189,13 @@ export default function CompaniesGrid({ data }: { data: Array }) {data.map((imgProps) => ( diff --git a/docs/src/components/home/DiamondSponsors.tsx b/docs/src/components/home/DiamondSponsors.tsx index 244567b64636c6..aa9ba2ccf9f79d 100644 --- a/docs/src/components/home/DiamondSponsors.tsx +++ b/docs/src/components/home/DiamondSponsors.tsx @@ -61,12 +61,12 @@ export default function DiamondSponsors() { {DIAMONDs.map((item) => ( - + ))} {spotIsAvailable && ( - + {GOLDs.map((item) => ( - + ))} - + - + {inView ? ( diff --git a/docs/src/components/home/UserFeedbacks.tsx b/docs/src/components/home/UserFeedbacks.tsx index 139e59ada59fdb..30cf0e8a81d135 100644 --- a/docs/src/components/home/UserFeedbacks.tsx +++ b/docs/src/components/home/UserFeedbacks.tsx @@ -176,7 +176,7 @@ export default function UserFeedbacks() { > {TESTIMONIALS.map((item) => ( - + ))} diff --git a/docs/src/components/home/ValueProposition.tsx b/docs/src/components/home/ValueProposition.tsx index 29d24f2664d899..7f06c970ff3911 100644 --- a/docs/src/components/home/ValueProposition.tsx +++ b/docs/src/components/home/ValueProposition.tsx @@ -51,7 +51,7 @@ export default function ValueProposition() { /> {content.map(({ icon, title, description }) => ( - + ))} diff --git a/docs/src/components/pricing/PricingFAQ.tsx b/docs/src/components/pricing/PricingFAQ.tsx index d11eb2219b0f49..6e13b94c077914 100644 --- a/docs/src/components/pricing/PricingFAQ.tsx +++ b/docs/src/components/pricing/PricingFAQ.tsx @@ -271,19 +271,19 @@ export default function PricingFAQ() { Frequently asked questions - + {renderItem(0)} {renderItem(1)} {renderItem(2)} {renderItem(3)} - + {renderItem(4)} {renderItem(5)} {renderItem(6)} {renderItem(7)} - + ({ diff --git a/docs/src/components/productBaseUI/BaseUIComponents.tsx b/docs/src/components/productBaseUI/BaseUIComponents.tsx index 327dc9ca9cd0e8..97709951c7ed83 100644 --- a/docs/src/components/productBaseUI/BaseUIComponents.tsx +++ b/docs/src/components/productBaseUI/BaseUIComponents.tsx @@ -72,7 +72,7 @@ export default function BaseUIComponents() { return (
- + - + - + - + li': { alignItems: 'flex-start' } }}> } /> diff --git a/docs/src/components/productBaseUI/BaseUISummary.tsx b/docs/src/components/productBaseUI/BaseUISummary.tsx index 2bbe8a64a7dd72..ccf05616baf70a 100644 --- a/docs/src/components/productBaseUI/BaseUISummary.tsx +++ b/docs/src/components/productBaseUI/BaseUISummary.tsx @@ -50,7 +50,7 @@ export default function BaseUISummary() { {content.map(({ icon, title, description, link }) => ( - + ))} diff --git a/docs/src/components/productBaseUI/BaseUITestimonial.tsx b/docs/src/components/productBaseUI/BaseUITestimonial.tsx index 2422646619345f..6f5c85def523df 100644 --- a/docs/src/components/productBaseUI/BaseUITestimonial.tsx +++ b/docs/src/components/productBaseUI/BaseUITestimonial.tsx @@ -14,7 +14,7 @@ export default function BaseUITestimonial() { return (
- + - + “After considering various options, we decided to migrate our custom components to Material UI, and that's when we discovered Base UI. As a set of headless diff --git a/docs/src/components/productDesignKit/DesignKitDemo.tsx b/docs/src/components/productDesignKit/DesignKitDemo.tsx index 335b7232c80fd1..a1385a49445658 100644 --- a/docs/src/components/productDesignKit/DesignKitDemo.tsx +++ b/docs/src/components/productDesignKit/DesignKitDemo.tsx @@ -193,7 +193,7 @@ export default function DesignKitsDemo() { return (
- + - + diff --git a/docs/src/components/productDesignKit/DesignKitFAQ.tsx b/docs/src/components/productDesignKit/DesignKitFAQ.tsx index 543a7ca743ef11..e54fef7f10753b 100644 --- a/docs/src/components/productDesignKit/DesignKitFAQ.tsx +++ b/docs/src/components/productDesignKit/DesignKitFAQ.tsx @@ -149,12 +149,12 @@ export default function DesignKitFAQ() { Frequently asked questions - + {renderItem(0)} {renderItem(1)} {renderItem(2)} - + {renderItem(3)} {renderItem(4)} {content.map(({ icon, title, description }) => ( - + ))} diff --git a/docs/src/components/productDesignKit/SyncFeatures.tsx b/docs/src/components/productDesignKit/SyncFeatures.tsx index 585be085b20ccf..a5246c8ba7b8bc 100644 --- a/docs/src/components/productDesignKit/SyncFeatures.tsx +++ b/docs/src/components/productDesignKit/SyncFeatures.tsx @@ -41,7 +41,7 @@ export default function ConnectFeatures() { return (
- + - + - + - + diff --git a/docs/src/components/productMaterial/MaterialDesignKits.tsx b/docs/src/components/productMaterial/MaterialDesignKits.tsx index ff8a0f86272b75..1c216e201809b7 100644 --- a/docs/src/components/productMaterial/MaterialDesignKits.tsx +++ b/docs/src/components/productMaterial/MaterialDesignKits.tsx @@ -43,7 +43,7 @@ export default function MaterialDesignKits({ gradient }: MaterialDesignKitsProps return (
- + - + diff --git a/docs/src/components/productMaterial/MaterialEnd.tsx b/docs/src/components/productMaterial/MaterialEnd.tsx index b6ffed542dc178..c43278f35b5e59 100644 --- a/docs/src/components/productMaterial/MaterialEnd.tsx +++ b/docs/src/components/productMaterial/MaterialEnd.tsx @@ -59,7 +59,7 @@ export default function MaterialEnd({ noFaq }: MaterialEndProps) { ) : ( - + - + li': { alignItems: 'flex-start' } }}> } /> diff --git a/docs/src/components/productMaterial/MaterialStyling.tsx b/docs/src/components/productMaterial/MaterialStyling.tsx index 84be6504570408..7b4175577e8df4 100644 --- a/docs/src/components/productMaterial/MaterialStyling.tsx +++ b/docs/src/components/productMaterial/MaterialStyling.tsx @@ -154,7 +154,7 @@ export default function MaterialStyling() { return (
- + - + - + - + - + - + - + {componentIndex === 0 && } diff --git a/docs/src/components/productX/XDataGrid.tsx b/docs/src/components/productX/XDataGrid.tsx index 11bcd5b7036d36..2905340a3cfb0f 100644 --- a/docs/src/components/productX/XDataGrid.tsx +++ b/docs/src/components/productX/XDataGrid.tsx @@ -119,7 +119,7 @@ export default function XDataGrid() { return (
- + - + - + - + {content.map(({ icon, title, description, link }) => ( diff --git a/docs/src/components/productX/XRoadmap.tsx b/docs/src/components/productX/XRoadmap.tsx index feeb46553e1c2d..6ddd927c2aeca1 100644 --- a/docs/src/components/productX/XRoadmap.tsx +++ b/docs/src/components/productX/XRoadmap.tsx @@ -101,7 +101,7 @@ export default function XRoadmap() { }} > - + - + - + - + - + - + {customized ? ( {content.map(({ icon, title, description, link }) => ( - + item[sortFunctionName] !== undefined) .sort(sortFunction) .map((app) => ( - + {app.image ? ( {content.map(({ icon, title, description, link }) => ( - + {utilComponents.map(({ icon, title, link }) => ( - + ))} diff --git a/docs/src/modules/components/MaterialUIDesignResources.js b/docs/src/modules/components/MaterialUIDesignResources.js index 51f5affd1be9c0..3b9034f3b049d9 100644 --- a/docs/src/modules/components/MaterialUIDesignResources.js +++ b/docs/src/modules/components/MaterialUIDesignResources.js @@ -48,7 +48,7 @@ export default function MaterialUIDesignResources() { return ( {content.map(({ svg, title, link }) => ( - + ))} diff --git a/docs/src/modules/components/MaterialUIExampleCollection.js b/docs/src/modules/components/MaterialUIExampleCollection.js index e613c3331a87cc..a1128bdefe06b7 100644 --- a/docs/src/modules/components/MaterialUIExampleCollection.js +++ b/docs/src/modules/components/MaterialUIExampleCollection.js @@ -106,7 +106,7 @@ export default function MaterialUIExampleCollection() { return ( {examples.map((example) => ( - + ({ diff --git a/docs/translations/api-docs/grid/grid.json b/docs/translations/api-docs/grid/grid.json index 55af5efb02d225..284d73c71a45f1 100644 --- a/docs/translations/api-docs/grid/grid.json +++ b/docs/translations/api-docs/grid/grid.json @@ -12,44 +12,18 @@ "direction": { "description": "Defines the flex-direction style property. It is applied for all screen sizes." }, - "lg": { - "description": "If a number, it sets the number of columns the grid item uses. It can't be greater than the total number of columns of the container (12 by default). If 'auto', the grid item's width matches its content. If false, the prop is ignored. If true, the grid item's width grows to use the space available in the grid container. The value is applied for the lg breakpoint and wider screens if not overridden." - }, - "lgOffset": { - "description": "If a number, it sets the margin-left equals to the number of columns the grid item uses. If 'auto', the grid item push itself to the right-end of the container. The value is applied for the lg breakpoint and wider screens if not overridden." - }, - "md": { - "description": "If a number, it sets the number of columns the grid item uses. It can't be greater than the total number of columns of the container (12 by default). If 'auto', the grid item's width matches its content. If false, the prop is ignored. If true, the grid item's width grows to use the space available in the grid container. The value is applied for the md breakpoint and wider screens if not overridden." - }, - "mdOffset": { - "description": "If a number, it sets the margin-left equals to the number of columns the grid item uses. If 'auto', the grid item push itself to the right-end of the container. The value is applied for the md breakpoint and wider screens if not overridden." + "offset": { + "description": "Defines the offset value for the type item components." }, "rowSpacing": { "description": "Defines the vertical space between the type item components. It overrides the value of the spacing prop." }, - "sm": { - "description": "If a number, it sets the number of columns the grid item uses. It can't be greater than the total number of columns of the container (12 by default). If 'auto', the grid item's width matches its content. If false, the prop is ignored. If true, the grid item's width grows to use the space available in the grid container. The value is applied for the sm breakpoint and wider screens if not overridden." - }, - "smOffset": { - "description": "If a number, it sets the margin-left equals to the number of columns the grid item uses. If 'auto', the grid item push itself to the right-end of the container. The value is applied for the sm breakpoint and wider screens if not overridden." - }, + "size": { "description": "Defines the size of the the type item components." }, "spacing": { "description": "Defines the space between the type item components. It can only be used on a type container component." }, "wrap": { "description": "Defines the flex-wrap style property. It's applied for all screen sizes." - }, - "xl": { - "description": "If a number, it sets the number of columns the grid item uses. It can't be greater than the total number of columns of the container (12 by default). If 'auto', the grid item's width matches its content. If false, the prop is ignored. If true, the grid item's width grows to use the space available in the grid container. The value is applied for the xl breakpoint and wider screens if not overridden." - }, - "xlOffset": { - "description": "If a number, it sets the margin-left equals to the number of columns the grid item uses. If 'auto', the grid item push itself to the right-end of the container. The value is applied for the xl breakpoint and wider screens if not overridden." - }, - "xs": { - "description": "If a number, it sets the number of columns the grid item uses. It can't be greater than the total number of columns of the container (12 by default). If 'auto', the grid item's width matches its content. If false, the prop is ignored. If true, the grid item's width grows to use the space available in the grid container. The value is applied for all the screen sizes with the lowest priority." - }, - "xsOffset": { - "description": "If a number, it sets the margin-left equals to the number of columns the grid item uses. If 'auto', the grid item push itself to the right-end of the container. The value is applied for the xs breakpoint and wider screens if not overridden." } }, "classDescriptions": { diff --git a/packages/mui-codemod/README.md b/packages/mui-codemod/README.md index 87afe393fbe0f6..370e49ce8a6792 100644 --- a/packages/mui-codemod/README.md +++ b/packages/mui-codemod/README.md @@ -1759,6 +1759,36 @@ However, it has some **limitations**: })); ``` +#### `grid-v2-props` + +```bash +npx @mui/codemod@next v6.0.0/grid-v2-props +``` + +Updates the usage of the `Unstable_Grid` (Grid v2) component to have the same API as the `PigmentGrid`. + +```diff + +``` + +You can provide the theme breakpoints via options, for example, `--jscodeshift='--muiBreakpoints=mobile,desktop'`, to use your custom breakpoints in the transformation. + +```bash +npx @mui/codemod@next v6.0.0/grid-v2-props --jscodeshift='--muiBreakpoints=mobile,desktop' +``` + +```diff +- ++ +``` + ### v5.0.0 #### `base-use-named-exports` diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js new file mode 100644 index 00000000000000..18162b4e916546 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js @@ -0,0 +1,202 @@ +const possibleDefaultImports = [ + '@mui/material/Unstable_Grid2', + '@mui/system/Unstable_Grid', + '@mui/joy/Grid', +]; +const possibleNamedImports = { + '@mui/material': 'Unstable_Grid2', + '@mui/system': 'Unstable_Grid', + '@mui/joy': 'Grid', +}; + +const defaultBreakpoints = ['xs', 'sm', 'md', 'lg', 'xl']; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function gridV2Props(file, api, options) { + if (file.path?.endsWith('.json') || file.path?.endsWith('.d.ts')) { + return file.source; + } + const j = api.jscodeshift; + const root = j(file.source); + const breakpoints = options.muiBreakpoints?.split(',') || defaultBreakpoints; + const printOptions = options.printOptions; + + const gridLocalNames = []; + + root + .find(j.ImportDeclaration, (decl) => possibleDefaultImports.includes(decl.source.value)) + .forEach((decl) => { + decl.node.specifiers.forEach((spec) => { + if (spec.type === 'ImportDefaultSpecifier') { + gridLocalNames.push(spec.local.name); + } + }); + }); + + root + .find(j.ImportDeclaration, (decl) => + Object.keys(possibleNamedImports).includes(decl.source.value), + ) + .forEach((decl) => { + decl.node.specifiers.forEach((spec) => { + if (spec.type === 'ImportSpecifier') { + if (possibleNamedImports[decl.node.source.value] === spec.imported.name) { + gridLocalNames.push(spec.local.name); + } + } + }); + }); + + root + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => gridLocalNames.includes(name), + }, + }, + }) + .forEach((el) => { + const size = j.objectExpression([]); + + const spreadProps = []; + const attributesToPrune = []; + + el.node.openingElement.attributes.forEach((attr) => { + if (attr.type === 'JSXSpreadAttribute') { + spreadProps.push(attr); + } + }); + + const breakpointNodes = j(el) + .find(j.JSXAttribute) + .filter( + (path) => + path.parent.parent.node === el.node && breakpoints.includes(path.node.name.name), + ); + + breakpointNodes.nodes().forEach((node) => { + const breakpoint = node.name.name; + const nodeValue = node.value; + let value; + + if (nodeValue === null) { + value = j.stringLiteral('grow'); + } else if (nodeValue.type === 'JSXExpressionContainer') { + if (nodeValue.expression.value === true) { + value = j.stringLiteral('grow'); + } else { + value = nodeValue.expression; + } + } else { + value = nodeValue; + } + + size.properties.push(j.property('init', j.identifier(breakpoint), value)); + }); + + spreadProps.forEach((spreadProp) => { + const spreadPropArgument = spreadProp.argument; + if (spreadPropArgument.type === 'ObjectExpression') { + const propertiesToPrune = []; + spreadPropArgument.properties.forEach((property) => { + if (breakpoints.includes(property.key.name)) { + size.properties.push(j.property('init', property.key, property.value)); + propertiesToPrune.push(property.key.name); + } + }); + spreadPropArgument.properties = spreadPropArgument.properties.filter( + (prop) => !propertiesToPrune.includes(prop.key.name), + ); + if (spreadPropArgument.properties.length === 0) { + attributesToPrune.push(spreadProp); + } + } + }); + + if (size.properties.length) { + let sizePropValue = size; + if (size.properties.length === 1 && size.properties[0].key.name === 'xs') { + sizePropValue = size.properties[0].value; + } + if (sizePropValue.type !== 'StringLiteral') { + sizePropValue = j.jsxExpressionContainer(sizePropValue); + } + + el.node.openingElement.attributes.push( + j.jsxAttribute(j.jsxIdentifier('size'), sizePropValue), + ); + } + + el.node.openingElement.attributes = el.node.openingElement.attributes.filter( + (attr) => !breakpoints.includes(attr?.name?.name), + ); + + const offset = j.objectExpression([]); + + const offsetNodes = j(el) + .find(j.JSXAttribute) + .filter( + (path) => + path.parent.parent.node === el.node && + path.node.name.name.endsWith('Offset') && + breakpoints.includes(path.node.name.name.replace('Offset', '')), + ); + + offsetNodes.nodes().forEach((node) => { + const breakpoint = node.name.name.replace('Offset', ''); + const value = + node.value.type === 'JSXExpressionContainer' ? node.value.expression : node.value; + + offset.properties.push(j.property('init', j.identifier(breakpoint), value)); + }); + + spreadProps.forEach((spreadProp) => { + const spreadPropArgument = spreadProp.argument; + if (spreadPropArgument.type === 'ObjectExpression') { + const propertiesToPrune = []; + spreadPropArgument.properties.forEach((property) => { + const breakpoint = property.key.name.replace('Offset', ''); + if (property.key.name.endsWith('Offset') && breakpoints.includes(breakpoint)) { + offset.properties.push(j.property('init', j.identifier(breakpoint), property.value)); + propertiesToPrune.push(property.key.name); + } + }); + spreadPropArgument.properties = spreadPropArgument.properties.filter( + (prop) => !propertiesToPrune.includes(prop.key.name), + ); + if (spreadPropArgument.properties.length === 0) { + attributesToPrune.push(spreadProp); + } + } + }); + + if (offset.properties.length) { + let offsetPropValue = offset; + + if (offset.properties.length === 1 && offset.properties[0].key.name === 'xs') { + offsetPropValue = offset.properties[0].value; + } + + if (offsetPropValue.type !== 'StringLiteral') { + offsetPropValue = j.jsxExpressionContainer(offsetPropValue); + } + + el.node.openingElement.attributes.push( + j.jsxAttribute(j.jsxIdentifier('offset'), offsetPropValue), + ); + } + + el.node.openingElement.attributes = el.node.openingElement.attributes.filter( + (attr) => !breakpoints.includes(attr?.name?.name.replace('Offset', '')), + ); + + el.node.openingElement.attributes = el.node.openingElement.attributes.filter( + (attr) => !attributesToPrune.includes(attr), + ); + }); + + return root.toSource(printOptions); +} diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.test.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.test.js new file mode 100644 index 00000000000000..f3ceb48bd38e3e --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.test.js @@ -0,0 +1,23 @@ +import { describeJscodeshiftTransform } from '../../../testUtils'; +import transform from './grid-v2-props'; + +describe('@mui/codemod', () => { + describe('deprecations', () => { + describeJscodeshiftTransform({ + transform, + transformName: 'grid-props', + dirname: __dirname, + testCases: [ + { + actual: '/test-cases/actual.js', + expected: '/test-cases/expected.js', + }, + { + actual: '/test-cases/custom-breakpoints.actual.js', + expected: '/test-cases/custom-breakpoints.expected.js', + options: { muiBreakpoints: 'customXs,customSm,customMd' }, + }, + ], + }); + }); +}); diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/index.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/index.js new file mode 100644 index 00000000000000..ff55c7967fed58 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/index.js @@ -0,0 +1 @@ +export { default } from './grid-v2-props'; diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/actual.js new file mode 100644 index 00000000000000..4d4078308224e8 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/actual.js @@ -0,0 +1,38 @@ +import GridA from '@mui/material/Unstable_Grid2'; +import GridB from '@mui/system/Unstable_Grid'; +import GridC from '@mui/joy/Grid'; +import { Unstable_Grid2 as GridD, Grid as GridV1 } from '@mui/material'; +import { Unstable_Grid as GridE } from '@mui/system'; +import { Grid as GridF } from '@mui/joy'; + +// Transforms on all the possible imports +; +; +; +; +; +; + +// Transforms responsive sizes +; + +// Transforms all the possible size values +; + +// Doesn't add jsx object expression for single string values +; + +// Transforms offset +; + +// Transforms responsive offset +; + +// Transforms all the possible offset values +; + +// Transforms spread props +; + +// Doesn't transform Grid v1 +; diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.actual.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.actual.js new file mode 100644 index 00000000000000..edd2527bf9d24b --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.actual.js @@ -0,0 +1,7 @@ +import Grid from '@mui/material/Unstable_Grid2'; + +// Transforms custom breakpoints +; + +// Transforms custom breakpoints offset +; diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.expected.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.expected.js new file mode 100644 index 00000000000000..ede253532be318 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/custom-breakpoints.expected.js @@ -0,0 +1,17 @@ +import Grid from '@mui/material/Unstable_Grid2'; + +// Transforms custom breakpoints +; + +// Transforms custom breakpoints offset +; diff --git a/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/expected.js new file mode 100644 index 00000000000000..027e79fc502414 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/grid-v2-props/test-cases/expected.js @@ -0,0 +1,71 @@ +import GridA from '@mui/material/Unstable_Grid2'; +import GridB from '@mui/system/Unstable_Grid'; +import GridC from '@mui/joy/Grid'; +import { Unstable_Grid2 as GridD, Grid as GridV1 } from '@mui/material'; +import { Unstable_Grid as GridE } from '@mui/system'; +import { Grid as GridF } from '@mui/joy'; + +// Transforms on all the possible imports +; +; +; +; +; +; + +// Transforms responsive sizes +; + +// Transforms all the possible size values +; + +// Doesn't add jsx object expression for single string values +; + +// Transforms offset +; + +// Transforms responsive offset +; + +// Transforms all the possible offset values +; + +// Transforms spread props +; + +// Doesn't transform Grid v1 +; diff --git a/packages/mui-codemod/testUtils/index.js b/packages/mui-codemod/testUtils/index.js index e7bad6b85dbca0..37d435828282fb 100644 --- a/packages/mui-codemod/testUtils/index.js +++ b/packages/mui-codemod/testUtils/index.js @@ -19,7 +19,9 @@ export function describeJscodeshiftTransform({ transformName, transform, testCas { source: read(dirname, testCase.actual) }, { jscodeshift }, { + ...testCase.options, printOptions: { + ...testCase.options?.printOptions, lineTerminator: EOL, }, }, @@ -34,7 +36,9 @@ export function describeJscodeshiftTransform({ transformName, transform, testCas { source: read(dirname, testCase.expected) }, { jscodeshift }, { + ...testCase.options, printOptions: { + ...testCase.options?.printOptions, lineTerminator: EOL, }, }, diff --git a/packages/mui-system/src/Unstable_Grid/Grid.test.js b/packages/mui-system/src/Unstable_Grid/Grid.test.js index 2c2e101d001a70..e21ec6418441e3 100644 --- a/packages/mui-system/src/Unstable_Grid/Grid.test.js +++ b/packages/mui-system/src/Unstable_Grid/Grid.test.js @@ -33,17 +33,17 @@ describe('System ', () => { describe('prop: xs', () => { it('should apply the flex-grow class', () => { - const { container } = render(); - expect(container.firstChild).to.have.class(classes['grid-xs-true']); + const { container } = render(); + expect(container.firstChild).to.have.class(classes['grid-xs-grow']); }); it('should apply the flex size class', () => { - const { container } = render(); + const { container } = render(); expect(container.firstChild).to.have.class(classes['grid-xs-3']); }); it('should apply the flex auto class', () => { - const { container } = render(); + const { container } = render(); expect(container.firstChild).to.have.class(classes['grid-xs-auto']); }); @@ -55,10 +55,10 @@ describe('System ', () => { render( - +
- + , ); expect(screen.getByTestId('auto')).toHaveComputedStyle({ @@ -210,7 +210,13 @@ describe('System ', () => { })} > {/* `lg` is to mimic mistake, it is not a breakpoint anymore */} - + , ); @@ -220,8 +226,6 @@ describe('System ', () => { // The grid should not have class for `lg` prop expect(container.firstChild).not.to.have.class('MuiGrid-grid-lg-5'); - // The `lg` prop is treated as native props that spread to DOM - expect(container.firstChild).to.have.attribute('lg', '5'); }); it('should apply the custom breakpoint spacing class', () => { diff --git a/packages/mui-system/src/Unstable_Grid/Grid.tsx b/packages/mui-system/src/Unstable_Grid/Grid.tsx index 56605f827e9c3e..f9a7ba0ee0d26a 100644 --- a/packages/mui-system/src/Unstable_Grid/Grid.tsx +++ b/packages/mui-system/src/Unstable_Grid/Grid.tsx @@ -59,37 +59,14 @@ Grid.propTypes /* remove-proptypes */ = { PropTypes.object, ]), /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `lg` breakpoint and wider screens if not overridden. - * @default false - */ - lg: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `lg` breakpoint and wider screens if not overridden. - */ - lgOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `md` breakpoint and wider screens if not overridden. - * @default false - */ - md: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `md` breakpoint and wider screens if not overridden. + * Defines the offset value for the type `item` components. */ - mdOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), + offset: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), + PropTypes.object, + ]), /** * Defines the vertical space between the type `item` components. * It overrides the value of the `spacing` prop. @@ -101,21 +78,15 @@ Grid.propTypes /* remove-proptypes */ = { PropTypes.string, ]), /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `sm` breakpoint and wider screens if not overridden. - * @default false - */ - sm: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `sm` breakpoint and wider screens if not overridden. + * Defines the size of the the type `item` components. */ - smOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), + size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.string, + PropTypes.bool, + PropTypes.number, + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number])), + PropTypes.object, + ]), /** * Defines the space between the type `item` components. * It can only be used on a type `container` component. @@ -164,38 +135,6 @@ Grid.propTypes /* remove-proptypes */ = { * @default 'wrap' */ wrap: PropTypes.oneOf(['nowrap', 'wrap-reverse', 'wrap']), - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `xl` breakpoint and wider screens if not overridden. - * @default false - */ - xl: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `xl` breakpoint and wider screens if not overridden. - */ - xlOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for all the screen sizes with the lowest priority. - * @default false - */ - xs: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `xs` breakpoint and wider screens if not overridden. - */ - xsOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), } as any; export default Grid; diff --git a/packages/mui-system/src/Unstable_Grid/GridProps.ts b/packages/mui-system/src/Unstable_Grid/GridProps.ts index fbe77c10c0b0f1..51f891342908ee 100644 --- a/packages/mui-system/src/Unstable_Grid/GridProps.ts +++ b/packages/mui-system/src/Unstable_Grid/GridProps.ts @@ -1,7 +1,7 @@ import * as React from 'react'; -import { OverrideProps, IfEquals } from '@mui/types'; +import { OverrideProps, PartiallyRequired } from '@mui/types'; import { SxProps } from '../styleFunctionSx'; -import { Theme, Breakpoint, BreakpointOverrides } from '../createTheme'; +import { Theme, Breakpoint } from '../createTheme'; import { SystemProps } from '../Box'; type ResponsiveStyleValue = T | Array | { [key in Breakpoint]?: T | null }; @@ -12,105 +12,11 @@ export type GridSpacing = number | string; export type GridWrap = 'nowrap' | 'wrap' | 'wrap-reverse'; -export type GridSize = 'auto' | number; +export type GridSize = 'auto' | 'grow' | number | false; -export interface GridDefaultBreakpoints { - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `lg` breakpoint and wider screens if not overridden. - * @default false - */ - lg?: boolean | GridSize; - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `lg` breakpoint and wider screens if not overridden. - */ - lgOffset?: GridSize; - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `md` breakpoint and wider screens if not overridden. - * @default false - */ - md?: boolean | GridSize; - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `md` breakpoint and wider screens if not overridden. - */ - mdOffset?: GridSize; - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `sm` breakpoint and wider screens if not overridden. - * @default false - */ - sm?: boolean | GridSize; - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `sm` breakpoint and wider screens if not overridden. - */ - smOffset?: GridSize; - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for the `xl` breakpoint and wider screens if not overridden. - * @default false - */ - xl?: boolean | GridSize; - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `xl` breakpoint and wider screens if not overridden. - */ - xlOffset?: GridSize; - /** - * If a number, it sets the number of columns the grid item uses. - * It can't be greater than the total number of columns of the container (12 by default). - * If 'auto', the grid item's width matches its content. - * If false, the prop is ignored. - * If true, the grid item's width grows to use the space available in the grid container. - * The value is applied for all the screen sizes with the lowest priority. - * @default false - */ - xs?: boolean | GridSize; - /** - * If a number, it sets the margin-left equals to the number of columns the grid item uses. - * If 'auto', the grid item push itself to the right-end of the container. - * The value is applied for the `xs` breakpoint and wider screens if not overridden. - */ - xsOffset?: GridSize; -} +export type GridOffset = 'auto' | number; -type CustomBreakpoints = Partial< - Record & Record<`${Breakpoint}Offset`, GridSize> ->; - -interface BreakpointOverridesEmpty {} - -type Breakpoints = IfEquals< - BreakpointOverrides, - BreakpointOverridesEmpty, - GridDefaultBreakpoints, - CustomBreakpoints ->; - -export interface GridBaseProps extends Breakpoints { +export interface GridBaseProps { /** * The content of the component. */ @@ -137,6 +43,10 @@ export interface GridBaseProps extends Breakpoints { * @default 'row' */ direction?: ResponsiveStyleValue; + /** + * Defines the offset value for the type `item` components. + */ + offset?: ResponsiveStyleValue; /** * @internal * The level of the grid starts from `0` @@ -165,6 +75,10 @@ export interface GridBaseProps extends Breakpoints { * It overrides the value of the `spacing` prop. */ rowSpacing?: ResponsiveStyleValue; + /** + * Defines the size of the the type `item` components. + */ + size?: ResponsiveStyleValue; /** * Defines the space between the type `item` components. * It can only be used on a type `container` component. @@ -179,11 +93,7 @@ export interface GridBaseProps extends Breakpoints { wrap?: GridWrap; } -export interface GridOwnerState extends GridBaseProps { - unstable_level: number; - gridSize: Partial>; - gridOffset: Partial>; -} +export type GridOwnerState = PartiallyRequired; export interface GridTypeMap< AdditionalProps = {}, diff --git a/packages/mui-system/src/Unstable_Grid/createGrid.tsx b/packages/mui-system/src/Unstable_Grid/createGrid.tsx index b8069beeb88300..6cfe366a082b0d 100644 --- a/packages/mui-system/src/Unstable_Grid/createGrid.tsx +++ b/packages/mui-system/src/Unstable_Grid/createGrid.tsx @@ -9,7 +9,7 @@ import systemStyled from '../styled'; import useThemePropsSystem from '../useThemeProps'; import useTheme from '../useTheme'; import { extendSxProp } from '../styleFunctionSx'; -import createTheme from '../createTheme'; +import createTheme, { Breakpoint, Breakpoints } from '../createTheme'; import { generateGridStyles, generateGridSizeStyles, @@ -23,8 +23,7 @@ import { generateDirectionClasses, } from './gridGenerator'; import { CreateMUIStyled } from '../createStyled'; -import { GridTypeMap, GridOwnerState, GridProps } from './GridProps'; -import type { Breakpoint } from '../createTheme'; +import { GridTypeMap, GridOwnerState, GridProps, GridOffset, GridSize } from './GridProps'; const defaultTheme = createTheme(); @@ -58,14 +57,14 @@ export default function createGrid( } = options; const useUtilityClasses = (ownerState: GridOwnerState, theme: typeof defaultTheme) => { - const { container, direction, spacing, wrap, gridSize } = ownerState; + const { container, direction, spacing, wrap, size } = ownerState; const slots = { root: [ 'root', container && 'container', wrap !== 'wrap' && `wrap-xs-${String(wrap)}`, ...generateDirectionClasses(direction), - ...generateSizeClassNames(gridSize), + ...generateSizeClassNames(size), ...(container ? generateSpacingClassNames(spacing, theme.breakpoints.keys[0]) : []), ], }; @@ -73,6 +72,37 @@ export default function createGrid( return composeClasses(slots, (slot) => generateUtilityClass(componentName, slot), {}); }; + function parseResponsiveProp( + propValue: T | null | (T | null)[] | { [key in Breakpoint]?: T | null }, + breakpoints: Breakpoints, + shouldUseValue: (val: T) => boolean = () => true, + ): { [key in Breakpoint]: T } { + const parsedProp = {} as { [key in Breakpoint]: T }; + + if (propValue === null) { + return parsedProp; + } + + if (Array.isArray(propValue)) { + propValue.forEach((value, index) => { + if (value !== null && shouldUseValue(value) && breakpoints.keys[index]) { + parsedProp[breakpoints.keys[index]] = value; + } + }); + } else if (typeof propValue === 'object') { + Object.keys(propValue).forEach((key) => { + const value = propValue[key as Breakpoint]; + if (value !== null && value !== undefined && shouldUseValue(value)) { + parsedProp[key as Breakpoint] = value; + } + }); + } else { + parsedProp[breakpoints.keys[0]] = propValue; + } + + return parsedProp; + } + const GridRoot = createStyledComponent<{ ownerState: GridOwnerState; }>( @@ -97,26 +127,16 @@ export default function createGrid( component = 'div', direction = 'row', wrap = 'wrap', + size: sizeProp = {}, + offset: offsetProp = {}, spacing: spacingProp = 0, rowSpacing: rowSpacingProp = spacingProp, columnSpacing: columnSpacingProp = spacingProp, unstable_level: level = 0, ...rest } = props; - // collect breakpoints related props because they can be customized from the theme. - const gridSize = {} as GridOwnerState['gridSize']; - const gridOffset = {} as GridOwnerState['gridOffset']; - const other: Record = {}; - - Object.entries(rest).forEach(([key, val]) => { - if (theme.breakpoints.values[key as Breakpoint] !== undefined) { - gridSize[key as Breakpoint] = val; - } else if (theme.breakpoints.values[key.replace('Offset', '') as Breakpoint] !== undefined) { - gridOffset[key.replace('Offset', '') as Breakpoint] = val; - } else { - other[key] = val; - } - }); + const size = parseResponsiveProp(sizeProp, theme.breakpoints, (val) => val !== false); + const offset = parseResponsiveProp(offsetProp, theme.breakpoints); const columns = inProps.columns ?? (level ? undefined : columnsProp); const spacing = inProps.spacing ?? (level ? undefined : spacingProp); @@ -134,8 +154,8 @@ export default function createGrid( spacing, rowSpacing, columnSpacing, - gridSize, - gridOffset, + size, + offset, }; const classes = useUtilityClasses(ownerState, theme); @@ -146,7 +166,7 @@ export default function createGrid( as={component} ownerState={ownerState} className={clsx(classes.root, className)} - {...other} + {...rest} > {React.Children.map(children, (child) => { if (React.isValidElement(child) && isMuiElement(child, ['Grid'])) { @@ -181,18 +201,25 @@ export default function createGrid( PropTypes.arrayOf(PropTypes.oneOf(['column-reverse', 'column', 'row-reverse', 'row'])), PropTypes.object, ]), - lg: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - lgOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), - md: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - mdOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), + offset: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), + PropTypes.object, + ]), rowSpacing: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), PropTypes.number, PropTypes.object, PropTypes.string, ]), - sm: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - smOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), + size: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.bool, + PropTypes.number, + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number])), + PropTypes.object, + ]), spacing: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), PropTypes.number, @@ -205,10 +232,6 @@ export default function createGrid( PropTypes.object, ]), wrap: PropTypes.oneOf(['nowrap', 'wrap-reverse', 'wrap']), - xl: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - xlOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), - xs: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.bool]), - xsOffset: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]), }; // @ts-ignore internal logic for nested grid diff --git a/packages/mui-system/src/Unstable_Grid/gridClasses.ts b/packages/mui-system/src/Unstable_Grid/gridClasses.ts index 93b59de11cb538..6992ec33231f58 100644 --- a/packages/mui-system/src/Unstable_Grid/gridClasses.ts +++ b/packages/mui-system/src/Unstable_Grid/gridClasses.ts @@ -27,7 +27,7 @@ export function getGridUtilityClass(slot: string): string { const SPACINGS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as const; const DIRECTIONS = ['column-reverse', 'column', 'row-reverse', 'row'] as const; const WRAPS = ['nowrap', 'wrap-reverse', 'wrap'] as const; -const GRID_SIZES = ['auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] as const; +const GRID_SIZES = ['auto', 'grow', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] as const; const gridClasses: GridClasses = generateUtilityClasses('MuiGrid', [ 'root', diff --git a/packages/mui-system/src/Unstable_Grid/gridGenerator.test.js b/packages/mui-system/src/Unstable_Grid/gridGenerator.test.js index 42635f63b982e8..0a578dedac2d84 100644 --- a/packages/mui-system/src/Unstable_Grid/gridGenerator.test.js +++ b/packages/mui-system/src/Unstable_Grid/gridGenerator.test.js @@ -59,10 +59,10 @@ describe('grid generator', () => { generateGridSizeStyles({ theme: { breakpoints }, ownerState: { - gridSize: { + size: { xs: 'auto', sm: 6, - md: true, + md: 'grow', lg: 4, xl: 'auto', }, @@ -283,7 +283,7 @@ describe('grid generator', () => { expect( generateGridOffsetStyles({ theme: { breakpoints, spacing }, - ownerState: { gridOffset: { xs: 0, md: 5, lg: 'auto' } }, + ownerState: { offset: { xs: 0, md: 5, lg: 'auto' } }, }), ).to.deep.equal({ marginLeft: '0px', diff --git a/packages/mui-system/src/Unstable_Grid/gridGenerator.ts b/packages/mui-system/src/Unstable_Grid/gridGenerator.ts index 679fb0b08d9b5d..2a70149eb55778 100644 --- a/packages/mui-system/src/Unstable_Grid/gridGenerator.ts +++ b/packages/mui-system/src/Unstable_Grid/gridGenerator.ts @@ -45,12 +45,12 @@ function getParentColumns(ownerState: Props['ownerState']) { export const generateGridSizeStyles = ({ theme, ownerState }: Props) => { const getParentSpacing = createGetParentSpacing(ownerState); const styles = {}; - traverseBreakpoints<'auto' | number | true>( + traverseBreakpoints<'auto' | 'grow' | number | false>( theme.breakpoints, - ownerState.gridSize, + ownerState.size, (appendStyle, value) => { let style = {}; - if (value === true) { + if (value === 'grow') { style = { flexBasis: 0, flexGrow: 1, @@ -84,7 +84,7 @@ export const generateGridOffsetStyles = ({ theme, ownerState }: Props) => { const styles = {}; traverseBreakpoints( theme.breakpoints, - ownerState.gridOffset, + ownerState.offset, (appendStyle, value) => { let style = {}; if (value === 'auto') { @@ -202,13 +202,14 @@ export const generateGridStyles = ({ ownerState }: Props): {} => { }; }; -export const generateSizeClassNames = (gridSize: GridOwnerState['gridSize']) => { +export const generateSizeClassNames = (size: GridOwnerState['size']) => { const classNames: string[] = []; - Object.entries(gridSize).forEach(([key, value]) => { + Object.entries(size).forEach(([key, value]) => { if (value !== false && value !== undefined) { classNames.push(`grid-${key}-${String(value)}`); } }); + return classNames; }; diff --git a/packages/mui-system/src/createTheme/createTheme.d.ts b/packages/mui-system/src/createTheme/createTheme.d.ts index 0d6d555539d1b9..ad215cec97a15f 100644 --- a/packages/mui-system/src/createTheme/createTheme.d.ts +++ b/packages/mui-system/src/createTheme/createTheme.d.ts @@ -6,7 +6,7 @@ import { SxConfig, SxProps } from '../styleFunctionSx'; import { ApplyStyles } from './applyStyles'; import { CssContainerQueries } from '../cssContainerQueries'; -export { Breakpoint, BreakpointOverrides } from './createBreakpoints'; +export { Breakpoint, Breakpoints, BreakpointOverrides } from './createBreakpoints'; export type Direction = 'ltr' | 'rtl'; diff --git a/test/regressions/fixtures/Grid/StressNestedGrid2.js b/test/regressions/fixtures/Grid/StressNestedGrid2.js index f40b38d9f31d0e..43af25b5004974 100644 --- a/test/regressions/fixtures/Grid/StressNestedGrid2.js +++ b/test/regressions/fixtures/Grid/StressNestedGrid2.js @@ -17,71 +17,71 @@ export default function StressNestedGrid2() { }} > - + xs=12 - + xs=6 - + xs=6 {/* This grid should start as a new root grid (doesn't inherit spacing from the top) */} - + xs=6 - + {/* nested spacing can be override by the explicit `spacing` prop */} - - + + xs=7 - + xs=5 - + xs=6 - - + + xs=6 - + xs=6 - - + + xs=8 - + xs=4 {/* The grids below should inherit spacing from the top */} - - + + xs=4 - + xs=4 - + xs=4 - - + + xs=6 - + xs=6 diff --git a/test/regressions/fixtures/Grid/StyledGrid2.js b/test/regressions/fixtures/Grid/StyledGrid2.js index f744e6d7636e7c..ac0b2bce4b7b8b 100644 --- a/test/regressions/fixtures/Grid/StyledGrid2.js +++ b/test/regressions/fixtures/Grid/StyledGrid2.js @@ -11,18 +11,18 @@ export default function StressNestedGrid2() { return ( - + Item 1 - - + + Item 2.1 - + Item 2.2 - + Item 3