build(deps): upgrade MUI to v9 (material + icons) and group @mui/* in Dependabot (#168)

Bump @mui/material and @mui/icons-material 7.3.1 -> ^9.1.1 together in
/web. They must move in lockstep (icons peer-depends on material), so
Dependabot's separate per-package PRs (#145/#146) could never go green
individually (ERESOLVE). Adds a 'mui' Dependabot group so future @mui/*
updates — including majors — are raised as one PR.

MUI v9 migration fixes (v7->v9 spans two majors):
- ListItemText: primaryTypographyProps -> slotProps.primary; fontSize
  moved into sx (Typography system props removed in v9).
- Autocomplete renderInput: params.InputProps -> params.slotProps.input;
  spread ...params.slotProps to retain inputLabel/htmlInput slots.
- Icons: @mui/icons-material/ErrorOutline -> ErrorOutlined (the plain
  ErrorOutline export was removed in v9).
- vitest: inline @mui/material + react-transition-group so Vite resolves
  v9's Transition.mjs directory import (native ESM loader can't).

Verified locally on Node 24: npm ci, npm run build, and npm test
(26 tests, 3 suites) all pass.
This commit is contained in:
Adam Moussa 2026-06-22 16:02:43 -04:00 • committed by GitHub
parent 433198c4e8
commit 36fc1120bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 81 additions and 61 deletions

View file

@ -19,6 +19,16 @@ updates:
interval: weekly interval: weekly
open-pull-requests-limit: 10 open-pull-requests-limit: 10
groups: groups:
# @mui/material and @mui/icons-material must move in lockstep (icons
# peer-depends on material), so group them — including majors — into a
# single PR. Listed before `web` so MUI deps land here, not there.
mui:
patterns:
- "@mui/*"
update-types:
- "major"
- "minor"
- "patch"
web: web:
patterns: patterns:
- "*" - "*"

100
web/package-lock.json generated
View file

@ -10,8 +10,8 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0", "@emotion/styled": "^11.14.0",
"@mui/icons-material": "^7.3.1", "@mui/icons-material": "^9.1.1",
"@mui/material": "^7.3.1", "@mui/material": "^9.1.1",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.11.2",
"@tanstack/react-query": "^5.101.0", "@tanstack/react-query": "^5.101.0",
"axios": "^1.18.0", "axios": "^1.18.0",
@ -1186,9 +1186,9 @@
} }
}, },
"node_modules/@mui/core-downloads-tracker": { "node_modules/@mui/core-downloads-tracker": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-9.1.1.tgz",
"integrity": "sha512-a7I/b/nBTdXYz2cOSlEmkQ9WWE1x8FHpqMhFPp+Y1VPFxcOw91G5ELOHARQAGSPy5V+UCgJua6K/1x70bAtQPw==", "integrity": "sha512-AupmMICbdJHqAh6FfOMaaiiIr7dfEgZJn5DFfiPuGNrbs+ZZy9cD1APwO0TSVBz5j08MJEEY6n7iC76/2wjMEA==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
@ -1196,12 +1196,12 @@
} }
}, },
"node_modules/@mui/icons-material": { "node_modules/@mui/icons-material": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-9.1.1.tgz",
"integrity": "sha512-+hz5ilwHZ3djd5es3sCErLioqe/NhZcYTsV/TNXZAMdJdb23F4xzJjqnnZdnurc3S1+ietcssRNqieOhPQLZ7Q==", "integrity": "sha512-OXhm9DajemStb58AumM06DuPhHTa3XD36TFD4yf6WtJyNRO5DfEZbbnHlBg/US2Y2oOXwM/XurMTBOD6L/YYZw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6" "@babel/runtime": "^7.29.2"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@ -1211,7 +1211,7 @@
"url": "https://opencollective.com/mui-org" "url": "https://opencollective.com/mui-org"
}, },
"peerDependencies": { "peerDependencies": {
"@mui/material": "^7.3.11", "@mui/material": "^9.1.1",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
}, },
@ -1222,22 +1222,22 @@
} }
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-9.1.1.tgz",
"integrity": "sha512-yq8bPc3LxOwKRWpcjRgDkYFmpM6aKlARfESTmOQcvLYFeJwtHte2tw6hJDrb8sk8wcvpDprHEHVaoUU0MslIkw==", "integrity": "sha512-Wv+gInjrpf99l1Q0oHe0eOWGTnlbkzs5nowClX65KCT/2fyPMwcbFEEkUsOHdpcHhB5UAbz/d7jlwt5ajWVvlA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"@mui/core-downloads-tracker": "^7.3.11", "@mui/core-downloads-tracker": "^9.1.1",
"@mui/system": "^7.3.11", "@mui/system": "^9.1.1",
"@mui/types": "^7.4.12", "@mui/types": "^9.1.1",
"@mui/utils": "^7.3.11", "@mui/utils": "^9.1.1",
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"@types/react-transition-group": "^4.4.12", "@types/react-transition-group": "^4.4.12",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"csstype": "^3.2.3", "csstype": "^3.2.3",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react-is": "^19.2.3", "react-is": "^19.2.6",
"react-transition-group": "^4.4.5" "react-transition-group": "^4.4.5"
}, },
"engines": { "engines": {
@ -1250,7 +1250,7 @@
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.5.0", "@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0", "@emotion/styled": "^11.3.0",
"@mui/material-pigment-css": "^7.3.11", "@mui/material-pigment-css": "^9.1.1",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@ -1271,13 +1271,13 @@
} }
}, },
"node_modules/@mui/private-theming": { "node_modules/@mui/private-theming": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-9.1.1.tgz",
"integrity": "sha512-9B+YKms0fRHbNrqp9tOT/DNbNnU5gyvJ1o3qAGXfq8GmZcbJnE3At9x07Zr/o0pkhzg4aDdwXVqe4+AcgtOCPA==", "integrity": "sha512-oH6c+d6sJ1CZT0Vg2/fHdUQ5zvo9Pn+f+WWk0tlQliHqqIRdN32DZ7UxjalW3LUj4OkHbdWR31biWuLxK9i7Cg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"@mui/utils": "^7.3.11", "@mui/utils": "^9.1.1",
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
}, },
"engines": { "engines": {
@ -1298,12 +1298,12 @@
} }
}, },
"node_modules/@mui/styled-engine": { "node_modules/@mui/styled-engine": {
"version": "7.3.10", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.10.tgz", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-9.1.1.tgz",
"integrity": "sha512-WxE9SiF8xskAQqGjsp0poXCkCqsoXFEsSr0HBXfApmGHR+DBnXRp+z46Vsltg4gpPM4Z96DeAQRpeAOnhNg7Ng==", "integrity": "sha512-neaYKdJfvEG54q8efHLJR7swpHG/gfSv9xGqW5iTSMsubD7yPCPFrhVBt284j1DOF3uZaaDJSHQL7gz6jGF21Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"@emotion/cache": "^11.14.0", "@emotion/cache": "^11.14.0",
"@emotion/serialize": "^1.3.3", "@emotion/serialize": "^1.3.3",
"@emotion/sheet": "^1.4.0", "@emotion/sheet": "^1.4.0",
@ -1332,16 +1332,16 @@
} }
}, },
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/system/-/system-9.1.1.tgz",
"integrity": "sha512-7izwGWdNawAKpBKcRlx7f2gFnAAjmASBWvMcyX4YYEeLOFsbfGRbUYGInvnAcUeql3rPxI7F9Ft4oY2OLRz44g==", "integrity": "sha512-q+aqNa58QZUwmmyUvJKKrStrej+4BcWFw4M0Ug+zRylPIQgR64cqvBnE3QTfLZm4OXulydp8Hl3zwKxMayrdsA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"@mui/private-theming": "^7.3.11", "@mui/private-theming": "^9.1.1",
"@mui/styled-engine": "^7.3.10", "@mui/styled-engine": "^9.1.1",
"@mui/types": "^7.4.12", "@mui/types": "^9.1.1",
"@mui/utils": "^7.3.11", "@mui/utils": "^9.1.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"csstype": "^3.2.3", "csstype": "^3.2.3",
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
@ -1372,12 +1372,12 @@
} }
}, },
"node_modules/@mui/types": { "node_modules/@mui/types": {
"version": "7.4.12", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.12.tgz", "resolved": "https://registry.npmjs.org/@mui/types/-/types-9.1.1.tgz",
"integrity": "sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w==", "integrity": "sha512-Zjt7u8wNvDg40rPTGoL+TnfkpuSKjwubsNSFRH1KAVZLcaV4I3AFNHIFbvH7p4F3alEibSbdd90xAgn5Rnfndg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6" "@babel/runtime": "^7.29.2"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
@ -1389,17 +1389,17 @@
} }
}, },
"node_modules/@mui/utils": { "node_modules/@mui/utils": {
"version": "7.3.11", "version": "9.1.1",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.11.tgz", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-9.1.1.tgz",
"integrity": "sha512-XTjGnifwteg71/ij+0e7Y7d+hwyntMYP5wPoA/g2drdGH+Flkvjwy0OfrVpKBbaOvofq4zU/LIyUZyKgmWu18g==", "integrity": "sha512-qSNfnkzZMptaaWFFklpDf4NPJztgwsMDVfM/sSDt+wq4ssYSBhLYwwjuB6eS/+p2IUYbeRzHluzXbw0Zn7aI4A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.29.2",
"@mui/types": "^7.4.12", "@mui/types": "^9.1.1",
"@types/prop-types": "^15.7.15", "@types/prop-types": "^15.7.15",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react-is": "^19.2.3" "react-is": "^19.2.6"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@ -3471,9 +3471,9 @@
} }
}, },
"node_modules/react-is": { "node_modules/react-is": {
"version": "19.2.6", "version": "19.2.7",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz",
"integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-redux": { "node_modules/react-redux": {

View file

@ -13,8 +13,8 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0", "@emotion/styled": "^11.14.0",
"@mui/icons-material": "^7.3.1", "@mui/icons-material": "^9.1.1",
"@mui/material": "^7.3.1", "@mui/material": "^9.1.1",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.11.2",
"@tanstack/react-query": "^5.101.0", "@tanstack/react-query": "^5.101.0",
"axios": "^1.18.0", "axios": "^1.18.0",

View file

@ -106,7 +106,7 @@ export default function Sidebar() {
{item.icon} {item.icon}
</ListItemIcon> </ListItemIcon>
{!isCollapsed && ( {!isCollapsed && (
<ListItemText primary={item.label} primaryTypographyProps={{ fontSize: '13px' }} /> <ListItemText primary={item.label} slotProps={{ primary: { sx: { fontSize: '13px' } } }} />
)} )}
</ListItemButton> </ListItemButton>
); );

View file

@ -27,7 +27,7 @@ import {
import SearchIcon from '@mui/icons-material/Search'; import SearchIcon from '@mui/icons-material/Search';
import AddIcon from '@mui/icons-material/Add'; import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { import {
customersApi, customersApi,

View file

@ -34,7 +34,7 @@ import TimerIcon from '@mui/icons-material/Timer';
import DescriptionIcon from '@mui/icons-material/Description'; import DescriptionIcon from '@mui/icons-material/Description';
import WarningAmberIcon from '@mui/icons-material/WarningAmber'; import WarningAmberIcon from '@mui/icons-material/WarningAmber';
import ReportIcon from '@mui/icons-material/Report'; import ReportIcon from '@mui/icons-material/Report';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
import { usePaginatedList } from '../../../hooks/usePaginatedList'; import { usePaginatedList } from '../../../hooks/usePaginatedList';

View file

@ -28,7 +28,7 @@ import {
import AddIcon from '@mui/icons-material/Add'; import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete'; import DeleteIcon from '@mui/icons-material/Delete';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { import {
pricingLibraryApi, pricingLibraryApi,

View file

@ -22,7 +22,7 @@ import DescriptionIcon from '@mui/icons-material/Description';
import HourglassTopIcon from '@mui/icons-material/HourglassTop'; import HourglassTopIcon from '@mui/icons-material/HourglassTop';
import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import SendIcon from '@mui/icons-material/Send'; import SendIcon from '@mui/icons-material/Send';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutlined';
import Tooltip from '@mui/material/Tooltip'; import Tooltip from '@mui/material/Tooltip';
import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals'; import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals';
import { QUERY_KEYS } from '../../constants/queryKeys'; import { QUERY_KEYS } from '../../constants/queryKeys';

View file

@ -267,12 +267,13 @@ export default function ProposalFormPage() {
required required
placeholder="Search or type a customer name..." placeholder="Search or type a customer name..."
slotProps={{ slotProps={{
...params.slotProps,
input: { input: {
...params.InputProps, ...params.slotProps.input,
endAdornment: ( endAdornment: (
<> <>
{customerLoading && <CircularProgress size={20} />} {customerLoading && <CircularProgress size={20} />}
{params.InputProps.endAdornment} {params.slotProps.input.endAdornment}
</> </>
), ),
}, },
@ -417,12 +418,13 @@ export default function ProposalFormPage() {
required required
placeholder="Search by site code..." placeholder="Search by site code..."
slotProps={{ slotProps={{
...params.slotProps,
input: { input: {
...params.InputProps, ...params.slotProps.input,
endAdornment: ( endAdornment: (
<> <>
{siteLoading && <CircularProgress size={20} />} {siteLoading && <CircularProgress size={20} />}
{params.InputProps.endAdornment} {params.slotProps.input.endAdornment}
</> </>
), ),
}, },

View file

@ -8,5 +8,13 @@ export default defineConfig({
globals: true, globals: true,
setupFiles: ['./src/test/setup.ts'], setupFiles: ['./src/test/setup.ts'],
include: ['src/**/*.test.{ts,tsx}'], include: ['src/**/*.test.{ts,tsx}'],
server: {
deps: {
// MUI v9's ESM build (Transition.mjs) does a directory import of
// react-transition-group/TransitionGroupContext, which Node's native
// ESM loader can't resolve. Inline these so Vite resolves them.
inline: [/@mui\/material/, 'react-transition-group'],
},
},
}, },
}); });