vendure icon indicating copy to clipboard operation
vendure copied to clipboard

fix(dashboard): Support localized decimal separator in tax rate input

Open starry-osean opened this issue 1 month ago • 7 comments

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.5 resulted in: “Please enter a valid value” (not localized).
    • Entering 5,5 resulted in: “Expected number, received nan” (also not localized).
  • As a result, it was impossible to save a tax rate with a decimal value.

What has been changed?

  1. PercentageSuffixInputComponent

    • Changed the internal input type from number to text to 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.
  2. 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.

Expected behaviour after this change

  • With English locale:
    • 5.5 is accepted and saved as a decimal tax rate.
  • With German locale:
    • 5,5 is 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.5 and 5,5 as 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.

starry-osean avatar Dec 02 '25 14:12 starry-osean

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview Dec 16, 2025 2:52pm
vendure-storybook Ready Ready Preview, Comment Dec 16, 2025 2:52pm

vercel[bot] avatar Dec 02 '25 14:12 vercel[bot]

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

github-actions[bot] avatar Dec 02 '25 14:12 github-actions[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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Dec 02 '25 14:12 coderabbitai[bot]

I have read the CLA Document and I hereby sign the CLA

starry-osean avatar Dec 03 '25 09:12 starry-osean

@michaelbromley .Thanks for the review! I’ve addressed both concerns:

  1. 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 using NumberInput benefits without per-page special code. The tax rate detail view now just uses NumberInput with a % suffix.

starry-osean avatar Dec 10 '25 09:12 starry-osean

@starry-osean thanks for quickly responding to the feedback! @gabriellbui from our team will be reviewing and testing this in the coming week 👍

michaelbromley avatar Dec 10 '25 09:12 michaelbromley

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!

gabriellbui avatar Dec 17 '25 10:12 gabriellbui