From 4109ca17ad2354716782688b2bf55b2dc0a8aa48 Mon Sep 17 00:00:00 2001 From: sai chand <60743144+sai6855@users.noreply.github.com> Date: Wed, 12 Apr 2023 12:37:14 +0530 Subject: [PATCH 001/100] [TextField] Fix type error when using `inputTypeSearch` class for `outlined` and `filled` inputs (#36740) Co-authored-by: ZeeshanTamboli --- docs/pages/material-ui/api/filled-input.json | 3 ++- docs/pages/material-ui/api/outlined-input.json | 3 ++- docs/translations/api-docs/filled-input/filled-input.json | 5 +++++ .../api-docs/outlined-input/outlined-input.json | 5 +++++ .../mui-material/src/FilledInput/filledInputClasses.ts | 2 ++ .../mui-material/src/OutlinedInput/outlinedInputClasses.ts | 2 ++ packages/mui-material/src/TextField/TextField.spec.tsx | 7 +++++++ 7 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/pages/material-ui/api/filled-input.json b/docs/pages/material-ui/api/filled-input.json index 37a8b6bc68212f..b26619675340ad 100644 --- a/docs/pages/material-ui/api/filled-input.json +++ b/docs/pages/material-ui/api/filled-input.json @@ -75,7 +75,8 @@ "inputHiddenLabel", "inputMultiline", "inputAdornedStart", - "inputAdornedEnd" + "inputAdornedEnd", + "inputTypeSearch" ], "globalClasses": { "focused": "Mui-focused", "disabled": "Mui-disabled", "error": "Mui-error" }, "name": "MuiFilledInput" diff --git a/docs/pages/material-ui/api/outlined-input.json b/docs/pages/material-ui/api/outlined-input.json index 6fa23be0676aa6..5697dc415b145a 100644 --- a/docs/pages/material-ui/api/outlined-input.json +++ b/docs/pages/material-ui/api/outlined-input.json @@ -65,7 +65,8 @@ "inputSizeSmall", "inputMultiline", "inputAdornedStart", - "inputAdornedEnd" + "inputAdornedEnd", + "inputTypeSearch" ], "globalClasses": { "focused": "Mui-focused", "disabled": "Mui-disabled", "error": "Mui-error" }, "name": "MuiOutlinedInput" diff --git a/docs/translations/api-docs/filled-input/filled-input.json b/docs/translations/api-docs/filled-input/filled-input.json index 31ee65d9696963..d2d4688110a7ca 100644 --- a/docs/translations/api-docs/filled-input/filled-input.json +++ b/docs/translations/api-docs/filled-input/filled-input.json @@ -112,6 +112,11 @@ "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the input element", "conditions": "endAdornment is provided" + }, + "inputTypeSearch": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the input element", + "conditions": "type=\"search\"" } } } diff --git a/docs/translations/api-docs/outlined-input/outlined-input.json b/docs/translations/api-docs/outlined-input/outlined-input.json index 0f12a4e767881a..ea097c684e62ce 100644 --- a/docs/translations/api-docs/outlined-input/outlined-input.json +++ b/docs/translations/api-docs/outlined-input/outlined-input.json @@ -99,6 +99,11 @@ "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the input element", "conditions": "endAdornment is provided" + }, + "inputTypeSearch": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the input element", + "conditions": "type=\"search\"" } } } diff --git a/packages/mui-material/src/FilledInput/filledInputClasses.ts b/packages/mui-material/src/FilledInput/filledInputClasses.ts index 67ec2bdb879b63..2032773788288d 100644 --- a/packages/mui-material/src/FilledInput/filledInputClasses.ts +++ b/packages/mui-material/src/FilledInput/filledInputClasses.ts @@ -37,6 +37,8 @@ export interface FilledInputClasses { inputAdornedStart: string; /** Styles applied to the input element if `endAdornment` is provided. */ inputAdornedEnd: string; + /** Styles applied to the input element if `type="search"`. */ + inputTypeSearch: string; } export type FilledInputClassKey = keyof FilledInputClasses; diff --git a/packages/mui-material/src/OutlinedInput/outlinedInputClasses.ts b/packages/mui-material/src/OutlinedInput/outlinedInputClasses.ts index bc209e29c16627..86aaa1e0e0302f 100644 --- a/packages/mui-material/src/OutlinedInput/outlinedInputClasses.ts +++ b/packages/mui-material/src/OutlinedInput/outlinedInputClasses.ts @@ -33,6 +33,8 @@ export interface OutlinedInputClasses { inputAdornedStart: string; /** Styles applied to the input element if `endAdornment` is provided. */ inputAdornedEnd: string; + /** Styles applied to the input element if `type="search"`. */ + inputTypeSearch: string; } export type OutlinedInputClassKey = keyof OutlinedInputClasses; diff --git a/packages/mui-material/src/TextField/TextField.spec.tsx b/packages/mui-material/src/TextField/TextField.spec.tsx index 56846edd6b25c5..aef486d4692d48 100644 --- a/packages/mui-material/src/TextField/TextField.spec.tsx +++ b/packages/mui-material/src/TextField/TextField.spec.tsx @@ -10,6 +10,13 @@ import { expectType } from '@mui/types'; const standard = ( ); + + const outlinedInputTypeSearch = ( + + ); + const filledInputTypeSearch = ( + + ); const standardOutlinedClassname = ( Date: Wed, 12 Apr 2023 12:40:34 +0530 Subject: [PATCH 002/100] [docs][Select] Fix duplicate ID in small size Select demo (#36792) --- docs/data/material/components/selects/SelectSmall.js | 4 ++-- docs/data/material/components/selects/SelectSmall.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/material/components/selects/SelectSmall.js b/docs/data/material/components/selects/SelectSmall.js index 97671949b312fd..99d073e5ed2a93 100644 --- a/docs/data/material/components/selects/SelectSmall.js +++ b/docs/data/material/components/selects/SelectSmall.js @@ -13,9 +13,9 @@ export default function SelectSmall() { return ( - Age + Age Date: Wed, 12 Apr 2023 08:37:00 +0100 Subject: [PATCH 003/100] [docs][base] Move styles to the bottom of demos code for `TablePagination` (#36593) --- .../table-pagination/TableCustomized.js | 152 ++++++++-------- .../table-pagination/TableCustomized.tsx | 162 +++++++++--------- .../table-pagination/TableUnstyled.js | 148 ++++++++-------- .../table-pagination/TableUnstyled.tsx | 148 ++++++++-------- .../UnstyledPaginationIntroduction.js | 86 +++++----- .../UnstyledPaginationIntroduction.tsx | 96 +++++------ 6 files changed, 396 insertions(+), 396 deletions(-) diff --git a/docs/data/base/components/table-pagination/TableCustomized.js b/docs/data/base/components/table-pagination/TableCustomized.js index 510e9786182dab..7c84dab7aaa9bf 100644 --- a/docs/data/base/components/table-pagination/TableCustomized.js +++ b/docs/data/base/components/table-pagination/TableCustomized.js @@ -4,6 +4,82 @@ import TablePaginationUnstyled, { tablePaginationUnstyledClasses as classes, } from '@mui/base/TablePaginationUnstyled'; +export default function UnstyledTable() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + + // Avoid a layout jump when reaching the last page with empty rows. + const emptyRows = + page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + + + + + + + + + {(rowsPerPage > 0 + ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + : rows + ).map((row) => ( + + + + + + ))} + + {emptyRows > 0 && ( + + + )} + + + + + + +
DessertCaloriesFat
{row.name} + {row.calories} + + {row.fat} +
+
+
+ ); +} + function createData(name, calories, fat) { return { name, calories, fat }; } @@ -132,79 +208,3 @@ const CustomTablePagination = styled(TablePaginationUnstyled)( } `, ); - -export default function UnstyledTable() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - - // Avoid a layout jump when reaching the last page with empty rows. - const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; - - const handleChangePage = (event, newPage) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - return ( - - - - - - - - - - - {(rowsPerPage > 0 - ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - : rows - ).map((row) => ( - - - - - - ))} - - {emptyRows > 0 && ( - - - )} - - - - - - -
DessertCaloriesFat
{row.name} - {row.calories} - - {row.fat} -
-
-
- ); -} diff --git a/docs/data/base/components/table-pagination/TableCustomized.tsx b/docs/data/base/components/table-pagination/TableCustomized.tsx index 9d0b38a5565d72..ea65d3fe06ef81 100644 --- a/docs/data/base/components/table-pagination/TableCustomized.tsx +++ b/docs/data/base/components/table-pagination/TableCustomized.tsx @@ -4,6 +4,87 @@ import TablePaginationUnstyled, { tablePaginationUnstyledClasses as classes, } from '@mui/base/TablePaginationUnstyled'; +export default function UnstyledTable() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + + // Avoid a layout jump when reaching the last page with empty rows. + const emptyRows = + page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + + const handleChangePage = ( + event: React.MouseEvent | null, + newPage: number, + ) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = ( + event: React.ChangeEvent, + ) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + + + + + + + + + {(rowsPerPage > 0 + ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + : rows + ).map((row) => ( + + + + + + ))} + + {emptyRows > 0 && ( + + + )} + + + + + + +
DessertCaloriesFat
{row.name} + {row.calories} + + {row.fat} +
+
+
+ ); +} + function createData(name: string, calories: number, fat: number) { return { name, calories, fat }; } @@ -132,84 +213,3 @@ const CustomTablePagination = styled(TablePaginationUnstyled)( } `, ); - -export default function UnstyledTable() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - - // Avoid a layout jump when reaching the last page with empty rows. - const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; - - const handleChangePage = ( - event: React.MouseEvent | null, - newPage: number, - ) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = ( - event: React.ChangeEvent, - ) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - return ( - - - - - - - - - - - {(rowsPerPage > 0 - ? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - : rows - ).map((row) => ( - - - - - - ))} - - {emptyRows > 0 && ( - - - )} - - - - - - -
DessertCaloriesFat
{row.name} - {row.calories} - - {row.fat} -
-
-
- ); -} diff --git a/docs/data/base/components/table-pagination/TableUnstyled.js b/docs/data/base/components/table-pagination/TableUnstyled.js index 5bf9fd25db2273..6324271f2d54a7 100644 --- a/docs/data/base/components/table-pagination/TableUnstyled.js +++ b/docs/data/base/components/table-pagination/TableUnstyled.js @@ -4,80 +4,6 @@ import TablePaginationUnstyled, { tablePaginationUnstyledClasses as classes, } from '@mui/base/TablePaginationUnstyled'; -function createData(name, calories, fat) { - return { name, calories, fat }; -} - -const rows = [ - createData('Cupcake', 305, 3.7), - createData('Donut', 452, 25.0), - createData('Eclair', 262, 16.0), - createData('Frozen yoghurt', 159, 6.0), - createData('Gingerbread', 356, 16.0), - createData('Honeycomb', 408, 3.2), - createData('Ice cream sandwich', 237, 9.0), - createData('Jelly Bean', 375, 0.0), - createData('KitKat', 518, 26.0), - createData('Lollipop', 392, 0.2), - createData('Marshmallow', 318, 0), - createData('Nougat', 360, 19.0), - createData('Oreo', 437, 18.0), -].sort((a, b) => (a.calories < b.calories ? -1 : 1)); - -const Root = styled('div')` - table { - font-family: arial, sans-serif; - border-collapse: collapse; - width: 100%; - } - - td, - th { - border: 1px solid #ddd; - text-align: left; - padding: 8px; - } - - th { - background-color: #ddd; - } -`; - -const CustomTablePagination = styled(TablePaginationUnstyled)` - & .${classes.toolbar} { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 10px; - - @media (min-width: 768px) { - flex-direction: row; - align-items: center; - } - } - - & .${classes.selectLabel} { - margin: 0; - } - - & .${classes.displayedRows} { - margin: 0; - - @media (min-width: 768px) { - margin-left: auto; - } - } - - & .${classes.spacer} { - display: none; - } - - & .${classes.actions} { - display: flex; - gap: 0.25rem; - } -`; - export default function UnstyledTable() { const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(5); @@ -153,3 +79,77 @@ export default function UnstyledTable() { ); } + +function createData(name, calories, fat) { + return { name, calories, fat }; +} + +const rows = [ + createData('Cupcake', 305, 3.7), + createData('Donut', 452, 25.0), + createData('Eclair', 262, 16.0), + createData('Frozen yoghurt', 159, 6.0), + createData('Gingerbread', 356, 16.0), + createData('Honeycomb', 408, 3.2), + createData('Ice cream sandwich', 237, 9.0), + createData('Jelly Bean', 375, 0.0), + createData('KitKat', 518, 26.0), + createData('Lollipop', 392, 0.2), + createData('Marshmallow', 318, 0), + createData('Nougat', 360, 19.0), + createData('Oreo', 437, 18.0), +].sort((a, b) => (a.calories < b.calories ? -1 : 1)); + +const Root = styled('div')` + table { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + } + + td, + th { + border: 1px solid #ddd; + text-align: left; + padding: 8px; + } + + th { + background-color: #ddd; + } +`; + +const CustomTablePagination = styled(TablePaginationUnstyled)` + & .${classes.toolbar} { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; + + @media (min-width: 768px) { + flex-direction: row; + align-items: center; + } + } + + & .${classes.selectLabel} { + margin: 0; + } + + & .${classes.displayedRows} { + margin: 0; + + @media (min-width: 768px) { + margin-left: auto; + } + } + + & .${classes.spacer} { + display: none; + } + + & .${classes.actions} { + display: flex; + gap: 0.25rem; + } +`; diff --git a/docs/data/base/components/table-pagination/TableUnstyled.tsx b/docs/data/base/components/table-pagination/TableUnstyled.tsx index 9fed1be7dd8143..f0fb9575fcfa2e 100644 --- a/docs/data/base/components/table-pagination/TableUnstyled.tsx +++ b/docs/data/base/components/table-pagination/TableUnstyled.tsx @@ -4,80 +4,6 @@ import TablePaginationUnstyled, { tablePaginationUnstyledClasses as classes, } from '@mui/base/TablePaginationUnstyled'; -function createData(name: string, calories: number, fat: number) { - return { name, calories, fat }; -} - -const rows = [ - createData('Cupcake', 305, 3.7), - createData('Donut', 452, 25.0), - createData('Eclair', 262, 16.0), - createData('Frozen yoghurt', 159, 6.0), - createData('Gingerbread', 356, 16.0), - createData('Honeycomb', 408, 3.2), - createData('Ice cream sandwich', 237, 9.0), - createData('Jelly Bean', 375, 0.0), - createData('KitKat', 518, 26.0), - createData('Lollipop', 392, 0.2), - createData('Marshmallow', 318, 0), - createData('Nougat', 360, 19.0), - createData('Oreo', 437, 18.0), -].sort((a, b) => (a.calories < b.calories ? -1 : 1)); - -const Root = styled('div')` - table { - font-family: arial, sans-serif; - border-collapse: collapse; - width: 100%; - } - - td, - th { - border: 1px solid #ddd; - text-align: left; - padding: 8px; - } - - th { - background-color: #ddd; - } -`; - -const CustomTablePagination = styled(TablePaginationUnstyled)` - & .${classes.toolbar} { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 10px; - - @media (min-width: 768px) { - flex-direction: row; - align-items: center; - } - } - - & .${classes.selectLabel} { - margin: 0; - } - - & .${classes.displayedRows} { - margin: 0; - - @media (min-width: 768px) { - margin-left: auto; - } - } - - & .${classes.spacer} { - display: none; - } - - & .${classes.actions} { - display: flex; - gap: 0.25rem; - } -`; - export default function UnstyledTable() { const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(5); @@ -157,3 +83,77 @@ export default function UnstyledTable() { ); } + +function createData(name: string, calories: number, fat: number) { + return { name, calories, fat }; +} + +const rows = [ + createData('Cupcake', 305, 3.7), + createData('Donut', 452, 25.0), + createData('Eclair', 262, 16.0), + createData('Frozen yoghurt', 159, 6.0), + createData('Gingerbread', 356, 16.0), + createData('Honeycomb', 408, 3.2), + createData('Ice cream sandwich', 237, 9.0), + createData('Jelly Bean', 375, 0.0), + createData('KitKat', 518, 26.0), + createData('Lollipop', 392, 0.2), + createData('Marshmallow', 318, 0), + createData('Nougat', 360, 19.0), + createData('Oreo', 437, 18.0), +].sort((a, b) => (a.calories < b.calories ? -1 : 1)); + +const Root = styled('div')` + table { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + } + + td, + th { + border: 1px solid #ddd; + text-align: left; + padding: 8px; + } + + th { + background-color: #ddd; + } +`; + +const CustomTablePagination = styled(TablePaginationUnstyled)` + & .${classes.toolbar} { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; + + @media (min-width: 768px) { + flex-direction: row; + align-items: center; + } + } + + & .${classes.selectLabel} { + margin: 0; + } + + & .${classes.displayedRows} { + margin: 0; + + @media (min-width: 768px) { + margin-left: auto; + } + } + + & .${classes.spacer} { + display: none; + } + + & .${classes.actions} { + display: flex; + gap: 0.25rem; + } +`; diff --git a/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.js b/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.js index 9fa90157e29f49..b8d003fe3f8ca7 100644 --- a/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.js +++ b/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.js @@ -8,6 +8,49 @@ function createData(name, calories, fat) { return { name, calories, fat }; } +export default function UnstyledPaginationIntroduction() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + + + + + +
+
+ ); +} + const rows = [ createData('Cupcake', 305, 3.7), createData('Donut', 452, 25.0), @@ -140,46 +183,3 @@ const CustomTablePagination = styled(TablePaginationUnstyled)( } `, ); - -export default function UnstyledPaginationIntroduction() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - - const handleChangePage = (event, newPage) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - return ( - - - - - - - -
-
- ); -} diff --git a/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.tsx b/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.tsx index a871a4948c408c..6099a6dd52e2ef 100644 --- a/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.tsx +++ b/docs/data/base/components/table-pagination/UnstyledPaginationIntroduction.tsx @@ -8,6 +8,54 @@ function createData(name: string, calories: number, fat: number) { return { name, calories, fat }; } +export default function UnstyledPaginationIntroduction() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + + const handleChangePage = ( + event: React.MouseEvent | null, + newPage: number, + ) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = ( + event: React.ChangeEvent, + ) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + + + + + +
+
+ ); +} + const rows = [ createData('Cupcake', 305, 3.7), createData('Donut', 452, 25.0), @@ -140,51 +188,3 @@ const CustomTablePagination = styled(TablePaginationUnstyled)( } `, ); - -export default function UnstyledPaginationIntroduction() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - - const handleChangePage = ( - event: React.MouseEvent | null, - newPage: number, - ) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = ( - event: React.ChangeEvent, - ) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - return ( - - - - - - - -
-
- ); -} From dd9cdd451ff137fe99e378bdc0d1a7a6e4cf5eb5 Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Wed, 12 Apr 2023 08:38:45 +0100 Subject: [PATCH 004/100] [docs][base] Move styles to the bottom of demos code for `Popper` (#36578) --- .../base/components/popper/SimplePopper.js | 20 +++++++++---------- .../base/components/popper/SimplePopper.tsx | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/data/base/components/popper/SimplePopper.js b/docs/data/base/components/popper/SimplePopper.js index 7bdff93caccf33..7caac16c17bcc5 100644 --- a/docs/data/base/components/popper/SimplePopper.js +++ b/docs/data/base/components/popper/SimplePopper.js @@ -2,16 +2,6 @@ import * as React from 'react'; import PopperUnstyled from '@mui/base/PopperUnstyled'; import { styled } from '@mui/system'; -const StyledPopperDiv = styled('div')( - ({ theme }) => ` - padding: 0.5rem; - border: 1px solid; - background-color: ${theme.palette.mode === 'dark' ? '#121212' : '#fff'}; - opacity: 1; - margin: 0.25rem 0px; -`, -); - export default function SimplePopper() { const [anchorEl, setAnchorEl] = React.useState(null); @@ -33,3 +23,13 @@ export default function SimplePopper() { ); } + +const StyledPopperDiv = styled('div')( + ({ theme }) => ` + padding: 0.5rem; + border: 1px solid; + background-color: ${theme.palette.mode === 'dark' ? '#121212' : '#fff'}; + opacity: 1; + margin: 0.25rem 0px; +`, +); diff --git a/docs/data/base/components/popper/SimplePopper.tsx b/docs/data/base/components/popper/SimplePopper.tsx index 551c6911ee4f27..9c67d502aa85d9 100644 --- a/docs/data/base/components/popper/SimplePopper.tsx +++ b/docs/data/base/components/popper/SimplePopper.tsx @@ -2,16 +2,6 @@ import * as React from 'react'; import PopperUnstyled from '@mui/base/PopperUnstyled'; import { styled, Theme } from '@mui/system'; -const StyledPopperDiv = styled('div')( - ({ theme }: { theme: Theme }) => ` - padding: 0.5rem; - border: 1px solid; - background-color: ${theme.palette.mode === 'dark' ? '#121212' : '#fff'}; - opacity: 1; - margin: 0.25rem 0px; -`, -); - export default function SimplePopper() { const [anchorEl, setAnchorEl] = React.useState(null); @@ -33,3 +23,13 @@ export default function SimplePopper() { ); } + +const StyledPopperDiv = styled('div')( + ({ theme }: { theme: Theme }) => ` + padding: 0.5rem; + border: 1px solid; + background-color: ${theme.palette.mode === 'dark' ? '#121212' : '#fff'}; + opacity: 1; + margin: 0.25rem 0px; +`, +); From 7fd18fe6cf05b1b9604ad9c316e3d0b179e85d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A4=80=ED=98=95?= Date: Wed, 12 Apr 2023 17:08:46 +0900 Subject: [PATCH 005/100] [Tabs] Fix null reference in ScrollbarSize after unmounting (#36485) --- packages/mui-material/src/Tabs/ScrollbarSize.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mui-material/src/Tabs/ScrollbarSize.js b/packages/mui-material/src/Tabs/ScrollbarSize.js index 2811d02180205d..edea6b1620db1c 100644 --- a/packages/mui-material/src/Tabs/ScrollbarSize.js +++ b/packages/mui-material/src/Tabs/ScrollbarSize.js @@ -1,7 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import debounce from '../utils/debounce'; -import { ownerWindow } from '../utils'; +import { ownerWindow, unstable_useEnhancedEffect as useEnhancedEffect } from '../utils'; const styles = { width: 99, @@ -25,7 +25,7 @@ export default function ScrollbarSize(props) { scrollbarHeight.current = nodeRef.current.offsetHeight - nodeRef.current.clientHeight; }; - React.useEffect(() => { + useEnhancedEffect(() => { const handleResize = debounce(() => { const prevHeight = scrollbarHeight.current; setMeasurements(); From 0a4fe40804845a469ec08052cbcf295dad92c6f5 Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Wed, 12 Apr 2023 09:20:04 +0100 Subject: [PATCH 006/100] [docs][base] Move styles to the bottom of demos code for `Tabs` (#36577) --- .../components/tabs/KeyboardNavigation.js | 62 +++++++++---------- .../components/tabs/KeyboardNavigation.tsx | 62 +++++++++---------- .../components/tabs/UnstyledTabsCustomized.js | 30 ++++----- .../tabs/UnstyledTabsCustomized.tsx | 30 ++++----- .../tabs/UnstyledTabsIntroduction.js | 30 ++++----- .../tabs/UnstyledTabsIntroduction.tsx | 30 ++++----- 6 files changed, 122 insertions(+), 122 deletions(-) diff --git a/docs/data/base/components/tabs/KeyboardNavigation.js b/docs/data/base/components/tabs/KeyboardNavigation.js index 57b80cd3c336e3..0b249562e40f33 100644 --- a/docs/data/base/components/tabs/KeyboardNavigation.js +++ b/docs/data/base/components/tabs/KeyboardNavigation.js @@ -5,6 +5,37 @@ import TabsUnstyled from '@mui/base/TabsUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; import TabsListUnstyled from '@mui/base/TabsListUnstyled'; +export default function AccessibleTabs() { + return ( +
+

Selection following focus:

+ + + One + Two + Three + + + +

Selection independent of focus (default behavior):

+ + + One + Two + Three + + +
+ ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -79,34 +110,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 8px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function AccessibleTabs1() { - return ( -
-

Selection following focus:

- - - One - Two - Three - - - -

Selection independent of focus (default behavior):

- - - One - Two - Three - - -
- ); -} diff --git a/docs/data/base/components/tabs/KeyboardNavigation.tsx b/docs/data/base/components/tabs/KeyboardNavigation.tsx index 57b80cd3c336e3..0b249562e40f33 100644 --- a/docs/data/base/components/tabs/KeyboardNavigation.tsx +++ b/docs/data/base/components/tabs/KeyboardNavigation.tsx @@ -5,6 +5,37 @@ import TabsUnstyled from '@mui/base/TabsUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; import TabsListUnstyled from '@mui/base/TabsListUnstyled'; +export default function AccessibleTabs() { + return ( +
+

Selection following focus:

+ + + One + Two + Three + + + +

Selection independent of focus (default behavior):

+ + + One + Two + Three + + +
+ ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -79,34 +110,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 8px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function AccessibleTabs1() { - return ( -
-

Selection following focus:

- - - One - Two - Three - - - -

Selection independent of focus (default behavior):

- - - One - Two - Three - - -
- ); -} diff --git a/docs/data/base/components/tabs/UnstyledTabsCustomized.js b/docs/data/base/components/tabs/UnstyledTabsCustomized.js index d7c9220c3b0f43..86a2cfc41ee3ff 100644 --- a/docs/data/base/components/tabs/UnstyledTabsCustomized.js +++ b/docs/data/base/components/tabs/UnstyledTabsCustomized.js @@ -6,6 +6,21 @@ import TabPanelUnstyled from '@mui/base/TabPanelUnstyled'; import { buttonUnstyledClasses } from '@mui/base/ButtonUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; +export default function UnstyledTabsCustomized() { + return ( + + + One + Two + Three + + First page + Second page + Third page + + ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -86,18 +101,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 8px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function UnstyledTabsCustomized() { - return ( - - - One - Two - Three - - First page - Second page - Third page - - ); -} diff --git a/docs/data/base/components/tabs/UnstyledTabsCustomized.tsx b/docs/data/base/components/tabs/UnstyledTabsCustomized.tsx index d7c9220c3b0f43..86a2cfc41ee3ff 100644 --- a/docs/data/base/components/tabs/UnstyledTabsCustomized.tsx +++ b/docs/data/base/components/tabs/UnstyledTabsCustomized.tsx @@ -6,6 +6,21 @@ import TabPanelUnstyled from '@mui/base/TabPanelUnstyled'; import { buttonUnstyledClasses } from '@mui/base/ButtonUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; +export default function UnstyledTabsCustomized() { + return ( + + + One + Two + Three + + First page + Second page + Third page + + ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -86,18 +101,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 8px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function UnstyledTabsCustomized() { - return ( - - - One - Two - Three - - First page - Second page - Third page - - ); -} diff --git a/docs/data/base/components/tabs/UnstyledTabsIntroduction.js b/docs/data/base/components/tabs/UnstyledTabsIntroduction.js index 6f8c6345249b89..6c92434fce3d6e 100644 --- a/docs/data/base/components/tabs/UnstyledTabsIntroduction.js +++ b/docs/data/base/components/tabs/UnstyledTabsIntroduction.js @@ -6,6 +6,21 @@ import TabPanelUnstyled from '@mui/base/TabPanelUnstyled'; import { buttonUnstyledClasses } from '@mui/base/ButtonUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; +export default function UnstyledTabsIntroduction() { + return ( + + + My account + Profile + Language + + My account page + Profile page + Language page + + ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -93,18 +108,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function UnstyledTabsIntroduction() { - return ( - - - My account - Profile - Language - - My account page - Profile page - Language page - - ); -} diff --git a/docs/data/base/components/tabs/UnstyledTabsIntroduction.tsx b/docs/data/base/components/tabs/UnstyledTabsIntroduction.tsx index 6f8c6345249b89..6c92434fce3d6e 100644 --- a/docs/data/base/components/tabs/UnstyledTabsIntroduction.tsx +++ b/docs/data/base/components/tabs/UnstyledTabsIntroduction.tsx @@ -6,6 +6,21 @@ import TabPanelUnstyled from '@mui/base/TabPanelUnstyled'; import { buttonUnstyledClasses } from '@mui/base/ButtonUnstyled'; import TabUnstyled, { tabUnstyledClasses } from '@mui/base/TabUnstyled'; +export default function UnstyledTabsIntroduction() { + return ( + + + My account + Profile + Language + + My account page + Profile page + Language page + + ); +} + const blue = { 50: '#F0F7FF', 100: '#C2E0FF', @@ -93,18 +108,3 @@ const TabsList = styled(TabsListUnstyled)( box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; `, ); - -export default function UnstyledTabsIntroduction() { - return ( - - - My account - Profile - Language - - My account page - Profile page - Language page - - ); -} From c6b330bf8851c5c885896f706d5860217eb2367b Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Wed, 12 Apr 2023 09:20:22 +0100 Subject: [PATCH 007/100] [docs][base] Move styles to the bottom of demos code for `ModalUnstyled` (#36580) --- .../base/components/modal/KeepMountedModal.js | 54 ++++---- .../components/modal/KeepMountedModal.tsx | 54 ++++---- .../base/components/modal/ModalUnstyled.js | 52 ++++---- .../base/components/modal/ModalUnstyled.tsx | 52 ++++---- .../data/base/components/modal/NestedModal.js | 124 +++++++++--------- .../base/components/modal/NestedModal.tsx | 124 +++++++++--------- .../data/base/components/modal/ServerModal.js | 42 +++--- .../base/components/modal/ServerModal.tsx | 42 +++--- .../data/base/components/modal/SpringModal.js | 58 ++++---- .../base/components/modal/SpringModal.tsx | 58 ++++---- .../base/components/modal/TransitionsModal.js | 58 ++++---- .../components/modal/TransitionsModal.tsx | 58 ++++---- 12 files changed, 388 insertions(+), 388 deletions(-) diff --git a/docs/data/base/components/modal/KeepMountedModal.js b/docs/data/base/components/modal/KeepMountedModal.js index 546d1e24fc3de8..10027a57d3bffb 100644 --- a/docs/data/base/components/modal/KeepMountedModal.js +++ b/docs/data/base/components/modal/KeepMountedModal.js @@ -4,6 +4,33 @@ import clsx from 'clsx'; import { styled, Box } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; +export default function KeepMountedModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + +

Text in a modal

+

Aliquid amet deserunt earum!

+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef((props, ref) => { const { open, className, ...other } = props; return ( @@ -52,30 +79,3 @@ const style = (theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -export default function ModalUnstyledDemo() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - -

Text in a modal

-

Aliquid amet deserunt earum!

-
-
-
- ); -} diff --git a/docs/data/base/components/modal/KeepMountedModal.tsx b/docs/data/base/components/modal/KeepMountedModal.tsx index 95bea81f5546f3..bebb7a212475b5 100644 --- a/docs/data/base/components/modal/KeepMountedModal.tsx +++ b/docs/data/base/components/modal/KeepMountedModal.tsx @@ -3,6 +3,33 @@ import clsx from 'clsx'; import { styled, Box, Theme } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; +export default function KeepMountedModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + +

Text in a modal

+

Aliquid amet deserunt earum!

+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef< HTMLDivElement, { open?: boolean; className: string } @@ -49,30 +76,3 @@ const style = (theme: Theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -export default function ModalUnstyledDemo() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - -

Text in a modal

-

Aliquid amet deserunt earum!

-
-
-
- ); -} diff --git a/docs/data/base/components/modal/ModalUnstyled.js b/docs/data/base/components/modal/ModalUnstyled.js index 196507ec5245b3..09bd287b61e86b 100644 --- a/docs/data/base/components/modal/ModalUnstyled.js +++ b/docs/data/base/components/modal/ModalUnstyled.js @@ -4,6 +4,32 @@ import clsx from 'clsx'; import { styled, Box } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; +export default function ModalUnstyledDemo() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + +

Text in a modal

+

Aliquid amet deserunt earum!

+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef((props, ref) => { const { open, className, ...other } = props; return ( @@ -49,29 +75,3 @@ const style = (theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -export default function ModalUnstyledDemo() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - -

Text in a modal

-

Aliquid amet deserunt earum!

-
-
-
- ); -} diff --git a/docs/data/base/components/modal/ModalUnstyled.tsx b/docs/data/base/components/modal/ModalUnstyled.tsx index 8bb0cd53ec23b1..28cc191a4d7c97 100644 --- a/docs/data/base/components/modal/ModalUnstyled.tsx +++ b/docs/data/base/components/modal/ModalUnstyled.tsx @@ -3,6 +3,32 @@ import clsx from 'clsx'; import { styled, Box, Theme } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; +export default function ModalUnstyledDemo() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + +

Text in a modal

+

Aliquid amet deserunt earum!

+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef< HTMLDivElement, { open?: boolean; className: string } @@ -46,29 +72,3 @@ const style = (theme: Theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -export default function ModalUnstyledDemo() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - -

Text in a modal

-

Aliquid amet deserunt earum!

-
-
-
- ); -} diff --git a/docs/data/base/components/modal/NestedModal.js b/docs/data/base/components/modal/NestedModal.js index 9a392e3974b153..01af4585a2046b 100644 --- a/docs/data/base/components/modal/NestedModal.js +++ b/docs/data/base/components/modal/NestedModal.js @@ -5,6 +5,68 @@ import { styled, Box } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; import Button from '@mui/base/ButtonUnstyled'; +export default function NestedModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => { + setOpen(true); + }; + const handleClose = () => { + setOpen(false); + }; + + return ( +
+ + + +

Text in a modal

+

+ Duis mollis, est non commodo luctus, nisi erat porttitor ligula. +

+ +
+
+
+ ); +} + +function ChildModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => { + setOpen(true); + }; + const handleClose = () => { + setOpen(false); + }; + + return ( + + + + +

Text in a child modal

+

+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. +

+ +
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef((props, ref) => { const { open, className, ...other } = props; return ( @@ -54,65 +116,3 @@ const style = (theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -function ChildModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => { - setOpen(true); - }; - const handleClose = () => { - setOpen(false); - }; - - return ( - - - - -

Text in a child modal

-

- Lorem ipsum, dolor sit amet consectetur adipisicing elit. -

- -
-
-
- ); -} - -export default function NestedModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => { - setOpen(true); - }; - const handleClose = () => { - setOpen(false); - }; - - return ( -
- - - -

Text in a modal

-

- Duis mollis, est non commodo luctus, nisi erat porttitor ligula. -

- -
-
-
- ); -} diff --git a/docs/data/base/components/modal/NestedModal.tsx b/docs/data/base/components/modal/NestedModal.tsx index 244ef3ac6bd126..ca0d2901fcaf9f 100644 --- a/docs/data/base/components/modal/NestedModal.tsx +++ b/docs/data/base/components/modal/NestedModal.tsx @@ -4,6 +4,68 @@ import { styled, Box, Theme } from '@mui/system'; import ModalUnstyled from '@mui/base/ModalUnstyled'; import Button from '@mui/base/ButtonUnstyled'; +export default function NestedModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => { + setOpen(true); + }; + const handleClose = () => { + setOpen(false); + }; + + return ( +
+ + + +

Text in a modal

+

+ Duis mollis, est non commodo luctus, nisi erat porttitor ligula. +

+ +
+
+
+ ); +} + +function ChildModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => { + setOpen(true); + }; + const handleClose = () => { + setOpen(false); + }; + + return ( + + + + +

Text in a child modal

+

+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. +

+ +
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef< HTMLDivElement, { open?: boolean; className: string } @@ -51,65 +113,3 @@ const style = (theme: Theme) => ({ border: '2px solid currentColor', padding: '16px 32px 24px 32px', }); - -function ChildModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => { - setOpen(true); - }; - const handleClose = () => { - setOpen(false); - }; - - return ( - - - - -

Text in a child modal

-

- Lorem ipsum, dolor sit amet consectetur adipisicing elit. -

- -
-
-
- ); -} - -export default function NestedModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => { - setOpen(true); - }; - const handleClose = () => { - setOpen(false); - }; - - return ( -
- - - -

Text in a modal

-

- Duis mollis, est non commodo luctus, nisi erat porttitor ligula. -

- -
-
-
- ); -} diff --git a/docs/data/base/components/modal/ServerModal.js b/docs/data/base/components/modal/ServerModal.js index ee000bb5536248..34fa4ea311fe53 100644 --- a/docs/data/base/components/modal/ServerModal.js +++ b/docs/data/base/components/modal/ServerModal.js @@ -2,27 +2,6 @@ import * as React from 'react'; import ModalUnstyled from '@mui/base/ModalUnstyled'; import { Box, styled } from '@mui/system'; -const StyledModal = styled(ModalUnstyled)` - position: fixed; - z-index: 1300; - right: 0; - bottom: 0; - top: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; - background: inherit; -`; - -const style = { - position: 'relative', - width: 400, - border: '2px solid currentColor', - padding: '16px 32px 24px 32px', -}; - export default function ServerModal() { const rootRef = React.useRef(null); @@ -60,3 +39,24 @@ export default function ServerModal() { ); } + +const StyledModal = styled(ModalUnstyled)` + position: fixed; + z-index: 1300; + right: 0; + bottom: 0; + top: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 8px; + background: inherit; +`; + +const style = { + position: 'relative', + width: 400, + border: '2px solid currentColor', + padding: '16px 32px 24px 32px', +}; diff --git a/docs/data/base/components/modal/ServerModal.tsx b/docs/data/base/components/modal/ServerModal.tsx index 18383f1bc7a35f..2ee764dbf0d4d4 100644 --- a/docs/data/base/components/modal/ServerModal.tsx +++ b/docs/data/base/components/modal/ServerModal.tsx @@ -2,27 +2,6 @@ import * as React from 'react'; import ModalUnstyled from '@mui/base/ModalUnstyled'; import { Box, styled } from '@mui/system'; -const StyledModal = styled(ModalUnstyled)` - position: fixed; - z-index: 1300; - right: 0; - bottom: 0; - top: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; - background: inherit; -`; - -const style = { - position: 'relative', - width: 400, - border: '2px solid currentColor', - padding: '16px 32px 24px 32px', -}; - export default function ServerModal() { const rootRef = React.useRef(null); @@ -60,3 +39,24 @@ export default function ServerModal() { ); } + +const StyledModal = styled(ModalUnstyled)` + position: fixed; + z-index: 1300; + right: 0; + bottom: 0; + top: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 8px; + background: inherit; +`; + +const style = { + position: 'relative', + width: 400, + border: '2px solid currentColor', + padding: '16px 32px 24px 32px', +}; diff --git a/docs/data/base/components/modal/SpringModal.js b/docs/data/base/components/modal/SpringModal.js index f52fa91f991376..7265414faecc29 100644 --- a/docs/data/base/components/modal/SpringModal.js +++ b/docs/data/base/components/modal/SpringModal.js @@ -5,6 +5,35 @@ import ModalUnstyled from '@mui/base/ModalUnstyled'; import Button from '@mui/base/ButtonUnstyled'; import { useSpring, animated } from '@react-spring/web'; +export default function SpringModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + + +

Text in a modal

+ + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + +
+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef((props, ref) => { const { open, ...other } = props; return ; @@ -79,32 +108,3 @@ const style = (theme) => ({ boxShadow: 24, padding: '16px 32px 24px 32px', }); - -export default function SpringModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - - -

Text in a modal

- - Duis mollis, est non commodo luctus, nisi erat porttitor ligula. - -
-
-
-
- ); -} diff --git a/docs/data/base/components/modal/SpringModal.tsx b/docs/data/base/components/modal/SpringModal.tsx index 5d84459dd26e3f..853b423a43abac 100644 --- a/docs/data/base/components/modal/SpringModal.tsx +++ b/docs/data/base/components/modal/SpringModal.tsx @@ -4,6 +4,35 @@ import ModalUnstyled from '@mui/base/ModalUnstyled'; import Button from '@mui/base/ButtonUnstyled'; import { useSpring, animated } from '@react-spring/web'; +export default function SpringModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + + +

Text in a modal

+ + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + +
+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef< HTMLDivElement, { children: React.ReactElement; open: boolean } @@ -78,32 +107,3 @@ const style = (theme: Theme) => ({ boxShadow: 24, padding: '16px 32px 24px 32px', }); - -export default function SpringModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - - -

Text in a modal

- - Duis mollis, est non commodo luctus, nisi erat porttitor ligula. - -
-
-
-
- ); -} diff --git a/docs/data/base/components/modal/TransitionsModal.js b/docs/data/base/components/modal/TransitionsModal.js index 4d579afa004460..c5893ba3039744 100644 --- a/docs/data/base/components/modal/TransitionsModal.js +++ b/docs/data/base/components/modal/TransitionsModal.js @@ -5,6 +5,35 @@ import ModalUnstyled from '@mui/base/ModalUnstyled'; import Fade from '@mui/material/Fade'; import Button from '@mui/base/ButtonUnstyled'; +export default function TransitionsModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + + +

Text in a modal

+ + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + +
+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef((props, ref) => { const { open, ...other } = props; return ( @@ -52,32 +81,3 @@ const style = (theme) => ({ boxShadow: 24, padding: '16px 32px 24px 32px', }); - -export default function TransitionsModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - - -

Text in a modal

- - Duis mollis, est non commodo luctus, nisi erat porttitor ligula. - -
-
-
-
- ); -} diff --git a/docs/data/base/components/modal/TransitionsModal.tsx b/docs/data/base/components/modal/TransitionsModal.tsx index 35b7ab07d2602e..581258ae3d4cc5 100644 --- a/docs/data/base/components/modal/TransitionsModal.tsx +++ b/docs/data/base/components/modal/TransitionsModal.tsx @@ -4,6 +4,35 @@ import ModalUnstyled from '@mui/base/ModalUnstyled'; import Fade from '@mui/material/Fade'; import Button from '@mui/base/ButtonUnstyled'; +export default function TransitionsModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( +
+ + + + +

Text in a modal

+ + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + +
+
+
+
+ ); +} + const BackdropUnstyled = React.forwardRef( (props, ref) => { const { open, ...other } = props; @@ -49,32 +78,3 @@ const style = (theme: Theme) => ({ boxShadow: 24, padding: '16px 32px 24px 32px', }); - -export default function TransitionsModal() { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( -
- - - - -

Text in a modal

- - Duis mollis, est non commodo luctus, nisi erat porttitor ligula. - -
-
-
-
- ); -} From 1a4263a50af00eaffdca2e58b8ff16d62c4408a7 Mon Sep 17 00:00:00 2001 From: Varun Mulay <35381801+varunmulay22@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:10:10 +0530 Subject: [PATCH 008/100] [docs][base] Move styles to the bottom of demos code for `BadgeUnstyled` (#36723) --- .../base/components/badge/AccessibleBadges.js | 39 ++++---- .../components/badge/AccessibleBadges.tsx | 39 ++++---- docs/data/base/components/badge/BadgeMax.js | 31 +++--- docs/data/base/components/badge/BadgeMax.tsx | 31 +++--- .../base/components/badge/BadgeVisibility.js | 97 +++++++++---------- .../base/components/badge/BadgeVisibility.tsx | 97 +++++++++---------- .../base/components/badge/ShowZeroBadge.js | 26 ++--- .../base/components/badge/ShowZeroBadge.tsx | 26 ++--- .../base/components/badge/UnstyledBadge.js | 50 +++++----- .../base/components/badge/UnstyledBadge.tsx | 50 +++++----- .../badge/UnstyledBadgeIntroduction.js | 50 +++++----- .../badge/UnstyledBadgeIntroduction.tsx | 50 +++++----- 12 files changed, 290 insertions(+), 296 deletions(-) diff --git a/docs/data/base/components/badge/AccessibleBadges.js b/docs/data/base/components/badge/AccessibleBadges.js index 9eb163092ff855..c61ac293a61ca6 100644 --- a/docs/data/base/components/badge/AccessibleBadges.js +++ b/docs/data/base/components/badge/AccessibleBadges.js @@ -3,6 +3,25 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +function notificationsLabel(count) { + if (count === 0) { + return 'no notifications'; + } + if (count > 99) { + return 'more than 99 notifications'; + } + return `${count} notifications`; +} + +export default function AccessibleBadges() { + return ( +
+ + + +
+ ); +} const blue = { 500: '#007FFF', }; @@ -46,23 +65,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function notificationsLabel(count) { - if (count === 0) { - return 'no notifications'; - } - if (count > 99) { - return 'more than 99 notifications'; - } - return `${count} notifications`; -} - -export default function AccessibleBadges() { - return ( -
- - - -
- ); -} diff --git a/docs/data/base/components/badge/AccessibleBadges.tsx b/docs/data/base/components/badge/AccessibleBadges.tsx index 1d6006093cd0d0..d772df26b81ee8 100644 --- a/docs/data/base/components/badge/AccessibleBadges.tsx +++ b/docs/data/base/components/badge/AccessibleBadges.tsx @@ -3,6 +3,25 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +function notificationsLabel(count: number) { + if (count === 0) { + return 'no notifications'; + } + if (count > 99) { + return 'more than 99 notifications'; + } + return `${count} notifications`; +} + +export default function AccessibleBadges() { + return ( +
+ + + +
+ ); +} const blue = { 500: '#007FFF', }; @@ -46,23 +65,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function notificationsLabel(count: number) { - if (count === 0) { - return 'no notifications'; - } - if (count > 99) { - return 'more than 99 notifications'; - } - return `${count} notifications`; -} - -export default function AccessibleBadges() { - return ( -
- - - -
- ); -} diff --git a/docs/data/base/components/badge/BadgeMax.js b/docs/data/base/components/badge/BadgeMax.js index df0553434f79f8..e97901513f315b 100644 --- a/docs/data/base/components/badge/BadgeMax.js +++ b/docs/data/base/components/badge/BadgeMax.js @@ -4,6 +4,21 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +export default function BadgeMax() { + return ( + + + + + + + + + + + + ); +} const blue = { 500: '#007FFF', }; @@ -47,19 +62,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -export default function BadgeMax() { - return ( - - - - - - - - - - - - ); -} diff --git a/docs/data/base/components/badge/BadgeMax.tsx b/docs/data/base/components/badge/BadgeMax.tsx index df0553434f79f8..e97901513f315b 100644 --- a/docs/data/base/components/badge/BadgeMax.tsx +++ b/docs/data/base/components/badge/BadgeMax.tsx @@ -4,6 +4,21 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +export default function BadgeMax() { + return ( + + + + + + + + + + + + ); +} const blue = { 500: '#007FFF', }; @@ -47,19 +62,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -export default function BadgeMax() { - return ( - - - - - - - - - - - - ); -} diff --git a/docs/data/base/components/badge/BadgeVisibility.js b/docs/data/base/components/badge/BadgeVisibility.js index 9cf0cb40f4b627..8a774397991655 100644 --- a/docs/data/base/components/badge/BadgeVisibility.js +++ b/docs/data/base/components/badge/BadgeVisibility.js @@ -10,55 +10,6 @@ import MailIcon from '@mui/icons-material/Mail'; import Switch from '@mui/material/Switch'; import FormControlLabel from '@mui/material/FormControlLabel'; -const blue = { - 500: '#007FFF', -}; - -const grey = { - 300: '#afb8c1', - 900: '#24292f', -}; - -const StyledBadge = styled(BadgeUnstyled)( - ({ theme }) => ` - box-sizing: border-box; - margin: 0; - padding: 0; - font-size: 14px; - list-style: none; - font-family: IBM Plex Sans, sans-serif; - position: relative; - display: inline-block; - line-height: 1; - - & .${badgeUnstyledClasses.badge} { - z-index: auto; - position: absolute; - top: 0; - right: 0; - min-width: 22px; - height: 22px; - padding: 0 6px; - color: #fff; - font-weight: 600; - font-size: 12px; - line-height: 22px; - white-space: nowrap; - text-align: center; - border-radius: 12px; - background: ${blue[500]}; - box-shadow: 0px 4px 6x ${theme.palette.mode === 'dark' ? grey[900] : grey[300]}; - transform: translate(50%, -50%); - transform-origin: 100% 0; - } - - & .${badgeUnstyledClasses.invisible} { - opacity: 0; - pointer-events: none; - } - `, -); - export default function BadgeVisibility() { const [count, setCount] = React.useState(1); const [invisible, setInvisible] = React.useState(false); @@ -117,3 +68,51 @@ export default function BadgeVisibility() { ); } +const blue = { + 500: '#007FFF', +}; + +const grey = { + 300: '#afb8c1', + 900: '#24292f', +}; + +const StyledBadge = styled(BadgeUnstyled)( + ({ theme }) => ` + box-sizing: border-box; + margin: 0; + padding: 0; + font-size: 14px; + list-style: none; + font-family: IBM Plex Sans, sans-serif; + position: relative; + display: inline-block; + line-height: 1; + + & .${badgeUnstyledClasses.badge} { + z-index: auto; + position: absolute; + top: 0; + right: 0; + min-width: 22px; + height: 22px; + padding: 0 6px; + color: #fff; + font-weight: 600; + font-size: 12px; + line-height: 22px; + white-space: nowrap; + text-align: center; + border-radius: 12px; + background: ${blue[500]}; + box-shadow: 0px 4px 6x ${theme.palette.mode === 'dark' ? grey[900] : grey[300]}; + transform: translate(50%, -50%); + transform-origin: 100% 0; + } + + & .${badgeUnstyledClasses.invisible} { + opacity: 0; + pointer-events: none; + } + `, +); diff --git a/docs/data/base/components/badge/BadgeVisibility.tsx b/docs/data/base/components/badge/BadgeVisibility.tsx index 9cf0cb40f4b627..8a774397991655 100644 --- a/docs/data/base/components/badge/BadgeVisibility.tsx +++ b/docs/data/base/components/badge/BadgeVisibility.tsx @@ -10,55 +10,6 @@ import MailIcon from '@mui/icons-material/Mail'; import Switch from '@mui/material/Switch'; import FormControlLabel from '@mui/material/FormControlLabel'; -const blue = { - 500: '#007FFF', -}; - -const grey = { - 300: '#afb8c1', - 900: '#24292f', -}; - -const StyledBadge = styled(BadgeUnstyled)( - ({ theme }) => ` - box-sizing: border-box; - margin: 0; - padding: 0; - font-size: 14px; - list-style: none; - font-family: IBM Plex Sans, sans-serif; - position: relative; - display: inline-block; - line-height: 1; - - & .${badgeUnstyledClasses.badge} { - z-index: auto; - position: absolute; - top: 0; - right: 0; - min-width: 22px; - height: 22px; - padding: 0 6px; - color: #fff; - font-weight: 600; - font-size: 12px; - line-height: 22px; - white-space: nowrap; - text-align: center; - border-radius: 12px; - background: ${blue[500]}; - box-shadow: 0px 4px 6x ${theme.palette.mode === 'dark' ? grey[900] : grey[300]}; - transform: translate(50%, -50%); - transform-origin: 100% 0; - } - - & .${badgeUnstyledClasses.invisible} { - opacity: 0; - pointer-events: none; - } - `, -); - export default function BadgeVisibility() { const [count, setCount] = React.useState(1); const [invisible, setInvisible] = React.useState(false); @@ -117,3 +68,51 @@ export default function BadgeVisibility() { ); } +const blue = { + 500: '#007FFF', +}; + +const grey = { + 300: '#afb8c1', + 900: '#24292f', +}; + +const StyledBadge = styled(BadgeUnstyled)( + ({ theme }) => ` + box-sizing: border-box; + margin: 0; + padding: 0; + font-size: 14px; + list-style: none; + font-family: IBM Plex Sans, sans-serif; + position: relative; + display: inline-block; + line-height: 1; + + & .${badgeUnstyledClasses.badge} { + z-index: auto; + position: absolute; + top: 0; + right: 0; + min-width: 22px; + height: 22px; + padding: 0 6px; + color: #fff; + font-weight: 600; + font-size: 12px; + line-height: 22px; + white-space: nowrap; + text-align: center; + border-radius: 12px; + background: ${blue[500]}; + box-shadow: 0px 4px 6x ${theme.palette.mode === 'dark' ? grey[900] : grey[300]}; + transform: translate(50%, -50%); + transform-origin: 100% 0; + } + + & .${badgeUnstyledClasses.invisible} { + opacity: 0; + pointer-events: none; + } + `, +); diff --git a/docs/data/base/components/badge/ShowZeroBadge.js b/docs/data/base/components/badge/ShowZeroBadge.js index 67d776c969e496..8574a6d3dc51b7 100644 --- a/docs/data/base/components/badge/ShowZeroBadge.js +++ b/docs/data/base/components/badge/ShowZeroBadge.js @@ -4,6 +4,19 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +export default function ShowZeroBadge() { + return ( + + + + + + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -51,16 +64,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -export default function ShowZeroBadge() { - return ( - - - - - - - - - ); -} diff --git a/docs/data/base/components/badge/ShowZeroBadge.tsx b/docs/data/base/components/badge/ShowZeroBadge.tsx index 67d776c969e496..8574a6d3dc51b7 100644 --- a/docs/data/base/components/badge/ShowZeroBadge.tsx +++ b/docs/data/base/components/badge/ShowZeroBadge.tsx @@ -4,6 +4,19 @@ import { styled } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; +export default function ShowZeroBadge() { + return ( + + + + + + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -51,16 +64,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -export default function ShowZeroBadge() { - return ( - - - - - - - - - ); -} diff --git a/docs/data/base/components/badge/UnstyledBadge.js b/docs/data/base/components/badge/UnstyledBadge.js index 7ad760e63bf762..90a7210fbde549 100644 --- a/docs/data/base/components/badge/UnstyledBadge.js +++ b/docs/data/base/components/badge/UnstyledBadge.js @@ -2,6 +2,31 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; +function BadgeContent() { + return ( + + theme.palette.mode === 'dark' ? grey[400] : grey[300], + display: 'inline-block', + verticalAlign: 'middle', + }} + /> + ); +} + +export default function UnstyledBadge() { + return ( + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -47,28 +72,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function BadgeContent() { - return ( - - theme.palette.mode === 'dark' ? grey[400] : grey[300], - display: 'inline-block', - verticalAlign: 'middle', - }} - /> - ); -} - -export default function UnstyledBadge() { - return ( - - - - ); -} diff --git a/docs/data/base/components/badge/UnstyledBadge.tsx b/docs/data/base/components/badge/UnstyledBadge.tsx index 7ad760e63bf762..90a7210fbde549 100644 --- a/docs/data/base/components/badge/UnstyledBadge.tsx +++ b/docs/data/base/components/badge/UnstyledBadge.tsx @@ -2,6 +2,31 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; +function BadgeContent() { + return ( + + theme.palette.mode === 'dark' ? grey[400] : grey[300], + display: 'inline-block', + verticalAlign: 'middle', + }} + /> + ); +} + +export default function UnstyledBadge() { + return ( + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -47,28 +72,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function BadgeContent() { - return ( - - theme.palette.mode === 'dark' ? grey[400] : grey[300], - display: 'inline-block', - verticalAlign: 'middle', - }} - /> - ); -} - -export default function UnstyledBadge() { - return ( - - - - ); -} diff --git a/docs/data/base/components/badge/UnstyledBadgeIntroduction.js b/docs/data/base/components/badge/UnstyledBadgeIntroduction.js index cb3aba3d7eb4e8..984d54b6a81dfc 100644 --- a/docs/data/base/components/badge/UnstyledBadgeIntroduction.js +++ b/docs/data/base/components/badge/UnstyledBadgeIntroduction.js @@ -2,6 +2,31 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; +function BadgeContent() { + return ( + + theme.palette.mode === 'dark' ? grey[400] : grey[300], + display: 'inline-block', + verticalAlign: 'middle', + }} + /> + ); +} + +export default function UnstyledBadgeIntroduction() { + return ( + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -49,28 +74,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function BadgeContent() { - return ( - - theme.palette.mode === 'dark' ? grey[400] : grey[300], - display: 'inline-block', - verticalAlign: 'middle', - }} - /> - ); -} - -export default function UnstyledBadgeIntroduction() { - return ( - - - - ); -} diff --git a/docs/data/base/components/badge/UnstyledBadgeIntroduction.tsx b/docs/data/base/components/badge/UnstyledBadgeIntroduction.tsx index cb3aba3d7eb4e8..984d54b6a81dfc 100644 --- a/docs/data/base/components/badge/UnstyledBadgeIntroduction.tsx +++ b/docs/data/base/components/badge/UnstyledBadgeIntroduction.tsx @@ -2,6 +2,31 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; +function BadgeContent() { + return ( + + theme.palette.mode === 'dark' ? grey[400] : grey[300], + display: 'inline-block', + verticalAlign: 'middle', + }} + /> + ); +} + +export default function UnstyledBadgeIntroduction() { + return ( + + + + ); +} + const blue = { 500: '#007FFF', }; @@ -49,28 +74,3 @@ const StyledBadge = styled(BadgeUnstyled)( } `, ); - -function BadgeContent() { - return ( - - theme.palette.mode === 'dark' ? grey[400] : grey[300], - display: 'inline-block', - verticalAlign: 'middle', - }} - /> - ); -} - -export default function UnstyledBadgeIntroduction() { - return ( - - - - ); -} From 7239a54451ab85f85a9207d11cc1ce63cb39ad63 Mon Sep 17 00:00:00 2001 From: Emil Laine Date: Wed, 12 Apr 2023 13:59:52 +0300 Subject: [PATCH 009/100] [FormControlLabel] Add `required` prop (#34207) Signed-off-by: Emil Laine Co-authored-by: ZeeshanTamboli --- .../components/checkboxes/CheckboxLabels.js | 1 + .../components/checkboxes/CheckboxLabels.tsx | 1 + .../checkboxes/CheckboxLabels.tsx.preview | 1 + .../components/switches/SwitchLabels.js | 1 + .../components/switches/SwitchLabels.tsx | 1 + .../switches/SwitchLabels.tsx.preview | 1 + .../material-ui/api/form-control-label.json | 11 +++- .../form-control-label.json | 10 ++++ .../FormControlLabel/FormControlLabel.d.ts | 4 ++ .../src/FormControlLabel/FormControlLabel.js | 35 +++++++++--- .../FormControlLabel/FormControlLabel.test.js | 55 +++++++++++++++++++ .../formControlLabelClasses.ts | 6 ++ 12 files changed, 117 insertions(+), 10 deletions(-) diff --git a/docs/data/material/components/checkboxes/CheckboxLabels.js b/docs/data/material/components/checkboxes/CheckboxLabels.js index 78ef5d8319ce48..73e53a5d418059 100644 --- a/docs/data/material/components/checkboxes/CheckboxLabels.js +++ b/docs/data/material/components/checkboxes/CheckboxLabels.js @@ -7,6 +7,7 @@ export default function CheckboxLabels() { return ( } label="Label" /> + } label="Required" /> } label="Disabled" /> ); diff --git a/docs/data/material/components/checkboxes/CheckboxLabels.tsx b/docs/data/material/components/checkboxes/CheckboxLabels.tsx index 78ef5d8319ce48..73e53a5d418059 100644 --- a/docs/data/material/components/checkboxes/CheckboxLabels.tsx +++ b/docs/data/material/components/checkboxes/CheckboxLabels.tsx @@ -7,6 +7,7 @@ export default function CheckboxLabels() { return ( } label="Label" /> + } label="Required" /> } label="Disabled" /> ); diff --git a/docs/data/material/components/checkboxes/CheckboxLabels.tsx.preview b/docs/data/material/components/checkboxes/CheckboxLabels.tsx.preview index e06590be325907..e64bb06b581301 100644 --- a/docs/data/material/components/checkboxes/CheckboxLabels.tsx.preview +++ b/docs/data/material/components/checkboxes/CheckboxLabels.tsx.preview @@ -1,4 +1,5 @@ } label="Label" /> + } label="Required" /> } label="Disabled" /> \ No newline at end of file diff --git a/docs/data/material/components/switches/SwitchLabels.js b/docs/data/material/components/switches/SwitchLabels.js index 63ecc578350253..0c1afeddf258df 100644 --- a/docs/data/material/components/switches/SwitchLabels.js +++ b/docs/data/material/components/switches/SwitchLabels.js @@ -7,6 +7,7 @@ export default function SwitchLabels() { return ( } label="Label" /> + } label="Required" /> } label="Disabled" /> ); diff --git a/docs/data/material/components/switches/SwitchLabels.tsx b/docs/data/material/components/switches/SwitchLabels.tsx index 63ecc578350253..0c1afeddf258df 100644 --- a/docs/data/material/components/switches/SwitchLabels.tsx +++ b/docs/data/material/components/switches/SwitchLabels.tsx @@ -7,6 +7,7 @@ export default function SwitchLabels() { return ( } label="Label" /> + } label="Required" /> } label="Disabled" /> ); diff --git a/docs/data/material/components/switches/SwitchLabels.tsx.preview b/docs/data/material/components/switches/SwitchLabels.tsx.preview index ddfefaf50249f7..f388391917b436 100644 --- a/docs/data/material/components/switches/SwitchLabels.tsx.preview +++ b/docs/data/material/components/switches/SwitchLabels.tsx.preview @@ -1,4 +1,5 @@ } label="Label" /> + } label="Required" /> } label="Disabled" /> \ No newline at end of file diff --git a/docs/pages/material-ui/api/form-control-label.json b/docs/pages/material-ui/api/form-control-label.json index c6eae1100d6781..58d7aea55a2197 100644 --- a/docs/pages/material-ui/api/form-control-label.json +++ b/docs/pages/material-ui/api/form-control-label.json @@ -19,6 +19,7 @@ "default": "'end'" }, "onChange": { "type": { "name": "func" } }, + "required": { "type": { "name": "bool" } }, "slotProps": { "type": { "name": "shape", "description": "{ typography?: object }" }, "default": "{}" @@ -40,9 +41,15 @@ "labelPlacementBottom", "disabled", "label", - "error" + "error", + "required", + "asterisk" ], - "globalClasses": { "disabled": "Mui-disabled", "error": "Mui-error" }, + "globalClasses": { + "disabled": "Mui-disabled", + "error": "Mui-error", + "required": "Mui-required" + }, "name": "MuiFormControlLabel" }, "spread": true, diff --git a/docs/translations/api-docs/form-control-label/form-control-label.json b/docs/translations/api-docs/form-control-label/form-control-label.json index 8c49084c0616f1..dbc53fd9336d6b 100644 --- a/docs/translations/api-docs/form-control-label/form-control-label.json +++ b/docs/translations/api-docs/form-control-label/form-control-label.json @@ -11,6 +11,7 @@ "label": "A text or an element to be used in an enclosing label element.", "labelPlacement": "The position of the label.", "onChange": "Callback fired when the state is changed.

Signature:
function(event: React.SyntheticEvent) => void
event: The event source of the callback. You can pull out the new checked state by accessing event.target.checked (boolean).", + "required": "If true, the label will indicate that the input is required.", "slotProps": "The props used for each slot inside.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.", "value": "The value of the component." @@ -45,6 +46,15 @@ "description": "State class applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "error={true}" + }, + "required": { + "description": "State class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "required={true}" + }, + "asterisk": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the asterisk element" } } } diff --git a/packages/mui-material/src/FormControlLabel/FormControlLabel.d.ts b/packages/mui-material/src/FormControlLabel/FormControlLabel.d.ts index cf996bf87696aa..3ba48a2d665a03 100644 --- a/packages/mui-material/src/FormControlLabel/FormControlLabel.d.ts +++ b/packages/mui-material/src/FormControlLabel/FormControlLabel.d.ts @@ -59,6 +59,10 @@ export interface FormControlLabelProps * You can pull out the new checked state by accessing `event.target.checked` (boolean). */ onChange?: (event: React.SyntheticEvent, checked: boolean) => void; + /** + * If `true`, the label will indicate that the `input` is required. + */ + required?: boolean; /** * The props used for each slot inside. * @default {} diff --git a/packages/mui-material/src/FormControlLabel/FormControlLabel.js b/packages/mui-material/src/FormControlLabel/FormControlLabel.js index 2f4e89c2f3eca3..566b4c83b04d47 100644 --- a/packages/mui-material/src/FormControlLabel/FormControlLabel.js +++ b/packages/mui-material/src/FormControlLabel/FormControlLabel.js @@ -14,15 +14,17 @@ import formControlLabelClasses, { import formControlState from '../FormControl/formControlState'; const useUtilityClasses = (ownerState) => { - const { classes, disabled, labelPlacement, error } = ownerState; + const { classes, disabled, labelPlacement, error, required } = ownerState; const slots = { root: [ 'root', disabled && 'disabled', `labelPlacement${capitalize(labelPlacement)}`, error && 'error', + required && 'required', ], label: ['label', disabled && 'disabled'], + asterisk: ['asterisk', error && 'error'], }; return composeClasses(slots, getFormControlLabelUtilityClasses, classes); @@ -72,6 +74,16 @@ export const FormControlLabelRoot = styled('label', { }, })); +const AsteriskComponent = styled('span', { + name: 'MuiFormControlLabel', + slot: 'Asterisk', + overridesResolver: (props, styles) => styles.asterisk, +})(({ theme }) => ({ + [`&.${formControlLabelClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, + }, +})); + /** * Drop-in replacement of the `Radio`, `Switch` and `Checkbox` component. * Use this component if you want to display an extra label. @@ -90,6 +102,7 @@ const FormControlLabel = React.forwardRef(function FormControlLabel(inProps, ref labelPlacement = 'end', name, onChange, + required: requiredProp, slotProps = {}, value, ...other @@ -97,16 +110,12 @@ const FormControlLabel = React.forwardRef(function FormControlLabel(inProps, ref const muiFormControl = useFormControl(); - let disabled = disabledProp; - if (typeof disabled === 'undefined' && typeof control.props.disabled !== 'undefined') { - disabled = control.props.disabled; - } - if (typeof disabled === 'undefined' && muiFormControl) { - disabled = muiFormControl.disabled; - } + const disabled = disabledProp ?? control.props.disabled ?? muiFormControl?.disabled; + const required = requiredProp ?? control.props.required; const controlProps = { disabled, + required, }; ['checked', 'name', 'onChange', 'value', 'inputRef'].forEach((key) => { @@ -125,6 +134,7 @@ const FormControlLabel = React.forwardRef(function FormControlLabel(inProps, ref ...props, disabled, labelPlacement, + required, error: fcs.error, }; @@ -154,6 +164,11 @@ const FormControlLabel = React.forwardRef(function FormControlLabel(inProps, ref > {React.cloneElement(control, controlProps)} {label} + {required && ( + +  {'*'} + + )} ); }); @@ -218,6 +233,10 @@ FormControlLabel.propTypes /* remove-proptypes */ = { * You can pull out the new checked state by accessing `event.target.checked` (boolean). */ onChange: PropTypes.func, + /** + * If `true`, the label will indicate that the `input` is required. + */ + required: PropTypes.bool, /** * The props used for each slot inside. * @default {} diff --git a/packages/mui-material/src/FormControlLabel/FormControlLabel.test.js b/packages/mui-material/src/FormControlLabel/FormControlLabel.test.js index 648f8bf43e92c8..f2ef25f819bd64 100644 --- a/packages/mui-material/src/FormControlLabel/FormControlLabel.test.js +++ b/packages/mui-material/src/FormControlLabel/FormControlLabel.test.js @@ -179,6 +179,23 @@ describe('', () => { }); }); + describe('prop: required', () => { + it('should visually show an asterisk but not include it in the a11y tree', () => { + const { container } = render(} />); + + expect(container.querySelector('label')).to.have.text('Pizza\u2009*'); + expect(container.querySelectorAll(`.${classes.asterisk}`)).to.have.lengthOf(1); + expect(container.querySelector(`.${classes.asterisk}`)).toBeInaccessible(); + }); + + it('should not show an asterisk by default', () => { + const { container } = render(} />); + + expect(container.querySelector('label')).to.have.text('Pizza'); + expect(container.querySelectorAll(`.${classes.asterisk}`)).to.have.lengthOf(0); + }); + }); + describe('componentsProps: typography', () => { it('should spread its contents to the typography element', () => { const { getByTestId } = render( @@ -210,6 +227,7 @@ describe('', () => { expect(getByTestId('FormControlLabel')).to.have.class(classes.error); }); }); + describe('enabled', () => { it('should not have the disabled class', () => { const { getByTestId } = render( @@ -263,6 +281,43 @@ describe('', () => { expect(getByTestId('FormControlLabel')).not.to.have.class(classes.disabled); }); }); + + describe('required', () => { + it('should not have the required class', () => { + const { getByTestId } = render( + + } label="Pizza" /> + , + ); + + expect(getByTestId('FormControlLabel')).not.to.have.class(classes.required); + }); + + it('should be overridden by props', () => { + const { getByTestId } = render( + + } + required + label="Pizza" + /> + , + ); + + expect(getByTestId('FormControlLabel')).to.have.class(classes.required); + }); + + it('should not have the required attribute', () => { + const { container } = render( + + } label="Pizza" /> + , + ); + const input = container.querySelector('input'); + expect(input).to.have.property('required', false); + }); + }); }); it('should not inject extra props', () => { diff --git a/packages/mui-material/src/FormControlLabel/formControlLabelClasses.ts b/packages/mui-material/src/FormControlLabel/formControlLabelClasses.ts index 65b25aa6cccaa0..b66860a7a362b5 100644 --- a/packages/mui-material/src/FormControlLabel/formControlLabelClasses.ts +++ b/packages/mui-material/src/FormControlLabel/formControlLabelClasses.ts @@ -16,6 +16,10 @@ export interface FormControlLabelClasses { label: string; /** State class applied to the root element if `error={true}`. */ error: string; + /** State class applied to the root element if `required={true}`. */ + required: string; + /** Styles applied to the asterisk element. */ + asterisk: string; } export type FormControlLabelClassKey = keyof FormControlLabelClasses; @@ -34,6 +38,8 @@ const formControlLabelClasses: FormControlLabelClasses = generateUtilityClasses( 'disabled', 'label', 'error', + 'required', + 'asterisk', ], ); From d30c1fc42f67eca3023999e7f1c8f1916b31da0f Mon Sep 17 00:00:00 2001 From: navedqb <109583873+navedqb@users.noreply.github.com> Date: Wed, 12 Apr 2023 20:01:24 +0530 Subject: [PATCH 010/100] [docs] Content changed from 'row' to 'orientation=horizontal' (#36858) --- docs/data/joy/components/card/card.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/joy/components/card/card.md b/docs/data/joy/components/card/card.md index 700e430d9b746e..00b1516e8f4bf9 100644 --- a/docs/data/joy/components/card/card.md +++ b/docs/data/joy/components/card/card.md @@ -77,7 +77,7 @@ You can add any number of Card Covers to create more sophisticated stacked layer ### Horizontal alignment Card contents are arranged in a column by default. -For horizontal alignment, add the `row` prop to the Card. +For horizontal alignment, add the `orientation="horizontal"` prop to the Card. If present, the [Card Overflow](#expand-to-fill) component will adapt accordingly. {{"demo": "RowCard.js" }} From 01f329aaf9d7e982ab5b38b6736c94d519f6c236 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Wed, 12 Apr 2023 21:32:54 +0700 Subject: [PATCH 011/100] [CssVarsProvider] Always generate new `css` object (#36853) --- .../src/cssVars/prepareCssVars.test.ts | 39 +++++++++++++++++++ .../mui-system/src/cssVars/prepareCssVars.ts | 7 +++- .../CssVarsProvider/MaterialUIDefaultDark.js | 6 +++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 packages/mui-system/src/cssVars/prepareCssVars.test.ts diff --git a/packages/mui-system/src/cssVars/prepareCssVars.test.ts b/packages/mui-system/src/cssVars/prepareCssVars.test.ts new file mode 100644 index 00000000000000..4de3389c90cd12 --- /dev/null +++ b/packages/mui-system/src/cssVars/prepareCssVars.test.ts @@ -0,0 +1,39 @@ +import { expect } from 'chai'; +import prepareCssVars from './prepareCssVars'; + +describe('prepareCssVars', () => { + it('`generateCssVars` should always return a new object', () => { + const result = prepareCssVars({ + colorSchemes: { + dark: { + color: 'red', + }, + }, + }); + + const { css: css1 } = result.generateCssVars('dark'); + const { css: css2 } = result.generateCssVars('dark'); + + expect(css1).to.not.equal(css2); + }); + + it('delete css fields should not affect the next call', () => { + const result = prepareCssVars({ + colorSchemes: { + dark: { + color: 'red', + }, + }, + }); + + const { css: css1 } = result.generateCssVars('dark'); + + delete css1['--color']; + + expect(css1).to.deep.equal({}); + + const { css: css2 } = result.generateCssVars('dark'); + + expect(css2).to.deep.equal({ '--color': 'red' }); + }); +}); diff --git a/packages/mui-system/src/cssVars/prepareCssVars.ts b/packages/mui-system/src/cssVars/prepareCssVars.ts index 5123a33a090b5b..c73dc7240ecdb7 100644 --- a/packages/mui-system/src/cssVars/prepareCssVars.ts +++ b/packages/mui-system/src/cssVars/prepareCssVars.ts @@ -38,9 +38,12 @@ function prepareCssVars { if (!colorScheme) { - return { css: rootCss, vars: rootVars }; + return { css: { ...rootCss }, vars: rootVars }; } - return colorSchemesMap[colorScheme]; + return { + css: { ...colorSchemesMap[colorScheme].css }, + vars: colorSchemesMap[colorScheme].vars, + }; }; return { diff --git a/test/regressions/fixtures/CssVarsProvider/MaterialUIDefaultDark.js b/test/regressions/fixtures/CssVarsProvider/MaterialUIDefaultDark.js index 462062e9449c07..c8b6477f284bb9 100644 --- a/test/regressions/fixtures/CssVarsProvider/MaterialUIDefaultDark.js +++ b/test/regressions/fixtures/CssVarsProvider/MaterialUIDefaultDark.js @@ -6,6 +6,12 @@ import Paper from '@mui/material/Paper'; import Toolbar from '@mui/material/Toolbar'; export default function MaterialUIDefaultDark() { + const [, rerender] = React.useState(false); + React.useEffect(() => { + // Trigger rerender to ensure that the UI does not change after the first render. + // To catch bug like https://github.com/mui/material-ui/issues/36452 + rerender(true); + }, []); return ( Date: Wed, 12 Apr 2023 18:35:22 -0500 Subject: [PATCH 012/100] [docs] Add guides to overriding component structure in Base UI and Joy UI docs (#34990) Signed-off-by: Sam Sycamore <71297412+samuelsycamore@users.noreply.github.com> Co-authored-by: Siriwat K --- .../OverridingInternalSlot.js | 12 ++ .../OverridingInternalSlot.tsx | 12 ++ .../OverridingInternalSlot.tsx.preview | 4 + .../OverridingRootSlot.js | 6 + .../OverridingRootSlot.tsx | 6 + .../OverridingRootSlot.tsx.preview | 1 + .../overriding-component-structure.md | 107 ++++++++++++++++++ docs/data/base/pages.ts | 4 + .../OverridingInternalSlot.js | 26 +++++ .../OverridingInternalSlot.tsx | 26 +++++ .../OverridingInternalSlot.tsx.preview | 15 +++ .../OverridingRootSlot.js | 15 +++ .../OverridingRootSlot.tsx | 15 +++ .../OverridingRootSlot.tsx.preview | 8 ++ .../overriding-component-structure.md | 94 +++++++++++++++ docs/data/joy/pages.ts | 4 + .../guides/overriding-component-structure.js | 7 ++ .../guides/overriding-component-structure.js | 7 ++ docs/translations/translations.json | 2 + 19 files changed, 371 insertions(+) create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingRootSlot.js create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx create mode 100644 docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx.preview create mode 100644 docs/data/base/guides/overriding-component-structure/overriding-component-structure.md create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingInternalSlot.js create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingInternalSlot.tsx create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.js create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx create mode 100644 docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview create mode 100644 docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md create mode 100644 docs/pages/base/guides/overriding-component-structure.js create mode 100644 docs/pages/joy-ui/guides/overriding-component-structure.js diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js new file mode 100644 index 00000000000000..8f195aea3f1a88 --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js @@ -0,0 +1,12 @@ +import * as React from 'react'; +import SelectUnstyled from '@mui/base/SelectUnstyled'; +import OptionUnstyled from '@mui/base/OptionUnstyled'; + +export default function OrderedListSelect() { + return ( + + First option + Second option + + ); +} diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx new file mode 100644 index 00000000000000..8f195aea3f1a88 --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import SelectUnstyled from '@mui/base/SelectUnstyled'; +import OptionUnstyled from '@mui/base/OptionUnstyled'; + +export default function OrderedListSelect() { + return ( + + First option + Second option + + ); +} diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview new file mode 100644 index 00000000000000..e5d56c16fb0fd8 --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview @@ -0,0 +1,4 @@ + + First option + Second option + \ No newline at end of file diff --git a/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.js b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.js new file mode 100644 index 00000000000000..f148067f05e38e --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.js @@ -0,0 +1,6 @@ +import * as React from 'react'; +import ButtonUnstyled from '@mui/base/ButtonUnstyled'; + +export default function DivButton() { + return Button; +} diff --git a/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx new file mode 100644 index 00000000000000..f148067f05e38e --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; +import ButtonUnstyled from '@mui/base/ButtonUnstyled'; + +export default function DivButton() { + return Button; +} diff --git a/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx.preview b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx.preview new file mode 100644 index 00000000000000..1f24878ebbdc23 --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/OverridingRootSlot.tsx.preview @@ -0,0 +1 @@ +Button \ No newline at end of file diff --git a/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md new file mode 100644 index 00000000000000..b014266a40488f --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md @@ -0,0 +1,107 @@ +# Overriding component structure + +

Learn how to override the default DOM structure of Base UI components.

+ +Base UI components are designed to suit the widest possible range of use cases, but you may occasionally need to change how a component's structure is rendered in the DOM. + +To understand how to do this, it helps to have an accurate mental model of MUI components. + +## The mental model + +A component's structure is determined by the elements that fill that component's **slots**. +Slots are most commonly filled by HTML tags, but may also be filled by React components. + +All components contain a root slot that defines their primary node in the DOM tree; more complex components also contain additional interior slots named after the elements they represent. + +All _non-utility_ Base UI components accept two props for overriding their rendered HTML structure: + +- `component`—to override the root slot +- `slots`—to override any interior slots (when present) as well as the root + +Additionally, you can pass custom props to interior slots using `slotProps`. + +## The root slot + +The root slot represents the component's outermost element. +For simpler components, the root slot is often filled by the native HTML element that the component is intended to replace. + +For example, the [Unstyled Button's](/base/react-button/) root slot is a ` + ); +} diff --git a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx new file mode 100644 index 00000000000000..d3199709507c20 --- /dev/null +++ b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import Button from '@mui/joy/Button'; + +export default function DivButton() { + return ( + + ); +} diff --git a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview new file mode 100644 index 00000000000000..a5f28043022c0d --- /dev/null +++ b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md new file mode 100644 index 00000000000000..072bf91c3c58d0 --- /dev/null +++ b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md @@ -0,0 +1,94 @@ +# Overriding component structure + +

Learn how to override the default DOM structure of Joy UI components.

+ +Joy UI components are designed to suit the widest possible range of use cases, but you may occasionally need to change how a component's structure is rendered in the DOM. + +To understand how to do this, it helps to have an accurate mental model of MUI components. + +## The mental model + +A component's structure is determined by the elements that fill that component's **slots**. +Slots are most commonly filled by HTML tags, but may also be filled by React components. + +All components contain a root slot that defines their primary node in the DOM tree; more complex components also contain additional interior slots named after the elements they represent. + +All _non-utility_ Joy UI components accept two props for overriding their rendered HTML structure: + +- `component`—to override the root slot +- `slots`—to replace any interior slots (when present) as well as the root + +Additionally, you can pass custom props to interior slots using `slotProps`. + +## The root slot + +The root slot represents the component's outermost element. It is filled by a styled component with an appropriate HTML element. + +For example, the [Button's](/joy-ui/react-button/) root slot is a `