Skip to content

Upgrade to React 19, MUI 9, and @material-table/core 8 - #335

Draft
rthaut wants to merge 2 commits into
react-18-router-7from
react-19-material-table-8
Draft

rthaut wants to merge 2 commits into
react-18-router-7from
react-19-material-table-8

Conversation

@rthaut

@rthaut rthaut commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #334, so review and merge that first. GitHub will retarget this PR to master once #334 merges.

Clears the uuid Dependabot alert (#121). uuid 9 comes from @material-table/core 6.x. Version 8 moves to uuid 14, but it needs React 19 and depends on @mui/material ^9.2.0. The UI stack has to move with it so the app doesn't end up with two copies of MUI.

Dependency changes

  • react / react-dom 18.3.1 -> 19.3.0
  • @mui/material and @mui/icons-material 5.18.0 -> 9.5.0
  • @material-table/core 6.2 -> 8.0 (8.0.3, uuid 14.0.3)
  • notistack 2.0.8 -> 3.0.2. Supersedes Bump notistack from 2.0.8 to 3.0.2 #282.
  • react-dropzone 14.2.3 -> 20.1.3. Supersedes Bump react-dropzone from 14.2.3 to 16.0.0 #280, which went to 16.
  • material-ui-confirm 3.0.9 -> 3.0.18. 3.0.9 doesn't allow React 19, and 3.0.18 has the same API, so I didn't take 4.0.
  • @mui/lab removed. The app only used Alert/AlertTitle from it, and those have been in @mui/material since v5.

Together with #334, this also covers #329 (react-dom 18). I didn't fold in #328 (the eslint/globals/vite minor group). It's dev tooling only, isn't needed for these alerts, and can merge on its own.

After this PR, npm audit --omit=dev reports 0 vulnerabilities.

Code changes

These keep the UI the same under the new APIs:

  • Grid (MUI 7+ replaced the old Grid): item xs={12} md={6} becomes size={{ xs: 12, md: 6 }} in the dashboard, filter views, and the unused ImportExportView.
  • Layout props: MUI 9 removed system props, so justifyContent/alignItems on Grid and Stack, and color on Box, move into sx. The development build logged unknown-prop warnings until this change.
  • The loading spinner in the create-filters dialog uses Stack, since MUI 9 removed direction="column" from Grid.
  • Typography: MUI 9 removed paragraph, so the footer uses component="p" with sx={{ marginBottom: 2 }}. That gives the same <p> and 16px margin.
  • Icons: MUI 9 removed the DeleteOutline icon, so it's now DeleteOutlined (same glyph).
  • ListItemIcon: MUI 9 changed its default min-width from 56px to 36px. The theme sets it back to 56px so the collapsed sidebar and the tag checklist keep their layout.
  • Import results: react-dropzone's file-selector now reports picked and dropped files as ./name, where it used to report name. The results table strips that prefix so it still shows the plain file name.

notistack 3 still supports the SnackbarProvider ref that the Dismiss action uses. The material-table props the app uses (icons, editable, actions, components.EditRow, MTableEditRow, MTableEditField) are unchanged in v8.

Checks

  • npm test passes: lint (same 2 existing warnings), unit tests (2/2), Chrome/Edge/Firefox builds, manifest smoke test, zips, and web-ext lint (0 errors).
    • web-ext lint now shows 9 warnings, up from 7. The two new ones are innerHTML assignments in the bundled manage chunk, coming from library code.
  • npm ls reports no invalid peer dependencies. There's one copy each of react, @mui/material, and uuid (14.0.3).
  • Smoke test in Playwright Chromium. It loaded both the production build (.output/chrome-mv3) and a development-mode build, so React and MUI dev warnings would show up. 14/14 checks passed on each:
    • The dashboard renders.
    • Sidebar navigation goes to #/users, #/keywords, and back to #/, and a deep link to #/keywords works.
    • User filters: add, invalid-name rejection with the pattern hint, and delete all work, and each step is checked against storage.local.
    • Adding a keyword filter works.
    • Importing a JSON file through the dropzone input works, and the results table shows import-smoke.json.
    • Dark mode works.
    • The create-filters dialog renders.
    • No console errors or warnings on either page.
  • Screenshots of the dashboard, import results, and filter tables matched the Upgrade to React 18 and react-router-dom 7 #334 build apart from hover and ripple state.

Risks

  • The minimum browser versions now match MUI 9: Chrome 117, Edge 121 and Firefox 121 (manifests, Vite build targets, browserslist and the manifest smoke test). Users on older browsers stop getting updates once this ships.
  • The manage bundle is larger because material-table 8 brings @mui/x-date-pickers 9 and date-fns 4.

Manual test list

  • Load the Chrome and Firefox builds. Open the management page and click through Dashboard, User Filters, and Keyword Filters with the drawer both collapsed and expanded. Check that the icon spacing matches the current release.
  • Add, edit, and delete user and keyword filters, including the wildcard checkbox and the "Yes/No" chip. Check that validation hints appear under the field.
  • Use "delete all" and check that the confirmation dialog, the error snackbar on a duplicate filter, and the snackbar's Dismiss button all work.
  • Use search and pagination on a large list. test-data/random_users1.json works for this.
  • Drag a JSON file onto the import box, then drag a non-JSON file. While dragging the non-JSON file, the error message should show and the border should turn red. Also export the filters.
  • On deviantart.com, use "create filters from deviation" from the context menu. Check the loading spinner, the user/tag selection, and the results screen.
  • Toggle dark mode and change each option on the dashboard.

@material-table/core 8 drops uuid 9 for uuid 14 but needs React 19 and
MUI 9, so those move with it. notistack, react-dropzone, and
material-ui-confirm move to versions that support React 19, and
@mui/lab is dropped since Alert is in @mui/material.

Code changes for MUI 9:
- Grid uses the size prop instead of item/xs/md/lg
- Layout props on Grid, Stack, and Box move into sx
- Typography paragraph becomes component="p" with a bottom margin
- DeleteOutline is now DeleteOutlined
- ListItemIcon keeps its old 56px minimum width through the theme

react-dropzone now reports picked files as "./name", so the import
results table strips that prefix to keep showing the plain file name.
MUI 9 supports Chrome 117, Edge 121 and Firefox 121 and later, so the
manifests, build targets and browserslist now use those versions.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant