Text input
<text-input> is built to work with Signal Forms with no adapter code at all. Signal Forms'
FormField directive looks for a value model on a value control, and <text-input>'s value is
a model(), so <text-input [formField]="f.name" /> is the entire integration. It also works as a
plain two-way binding without a form at all: [(value)].
import { TextInput, InputAccessoryView } from '@ng-native/components';
<text-input><input-accessory-view> once they are in the component's imports<text-input placeholder="Name" [formField]="profile.name" />The Signal Forms contract
<text-input> carries the whole control contract FormField writes to, not just value:
disabled and readonly both turn editable off (disabled also wins the announced
accessibility state); invalid and touched are published as the data-invalid and
data-touched attributes, since nothing native reads them - they exist for a stylesheet; and
touch fires from the native blur event, because there is no DOM blur for Signal Forms to listen
to instead.
text-input {
border-width: 1px;
border-color: #3a3a42;
}
text-input[data-invalid][data-touched] {
border-color: #ff6b6b;
}The point of writing data-invalid/data-touched only once both are true is the usual one: a
field an app has not touched yet should not look broken before anyone has had a chance to fill it
in.
Controlled, as in React Native
Bind value and the field shows what your state says. A keystroke emits valueChange and
changeText; whatever your state holds once the handler has run is what the field ends up
showing. Take the text as typed, refuse it, or rewrite it:
<!-- Digits only: anything else leaves the field as it was. -->
<text-input [value]="pin()" (changeText)="isDigits($event) && pin.set($event)" />
<!-- Shows what is typed in capitals, as it is typed. -->
<text-input [value]="code()" (changeText)="code.set($event.toUpperCase())" />When your state takes the text as typed, native already shows it and nothing is sent back. When
it refuses or rewrites it, native is showing text your state does not hold, and a refused
keystroke leaves your binding where it was, so there is no prop change to carry the correction.
Once the change detection pass the keystroke started has finished, <text-input> compares
value with the text native reported and, if they differ, sends React Native's
setTextAndSelection command. A value set from code after the user has typed goes the same way.
Any binding makes the field controlled, one-way [value] included, so a field bound one way with
nothing handling the change cannot be typed into, as in React Native. Decide in the handler, and
do it synchronously: the comparison runs once the pass has finished, so a value that arrives later
is compared as a refusal and then applied when it arrives. Leave value unbound and the field
keeps what is typed. [formField] counts as a binding, and since a form takes every value the
control gives it, typing into a form field sends nothing back.
That command carries the same counter as the rest of the typing protocol, the one React Native
uses to keep fast typing safe: native reports each change with a counter, the component sends the
latest one back, and native ignores anything older than what it already has. Without it, typing
fast into a controlled field drops characters. None of this is something an app manages; it is
what makes binding [(value)] straight to a signal safe. <switch>, on the
switch page, is controlled the same way.
Keyboards and behavior
keyboardType picks the keyboard ('email-address', 'number-pad', 'phone-pad' and the rest);
returnKeyType labels the return key, and submitBehavior decides what pressing it does
('submit', 'blurAndSubmit', or 'newline' - the default on a multiline field). multiline
allows more than one line, secureTextEntry hides what is typed, autoCapitalize and
autoCorrect control the usual typing assists, and maxLength is enforced natively so nothing
flickers past the limit before being trimmed back.
<text-input> exposes focus(), blur(), clear(), setSelection(start, end?) and
isFocused() as methods, reachable through a template reference or nativeRef. (changeText)
carries just the new string, matching React Native's onChangeText; (change), (focus),
(blur), (submitEditing), (endEditing), (selectionChange), (keyPress) and
(contentSizeChange) are the raw element events.
text-inputdirective@ng-native/componentsimport { TextInput } from '@ng-native/components';and add TextInput to the component's imports A text field, wired for signal forms. Commits as TextInput , single or multi line by prop.
Inputs
disabledunknown Refuse input and announce as disabled. Wins over editable .
readonlyunknown Refuse input, though still announced as enabled. Wins over editable .
invalidboolean = false Published as data-invalid ; nothing native reads it.
touchedboolean = false Published as data-touched ; nothing native reads it.
multilineunknownAllow more than one line.
scrollEnabledunknowniOS: whether a multiline field scrolls its text; off, it grows with it instead.
editableunknownSet to false to make the field read-only.
placeholderstringShown while the field is empty.
placeholderTextColorstringkeyboardTypeKeyboardTypeWhich keyboard to show.
returnKeyTypeReturnKeyTypeThe label on the return key.
submitBehaviorSubmitBehavior What return does. Defaults to blurAndSubmit on one line and newline on many.
secureTextEntryunknownHide what is typed, for passwords.
autoCapitalize'none' | 'sentences' | 'words' | 'characters' When the keyboard capitalises. Defaults to sentences .
autoCorrectunknownAuto-correct while typing. Defaults to true.
autoFocusunknownFocus the field as soon as it mounts.
maxLengthunknownThe most characters allowed, enforced natively so nothing flickers.
numberOfLinesunknownAndroid: the height of a multiline field, in lines.
selection{ readonly start: number; readonly end?: number } The selected range, or the caret when start equals end .
selectionColorstringselectTextOnFocusunknownSelect everything on focus.
caretHiddenunknowncontextMenuHiddenunknownDisable the copy, paste and share menu.
textAlign'left' | 'center' | 'right'allowFontScalingunknownmaxFontSizeMultiplierunknowninputAccessoryViewIDstring iOS: the nativeID of an <input-accessory-view> to dock above the keyboard.
clearButtonMode'never' | 'while-editing' | 'unless-editing' | 'always'iOS: when the clear button shows.
clearTextOnFocusunknowniOS: empty the field on focus.
enablesReturnKeyAutomaticallyunknowniOS: disable the return key while the field is empty.
keyboardAppearance'default' | 'light' | 'dark'iOS: the keyboard's colour scheme.
passwordRulesstringiOS: rules for a generated password, in Apple's Password Rules syntax.
spellCheckunknown iOS: underline misspellings. Follows autoCorrect by default.
smartInsertDeleteunknowniOS: add and remove spaces around pasted and deleted words.
dataDetectorTypesstring | readonly string[]iOS, multiline: turn phone numbers, links and addresses into taps.
textContentTypestringiOS: what the field holds, so the system can autofill it.
autoCompletestringAndroid: the autofill hint.
underlineColorAndroidstring = 'transparent'Android: the underline colour, transparent by default.
cursorColorstringAndroid: the caret colour.
selectionHandleColorstringAndroid: the selection handle colour.
textAlignVertical'auto' | 'top' | 'bottom' | 'center'Android: where text sits in a tall field.
importantForAutofill'auto' | 'no' | 'noExcludeDescendants' | 'yes' | 'yesExcludeDescendants'Android: whether autofill may fill this field.
showSoftInputOnFocusunknownAndroid: set to false to focus without raising the keyboard.
disableFullscreenUIunknownAndroid: keep the field in place in landscape rather than going full screen.
inlineImageLeftstringAndroid: a drawable resource shown at the left of the field.
inlineImagePaddingunknowntextBreakStrategy'simple' | 'highQuality' | 'balanced'Android: the line-breaking strategy.
Two-way
valuestring = ''Outputs
changeTextstringThe new text alone, on every native change.
touchvoidFocus left the field. What Signal Forms marks a field touched from.
Methods
focus(): voidBring the keyboard up on this field. A view command, so it reaches native directly.
clear(): voidEmpty the field.
setSelection(start: number, end = start): voidMove the caret, or select a range.
isFocused(): booleanWhether this field currently has the keyboard.
Props a browser has no name for
Several inputs exist only because a native keyboard is a different object than an <input>:
textContentType and autoComplete hint at autofill (a password manager, a one-time code) the
way autocomplete does on the web, but with platform-specific values. passwordRules (iOS)
constrains what a generated password looks like. On iOS, dataDetectorTypes makes recognised
links and phone numbers tappable when multiline is true and editable is false.
keyboardAppearance (iOS) sets
the keyboard's own light or dark look independent of the app's theme, and showSoftInputOnFocus
lets a field take focus (for a caret and a custom picker) without the system keyboard appearing at
all.
Input accessory view
<input-accessory-view> docks a bar above the keyboard on iOS. Pair it with a <text-input> by
giving the view a nativeID and the input the same string as inputAccessoryViewID. Android has
no native counterpart to this and the element commits as a plain view, so content placed inside it
simply sits inert rather than floating above the keyboard.
input-accessory-viewdirective@ng-native/componentsimport { InputAccessoryView } from '@ng-native/components';and add InputAccessoryView to the component's imports A bar docked above the keyboard, iOS only. Pair it with a text input by giving this view a nativeID and the input the same inputAccessoryViewID .
Inputs
backgroundColorstringThe bar's background.