Skip to content

feat: validated native currency and percent formatting - #5

Merged
AmatoGiulio merged 1 commit into
mainfrom
feat/validated-currency-formatting
Aug 17, 2026
Merged

feat: validated native currency and percent formatting#5
AmatoGiulio merged 1 commit into
mainfrom
feat/validated-currency-formatting

Conversation

@AmatoGiulio

Copy link
Copy Markdown
Owner

Validated successor to #4, originally contributed by @Amanfromearth.

This keeps the core API direction from #4 — one Intl.NumberFormatOptions-shaped format object plus the currency shorthand — but incorporates the native-motion and lifecycle work required to make formatted transitions hold up against the SwiftUI reference instead of only formatting the right string.

Public contract

  • format.style: decimal | currency | percent
  • currency shorthand
  • currencyDisplay: symbol | code
  • currencySign: standard | accounting (accounting is symbol-only)
  • grouping, integer padding, fraction bounds, significant-digit bounds
  • normalized ISO currency codes and bounded digit options before JS/native formatting
  • half-away-from-zero rounding across JS, iOS and Android
  • format-only transitions can animate even when the numeric value is unchanged
  • standard React Native accessibility props are forwarded; Android keeps the formatted number as the default description without overwriting an explicit accessibilityLabel

currencyDisplay: 'name' and trailingDecimalSeparator from the original proposal are deliberately deferred rather than exposed as partially validated contracts.

Native implementation

iOS

Uses the real SwiftUI .contentTransition(.numericText()), with the animation trigger bound to the rendered formatted text so format-only changes participate in the native transition.

Android

  • ICU-native formatting and semantic field extraction
  • semantic tokenization for digits, decimal/group separators, signs and arbitrary currency affixes
  • visual-order affix identity for bidi formats
  • currency/sign/affix glyphs routed through the same validated per-glyph roll/blur/scale/alpha physics as digits
  • separate outgoing/incoming raster geometry during structural format changes
  • rapid format retarget/reversal support, including exiting-ghost topology and same-glyph reversal fixes
  • held layout bounds during shrink transitions so outgoing glyphs are not clipped

No validated first-release motion constants were retuned as part of the structural fixes.

Validation

The example includes FormatLab.tsx as a deterministic validation harness while the public example entrypoint remains the normal Showcase.

The final 29-step currency/format GT covers USD symbol/code, format-only symbol↔code at the same value, EUR suffix, PAB punctuation, AED RTL + burst, accounting, repeated USD-code sign reversals, percent, JPY and BHD.

Validated during the review work:

  • iOS SwiftUI reference vs Android high-quality recordings, including full-sequence frame inspection
  • repeated USD-code A/B cycles after the first transition (regression fixed and device-validated)
  • Percent → JPY shrink/clipping regression (fixed and device-validated)
  • Android and iOS native builds after the currency bridge cleanup
  • final yarn check
  • final yarn prepare
  • final npm pack --dry-run
  • final Android run

The integration branch is a single clean commit over main; the long-lived fix/pr4-format-contract branch remains available as the validation/audit trail. The contributor's original upstream/intl-formatting branch was not modified.

Validated successor to #4, originally contributed by @Amanfromearth. Adds the Intl-shaped format contract, native iOS/Android formatting, currency/percent transitions, format retarget handling, regression coverage, and the FormatLab validation harness.
@AmatoGiulio
AmatoGiulio force-pushed the feat/validated-currency-formatting branch from fa242e5 to d742335 Compare August 17, 2026 09:37
@AmatoGiulio
AmatoGiulio merged commit 7aeaa8e into main Aug 17, 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.

1 participant