diff --git a/CHANGELOG.md b/CHANGELOG.md index b44ff828936714..0d5719526e40c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # [Versions](https://mui.com/versions/) +## 5.14.10 + + + +_Sep 18, 2023_ + +A big thanks to the 16 contributors who made this release possible. This release was mostly about 🐛 bug fixes and 📚 documentation improvements. + +### `@mui/material@5.14.10` + +- ​[Chip] Add cursor CSS property reset (#38984) @DiegoAndai + +### `@mui/utils@5.14.10` + +- ​[utils] Move @types/prop-types back to dependencies (#39030) @Methuselah96 + +### `@mui/base@5.0.0-beta.16` + +- ​[NumberInput][base-ui] Warn when changing control mode with `useControlled` (#38757) @sai6855 +- ​[Select][base-ui] Fix Select button layout shift, add placeholder prop (#38796) @mj12albert +- ​[useList][base-ui] Accept arbitrary external props and forward to root (#38848) @mj12albert +- ​[Autocomplete][base-ui] Added ref to getInputProps return value (#38919) @DarhkVoyd + +### `@mui/joy@5.0.0-beta.7` + +- ​[AccordionGroup][joy-ui] Fix console warning when using custom color (#38950) @sai6855 +- ​[GlobalStyles][joy-ui] Ensure compatibility with RSC (#38955) @mateuseap + +### Docs + +- ​[docs][base] Add Tailwind CSS + plain CSS demo on the NumberInput page (#38928) @alisasanib +- ​[docs][Dialog] Add non-modal dialog docs & demo (#38684) @mnajdova +- ​[docs] Fix number input wrong demo @oliviertassinari +- ​[docs] Exclude joy-ui LinearProgressCountup from visual regression (#38969) @siriwatknp +- ​[docs][joy-ui] Revise the Overview page (#38842) @danilo-leal +- ​[docs][material-ui][Pagination] Add `TablePagination` to the API components list (#38486) @MonstraG + +### Core + +- ​[core] Add more context about useEventCallback @oliviertassinari +- ​[core] Allow deeper import of @mui/utils (#38806) @oliviertassinari +- ​[core] Remove react-dom from @mui/utils peerDependencies (#38974) @michaldudak +- ​[core] Remove react from styled-engine dependencies (#38971) @michaldudak +- ​[core] Fix image loading bug on Safari @oliviertassinari +- ​[core] Fix bundle size upload to S3 job (#38956) @Janpot +- ​[core] Move eslint to peer dependencies of eslint-plugin-material-ui (#39033) @michaldudak +- ​[docs-infra] Display markdown lists correctly in docs for props description (#38973) @ZeeshanTamboli +- ​[website] Improve lighthouse score (#39011) @oliviertassinari +- ​[website] Fix lighthouse issues @oliviertassinari +- ​[website] Create the `InfoCard` component (#38987) @danilo-leal +- ​[website] Small tweaks for performance @oliviertassinari +- ​[zero][next] Setup nextjs plugin package (#38852) @brijeshb42 + +All contributors of this release in alphabetical order: @alisasanib, @brijeshb42, @danilo-leal, @DarhkVoyd, @DiegoAndai, @Janpot, @mateuseap, @Methuselah96, @michaldudak, @mj12albert, @mnajdova, @MonstraG, @oliviertassinari, @sai6855, @siriwatknp, @ZeeshanTamboli + ## 5.14.9 diff --git a/benchmark/package.json b/benchmark/package.json index 5b48fbcab00029..b3d04a28e8998f 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -15,9 +15,9 @@ "@emotion/react": "^11.11.1", "@emotion/server": "^11.11.0", "@emotion/styled": "^11.11.0", - "@mui/material": "^5.14.9", - "@mui/styles": "^5.14.9", - "@mui/system": "^5.14.9", + "@mui/material": "^5.14.10", + "@mui/styles": "^5.14.10", + "@mui/system": "^5.14.10", "@styled-system/css": "^5.1.5", "benchmark": "^2.1.4", "docs": "^5.0.0", diff --git a/docs/data/joy/components/autocomplete/Asynchronous.js b/docs/data/joy/components/autocomplete/Asynchronous.js index a449988fc78e95..82c987f77d8ea6 100644 --- a/docs/data/joy/components/autocomplete/Asynchronous.js +++ b/docs/data/joy/components/autocomplete/Asynchronous.js @@ -4,9 +4,11 @@ import FormLabel from '@mui/joy/FormLabel'; import Autocomplete from '@mui/joy/Autocomplete'; import CircularProgress from '@mui/joy/CircularProgress'; -function sleep(delay = 0) { +function sleep(duration) { return new Promise((resolve) => { - setTimeout(resolve, delay); + setTimeout(() => { + resolve(); + }, duration); }); } diff --git a/docs/data/joy/components/autocomplete/Asynchronous.tsx b/docs/data/joy/components/autocomplete/Asynchronous.tsx index e1379748d3c5bc..36c52369e77e78 100644 --- a/docs/data/joy/components/autocomplete/Asynchronous.tsx +++ b/docs/data/joy/components/autocomplete/Asynchronous.tsx @@ -4,9 +4,11 @@ import FormLabel from '@mui/joy/FormLabel'; import Autocomplete from '@mui/joy/Autocomplete'; import CircularProgress from '@mui/joy/CircularProgress'; -function sleep(delay = 0) { - return new Promise((resolve) => { - setTimeout(resolve, delay); +function sleep(duration: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, duration); }); } diff --git a/docs/data/joy/components/circular-progress/CircularProgressCountUp.js b/docs/data/joy/components/circular-progress/CircularProgressCountUp.js new file mode 100644 index 00000000000000..9c4b1e8de9616f --- /dev/null +++ b/docs/data/joy/components/circular-progress/CircularProgressCountUp.js @@ -0,0 +1,69 @@ +import * as React from 'react'; +import Stack from '@mui/joy/Stack'; +import Button from '@mui/joy/Button'; +import Typography from '@mui/joy/Typography'; +import CircularProgress from '@mui/joy/CircularProgress'; +import { useCountUp } from 'use-count-up'; + +export default function CircularProgressCountUp() { + const [isLoading, setIsLoading] = React.useState(false); + const [buttonLabel, setButtonLabel] = React.useState('Start'); + + const { value: value1, reset: resetValue1 } = useCountUp({ + isCounting: isLoading, + duration: 1, + start: 0, + end: 25, + onComplete: () => { + setIsLoading(false); + setButtonLabel('Reset'); + }, + }); + + const { value: value2, reset } = useCountUp({ + isCounting: true, + duration: 1, + start: 0, + end: 75, + }); + + const handleButtonClick = () => { + if (isLoading) { + setIsLoading(false); + setButtonLabel('Start'); + resetValue1(); + } else if (buttonLabel === 'Reset') { + setButtonLabel('Start'); + resetValue1(); + } else { + setIsLoading(true); + setButtonLabel('Reset'); + } + }; + + return ( + + + + {value1}% + + + + + + {value2}% + + + + + ); +} diff --git a/docs/data/joy/components/circular-progress/CircularProgressCountUp.tsx b/docs/data/joy/components/circular-progress/CircularProgressCountUp.tsx new file mode 100644 index 00000000000000..d6a01fc813a42f --- /dev/null +++ b/docs/data/joy/components/circular-progress/CircularProgressCountUp.tsx @@ -0,0 +1,69 @@ +import * as React from 'react'; +import Stack from '@mui/joy/Stack'; +import Button from '@mui/joy/Button'; +import Typography from '@mui/joy/Typography'; +import CircularProgress from '@mui/joy/CircularProgress'; +import { useCountUp } from 'use-count-up'; + +export default function CircularProgressCountUp() { + const [isLoading, setIsLoading] = React.useState(false); + const [buttonLabel, setButtonLabel] = React.useState('Start'); + + const { value: value1, reset: resetValue1 } = useCountUp({ + isCounting: isLoading, + duration: 1, + start: 0, + end: 25, + onComplete: () => { + setIsLoading(false); + setButtonLabel('Reset'); + }, + }); + + const { value: value2, reset } = useCountUp({ + isCounting: true, + duration: 1, + start: 0, + end: 75, + }); + + const handleButtonClick = () => { + if (isLoading) { + setIsLoading(false); + setButtonLabel('Start'); + resetValue1(); + } else if (buttonLabel === 'Reset') { + setButtonLabel('Start'); + resetValue1(); + } else { + setIsLoading(true); + setButtonLabel('Reset'); + } + }; + + return ( + + + + {value1}% + + + + + + {value2}% + + + + + ); +} diff --git a/docs/data/joy/components/circular-progress/circular-progress.md b/docs/data/joy/components/circular-progress/circular-progress.md index 1e3d4e7113575d..a764b83defe3d6 100644 --- a/docs/data/joy/components/circular-progress/circular-progress.md +++ b/docs/data/joy/components/circular-progress/circular-progress.md @@ -86,6 +86,14 @@ The size of the Circular Progress is controlled by a button, an icon button, or {{"demo": "CircularProgressButton.js"}} +## Third-party integrations + +### use-count-up + +Use the `useCountUp` hook from the [use-count-up](https://www.npmjs.com/package/use-count-up) package to create a counting animation by providing `start`, `end`, and `duration` values. + +{{"demo": "CircularProgressCountUp.js"}} + ## CSS variables playground Play around with all the CSS variables available on the component to see how the design changes. diff --git a/docs/data/joy/getting-started/templates/sign-in-side/App.tsx b/docs/data/joy/getting-started/templates/sign-in-side/App.tsx index 6348e1c013a851..77865e8a5c8522 100644 --- a/docs/data/joy/getting-started/templates/sign-in-side/App.tsx +++ b/docs/data/joy/getting-started/templates/sign-in-side/App.tsx @@ -5,14 +5,17 @@ import CssBaseline from '@mui/joy/CssBaseline'; import Box from '@mui/joy/Box'; import Button from '@mui/joy/Button'; import Checkbox from '@mui/joy/Checkbox'; +import Divider from '@mui/joy/Divider'; import FormControl from '@mui/joy/FormControl'; import FormLabel, { formLabelClasses } from '@mui/joy/FormLabel'; import IconButton, { IconButtonProps } from '@mui/joy/IconButton'; import Link from '@mui/joy/Link'; import Input from '@mui/joy/Input'; import Typography from '@mui/joy/Typography'; +import Stack from '@mui/joy/Stack'; import DarkModeRoundedIcon from '@mui/icons-material/DarkModeRounded'; import LightModeRoundedIcon from '@mui/icons-material/LightModeRounded'; +import BadgeRoundedIcon from '@mui/icons-material/BadgeRounded'; import GoogleIcon from './GoogleIcon'; interface FormElements extends HTMLFormControlsCollection { @@ -31,13 +34,13 @@ function ColorSchemeToggle({ onClick, ...props }: IconButtonProps) { setMounted(true); }, []); if (!mounted) { - return ; + return ; } return ( @@ -66,8 +66,8 @@ export default function JoySignInSideTemplate() { styles={{ ':root': { '--Collapsed-breakpoint': '769px', // form will stretch when viewport is below `769px` - '--Cover-width': '40vw', // must be `vw` only - '--Form-maxWidth': '700px', + '--Cover-width': '50vw', // must be `vw` only + '--Form-maxWidth': '800px', '--Transition-duration': '0.4s', // set to `none` to disable transition }, }} @@ -82,8 +82,8 @@ export default function JoySignInSideTemplate() { zIndex: 1, display: 'flex', justifyContent: 'flex-end', - backdropFilter: 'blur(4px)', - backgroundColor: 'rgba(255 255 255 / 0.6)', + backdropFilter: 'blur(12px)', + backgroundColor: 'rgba(255 255 255 / 0.2)', [theme.getColorSchemeSelector('dark')]: { backgroundColor: 'rgba(19 19 24 / 0.4)', }, @@ -105,30 +105,22 @@ export default function JoySignInSideTemplate() { sx={{ py: 3, display: 'flex', - alignItems: 'center', + alignItems: 'left', justifyContent: 'space-between', }} > - - `linear-gradient(45deg, ${theme.vars.palette.primary.solidBg}, ${theme.vars.palette.primary.solidBg} 30%, ${theme.vars.palette.primary.softBg})`, - borderRadius: '50%', - boxShadow: (theme) => theme.shadow.md, - '--joy-shadowChannel': (theme) => - theme.vars.palette.primary.mainChannel, - }} - /> - } + - Logo - + + + + Company logo + -
- - Sign in to your account - - - Welcome back - -
-
) => { - event.preventDefault(); - const formElements = event.currentTarget.elements; - const data = { - email: formElements.email.value, - password: formElements.password.value, - persistent: formElements.persistent.checked, - }; - alert(JSON.stringify(data, null, 2)); - }} - > - - Email - - - - Password - - - + + Sign in + + New to company?{' '} + + Sign up! + + + + + - - + or + + +
) => { + event.preventDefault(); + const formElements = event.currentTarget.elements; + const data = { + email: formElements.email.value, + password: formElements.password.value, + persistent: formElements.persistent.checked, + }; + alert(JSON.stringify(data, null, 2)); + }} + > + + Email + + + + Password + + + + + + + Forgot your password? + + + + +
+
diff --git a/docs/data/material/components/autocomplete/Asynchronous.js b/docs/data/material/components/autocomplete/Asynchronous.js index beb9c03846ee17..ada8153aa99fd6 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.js +++ b/docs/data/material/components/autocomplete/Asynchronous.js @@ -3,9 +3,11 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import CircularProgress from '@mui/material/CircularProgress'; -function sleep(delay = 0) { +function sleep(duration) { return new Promise((resolve) => { - setTimeout(resolve, delay); + setTimeout(() => { + resolve(); + }, duration); }); } diff --git a/docs/data/material/components/autocomplete/Asynchronous.tsx b/docs/data/material/components/autocomplete/Asynchronous.tsx index 7fbbd7e62684cd..c2c4e4720ed519 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.tsx +++ b/docs/data/material/components/autocomplete/Asynchronous.tsx @@ -8,9 +8,11 @@ interface Film { year: number; } -function sleep(delay = 0) { - return new Promise((resolve) => { - setTimeout(resolve, delay); +function sleep(duration: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, duration); }); } diff --git a/docs/data/material/components/dialogs/CookiesBanner.js b/docs/data/material/components/dialogs/CookiesBanner.js new file mode 100644 index 00000000000000..93b32a2e461b05 --- /dev/null +++ b/docs/data/material/components/dialogs/CookiesBanner.js @@ -0,0 +1,108 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import TrapFocus from '@mui/material/Unstable_TrapFocus'; +import CssBaseline from '@mui/material/CssBaseline'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Container from '@mui/material/Container'; +import IconButton from '@mui/material/IconButton'; +import MenuIcon from '@mui/icons-material/Menu'; +import Paper from '@mui/material/Paper'; +import Fade from '@mui/material/Fade'; +import Button from '@mui/material/Button'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; + +export default function CookiesBanner() { + const [bannerOpen, setBannerOpen] = React.useState(true); + + const closeBanner = () => { + setBannerOpen(false); + }; + + return ( + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non + enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus + imperdiet. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non + enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus + imperdiet. + + + + + + + + This website uses cookies + + example.com relies on cookies to improve your experience. + + + + + + + + + + + + ); +} diff --git a/docs/data/material/components/dialogs/CookiesBanner.tsx b/docs/data/material/components/dialogs/CookiesBanner.tsx new file mode 100644 index 00000000000000..93b32a2e461b05 --- /dev/null +++ b/docs/data/material/components/dialogs/CookiesBanner.tsx @@ -0,0 +1,108 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import TrapFocus from '@mui/material/Unstable_TrapFocus'; +import CssBaseline from '@mui/material/CssBaseline'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Container from '@mui/material/Container'; +import IconButton from '@mui/material/IconButton'; +import MenuIcon from '@mui/icons-material/Menu'; +import Paper from '@mui/material/Paper'; +import Fade from '@mui/material/Fade'; +import Button from '@mui/material/Button'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; + +export default function CookiesBanner() { + const [bannerOpen, setBannerOpen] = React.useState(true); + + const closeBanner = () => { + setBannerOpen(false); + }; + + return ( + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non + enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus + imperdiet. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non + enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus + imperdiet. + + + + + + + + This website uses cookies + + example.com relies on cookies to improve your experience. + + + + + + + + + + + + ); +} diff --git a/docs/data/material/components/dialogs/dialogs.md b/docs/data/material/components/dialogs/dialogs.md index 914cfeb72f5f42..cbf62b794778ed 100644 --- a/docs/data/material/components/dialogs/dialogs.md +++ b/docs/data/material/components/dialogs/dialogs.md @@ -108,6 +108,15 @@ Touching "Cancel" in a confirmation dialog, or pressing Back, cancels the action {{"demo": "ConfirmationDialog.js"}} +## Non-modal dialog + +Dialogs can also be non-modal, meaning they don't interrupt user interaction behind it. +Visit [the Nielsen Norman Group article](https://www.nngroup.com/articles/modal-nonmodal-dialog/) for more in-depth guidance about modal vs. non-modal dialog usage. + +The demo below shows a persistent cookie banner, a common non-modal dialog use case. + +{{"demo": "CookiesBanner.js", "iframe": true}} + ## Draggable dialog You can create a draggable dialog by using [react-draggable](https://github.com/react-grid-layout/react-draggable). diff --git a/docs/data/material/components/pagination/pagination.md b/docs/data/material/components/pagination/pagination.md index 93d45f33c76e33..dd50567a33336b 100644 --- a/docs/data/material/components/pagination/pagination.md +++ b/docs/data/material/components/pagination/pagination.md @@ -1,7 +1,7 @@ --- productId: material-ui title: React Pagination component -components: Pagination, PaginationItem +components: Pagination, PaginationItem, TablePagination githubLabel: 'component: pagination' --- diff --git a/docs/data/material/experimental-api/css-theme-variables/overview.md b/docs/data/material/experimental-api/css-theme-variables/overview.md index 20af073e857ccc..319b88daaf169f 100644 --- a/docs/data/material/experimental-api/css-theme-variables/overview.md +++ b/docs/data/material/experimental-api/css-theme-variables/overview.md @@ -27,11 +27,11 @@ With these variables, you can inject a theme into your app's stylesheet _at buil For server-side applications, there are some trade-offs to consider: -| | Compare to the default method | Reason | -| :--------------------------------------------------- | :---------------------------- | :----------------------------------------------------------------------------------------------------------- | -| HTML size | Bigger | CSS variables are generated for both light and dark mode at build time. | -| [First Contentful Paint (FCP)](https://web.dev/fcp/) | Larger | Since the HTML size is generally bigger, the time to download the HTML before showing the content is longer. | -| [Time to Interactive (TTI)](https://web.dev/tti/) | Smaller (for dark mode) | Stylesheets are not regenerated between light and dark mode, so it takes less time for JavaScript to run. | +| | Compare to the default method | Reason | +| :--------------------------------------------------- | :---------------------------- | :------------------------------------------------------------------------------------------------------------- | +| HTML size | Bigger | CSS variables are generated for both light and dark mode at build time. | +| [First Contentful Paint (FCP)](https://web.dev/fcp/) | Longer | Since the HTML size is bigger, the time to download the HTML before showing the content is a bit longer. | +| [Time to Interactive (TTI)](https://web.dev/tti/) | Shorter (for dark mode) | Stylesheets are not regenerated between light and dark mode, a lot less time is spent running JavaScript code. | :::warning The comparison described in the table above may not be applicable to large and complex applications since there are so many factors that can impact performance metrics. @@ -46,6 +46,8 @@ Adopting CSS variables requires some shifts in your mental model of theming and **[Default approach](/material-ui/customization/dark-mode/)**: Light and dark colors are created separately. ```js +import { createTheme } from '@mui/material/styles'; + const lightTheme = createTheme(); const darkTheme = createTheme({ @@ -58,6 +60,8 @@ const darkTheme = createTheme({ **CSS theme variables**: Light and dark colors are consolidated into a theme. ```js +import { experimental_extendTheme as extendTheme } from '@mui/material/styles'; + // `extendTheme` is a new API const theme = extendTheme({ colorSchemes: { diff --git a/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.js b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.js new file mode 100644 index 00000000000000..cbbdc835b12d7c --- /dev/null +++ b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.js @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { + experimental_extendTheme as extendTheme, + Experimental_CssVarsProvider as CssVarsProvider, +} from '@mui/material/styles'; +import Button from '@mui/material/Button'; + +const theme = extendTheme({ + cssVarPrefix: 'md-demo', +}); + +export default function CssVarsBasic() { + return ( + + + + ); +} diff --git a/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx new file mode 100644 index 00000000000000..cbbdc835b12d7c --- /dev/null +++ b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { + experimental_extendTheme as extendTheme, + Experimental_CssVarsProvider as CssVarsProvider, +} from '@mui/material/styles'; +import Button from '@mui/material/Button'; + +const theme = extendTheme({ + cssVarPrefix: 'md-demo', +}); + +export default function CssVarsBasic() { + return ( + + + + ); +} diff --git a/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx.preview b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx.preview new file mode 100644 index 00000000000000..511e5c2381dd78 --- /dev/null +++ b/docs/data/material/experimental-api/css-theme-variables/usage/CssVarsBasic.tsx.preview @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/data/material/experimental-api/css-theme-variables/usage.md b/docs/data/material/experimental-api/css-theme-variables/usage/usage.md similarity index 96% rename from docs/data/material/experimental-api/css-theme-variables/usage.md rename to docs/data/material/experimental-api/css-theme-variables/usage/usage.md index a1ea23f2a64609..f6bd3f239a5fe5 100644 --- a/docs/data/material/experimental-api/css-theme-variables/usage.md +++ b/docs/data/material/experimental-api/css-theme-variables/usage/usage.md @@ -7,14 +7,6 @@ The CSS variables API relies on a new experimental provider for the theme called `Experimental_CssVarsProvider` to inject styles into Material UI components. In addition to providing the theme in the inner React context, this new provider also generates CSS variables out of all tokens in the theme that are not functions, and makes them available in the context as well. -```js -import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles'; - -function App() { - return ...; -} -``` - Once the `App` renders on the screen, you will see the CSS theme variables in the html `:root` stylesheet. The variables are flattened and prefixed with `--mui` by default: @@ -29,6 +21,10 @@ The variables are flattened and prefixed with `--mui` by default: } ``` +The following demo uses `--md-demo` as a prefix for the variables: + +{{"demo": "CssVarsBasic.js", "defaultCodeOpen": true}} + :::info The `CssVarsProvider` is built on top of the [`ThemeProvider`](/material-ui/customization/theming/#themeprovider) with extra features like CSS variable generation, storage synchronization, unlimited color schemes, and more. ::: @@ -167,7 +163,6 @@ const StyledComponent = styled('button')(({ theme }) => ({ - `defaultMode?: 'light' | 'dark' | 'system'` - Application's default mode (`light` by default) - `disableTransitionOnChange : boolean` - Disable CSS transitions when switching between modes -- `prefix: string` - CSS variable prefix - `theme: ThemeInput` - the theme provided to React's context - `modeStorageKey?: string` - localStorage key used to store application `mode` - `attribute?: string` - DOM attribute for applying color scheme diff --git a/docs/data/system/experimental-api/css-theme-variables/css-theme-variables.md b/docs/data/system/experimental-api/css-theme-variables/css-theme-variables.md index 32f12482f900e1..ee5db55177a68a 100644 --- a/docs/data/system/experimental-api/css-theme-variables/css-theme-variables.md +++ b/docs/data/system/experimental-api/css-theme-variables/css-theme-variables.md @@ -27,11 +27,11 @@ You can checkout the [advantages](https://mui.com/material-ui/experimental-api/c For server-side applications, there are some trade-offs to consider: -| | Compare to the default method | Reason | -| :--------------------------------------------------- | :---------------------------- | :----------------------------------------------------------------------------------------------------------- | -| HTML size | Bigger | CSS variables are generated for both light and dark mode at build time. | -| [First Contentful Paint (FCP)](https://web.dev/fcp/) | Larger | Since the HTML size is generally bigger, the time to download the HTML before showing the content is longer. | -| [Time to Interactive (TTI)](https://web.dev/tti/) | Smaller (for dark mode) | Stylesheets are not regenerated between light and dark mode, so it takes less time for JavaScript to run. | +| | Compare to the default method | Reason | +| :--------------------------------------------------- | :---------------------------- | :------------------------------------------------------------------------------------------------------------- | +| HTML size | Bigger | CSS variables are generated for both light and dark mode at build time. | +| [First Contentful Paint (FCP)](https://web.dev/fcp/) | Longer | Since the HTML size is bigger, the time to download the HTML before showing the content is bit longer. | +| [Time to Interactive (TTI)](https://web.dev/tti/) | Shorter (for dark mode) | Stylesheets are not regenerated between light and dark mode, a lot less time is spent running JavaScript code. | :::warning The comparison described in the table above may not be applicable to large and complex applications since there are so many factors that can impact performance metrics. @@ -209,7 +209,6 @@ See the complete usage of `createVssVarsProvider` in [Material UI](https://githu - `defaultMode?: 'light' | 'dark' | 'system'` - Application's default mode (`light` by default) - `disableTransitionOnChange : boolean` - Disable CSS transitions when switching between modes -- `prefix: string` - CSS variable prefix - `theme: ThemeInput` - the theme provided to React's context - `modeStorageKey?: string` - localStorage key used to store application `mode` - `attribute?: string` - DOM attribute for applying color scheme diff --git a/docs/package.json b/docs/package.json index 0099c4152a77fe..f193821ecae8d1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -32,20 +32,20 @@ "@fortawesome/fontawesome-svg-core": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", - "@mui/base": "5.0.0-beta.15", - "@mui/docs": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/docs": "^5.14.10", "@mui/icons-material": "^5.14.9", - "@mui/joy": "5.0.0-beta.6", - "@mui/lab": "5.0.0-alpha.144", + "@mui/joy": "5.0.0-beta.7", + "@mui/lab": "5.0.0-alpha.145", "@mui/markdown": "^5.0.0", - "@mui/material": "^5.14.9", - "@mui/material-next": "6.0.0-alpha.101", - "@mui/styled-engine": "^5.14.9", - "@mui/styled-engine-sc": "^5.14.9", - "@mui/styles": "^5.14.9", - "@mui/system": "^5.14.9", + "@mui/material": "^5.14.10", + "@mui/material-next": "6.0.0-alpha.102", + "@mui/styled-engine": "^5.14.10", + "@mui/styled-engine-sc": "^5.14.10", + "@mui/styles": "^5.14.10", + "@mui/system": "^5.14.10", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "@mui/x-charts": "^6.0.0-alpha.9", "@mui/x-data-grid": "6.12.1", "@mui/x-data-grid-generator": "6.12.1", diff --git a/docs/pages/joy-ui/api/accordion-group.json b/docs/pages/joy-ui/api/accordion-group.json index 762cb6a3ddf8c7..da61d4e5823c9d 100644 --- a/docs/pages/joy-ui/api/accordion-group.json +++ b/docs/pages/joy-ui/api/accordion-group.json @@ -3,8 +3,8 @@ "children": { "type": { "name": "node" } }, "color": { "type": { - "name": "enum", - "description": "'danger'
| 'neutral'
| 'primary'
| 'success'
| 'warning'" + "name": "union", + "description": "'danger'
| 'neutral'
| 'primary'
| 'success'
| 'warning'
| string" }, "default": "'neutral'", "additionalInfo": { "joy-color": true } @@ -12,7 +12,10 @@ "component": { "type": { "name": "elementType" } }, "disableDivider": { "type": { "name": "bool" }, "default": "false" }, "size": { - "type": { "name": "enum", "description": "'sm'
| 'md'
| 'lg'" }, + "type": { + "name": "union", + "description": "'sm'
| 'md'
| 'lg'
| string" + }, "default": "'md'", "additionalInfo": { "joy-size": true } }, @@ -41,8 +44,8 @@ }, "variant": { "type": { - "name": "enum", - "description": "'outlined'
| 'plain'
| 'soft'
| 'solid'" + "name": "union", + "description": "'outlined'
| 'plain'
| 'soft'
| 'solid'
| string" }, "default": "'plain'", "additionalInfo": { "joy-variant": true } diff --git a/docs/pages/material-ui/api/table-pagination.json b/docs/pages/material-ui/api/table-pagination.json index f47303035ad4d5..0fe0e042df85bb 100644 --- a/docs/pages/material-ui/api/table-pagination.json +++ b/docs/pages/material-ui/api/table-pagination.json @@ -79,6 +79,6 @@ "forwardsRefTo": "HTMLTableCellElement", "filename": "/packages/mui-material/src/TablePagination/TablePagination.js", "inheritance": { "component": "TableCell", "pathname": "/material-ui/api/table-cell/" }, - "demos": "", + "demos": "", "cssComponent": false } diff --git a/docs/pages/material-ui/experimental-api/css-theme-variables/usage.js b/docs/pages/material-ui/experimental-api/css-theme-variables/usage.js index 182c27e2d146bd..50811f2f187adf 100644 --- a/docs/pages/material-ui/experimental-api/css-theme-variables/usage.js +++ b/docs/pages/material-ui/experimental-api/css-theme-variables/usage.js @@ -4,7 +4,7 @@ import { demos, docs, demoComponents, -} from 'docs/data/material/experimental-api/css-theme-variables/usage.md?@mui/markdown'; +} from 'docs/data/material/experimental-api/css-theme-variables/usage/usage.md?@mui/markdown'; export default function Page() { return ; diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/files-dark.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/files-dark.jpg index f60883e4f31d62..1fde3c4eccde5d 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/files-dark.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/files-dark.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/messages.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/messages.jpg index 5fda2388e2f6cc..15a318f7009c4a 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/messages.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/messages.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard-dark.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard-dark.jpg index 0d435d087c8bf9..7ee55d135f7a39 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard-dark.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard-dark.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard.jpg index e419b9b31cf572..b415d287a70e68 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/order-dashboard.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard-dark.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard-dark.jpg index 3f9ebc57a65f70..90ea71583bc2ac 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard-dark.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard-dark.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard.jpg index 5fcdc6ddc42759..d464c6e26cedbe 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/rental-dashboard.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side-dark.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side-dark.jpg index 2a1728bb605944..a80ee365734390 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side-dark.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side-dark.jpg differ diff --git a/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side.jpg b/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side.jpg index af4aea923421b7..2425b95b48b768 100644 Binary files a/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side.jpg and b/docs/public/static/screenshots/joy-ui/getting-started/templates/sign-in-side.jpg differ diff --git a/docs/src/modules/components/DemoErrorBoundary.js b/docs/src/modules/components/DemoErrorBoundary.js index bc79d35ae813fb..5817e494b47509 100644 --- a/docs/src/modules/components/DemoErrorBoundary.js +++ b/docs/src/modules/components/DemoErrorBoundary.js @@ -9,7 +9,7 @@ import Button from '@mui/material/Button'; * with node 8 + IE11 support i.e. not using URL (URLSearchParams.set replaced with Map.set) */ function newGitHubIssueUrl(options) { - const url = `https://github.com/${options.user}/${options.repo}/issues/new`; + const url = `${process.env.SOURCE_CODE_REPO}/issues/new`; const query = Object.keys(options) .map((type) => { @@ -38,23 +38,23 @@ export default class DemoErrorBoundary extends React.Component { const title = `[docs] Demo ${name} crashes`; const searchQuery = encodeURIComponent(`is:issue ${title}`); const issueLink = newGitHubIssueUrl({ - user: 'mui', - repo: 'material-ui', title, body: ` -- [ ] I have [searched for similar issues](https://github.com/mui/material-ui/issues?q=${searchQuery}) in this repository and believe that this is not a duplicate. +- [ ] I have [searched for similar issues](${ + process.env.SOURCE_CODE_REPO + }/issues?q=${searchQuery}) in this repository and believe that this is not a duplicate. -## Steps to Reproduce +## Steps to reproduce 1. Visit ${window.location.href} 2. ?? 3. demo *${name}* crashes -## Your Environment +## Your environment | Tech | Version | |--------------|---------| -| MUI | v${process.env.LIB_VERSION} | +| Version | v${process.env.LIB_VERSION} | | Netlify deploy | ${process.env.NETLIFY_DEPLOY_URL} | | Browser | ${ typeof window !== 'undefined' && window.navigator @@ -71,15 +71,15 @@ export default class DemoErrorBoundary extends React.Component { This demo had a runtime error!
- We would appreciate it if you{' '} + {'We would appreciate it if you '} report this error - {' '} - directly in our issue tracker. You will be provided with a prefilled description that - includes valuable information about this error. + + {` directly in our issue tracker with the steps you took to trigger it. +The "report this error" link prefills the issue description with valuable information.`}
{error.toString()}
- diff --git a/package.json b/package.json index e0779ec929640d..713dc77ce80719 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mui/monorepo", - "version": "5.14.9", + "version": "5.14.10", "private": true, "scripts": { "proptypes": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js\" ./scripts/generateProptypes.ts", diff --git a/packages/api-docs-builder/package.json b/packages/api-docs-builder/package.json index 4c0fb7e20f7254..88a910e16f9c22 100644 --- a/packages/api-docs-builder/package.json +++ b/packages/api-docs-builder/package.json @@ -12,7 +12,7 @@ "@babel/traverse": "^7.22.17", "@mui-internal/docs-utilities": "^1.0.0", "@mui/markdown": "^5.0.0", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "ast-types": "^0.14.2", "docs": "^5.0.0", "doctrine": "^3.0.0", diff --git a/packages/eslint-plugin-material-ui/package.json b/packages/eslint-plugin-material-ui/package.json index 85555720f539a4..3b137eb5c24c3d 100644 --- a/packages/eslint-plugin-material-ui/package.json +++ b/packages/eslint-plugin-material-ui/package.json @@ -12,6 +12,9 @@ "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.47.0" }, + "peerDependencies": { + "eslint": "^8.47.0" + }, "scripts": { "test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/eslint-plugin-material-ui/**/*.test.js'" }, diff --git a/packages/mui-base/package.json b/packages/mui-base/package.json index c4d0eeacea967a..1236c2b3efce42 100644 --- a/packages/mui-base/package.json +++ b/packages/mui-base/package.json @@ -1,6 +1,6 @@ { "name": "@mui/base", - "version": "5.0.0-beta.15", + "version": "5.0.0-beta.16", "private": false, "author": "MUI Team", "description": "A library of headless ('unstyled') React UI components and low-level hooks.", @@ -44,13 +44,13 @@ "@babel/runtime": "^7.22.15", "@floating-ui/react-dom": "^2.0.2", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "@popperjs/core": "^2.11.8", "clsx": "^2.0.0", "prop-types": "^15.8.1" }, "devDependencies": { - "@mui/material": "^5.14.9", + "@mui/material": "^5.14.10", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", "@types/chai": "^4.3.5", diff --git a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx index 1740aa8eb6b37b..3d70576baacd46 100644 --- a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx +++ b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx @@ -4,6 +4,8 @@ import sinon, { spy, stub } from 'sinon'; import { describeConformanceUnstyled, act, + screen, + waitFor, createMount, createRenderer, fireEvent, @@ -15,6 +17,29 @@ function getStyleValue(value: string) { return parseInt(value, 10) || 0; } +// TODO: merge into a shared test helpers. +// MUI X already have one under mui-x/test/utils/helperFn.ts +function sleep(duration: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, duration); + }); +} + +async function raf() { + return new Promise((resolve) => { + // Chrome and Safari have a bug where calling rAF once returns the current + // frame instead of the next frame, so we need to call a double rAF here. + // See crbug.com/675795 for more. + requestAnimationFrame(() => { + requestAnimationFrame(() => { + resolve(); + }); + }); + }); +} + describe('', () => { const { clock, render } = createRenderer(); const mount = createMount(); @@ -36,6 +61,109 @@ describe('', () => { ], })); + // For https://github.com/mui/material-ui/pull/33238 + it('should not crash when unmounting with Suspense', async () => { + const LazyRoute = React.lazy(() => { + // Force react to show fallback suspense + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + default: () =>
LazyRoute
, + }); + }, 0); + }); + }); + + function App() { + const [toggle, setToggle] = React.useState(false); + + return ( + + + {toggle ? : } + + ); + } + + render(); + const button = screen.getByRole('button'); + fireEvent.click(button); + await waitFor(() => { + expect(screen.queryByText('LazyRoute')).not.to.equal(null); + }); + }); + + // For https://github.com/mui/material-ui/pull/33253 + it('should update height without an infinite rendering loop', async () => { + function App() { + const [value, setValue] = React.useState('Controlled'); + + const handleChange = (event: React.ChangeEvent) => { + setValue(event.target.value); + }; + + return ; + } + const { container } = render(); + const input = container.querySelector('textarea')!; + act(() => { + input.focus(); + }); + const activeElement = document.activeElement!; + // set the value of the input to be 1 larger than its content width + fireEvent.change(activeElement, { + target: { value: 'Controlled\n' }, + }); + await sleep(0); + fireEvent.change(activeElement, { + target: { value: 'Controlled\n\n' }, + }); + }); + + // For https://github.com/mui/material-ui/pull/37135 + it('should update height without delay', async function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // It depends on ResizeObserver + this.skip(); + } + + function App() { + const ref = React.useRef(null); + return ( +
+ +
+ +
+
+ ); + } + const { container } = render(); + const input = container.querySelector('textarea')!; + const button = screen.getByRole('button'); + expect(parseInt(input.style.height, 10)).to.be.within(30, 32); + fireEvent.click(button); + await raf(); + await raf(); + expect(parseInt(input.style.height, 10)).to.be.within(15, 17); + }); + describe('layout', () => { const getComputedStyleStub = new Map>(); function setLayout( diff --git a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx index 164dbd478a2bde..9f582765f6e932 100644 --- a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx +++ b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx @@ -163,71 +163,66 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize( return; } - setState((prevState) => { - return updateState(prevState, newState); - }); + setState((prevState) => updateState(prevState, newState)); }, [getUpdatedState]); - const syncHeightWithFlushSync = () => { - const newState = getUpdatedState(); + useEnhancedEffect(() => { + const syncHeightWithFlushSync = () => { + const newState = getUpdatedState(); - if (isEmpty(newState)) { - return; - } + if (isEmpty(newState)) { + return; + } - // In React 18, state updates in a ResizeObserver's callback are happening after the paint which causes flickering - // when doing some visual updates in it. Using flushSync ensures that the dom will be painted after the states updates happen - // Related issue - https://github.com/facebook/react/issues/24331 - ReactDOM.flushSync(() => { - setState((prevState) => { - return updateState(prevState, newState); + // In React 18, state updates in a ResizeObserver's callback are happening after + // the paint, this leads to an infinite rendering. + // + // Using flushSync ensures that the states is updated before the next pain. + // Related issue - https://github.com/facebook/react/issues/24331 + ReactDOM.flushSync(() => { + setState((prevState) => updateState(prevState, newState)); }); - }); - }; + }; - React.useEffect(() => { const handleResize = () => { renders.current = 0; - - // If the TextareaAutosize component is replaced by Suspense with a fallback, the last - // ResizeObserver's handler that runs because of the change in the layout is trying to - // access a dom node that is no longer there (as the fallback component is being shown instead). - // See https://github.com/mui/material-ui/issues/32640 - if (inputRef.current) { - syncHeightWithFlushSync(); - } + syncHeightWithFlushSync(); }; - const handleResizeWindow = debounce(() => { - renders.current = 0; - - // If the TextareaAutosize component is replaced by Suspense with a fallback, the last - // ResizeObserver's handler that runs because of the change in the layout is trying to - // access a dom node that is no longer there (as the fallback component is being shown instead). - // See https://github.com/mui/material-ui/issues/32640 - if (inputRef.current) { - syncHeightWithFlushSync(); - } - }); - let resizeObserver: ResizeObserver; - + // Workaround a "ResizeObserver loop completed with undelivered notifications" error + // in test. + // Note that we might need to use this logic in production per https://github.com/WICG/resize-observer/issues/38 + // Also see https://github.com/mui/mui-x/issues/8733 + let rAF: any; + const rAFHandleResize = () => { + cancelAnimationFrame(rAF); + rAF = requestAnimationFrame(() => { + handleResize(); + }); + }; + const debounceHandleResize = debounce(handleResize); const input = inputRef.current!; const containerWindow = ownerWindow(input); - containerWindow.addEventListener('resize', handleResizeWindow); + containerWindow.addEventListener('resize', debounceHandleResize); + + let resizeObserver: ResizeObserver; if (typeof ResizeObserver !== 'undefined') { - resizeObserver = new ResizeObserver(handleResize); + resizeObserver = new ResizeObserver( + process.env.NODE_ENV === 'test' ? rAFHandleResize : handleResize, + ); resizeObserver.observe(input); } return () => { - handleResizeWindow.clear(); - containerWindow.removeEventListener('resize', handleResizeWindow); + debounceHandleResize.clear(); + cancelAnimationFrame(rAF); + containerWindow.removeEventListener('resize', debounceHandleResize); if (resizeObserver) { resizeObserver.disconnect(); } }; - }); + }, [getUpdatedState]); useEnhancedEffect(() => { syncHeight(); diff --git a/packages/mui-core-downloads-tracker/package.json b/packages/mui-core-downloads-tracker/package.json index 8d3e2a9780b6a0..5748505c1d7bf7 100644 --- a/packages/mui-core-downloads-tracker/package.json +++ b/packages/mui-core-downloads-tracker/package.json @@ -1,6 +1,6 @@ { "name": "@mui/core-downloads-tracker", - "version": "5.14.9", + "version": "5.14.10", "private": false, "author": "MUI Team", "description": "Internal package to track number of downloads of our design system libraries", diff --git a/packages/mui-docs/package.json b/packages/mui-docs/package.json index 9350dd0eb4c306..e7fd13bd425735 100644 --- a/packages/mui-docs/package.json +++ b/packages/mui-docs/package.json @@ -1,6 +1,6 @@ { "name": "@mui/docs", - "version": "5.14.9", + "version": "5.14.10", "private": false, "author": "MUI Team", "description": "MUI Docs - Documentation building blocks.", @@ -35,8 +35,8 @@ }, "dependencies": { "@babel/runtime": "^7.22.15", - "@mui/base": "5.0.0-beta.15", - "@mui/utils": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/utils": "^5.14.10", "nprogress": "^0.2.0", "prop-types": "^15.8.1" }, diff --git a/packages/mui-joy/package.json b/packages/mui-joy/package.json index 7a413d6a1029c6..c58bf59e2f3c50 100644 --- a/packages/mui-joy/package.json +++ b/packages/mui-joy/package.json @@ -1,6 +1,6 @@ { "name": "@mui/joy", - "version": "5.0.0-beta.6", + "version": "5.0.0-beta.7", "private": false, "author": "MUI Team", "description": "A library of beautifully designed React UI components.", @@ -39,16 +39,16 @@ }, "dependencies": { "@babel/runtime": "^7.22.15", - "@mui/base": "5.0.0-beta.15", - "@mui/core-downloads-tracker": "^5.14.9", - "@mui/system": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/core-downloads-tracker": "^5.14.10", + "@mui/system": "^5.14.10", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "clsx": "^2.0.0", "prop-types": "^15.8.1" }, "devDependencies": { - "@mui/material": "^5.14.9", + "@mui/material": "^5.14.10", "@types/chai": "^4.3.5", "@types/prop-types": "^15.7.5", "@types/react": "^18.2.21", diff --git a/packages/mui-joy/src/AccordionGroup/AccordionGroup.test.tsx b/packages/mui-joy/src/AccordionGroup/AccordionGroup.test.tsx index 44c0769e83594e..abb5e61b810f29 100644 --- a/packages/mui-joy/src/AccordionGroup/AccordionGroup.test.tsx +++ b/packages/mui-joy/src/AccordionGroup/AccordionGroup.test.tsx @@ -76,4 +76,11 @@ describe('', () => { describeJoyColorInversion(, { muiName: 'JoyAccordionGroup', classes }); }); + + it('should not warn when using custom color, variant, size', () => { + expect(() => { + // @ts-expect-error as `custom` color, varaint, size is not part of the type system + render(); + }).not.toErrorDev(); + }); }); diff --git a/packages/mui-joy/src/AccordionGroup/AccordionGroup.tsx b/packages/mui-joy/src/AccordionGroup/AccordionGroup.tsx index fca9d175c37647..73df8a92bf487f 100644 --- a/packages/mui-joy/src/AccordionGroup/AccordionGroup.tsx +++ b/packages/mui-joy/src/AccordionGroup/AccordionGroup.tsx @@ -141,7 +141,10 @@ AccordionGroup.propTypes /* remove-proptypes */ = { * The color of the component. It supports those theme colors that make sense for this component. * @default 'neutral' */ - color: PropTypes.oneOf(['danger', 'neutral', 'primary', 'success', 'warning']), + color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['danger', 'neutral', 'primary', 'success', 'warning']), + PropTypes.string, + ]), /** * The component used for the root node. * Either a string to use a HTML element or a component. @@ -156,7 +159,10 @@ AccordionGroup.propTypes /* remove-proptypes */ = { * The size of the component (affect other nested list* components). * @default 'md' */ - size: PropTypes.oneOf(['sm', 'md', 'lg']), + size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['sm', 'md', 'lg']), + PropTypes.string, + ]), /** * The props used for each slot inside. * @default {} @@ -194,7 +200,10 @@ AccordionGroup.propTypes /* remove-proptypes */ = { * The [global variant](https://mui.com/joy-ui/main-features/global-variants/) to use. * @default 'plain' */ - variant: PropTypes.oneOf(['outlined', 'plain', 'soft', 'solid']), + variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['outlined', 'plain', 'soft', 'solid']), + PropTypes.string, + ]), } as any; export default AccordionGroup; diff --git a/packages/mui-lab/package.json b/packages/mui-lab/package.json index 86388b708fa8b7..5700aacffa39dd 100644 --- a/packages/mui-lab/package.json +++ b/packages/mui-lab/package.json @@ -1,6 +1,6 @@ { "name": "@mui/lab", - "version": "5.0.0-alpha.144", + "version": "5.0.0-alpha.145", "private": false, "author": "MUI Team", "description": "Laboratory for new MUI modules.", @@ -42,10 +42,10 @@ }, "dependencies": { "@babel/runtime": "^7.22.15", - "@mui/base": "5.0.0-beta.15", - "@mui/system": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/system": "^5.14.10", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "@mui/x-tree-view": "6.0.0-alpha.1", "clsx": "^2.0.0", "prop-types": "^15.8.1" diff --git a/packages/mui-lab/src/Masonry/Masonry.js b/packages/mui-lab/src/Masonry/Masonry.js index b29c236c3f4cfe..c48e32772f9170 100644 --- a/packages/mui-lab/src/Masonry/Masonry.js +++ b/packages/mui-lab/src/Masonry/Masonry.js @@ -287,7 +287,7 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) { const resizeObserver = new ResizeObserver(() => { // see https://github.com/mui/material-ui/issues/36909 - animationFrame = window.requestAnimationFrame(handleResize); + animationFrame = requestAnimationFrame(handleResize); }); if (masonryRef.current) { diff --git a/packages/mui-material-next/package.json b/packages/mui-material-next/package.json index 162ee6e31c4641..c8b1a94e8ac2c7 100644 --- a/packages/mui-material-next/package.json +++ b/packages/mui-material-next/package.json @@ -1,6 +1,6 @@ { "name": "@mui/material-next", - "version": "6.0.0-alpha.101", + "version": "6.0.0-alpha.102", "private": false, "author": "MUI Team", "description": "v6-alpha: React components that implement Google's Material Design", @@ -41,11 +41,11 @@ }, "dependencies": { "@babel/runtime": "^7.22.15", - "@mui/base": "5.0.0-beta.15", - "@mui/material": "^5.14.9", - "@mui/system": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/material": "^5.14.10", + "@mui/system": "^5.14.10", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "@types/react-transition-group": "^4.4.6", "clsx": "^2.0.0", "prop-types": "^15.8.1", diff --git a/packages/mui-material/package.json b/packages/mui-material/package.json index e3ea7b96d8cf7a..0674d53907cc7a 100644 --- a/packages/mui-material/package.json +++ b/packages/mui-material/package.json @@ -1,6 +1,6 @@ { "name": "@mui/material", - "version": "5.14.9", + "version": "5.14.10", "private": false, "author": "MUI Team", "description": "React components that implement Google's Material Design.", @@ -43,11 +43,11 @@ }, "dependencies": { "@babel/runtime": "^7.22.15", - "@mui/base": "5.0.0-beta.15", - "@mui/core-downloads-tracker": "^5.14.9", - "@mui/system": "^5.14.9", + "@mui/base": "5.0.0-beta.16", + "@mui/core-downloads-tracker": "^5.14.10", + "@mui/system": "^5.14.10", "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.9", + "@mui/utils": "^5.14.10", "@types/react-transition-group": "^4.4.6", "clsx": "^2.0.0", "csstype": "^3.1.2", @@ -57,8 +57,8 @@ }, "devDependencies": { "@mui/icons-material": "^5.14.9", - "@mui/lab": "5.0.0-alpha.144", - "@mui/styles": "^5.14.9", + "@mui/lab": "^5.0.0-alpha.145", + "@mui/styles": "^5.14.10", "@popperjs/core": "^2.11.8", "@rollup/plugin-replace": "^5.0.2", "@testing-library/dom": "^9.3.1", diff --git a/packages/mui-material/src/Select/Select.test.js b/packages/mui-material/src/Select/Select.test.js index 0ee8903cc2cd83..cf99abe6b161f9 100644 --- a/packages/mui-material/src/Select/Select.test.js +++ b/packages/mui-material/src/Select/Select.test.js @@ -1047,6 +1047,20 @@ describe(' + Ten + Twenty + Thirty + , + ); + + fireEvent.mouseDown(getByRole('button')); + + expect(getByRole('listbox')).to.have.attribute('aria-multiselectable', 'true'); + }); + it('should serialize multiple select display value', () => { const { getByRole } = render(