Skip to content

Chakra UI 3 (lemon/react-js, portfolio); bmi's tests on Vitest (closes Dependabot alert #1) - #13

Merged
nklip merged 1 commit into
mainfrom
claude/focused-johnson-7n6j3f
Nov 2, 2026
Merged

nklip merged 1 commit into
mainfrom
claude/focused-johnson-7n6j3f

Conversation

@nklip

@nklip nklip commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

One commit with two changes: Chakra UI 3 in lemon/react-js and portfolio, and bmi's tests moved from Jest to Vitest, which closes Dependabot alert #1.

Chakra UI 3

Chakra 3.37 replaces 2.10 in both apps. lemon's date picker moves from chakra-dayzed-datepicker 0.2 to 3, the release built for Chakra 3. The changes follow Chakra's migration guide by hand. The codemod was not run.

Before migrating, I bumped both apps to 2.10.10, the last 2.x release. That was a safe step: lemon rendered pixel-identical. The 2.10 build is the baseline for every comparison below.

Chakra 2 Chakra 3
<ChakraProvider theme={…}> <ChakraProvider value={system}>: lemon builds one in src/lib/theme.js, portfolio uses defaultSystem
colorScheme colorPalette. lemon's palette defines the semantic tokens a custom palette needs
FormControl / FormLabel / FormErrorMessage Field.Root / Field.Label / Field.ErrorText
Select NativeSelect
AlertDialog Dialog with role="alertdialog"
Avatar Avatar.Root / Fallback / Image, now 2xl, the largest size
spacing, isLoading gap, loading
Heading sizes renumbered to the v3 size that matches what each heading rendered at before

@emotion/styled and framer-motion are no longer needed. dayzed and its React override in lemon go with the old picker. The react group in .github/dependabot.yml drops framer-motion.

What looks different

  • lemon shows its own design. Chakra 3 puts its styles in CSS cascade layers, so App.css now applies. Chakra 2's global styles used to override it. The page gets:

    • the #edefee background, green on narrow screens;
    • Markazi Text;
    • the 3rem h1.

    index.html loads Markazi Text and Open Sans as the vanilla-js site does. The theme returns <html> to transparent, as Chakra 2 left it, so the background reaches the edges of the window.

  • portfolio's avatar is a real 2xl avatar. The old size="3xl" never existed, so it rendered as a tiny fallback box.

  • Chakra 3 component defaults:

    • Form labels are 14px rather than 16px.
    • portfolio's purple button is a slightly different shade.

Behaviour kept on purpose

  • Alert dialogs close on a click outside. Chakra 3 keeps an alert dialog open on an outside click. These have no button, so on a touch screen, which has no Escape key, they could never be dismissed. closeOnInteractOutside restores the 2.x behaviour.
  • The date picker opens from a click anywhere in the field. Version 3's input variant opens only from a small icon, so the default button trigger stays, styled like the inputs around it.

Tests

  • Chakra 3 needs a ChakraProvider, so src/tests/test-utils.jsx wraps the component under test in one.
  • chakra-dayzed-datepicker has no exports map, so vitest loaded its CommonJS build. That build brings a second copy of Chakra, whose context the provider never reaches. A test-only alias in vite.config.js points vitest at the picker's ES module build, the one the app build already uses.

bmi: Jest to Vitest

The alert is deepmerge 4.3.1, which arrives through jest-config (GHSA-gcqx-w48m-w2h4, low). It can't be fixed while bmi stays on Jest:

  • No fixed deepmerge release. The advisory covers 4.2.0 through 4.3.1, and 4.3.1 is the newest release.
  • No Jest release without it. Every Jest release since 25.2 depends on deepmerge.
  • Downgrading would be a fake fix. deepmerge 4.1.1 falls outside the advisory's range, which would silence the alert. But a {"__proto__": …} source poisons the object 4.1.1 returns, which 4.2.0 began to block, so it is less safe, not more.

What changed:

  • bmi now tests with Vitest 5, which lemon, portfolio and weather already use and which has no deepmerge.
  • The lockfile falls from 288 entries to 60.
  • The glob and minimatch overrides that Jest needed are gone.
  • --globals keeps bare test() and expect(), so bmi.test.js is unchanged.
  • The page itself is untouched apart from a comment in bmi.js, and still runs unbuilt.
  • bmi/README.md, the root README.md and CLAUDE.md now name Vitest.

Verification

Checked in Chromium against the 2.10 build:

  • Form validation: 34 cases across both forms produce identical errors.
  • Date picker: opens, moves a month ahead and sets the same date.
  • Alert dialogs, success and error in both apps:
    • same text and colour;
    • Escape and an outside click both close them;
    • focus now moves into the dialog.
  • Navigation: lemon's router links reach the same routes.
  • Console: no new errors.

bmi:

  • The same 14 tests pass under Vitest as under Jest.
  • A bug planted in bmi.js turns one test red and makes npm test exit 1.

Advisories: I matched every lockfile against the GitHub-reviewed advisory database as of today. It finds the one deepmerge alert before this change and none after.

On Node 22 with npm 10 and on Node 26 with npm 11, all of these pass:

  • npm ci;
  • tests;
  • builds;
  • npm audit, with 0 findings in every project.

Bundles shrink: lemon goes from 243.5 to 219.4 kB gzip, and portfolio from 233 to 206.3 kB.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PJbZcrXFYA1x2ppHdCG5uT

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 <html> 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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJbZcrXFYA1x2ppHdCG5uT
@nklip
nklip force-pushed the claude/focused-johnson-7n6j3f branch from afbd828 to 2c7c007 Compare November 2, 2026 09:50
@nklip nklip changed the title Chakra UI: 2.10.10, then 3 (lemon/react-js, portfolio) Chakra UI 3 (lemon/react-js, portfolio); bmi's tests on Vitest (closes Dependabot alert #1) Nov 2, 2026
@nklip
nklip merged commit 9decd03 into main Nov 2, 2026
6 checks passed
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.

2 participants