fix(dashboard): Support localized decimal separator in tax rate input
Summary
Fixes an issue in the Admin UI where tax rates could not be entered as decimal values when using certain locales (e.g. German).
What was the problem?
In the new Admin UI, the tax rate field only accepted values entered with a dot (.) as the decimal separator via an <input type="number">. This caused the following issues:
- With German UI language:
- Entering
5.5resulted in: “Please enter a valid value” (not localized). - Entering
5,5resulted in: “Expected number, received nan” (also not localized).
- Entering
- As a result, it was impossible to save a tax rate with a decimal value.
What has been changed?
-
PercentageSuffixInputComponent
- Changed the internal input type from
numbertotextto allow localized characters (e.g. comma). - Added automatic detection of the current locale’s decimal separator using
Intl.NumberFormat. - Implemented parsing & formatting logic:
- User input is parsed using the locale-specific decimal separator.
- The internal form control value is always stored as a proper
number. - On blur / initialization the value is formatted back using the current locale.
- Changed the internal input type from
-
Tax rate detail form
- Replaced the raw
<input type="number">field with the enhanced<vdr-percentage-suffix-input>component for the tax rate (value) field.
- Replaced the raw
Expected behaviour after this change
- With English locale:
5.5is accepted and saved as a decimal tax rate.
- With German locale:
5,5is accepted and saved as the same decimal tax rate.
- No validation errors such as “Please enter a valid value” or “Expected number, received nan” should occur for valid localized decimal inputs.
- Error messages remain properly localizable via the existing i18n system.
Testing
- Set the Admin UI language to German.
- Navigate to
Settings → Tax Rates. - Create or edit a tax rate.
- Try entering:
5.5and5,5as the rate.
- Confirm that:
- The form allows saving the tax rate.
- The stored value is correct.
- No erroneous validation messages are shown.
Summary by CodeRabbit
-
Bug Fixes
- Fixes issues with tax rate entry—prevents invalid values/NaN and keeps displayed value synchronized with saved data on edit and blur.
-
Improvements
- Locale-aware numeric input: supports local decimal separators during typing and parsing.
- Supports configurable prefix/suffix (e.g., “%”) and preserves step/min/max behavior for smoother, predictable rate entry.
✏️ Tip: You can customize this high-level summary in your review settings.
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Review | Updated (UTC) |
|---|---|---|---|
| docs | Preview | Dec 16, 2025 2:52pm | |
| vendure-storybook | Preview, Comment | Dec 16, 2025 2:52pm |
All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.
Walkthrough
Replaces the tax rate numeric input with a locale-aware NumberInput component and updates the NumberInput implementation to use a display-aware text input that formats/parses decimal separators, supports prefix/suffix, and emits numeric values via onChange.
Changes
| Cohort / File(s) | Summary |
|---|---|
Route — tax rate input swap packages/dashboard/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx |
Replaces prior AffixedInput numeric rate field with the new NumberInput; removes explicit type/min/onChange handlers and uses field prop spreading plus step={0.01} and suffix="%". |
Locale-aware numeric input implementation packages/dashboard/src/lib/components/data-input/number-input.tsx |
Adds locale-aware NumberInput: maintains displayValue and numeric value, handles locale decimal separators (accepts '.' and ',' during typing), formats display on blur, exposes prefix/suffix props (and overridePrefix/overrideSuffix in signature), preserves min/max/step, and refactors input props/unified change handling. Introduces helpers formatDisplayValue and escapeRegExp. |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
- Review locale parsing/formatting edge cases and decimal-separator handling.
- Verify onChange emits numeric values and avoid NaN writes.
- Check prefix/suffix override behavior and integration with AffixedInput path.
- Confirm min/max/step enforcement and blur synchronization logic.
Possibly related issues
- vendure-ecommerce/vendure#4014 — Addresses locale-aware decimal parsing/formatting and tax-rate input localization described in the issue.
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title accurately summarizes the main change: adding support for localized decimal separators in the tax rate input field. |
| Description check | ✅ Passed | The description provides a comprehensive summary of the problem, changes, expected behavior, and testing steps, covering all essential information required by the template. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
I have read the CLA Document and I hereby sign the CLA
@michaelbromley .Thanks for the review! I’ve addressed both concerns:
- Removed the Chinese comments; everything is now in English.
2.Implemented localized decimal handling in the shared
NumberInput(text input with locale-aware./,parsing), so any page usingNumberInputbenefits without per-page special code. The tax rate detail view now just usesNumberInputwith a%suffix.
@starry-osean thanks for quickly responding to the feedback! @gabriellbui from our team will be reviewing and testing this in the coming week 👍
Quality Gate passed
Issues
3 New issues
0 Accepted issues
Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code
Hi @starry-osean! Thanks for the PR! I tested it locally and it fixes the original issue.
While reviewing it, I ran into a few concerns around the implementation of the number input (higher cognitive load, allowing arbitrary characters, etc ...). I’ve opened a separate PR to address those points with a simpler approach. I’d prefer to move forward with that solution instead.
Still great job on this and thanks again for the effort!