From 1c769998f792e5dd0e5ef61db3916ff66de04522 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:54:42 +0000 Subject: [PATCH 01/49] Bump eslint-plugin-react-compiler to 0.0.0 (#43762) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Aarón García Hervás --- package.json | 2 +- pnpm-lock.yaml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 342162d619f844..7329d97812349a 100644 --- a/package.json +++ b/package.json @@ -162,7 +162,7 @@ "eslint-plugin-material-ui": "workspace:^", "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-react": "^7.35.2", - "eslint-plugin-react-compiler": "0.0.0-experimental-b6997ec-20240910", + "eslint-plugin-react-compiler": "0.0.0-experimental-75b9fd4-20240912", "eslint-plugin-react-hooks": "^4.6.2", "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 358361e1d4d3ff..dcf5480e03f823 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -217,8 +217,8 @@ importers: specifier: ^7.35.2 version: 7.35.2(eslint@8.57.0) eslint-plugin-react-compiler: - specifier: 0.0.0-experimental-b6997ec-20240910 - version: 0.0.0-experimental-b6997ec-20240910(eslint@8.57.0) + specifier: 0.0.0-experimental-75b9fd4-20240912 + version: 0.0.0-experimental-75b9fd4-20240912(eslint@8.57.0) eslint-plugin-react-hooks: specifier: ^4.6.2 version: 4.6.2(eslint@8.57.0) @@ -7589,8 +7589,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-react-compiler@0.0.0-experimental-b6997ec-20240910: - resolution: {integrity: sha512-5VLQr2Lvxo4Ktf7TKC/0cPRJIKg4F34BreQmth5vHOc1aR8I6IZ84hY7T3ci2VlrfTKOHkEDEjGfOJWSoM9aZQ==} + eslint-plugin-react-compiler@0.0.0-experimental-75b9fd4-20240912: + resolution: {integrity: sha512-RDwZfd3leJZu/mLbFnv2H6991PG1eQLmpCx+6z/TUQxrIxpObplrsw5Bsb0SnxrGNuzkPkaNQDEJXszewF1Ycw==} engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} peerDependencies: eslint: '>=7' @@ -12936,8 +12936,8 @@ packages: resolution: {integrity: sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==} engines: {node: '>= 10'} - zod-validation-error@3.3.1: - resolution: {integrity: sha512-uFzCZz7FQis256dqw4AhPQgD6f3pzNca/Zh62RNELavlumQB3nDIUFbF5JQfFLcMbO1s02Q7Xg/gpcOBlEnYZA==} + zod-validation-error@3.4.0: + resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==} engines: {node: '>=18.0.0'} peerDependencies: zod: ^3.18.0 @@ -19387,7 +19387,7 @@ snapshots: globals: 13.24.0 rambda: 7.5.0 - eslint-plugin-react-compiler@0.0.0-experimental-b6997ec-20240910(eslint@8.57.0): + eslint-plugin-react-compiler@0.0.0-experimental-75b9fd4-20240912(eslint@8.57.0): dependencies: '@babel/core': 7.25.2 '@babel/parser': 7.25.6 @@ -19395,7 +19395,7 @@ snapshots: eslint: 8.57.0 hermes-parser: 0.20.1 zod: 3.23.8 - zod-validation-error: 3.3.1(zod@3.23.8) + zod-validation-error: 3.4.0(zod@3.23.8) transitivePeerDependencies: - supports-color @@ -25886,7 +25886,7 @@ snapshots: compress-commons: 4.1.1 readable-stream: 3.6.0 - zod-validation-error@3.3.1(zod@3.23.8): + zod-validation-error@3.4.0(zod@3.23.8): dependencies: zod: 3.23.8 From bbbcac8111b772820e72d3bde774b24e2fea6bfa Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:16:56 +0200 Subject: [PATCH 02/49] [docs] Revert icon search virtualization (#43569) Co-authored-by: Olivier Tassinari --- .../components/material-icons/SearchIcons.js | 160 +++++++++--------- 1 file changed, 81 insertions(+), 79 deletions(-) diff --git a/docs/data/material/components/material-icons/SearchIcons.js b/docs/data/material/components/material-icons/SearchIcons.js index cb000937495b7d..5c869ed7b00fdb 100644 --- a/docs/data/material/components/material-icons/SearchIcons.js +++ b/docs/data/material/components/material-icons/SearchIcons.js @@ -1,5 +1,4 @@ import * as React from 'react'; -import { VirtuosoGrid } from 'react-virtuoso'; import { styled } from '@mui/material/styles'; import MuiPaper from '@mui/material/Paper'; import copy from 'clipboard-copy'; @@ -94,21 +93,20 @@ function selectNode(node) { selection.addRange(range); } +const iconWidth = 35; + const StyledIcon = styled('span')(({ theme }) => ({ display: 'inline-flex', flexDirection: 'column', color: theme.palette.text.secondary, margin: '0 4px', '& > div': { - display: 'flex', - }, - '& > div > *': { flexGrow: 1, fontSize: '.6rem', overflow: 'hidden', textOverflow: 'ellipsis', textAlign: 'center', - width: 0, + width: `calc(${iconWidth}px + ${theme.spacing(2)} * 2 + 2px)`, }, })); @@ -117,6 +115,7 @@ const StyledSvgIcon = styled(SvgIcon)(({ theme }) => ({ cursor: 'pointer', color: theme.palette.text.primary, border: '1px solid transparent', + fontSize: iconWidth, borderRadius: '12px', transition: theme.transitions.create(['background-color', 'box-shadow'], { duration: theme.transitions.duration.shortest, @@ -129,56 +128,64 @@ const StyledSvgIcon = styled(SvgIcon)(({ theme }) => ({ }, })); -const ListWrapper = React.forwardRef(({ style, children, ...props }, ref) => { +const handleIconClick = (event) => { + const { iconName, iconTheme } = event.currentTarget.dataset; + + if (Math.random() < 0.1) { + window.gtag('event', 'material-icons', { + eventAction: 'click', + eventLabel: iconName, + }); + window.gtag('event', 'material-icons-theme', { + eventAction: 'click', + eventLabel: iconTheme, + }); + } +}; + +function handleLabelClick(event) { + selectNode(event.currentTarget); +} + +function Icon(props) { + const { icon, onOpenClick } = props; + /* eslint-disable jsx-a11y/click-events-have-key-events */ return ( -
- {children} -
+ + {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- TODO: a11y */} +
{icon.importName}
+ {/* eslint-enable jsx-a11y/click-events-have-key-events */} + ); -}); +} -function Icon(handleOpenClick) { - return function itemContent(_, icon) { - const handleIconClick = () => { - if (Math.random() < 0.1) { - window.gtag('event', 'material-icons', { - eventAction: 'click', - eventLabel: icon.name, - }); - window.gtag('event', 'material-icons-theme', { - eventAction: 'click', - eventLabel: icon.theme, - }); - } - }; +const Icons = React.memo(function Icons(props) { + const { icons, handleOpenClick } = props; - const handleLabelClick = (event) => { - selectNode(event.currentTarget); - }; + return ( +
+ {icons.map((icon) => ( + + ))} +
+ ); +}); - return ( - /* eslint-disable jsx-a11y/click-events-have-key-events */ - - -
- {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- TODO: a11y */} -
{icon.importName}
-
- {/* eslint-enable jsx-a11y/click-events-have-key-events */} -
- ); - }; -} +Icons.propTypes = { + handleOpenClick: PropTypes.func.isRequired, + icons: PropTypes.array.isRequired, +}; const ImportLink = styled(Link)(({ theme }) => ({ textAlign: 'right', @@ -439,7 +446,14 @@ DialogDetails.propTypes = { selectedIcon: PropTypes.object, }; +const Form = styled('form')({ + position: 'sticky', + top: 80, +}); + const Paper = styled(MuiPaper)(({ theme }) => ({ + position: 'sticky', + top: 80, display: 'flex', alignItems: 'center', marginBottom: theme.spacing(2), @@ -525,30 +539,26 @@ export default function SearchIcons() { setSelectedIcon(''); }, [setSelectedIcon]); - const deferredQuery = React.useDeferredValue(query); - const deferredTheme = React.useDeferredValue(theme); - - const isPending = query !== deferredQuery || theme !== deferredTheme; - const icons = React.useMemo(() => { - const keys = - deferredQuery === '' - ? null - : searchIndex.search(deferredQuery, { limit: 3000 }); + const keys = query === '' ? null : searchIndex.search(query, { limit: 3000 }); return (keys === null ? allIcons : keys.map((key) => allIconsMap[key])).filter( - (icon) => deferredTheme === icon.theme, + (icon) => theme === icon.theme, ); - }, [deferredQuery, deferredTheme]); + }, [query, theme]); + + const deferredIcons = React.useDeferredValue(icons); + + const isPending = deferredIcons !== icons; React.useEffect(() => { // Keep track of the no results so we can add synonyms in the future. - if (deferredQuery.length >= 4 && icons.length === 0) { + if (query.length >= 4 && icons.length === 0) { window.gtag('event', 'material-icons', { eventAction: 'no-results', - eventLabel: deferredQuery, + eventLabel: query, }); } - }, [deferredQuery, icons.length]); + }, [query, icons.length]); const dialogSelectedIcon = useLatest( selectedIcon ? allIconsMap[selectedIcon] : null, @@ -557,7 +567,7 @@ export default function SearchIcons() { return ( -
+ Filter the style @@ -578,7 +588,7 @@ export default function SearchIcons() { }, )} -
+
@@ -603,21 +613,13 @@ export default function SearchIcons() { {`${formatNumber( icons.length, )} matching results`} - + - {/* Temporary fix for Dialog not closing sometimes and Backdrop stuck at opacity 0 (see issue https://github.com/mui/material-ui/issues/32286). One disadvantage is that the closing animation is not applied. */} - {selectedIcon ? ( - - ) : null} +
); } From f4a9848d3dbbd355dd36f39f8238d553441ff259 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 16 Sep 2024 19:19:09 +0200 Subject: [PATCH 03/49] [docs-infra] Fix Vale config for TypeScript references (#43751) --- .../upgrade-to-v6/migrating-to-pigment-css.md | 2 +- docs/mui-vale.zip | Bin 4961 -> 4574 bytes .../styles/MUI/CorrectReferenceAllCases.yml | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/data/material/migration/upgrade-to-v6/migrating-to-pigment-css.md b/docs/data/material/migration/upgrade-to-v6/migrating-to-pigment-css.md index 4c5a2ef4309aea..e930a44fc56b89 100644 --- a/docs/data/material/migration/upgrade-to-v6/migrating-to-pigment-css.md +++ b/docs/data/material/migration/upgrade-to-v6/migrating-to-pigment-css.md @@ -255,7 +255,7 @@ Finally, update the `typography.fontFamily` value with the variable created in t }; ``` -### Typescript +### TypeScript If you are using TypeScript, you need to extend the Pigment CSS theme types with Material UI `Theme`. Add the following code to a file that is included in your `tsconfig.json`: diff --git a/docs/mui-vale.zip b/docs/mui-vale.zip index bb43a45783468a1c18a493c543882b569c0e9e31..3d14e91cba10c54ece0dc8ee098efc4c55a2b695 100644 GIT binary patch delta 1264 zcmaE;c2Aivz?+$civa|-q-aM@CH6 z%43Y0V3jPzSj_~P%>lN2vIvtUJIMB;2@f}iFo`m;fSfcrm&FPuI(Z$-cfl3`y~y)Z z|3#hwx-6BMfx%$1B9r*!IzhR5P6p;5m!717Fq-32gT3=^8wlKeEy66(8r~&#voL&# z>)l0p%r|Tg%#e!i(VX<4=gluOyKet$3q`DZH$SS*x2rjPo@ZZM?wM%}jj=Z>o0R7{ zD9LOVX7Wq9do5Dnl&$lb3A=iH{sdf%UwB~?qnw$JUp-r)VTi5a<3650iA_J%=QVTd zwCEmrdqUfv{S%wU^BLOPxeX^@?PF8n4>{Y=KV!l1Bd?PD8@Dp9IJ(c|MnZOic=GDX zRgUYAO6e!++?IafA~buM<$~qx?`D}r<*BGG=RSQ>*nD$&+v&1pOf#6(%*{Xi{JGo6 zQZ;FItPped(baafQ+=;~&BnNYArG&A zzU1IxdnRvlhNJGyo3{2hZoHP5u{4dV>ff}iv$5K66;bWVc#gn z$=keUe80!qwA{~jw)sMdV~OS5Jx{iFUyFOXJ*+ByE8qO23p3q&}O*8wg(c_!~?i0A}9 zb%f}CzF3H;0>2J3(BR1j1;iW>nFVMi90)K-K-mHeZylY1?A+2!-Lk}-RQ=+T%AC|< z{m>9r2ACmS2ty{z3P>^c0v(^gD>~U(ZafGA7{#HkN~#+fifj1v|VgGnl4~Qh}474eo1*iTu_(gl_@8;14uW8^uHk9*`zIBn=9n vFt{C~Tj>PU;0DA(C>p|fC(8>BUzt1vmip@_zA81KzSAk1_mJp z8HU`_Ox?1?oK$^1m*Du|lKi67&=5`r=DiQTrp|u!HMO*Yn}Lz#DY2vFDC8GE@7 z8Hlu=U+c`v;rj7tR{SdiI3@8?<(me%`wEnS$%<1>K9DH-F$gxz}@=iaA5h zmUv!9b_M5p6Tb}Ak>9EN6~&l|HUo;+4K-v90V2 zty%5UHvTX;m$N3|%*A$sgyS9!>nvRaj#M4qN zY9OJPmh2ipAt2tY$tcPs2vV0-p}6`kFvx0wVW&FzAe;E)3H-ubz@P~;8^PR@sldUR zG~YyVE%%?}FQS7S9?!e+>4e#jBnPFt3!C=01k^1QTBGiE*U7?XM?rr zbM}^m)E~$^lEhkaO^{92Ge+j(WD|ys7Ejo!?`pkp%24&UkXRD&Md$UNy-o8hC#`xt zxopR>eR<6bXE|@#BoHqXw6`kVB7ZqogHXwqrA_P4`%8XQRhpTi+&sbB@odX7pJnIo zct5LqH92mFIAd`)zY}Mh#`fBrS)AW&cJ!FUXZ~ij-oaMOvbxu|Dtk1eDH76;As~nkm`r;YWz~zfK%RSsEe*RVOiMFpd zbPut_?e=&(w=P@tdRV~84~7*ptEK6c0y$aMkAeUiDBOB9X z0e)>z>IW%?7!}7a#T?H9GD?FDVUQw5_CYadHY?cf$-ns(;iiE@* Date: Tue, 17 Sep 2024 10:33:31 +0700 Subject: [PATCH 04/49] [system] Pass the stylesheet directly to `GlobalStyles` (#43739) --- .../src/cssVars/createCssVarsProvider.js | 8 +--- .../InjectFirstWithThemeVars.js | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 test/regressions/fixtures/CssVarsProvider/InjectFirstWithThemeVars.js diff --git a/packages/mui-system/src/cssVars/createCssVarsProvider.js b/packages/mui-system/src/cssVars/createCssVarsProvider.js index 66a23b7a0451f8..435d0231618ee7 100644 --- a/packages/mui-system/src/cssVars/createCssVarsProvider.js +++ b/packages/mui-system/src/cssVars/createCssVarsProvider.js @@ -267,19 +267,13 @@ export default function createCssVarsProvider(options) { const element = ( - {shouldGenerateStyleSheet && ( - - {(theme.generateStyleSheets?.() || []).map((styles, index) => ( - - ))} - - )} {children} + {shouldGenerateStyleSheet && } ); diff --git a/test/regressions/fixtures/CssVarsProvider/InjectFirstWithThemeVars.js b/test/regressions/fixtures/CssVarsProvider/InjectFirstWithThemeVars.js new file mode 100644 index 00000000000000..c5fba10d094e84 --- /dev/null +++ b/test/regressions/fixtures/CssVarsProvider/InjectFirstWithThemeVars.js @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { + ThemeProvider, + createTheme, + StyledEngineProvider, + useColorScheme, +} from '@mui/material/styles'; +import Box from '@mui/material/Box'; + +const theme = createTheme({ + colorSchemes: { dark: true }, + cssVariables: { colorSchemeSelector: '.regression-inject-first-%s' }, +}); + +function AutoDark() { + const { setMode } = useColorScheme(); + React.useEffect(() => { + setMode('dark'); + }, [setMode]); + return null; +} + +export default function InjectFirstWithThemeVars() { + return ( + + + + + + + ); +} From 1275f3751a373854ee839b8fae6e77b9fa04ff21 Mon Sep 17 00:00:00 2001 From: Yash Shah <49yash@gmail.com> Date: Tue, 17 Sep 2024 09:06:50 +0530 Subject: [PATCH 05/49] [utils] Fix "useId" & "useSyncExternalStore" imports to not be statically analysable (#43360) --- packages/mui-system/src/useMediaQuery/useMediaQuery.ts | 7 ++++--- packages/mui-utils/src/useId/useId.test.js | 2 +- packages/mui-utils/src/useId/useId.ts | 10 ++++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/mui-system/src/useMediaQuery/useMediaQuery.ts b/packages/mui-system/src/useMediaQuery/useMediaQuery.ts index 17f0015e0dc433..0c4bf8c9e5e4e1 100644 --- a/packages/mui-system/src/useMediaQuery/useMediaQuery.ts +++ b/packages/mui-system/src/useMediaQuery/useMediaQuery.ts @@ -30,6 +30,7 @@ export interface UseMediaQueryOptions { ssrMatchMedia?: (query: string) => { matches: boolean }; } +// TODO React 17: Remove `useMediaQueryOld` once React 17 support is removed function useMediaQueryOld( query: string, defaultMatches: boolean, @@ -71,8 +72,9 @@ function useMediaQueryOld( return match; } -// eslint-disable-next-line no-useless-concat -- Workaround for https://github.com/webpack/webpack/issues/14814 -const maybeReactUseSyncExternalStore: undefined | any = (React as any)['useSyncExternalStore' + '']; +// See https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379 for why +const safeReact = { ...React }; +const maybeReactUseSyncExternalStore: undefined | any = safeReact.useSyncExternalStore; function useMediaQueryNew( query: string, @@ -148,7 +150,6 @@ export default function useMediaQuery( let query = typeof queryInput === 'function' ? queryInput(theme) : queryInput; query = query.replace(/^@media( ?)/m, ''); - // TODO: Drop `useMediaQueryOld` and use `use-sync-external-store` shim in `useMediaQueryNew` once the package is stable const useMediaQueryImplementation = maybeReactUseSyncExternalStore !== undefined ? useMediaQueryNew : useMediaQueryOld; const match = useMediaQueryImplementation( diff --git a/packages/mui-utils/src/useId/useId.test.js b/packages/mui-utils/src/useId/useId.test.js index 7a545ac2d5fac7..3042083d28d921 100644 --- a/packages/mui-utils/src/useId/useId.test.js +++ b/packages/mui-utils/src/useId/useId.test.js @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { createRenderer, screen } from '@mui/internal-test-utils'; -import useId from './useId'; +import useId from '@mui/utils/useId'; describe('useId', () => { const { render, renderToString } = createRenderer(); diff --git a/packages/mui-utils/src/useId/useId.ts b/packages/mui-utils/src/useId/useId.ts index 6f60170a8a72f4..2769752229cb8f 100644 --- a/packages/mui-utils/src/useId/useId.ts +++ b/packages/mui-utils/src/useId/useId.ts @@ -2,6 +2,8 @@ import * as React from 'react'; let globalId = 0; + +// TODO React 17: Remove `useGlobalId` once React 17 support is removed function useGlobalId(idOverride?: string): string | undefined { const [defaultId, setDefaultId] = React.useState(idOverride); const id = idOverride || defaultId; @@ -18,8 +20,10 @@ function useGlobalId(idOverride?: string): string | undefined { return id; } -// downstream bundlers may remove unnecessary concatenation, but won't remove toString call -- Workaround for https://github.com/webpack/webpack/issues/14814 -const maybeReactUseId: undefined | (() => string) = (React as any)['useId'.toString()]; +// See https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379 for why +const safeReact = { ...React }; +const maybeReactUseId: undefined | (() => string) = safeReact.useId; + /** * * @example
@@ -27,10 +31,12 @@ const maybeReactUseId: undefined | (() => string) = (React as any)['useId'.toStr * @returns {string} */ export default function useId(idOverride?: string): string | undefined { + // React.useId() is only available from React 17.0.0. if (maybeReactUseId !== undefined) { const reactId = maybeReactUseId(); return idOverride ?? reactId; } + // TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks -- `React.useId` is invariant at runtime. return useGlobalId(idOverride); From 2e1914f11e6774054d5232a15f0f2225b245af0a Mon Sep 17 00:00:00 2001 From: Sean Kelly Date: Mon, 16 Sep 2024 20:37:19 -0700 Subject: [PATCH 06/49] [docs] Fix minor typo (#42899) --- .../UnstyledTextareaIntroduction/css/index.js | 10 +++++----- .../UnstyledTextareaIntroduction/css/index.tsx | 10 +++++----- .../UnstyledTextareaIntroduction/css/index.tsx.preview | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/data/base/components/textarea-autosize/UnstyledTextareaIntroduction/css/index.js b/docs/data/base/components/textarea-autosize/UnstyledTextareaIntroduction/css/index.js index 1759a7e92e5d75..336d5ec5d544ff 100644 --- a/docs/data/base/components/textarea-autosize/UnstyledTextareaIntroduction/css/index.js +++ b/docs/data/base/components/textarea-autosize/UnstyledTextareaIntroduction/css/index.js @@ -6,7 +6,7 @@ export default function UnstyledTextareaIntroduction() { return ( @@ -52,7 +52,7 @@ function Styles() { return (