feat(frontend): complete locale-safe currency and amount formatting - #288
Open
Johnpii1 wants to merge 2 commits into
Open
feat(frontend): complete locale-safe currency and amount formatting#288Johnpii1 wants to merge 2 commits into
Johnpii1 wants to merge 2 commits into
Conversation
…y-formatting feat(frontend): canonicalize currency amounts and locale-safe parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes currency amount parsing and formatting issues caused by locale-specific separators and binary floating-point rounding. This ensures transfer amounts, quotes, fees, and receipts preserve the exact value entered by the user.
Motivation
Prevent locale-specific number formatting from changing submitted transfer amounts.
Eliminate floating-point rounding errors at quote and receipt boundaries.
Ensure deterministic amount handling using canonical decimal strings and currency-specific minor-unit precision.
Improve mobile amount entry with the appropriate decimal keyboard.
Changes Made
Added per-currency minor-unit metadata and the getCurrencyMinorUnits accessor.
Added parseCurrencyInput to normalize locale-specific digits, grouping separators, and decimal separators, including non-Latin numbering systems.
Added validation for unsupported decimal precision and exposed minor-unit values using BigInt.
Updated formatCurrencyInput and formatAmount to use canonical decimal values and currency precision.
Integrated canonical parsing into validation, live quoting, and submission flows across SendMoney, the quote service, and validation helpers.
Updated amount inputs to use inputMode="decimal" for improved mobile input.
Added tests for locale round-tripping, precision validation, zero/negative boundaries, and floating-point quote regression.
Type of Change
🐛 Bug fix (non-breaking change that fixes an issue)
✨ New feature (non-breaking change that adds functionality)
💥 Breaking change
📝 Documentation update
🎨 Style/UI update
♻️ Code refactoring
⚡ Performance improvement
✅ Test update
🔧 Chore
Testing
Tested locally in development mode
All existing tests pass (npm test)
Added new tests for the changes
Tested in production build (npm run build)
Lighthouse checks pass (if UI changes)
Test Evidence
npm test
✓ All tests passed
npx vitest run test/unit/format.test.js test/unit/quote.test.js
✓ All targeted tests passed
npm run build
✓ Production build completed successfully
ESLint reported pre-existing unrelated issues in other test/support files. No new lint issues were introduced by these changes.
Screenshots (if applicable)
Not applicable. This PR primarily addresses currency parsing, precision, validation, quoting, and submission correctness.
Before
Locale-specific separators and floating-point calculations could cause the submitted amount or receipt value to differ from the user's intended amount.
After
Currency values are normalized to canonical decimal strings using currency-specific precision, ensuring consistent values across input, validation, quotes, fees, submission, and receipts.
Accessibility
Semantic input behavior maintained
Appropriate amount input mode added with inputMode="decimal"
ARIA labels added where needed
Keyboard navigation tested
Minimum 44×44px touch targets maintained
Color contrast meets WCAG AA standards
Screen reader tested
Checklist
My code follows the project's style guidelines
I have performed a self-review of my code
I have commented my code where necessary
I have updated the documentation accordingly
My changes generate no new warnings or errors from the changed code
I have added tests that prove the fix is effective
New and existing unit tests pass locally
Production build succeeds
Any dependent changes have been verified
Related Issues
closes #280
Additional Notes
The implementation uses canonical decimal representations and currency minor-unit precision rather than JavaScript floating-point arithmetic for amount-sensitive operations. This prevents precision drift while preserving locale-aware user input.
Breaking Changes
No breaking changes. Existing amount input and currency flows remain compatible while using more deterministic parsing and formatting internally.