Repository navigation
nitro-input v0.4.0
·
2 commits
to main
since this release
- Android:
NitroNumber's numeric transition no longer blocks the UI
thread (ANRs). A glyph mask the warm thread had not made yet was blurred
inonDraw, and the shared mask cache made every mask inside its lock. Two
ANRs on low-end phones followed: the UI threadBlockedin the cache's
getbehind the warm thread (which runs atMIN_PRIORITY), and the UI
thread waiting for a GC while the blur allocated two float copies of a large
glyph. Now masks are made outside the lock, the UI thread never blurs (a
mask not warmed yet is drawn sharp for a frame while the warm thread makes
it), and the blur reuses per-thread buffers instead of allocating per mask.
A mask the screen is waiting on is made ahead of the warm-up's queue (it
waited behind every digit at every blur level, ~50 ms), the warm thread runs
at background priority rather than the lowest, and a mask that cannot be
made is skipped rather than crashing the app. - iOS: the numeric transition no longer blurs on the main thread. Its
digits were blurred and rasterized ahead of the first swap, but on the main
queue: opening a screen of numeric figures spent ~1 s of the main thread on
it (Release, simulator), in blocks of up to ~180 ms, and a prefix or suffix
that changed text was blurred on demand mid-frame. The warm-up now runs on
a background queue, a blur the screen is waiting on on a second one ahead
of it (drawn sharp until it lands), and the shared glyph caches are
thread-safe. NitroInputlays out at its real size in the commit that mounts it.
Its size came from the view, throughonSizeChangeand a React commit, so
the first layout had none: anautoWidthfield took its parent's width (or
none) for a commit, and every field without a fixed height moved by a pixel
or two as its line box arrived. Now a single-line field is measured on the JS
thread before its view exists (a newNitroInputMeasure), with the code the
view sizes itself with - fonts, affixes and their seams, number and mask
formatting, the placeholder andkeepPlaceholder's tail - as React
Native'sTextInputmeasures in its shadow node. About 0.1 ms per field;
the view's own report then matches and no longer costs a commit. A wrapping
field, atransformworklet and a style that sets both sides keep the old
path.- A framed field sizes itself. With no width or height from its style,
anoutlinedorfilledfield took the size of its text line alone: the
frame's side insets and the label were left out, so a resting label was
drawn outside the field and a filled one cut its text off. Its size now
includes the frame: the side insets either side of the text or the resting
label, whichever is wider, and above and below it the same 16 of padding
(and a filled field's label line) a wrapping field already had. A field
given a height in its style is unchanged. - A secure field fits its bullets. Android set the password input type
after the typeface, which switches the field to monospace, so its bullets
were wider than the field measured them; the typeface is now put back, as
React Native'sTextInputdoes. On iOS the field measured its text as
bullets in its own font, but UIKit draws U+2219 in the system font; it now
measures those. AnautoWidthsecure field showed●●●●…for 8 characters
on iOS and 5 bullets on Android. - No size jump on mount, and no amount sliding in on a reused field. A
size the view reported before its props were applied (the defaults', or a
recycled view's last element's) reached JS and made the field jump to it and
back. And on iOS a recycled view took the empty text its props reset fed the
engine for its first, so a reflowing amount on a reused view slid in instead
of showing as it is. - Android:
keepPlaceholder's greyed tail stays inside the field. The
rest of the placeholder, drawn after what was typed, was not clipped to the
text area as the field's own text and hint are: in a padded field narrower
than its placeholder (or once the typed text filled it), the tail ran over
the padding to the field's edge. iOS already clipped it. - A
TextInputstyle no longer crashes a field, andNitroInputreads
its typography from it. Fabric hands a view its style's keys as props,
and six to eight of each view's native props shared a name with a text
style key:style={{ fontWeight: '700' }}threw ("Value is a string,
expected a number") onNitroInput,NitroNumberandNitroText, and a
numericfontSizeorcolorthere was fought over by the style and the
prop. The native props are renamed (textSize,textWeight,
textFamily,textColor,textLetterSpacing,textLineHeight,
textAlignment,textVerticalAlignment); the components' own props keep
their names. A test now fails if any native prop shares a name with a React
Native style key or view prop.NitroInputalso takesfontSize,
fontWeight,fontFamily,color,letterSpacing,lineHeight,
textAlignandtextAlignVerticalfromstyle, asTextInputdoes (its
styleis typed asTextInput's); the props of the same name win. NitroInputmatchesTextInputin three more places, found by a
visual comparison of the two side by side:- Android:
textAligncenter/righton a plain field did nothing; the
alignment set when the field became plain (beforetextAlignarrived in
the same commit) overrode it. - A
stylepadding or border insets the text and adds to the size the
field works out for itself, asTextInput's does. AnautoWidthfield
withpaddingHorizontal: 8squeezed its text to "…" on iOS; on Android
the padding did not inset the text at all (React Native never hands a
Nitro view its padding there, so the view now insets its text, overlay and
frame itself). - iOS:
lineHeightsets a single line's height, as on Android; it was the
font's own line box whatever the prop said.
- Android: