Skip to content

[number field] Fix formatter locale cache#4999

Merged
atomiks merged 3 commits into
mui:masterfrom
atomiks:codex/fix-number-format-locale-cache
Jun 11, 2026
Merged

[number field] Fix formatter locale cache#4999
atomiks merged 3 commits into
mui:masterfrom
atomiks:codex/fix-number-format-locale-cache

Conversation

@atomiks

@atomiks atomiks commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Intl.Locale objects could reuse the wrong cached number formatter when two locales used the same formatting options.

Root cause

Intl.Locale instances serialize to {} with JSON.stringify, so the locale part of the formatter cache key was lost.

Changes

  • Stringify locale inputs before building the formatter cache key.
  • Add regression coverage for different Intl.Locale objects with the same options.

@atomiks atomiks added component: number field Changes related to the number field component. i18n Internationalization. The infrastructure used by localization. type: bug It doesn't behave as expected. labels Jun 10, 2026 — with ChatGPT Codex Connector
@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown

commit: 90439b6

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 10, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+4B(0.00%) 🔺+2B(0.00%)

Details of bundle changes

Performance

Total duration: 1,078.42 ms ▼-407.79 ms(-27.4%) | Renders: 50 (+0) | Paint: 1,638.75 ms ▼-598.87 ms(-26.8%)

Test Duration Renders
Tabs mount (200 instances) 208.55 ms ▼-64.12 ms(-23.5%) 4 (+0)
Menu mount (300 instances) 120.80 ms ▼-54.89 ms(-31.2%) 2 (+0)
Select mount (200 instances) 135.55 ms ▼-42.62 ms(-23.9%) 3 (+0)
Slider mount (300 instances) 140.16 ms ▼-39.65 ms(-22.1%) 3 (+0)
Scroll Area mount (300 instances) 83.80 ms ▼-38.88 ms(-31.7%) 3 (+0)

…and 7 more — details


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Jun 10, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 90439b6
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a2a1fcedac43d0008e848db
😎 Deploy Preview https://deploy-preview-4999--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks atomiks marked this pull request as ready for review June 10, 2026 08:08

atomiks commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Code Review (GPT-5.5)

Approve ✅ The formatter cache key now preserves Intl.Locale inputs correctly, and the regression is verified against the previous behavior.

1. Bugs / Issues (None)

I didn’t find any blocking or non-blocking issues in the full branch diff against freshly fetched upstream/master.

2. Root Cause & Patch Assessment

The fix targets the actual collision: JSON.stringify({ locale }) turns distinct Intl.Locale objects into {}, so same-option requests for different locales could share one cached formatter. Converting the locale input to String(locale) before building the JSON cache key keeps strings, Intl.Locale objects, and locale arrays distinguishable enough for the formatter cache.

3. Test Coverage Assessment

The new regression test covers the reported Intl.Locale object case. I also verified the old behavior on upstream/master with a direct repro: fr-FR and en-US reused the same formatter and both resolved to fr-FR. On the PR branch, the same repro returned separate formatters with fr-FR and en-US.

Validation run:

pnpm test:jsdom formatNumber --no-watch
pnpm test:chromium formatNumber --no-watch
git diff --check upstream/master...HEAD

All passed, and GitHub checks for the PR head are green.

@atomiks atomiks force-pushed the codex/fix-number-format-locale-cache branch from d974bb4 to f369783 Compare June 11, 2026 02:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an Intl.NumberFormat cache-key bug where Intl.Locale inputs were serialized as {} by JSON.stringify, causing formatter reuse across different locales when options matched.

Changes:

  • Introduced a stringifyLocale() utility to normalize Intl.LocalesArgument into a stable string for cache keys.
  • Updated getFormatter() to use the stringified locale when building the formatter cache key.
  • Added regression tests covering distinct Intl.Locale objects for both number formatting and collator-based filtering caches.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/react/src/utils/stringifyLocale.ts Adds a locale stringifier helper for stable cache keys.
packages/react/src/utils/stringifyLocale.test.ts Adds unit coverage for stringifyLocale() across supported locale argument shapes.
packages/react/src/utils/formatNumber.ts Fixes number formatter cache-key generation by stringifying locale inputs.
packages/react/src/utils/formatNumber.test.ts Adds regression coverage ensuring different Intl.Locale objects don’t share cached number formatters.
packages/react/src/internals/filter.ts Reuses the shared stringifyLocale() helper instead of duplicating logic.
packages/react/src/internals/filter.test.ts Adds regression coverage ensuring different Intl.Locale objects don’t share cached filters.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@atomiks atomiks merged commit f937ba7 into mui:master Jun 11, 2026
23 checks passed
@atomiks atomiks deleted the codex/fix-number-format-locale-cache branch June 11, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: number field Changes related to the number field component. i18n Internationalization. The infrastructure used by localization. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants