From 2c7c0072bf565eaf352158436d0349a1d4e51c66 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 09:50:27 +0000 Subject: [PATCH] migrate to Chakra UI 3, and move bmi's tests to Vitest Chakra UI 3.37 replaces 2.10 in lemon/react-js and portfolio, and lemon's date picker moves from chakra-dayzed-datepicker 0.2 to 3, the release built for Chakra 3. The codemod was not used; each change follows Chakra's migration guide by hand. API changes, in both apps unless named: - ChakraProvider takes a system: lemon builds one in src/lib/theme.js with createSystem, portfolio passes defaultSystem. - colorScheme becomes colorPalette. A custom palette needs its semantic tokens (solid, contrast, fg, muted, subtle, emphasized, focusRing), so lemon's theme defines them, all pointing at the one lemon shade. - FormControl, FormLabel and FormErrorMessage become Field.Root, Field.Label and Field.ErrorText; isInvalid becomes invalid. - Select becomes NativeSelect. Its arrow takes color="inherit", which keeps it visible on portfolio's purple section. - AlertDialog becomes Dialog with role="alertdialog". Chakra 3 keeps an alert dialog open on a click outside it. These dialogs have no button, so closeOnInteractOutside restores Chakra 2's behaviour; without it a touch screen could not dismiss them. - Avatar becomes Avatar.Root, Avatar.Fallback and Avatar.Image. The old size="3xl" never existed, so the avatar always rendered as a tiny fallback; it is now 2xl, the largest size. - spacing becomes gap, and isLoading becomes loading. - Heading sizes were renumbered. Each heading takes the v3 size matching what it rendered at before. - @emotion/styled and framer-motion are no longer needed, and Dependabot's react group drops framer-motion. dayzed and its React override go with the old date picker. lemon now shows its own design. Chakra 3 puts its styles in CSS cascade layers, so App.css, which Chakra 2's global styles had overridden, now applies: the #edefee background (green on narrow screens), Markazi Text, and the larger h1. index.html loads Markazi Text and Open Sans as the vanilla-js site does. The theme returns to transparent, as Chakra 2 left it, so the body background reaches the edges of the window. The date picker's trigger is a button styled like the inputs around it. Version 3's "input" variant opens the calendar only from a small icon, where the old picker opened on a click anywhere in the field. Tests: Chakra 3 needs a ChakraProvider, so src/tests/test-utils.jsx wraps the rendered component in one. chakra-dayzed-datepicker has no exports map, so vitest loaded its CommonJS build, which brings a second copy of Chakra whose context the provider does not reach. A test-only alias points vitest at the picker's ES module build, the one the app build already uses. Checked in Chromium against the 2.10 build: - form validation: 34 cases, identical errors - date picker: opens, moves a month, sets the same date - alert dialogs: same text and colour; Escape and an outside click close both outcomes in both apps. Focus now moves into the dialog. - navigation and console errors: unchanged Bundles shrink: lemon 243.5 -> 219.4 kB gzip, portfolio 233 -> 206.3 kB. bmi: Jest to Vitest, closing Dependabot alert #1. Every Jest release since 25.2 depends on deepmerge, and GHSA-gcqx-w48m-w2h4 covers deepmerge 4.2.0 through 4.3.1, the newest release; nothing fixes it. 4.1.1 lies outside that range but was not taken: its returned object takes a prototype from a {"__proto__": ...} source, which 4.2.0 began to block. Vitest 5, which lemon, portfolio and weather already use, has no deepmerge, and bmi's lockfile falls from 288 entries to 60. The glob and minimatch overrides Jest needed go with it. "--globals" keeps bare test() and expect(), so bmi.test.js is unchanged, and the same 14 tests pass; a bug planted in bmi.js turns one red and fails npm test. Matching every lockfile against the GitHub-reviewed advisory database finds that one alert before this change and none after. npm ci, tests, builds and npm audit (0 findings in every project) pass on Node 22 with npm 10 and on Node 26 with npm 11. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PJbZcrXFYA1x2ppHdCG5uT --- .github/dependabot.yml | 6 +- CLAUDE.md | 3 +- README.md | 2 +- bmi/README.md | 31 +- bmi/js/bmi.js | 2 +- bmi/package-lock.json | 4528 +++-------------- bmi/package.json | 15 +- lemon/react-js/README.md | 104 +- lemon/react-js/index.html | 6 + lemon/react-js/package-lock.json | 3722 +++++++------- lemon/react-js/package.json | 12 +- lemon/react-js/src/App.jsx | 13 +- lemon/react-js/src/components/About.jsx | 2 +- lemon/react-js/src/components/Alert.jsx | 43 +- lemon/react-js/src/components/Booking.jsx | 109 +- lemon/react-js/src/lib/theme.js | 35 + lemon/react-js/src/tests/Booking.test.jsx | 3 +- lemon/react-js/src/tests/test-utils.jsx | 13 + lemon/react-js/vite.config.js | 15 + portfolio/README.md | 19 +- portfolio/package-lock.json | 3812 +++++++------- portfolio/package.json | 4 +- portfolio/src/App.jsx | 4 +- portfolio/src/components/Alert.jsx | 43 +- portfolio/src/components/Card.jsx | 2 +- portfolio/src/components/ContactMeSection.jsx | 81 +- portfolio/src/components/Header.jsx | 2 +- portfolio/src/components/LandingSection.jsx | 13 +- portfolio/src/components/ProjectsSection.jsx | 4 +- 29 files changed, 4541 insertions(+), 8107 deletions(-) create mode 100644 lemon/react-js/src/lib/theme.js create mode 100644 lemon/react-js/src/tests/test-utils.jsx diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f1b091c..41ece4c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -21,9 +21,9 @@ updates: # one package that its peers reject. Dependabot puts a dependency in the # first group it matches, so these sit above `routine`. react: - # framer-motion 7 accepts only React 18, and @testing-library/react - # 13 only react-dom 18: neither can stay behind on React 19. - patterns: ["react", "react-dom", "@testing-library/react", "framer-motion"] + # @testing-library/react 13 accepts only react-dom 18, so it cannot + # stay behind on React 19. + patterns: ["react", "react-dom", "@testing-library/react"] fontawesome: # react-fontawesome 0.2 accepts fontawesome-svg-core up to 6, and the # icon packages track svg-core's major. diff --git a/CLAUDE.md b/CLAUDE.md index 0521454..fbfa322 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,7 +33,8 @@ point of this family — it rules out ES module `import` between files, `fetch() JSON, and anything else that needs an origin. Scripts communicate through globals on `window`, which is a deliberate trade, not an oversight. -`bmi/` has a `package.json`, but only for Jest. The page itself still runs unbuilt. +`bmi/` has a `package.json`, but only for its Vitest tests. Vite runs the tests; the page +itself still runs unbuilt. ### 2. Bundled apps (Vite) diff --git a/README.md b/README.md index 1ef9f96..dcc53ab 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Minor JavaScript and React applications ## Content -* [BMI](/bmi/README.md) - Body mass index calculator webpage + jest +* [BMI](/bmi/README.md) - Body mass index calculator webpage + vitest * [lemon](/lemon/README.md) - project for Meta-Front End Developer Professional Certificate * [mathparser](/mathparser/README.md) - a simple math calculator for complex expressions * [portfolio](/portfolio/README.md) - a React application diff --git a/bmi/README.md b/bmi/README.md index 9ce49f3..62fd0d1 100644 --- a/bmi/README.md +++ b/bmi/README.md @@ -58,27 +58,20 @@ The "?" button, next to the theme toggle, explains the units for each mode and h To run tests -> execute next command line: npm run test +The tests run on [Vitest](https://vitest.dev/). `--globals` in the `test` script provides +`test` and `expect` without an import, as Jest did, so `bmi.test.js` reads the same under +either. Vite is used only to run the tests; the page itself is never built. + +bmi tested with Jest until +[GHSA-gcqx-w48m-w2h4](https://github.com/advisories/GHSA-gcqx-w48m-w2h4) was published against +deepmerge, which every Jest release since 25.2 depends on and no deepmerge release fixes. +Vitest does not use deepmerge, and it is what `lemon/react-js`, `portfolio` and `weather` +already test with. + ## Notes [Back to top](#bmi) -* bmi.js is a js file with simple js functions, used both by the Jest tests and directly by index.html as a plain `