Skip to content

Review cleanup: one value limit, dark mode, per-frame work, submitBehavior, packaging - #11

Merged
ronickg merged 3 commits into
mainfrom
chore/review-cleanup
Sep 22, 2026
Merged

ronickg merged 3 commits into
mainfrom
chore/review-cleanup

Conversation

@ronickg

@ronickg ronickg commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Everything a code review of both packages turned up, fixed and verified: real bugs first, then per-frame work, then support and tooling.

Rolling number

  • One value limit for jumpTo and animateTo. A jump clamped the scaled magnitude at 10^15 and a roll at 10^17, so the two showed different digits above that (with 9 fraction digits, jumpTo collapsed anything above 10^6 to "1,000,000"). Both share one limit now; the stagger's longest delay is stored once per roll; the unused revealFraction is gone. Two engine tests cover it.
  • Light/dark switches are followed when no color is set: iOS rasterizes with the trait-resolved label colour and rebuilds on a trait or display-scale change (the scale comes from the view's traits, not the deprecated UIScreen.main, which visionOS lacks); Android rebuilds its paints on a configuration change.
  • Per frame: iOS reuses its wheel and element buffers, keys glyph caches by a value type and compares layers in place; Android pools its layout elements, splits affixes once per format and slides one cached shimmer gradient. Both format the accessibility text only when a screen reader asks; Android reads the animator scale once behind a settings observer.
  • Wrapper: one ref handle per mount, right-to-left tests, a guard test keeping the shared helpers identical to the input's copy.

Input

  • Android dropped five worklet handlers after any re-render that changed a handler (onChangeValue, onFocus/onBlur, onSelectionChange, onSubmitEditing, onEndEditing never marked config dirty).
  • submitBehavior gains 'newline', resolved as TextInput resolves it, and both platforms honour submit / blurAndSubmit on a multiline field natively.
  • iOS: trait-aware glyphs, frame, label and caret colours; the Fabric focus/blur commands reach multiline fields; maxIntegerDigits allows 30 as on Android; morph toggled back on re-feeds; no per-glyph allocation per frame; the caret is positioned once per step.
  • Android: re-feeds after secureTextEntry / morph toggles, maxLength only in text mode, tabular figures in every mode, showSoftInputOnFocus honoured, theme colours resolved once and on configuration changes, the outline geometry written into a reused buffer.
  • JS: no re-render per keystroke on uncontrolled fields, maskNotations and colours memoised, missing type exports, orphaned doc comments reattached, README props table completed and guarded by a test, 43 new tests.
  • The native affixAlign prop is gone (the wrapper already folded it into prefixAlign/suffixAlign); dead engine, mask and worklet-bridge methods removed.

Repo

  • Both packages ship ES module, CommonJS and declaration builds with import/require conditions (the old lib/ was ES modules only); type dev dependencies declared; react-native-worklets an optional peer.
  • packages.yml builds lib/; the docs workflow rebuilds both WebAssembly engines before deploying (the committed builds were stale against MorphEngine.cpp).
  • Gradle pins the Android plugin only for a standalone build, Java 17, CMake minimum declared first.
  • README: the test command was bun test (Bun's own runner, which fails on the Jest files); the Nitro 0.37 Android view-props patch is documented for consumers until fix(views): fill Props::rawProps on Android when overriding cloneProps margelo/nitro#1655 ships.
  • The demo gains a multiline field with a submitBehavior toggle, used for the device check below.

Verified

check result
typecheck, both packages clean
Jest 16 + 139 tests pass
C++ engine tests all pass, clean at -Wshadow -Wconversion
bun run build, docs typecheck pass
iOS example build, Android library and app builds succeed, no warnings in changed files

On an iPhone 17 simulator and a Pixel 9 emulator: right-to-left layout (iOS after a native relaunch), a light/dark round trip on both platforms, the market showcase with thirty numbers rolling, jumpTo then animateTo, the loading glint, all three submitBehavior modes on a multiline field on both platforms, and the benchmark at 24 copies (debug builds, so not comparable to BENCHMARKS.md).

Judgment calls to review

  • Affixes are now dropped with a one-time warning on multiline inputs (iOS never showed them there, Android did; the parity doc already said so).
  • Both changelogs sit under one "0.1.0 (unreleased)" heading, since nothing has been published.
  • The example app hard-codes a light palette but relies on the platform label colour, so its numbers now correctly turn white when the device is dark. Forcing the example to light appearance, or giving it colours, is a follow-up.

🤖 Generated with Claude Code

Ronald Goedeke and others added 3 commits September 21, 2026 22:23
The engine clamped the scaled magnitude at 10^15 for a jump and 10^17 for
a roll, so `jumpTo` and `animateTo` showed different digits above that;
both now share one limit, the stagger's longest delay is stored once per
roll, and the unused `revealFraction` is gone.

Both views follow a light/dark switch when no `color` is set: iOS
rasterizes the glyphs with the trait-resolved label color and rebuilds
them on a trait or display-scale change (the scale now comes from the
view's traits, not `UIScreen.main`), Android rebuilds its paints on a
configuration change. Per frame, iOS reuses its wheel and element
buffers, keys the glyph caches by a value type and compares layers in
place; Android pools its layout elements, splits the affixes once per
format and slides one cached shimmer gradient. Both format the
accessibility text only when a screen reader asks for it, and Android
reads the animator scale once behind a settings observer.

The wrapper keeps one `ref` handle per mount and tests the right-to-left
resolution; `lib/` ships ES module, CommonJS and declaration builds; the
Android Gradle plugin is pinned only for a standalone build, Java 17.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ltiline

Android never marked five worklet-id props dirty, so a changed handler
kept calling a dead id; they flush like the other three now. The view
also re-feeds after `secureTextEntry` or `morph` toggles, applies
`maxLength` only in text mode, sets tabular figures in every mode,
honours `showSoftInputOnFocus`, resolves its theme colours once and
again on a configuration change, and caches the animator scale.

iOS re-rasterizes glyphs and re-resolves frame, label and caret colours
on a trait or scale change (no more `UIScreen.main`), the Fabric
focus/blur commands find multiline fields, `maxIntegerDigits` allows 30
as on Android, a `morph` toggled back on re-feeds, and a frame no longer
allocates per glyph.

`submitBehavior` gains `'newline'`, resolved as `TextInput` resolves it,
and both platforms honour `submit` / `blurAndSubmit` on a multiline
field. The wrapper no longer re-renders on every keystroke of an
uncontrolled field, memoises `maskNotations` and the colours, exports
the missing types, drops affixes on multiline with a warning, and gains
43 tests; the README props table is complete and guarded by a test.

The native `affixAlign` prop is gone (the wrapper folds it), dead
engine, mask and worklet-bridge methods are removed, the outline
geometry writes into a reused buffer, and packaging mirrors the rolling
number's dual build with `react-native-worklets` as an optional peer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ented

The docs workflow rebuilds both engines to WebAssembly before deploying,
since a change under cpp/ used to trigger a deploy with a stale build
(the committed builds are refreshed here too, and the rolling engine's
script links with em++). The package workflow builds `lib/`.

The README's test command was `bun test`, which runs Bun's own runner
against the Jest files; it is `bun run test`. It also documents the
Android view-props patch for Nitro 0.37 that consumers need until the
upstream fix ships. The demo gains a multiline field with a
`submitBehavior` toggle, the row the device check of that feature used.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ronickg
ronickg merged commit ed9afa2 into main Sep 22, 2026
4 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