@ng-native/components 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gestures.js +9 -1
- package/dist/gestures.js.map +1 -1
- package/dist/keyboard-avoiding-view.d.ts +7 -3
- package/dist/keyboard-avoiding-view.js +9 -4
- package/dist/keyboard-avoiding-view.js.map +1 -1
- package/dist/keyboard-dock.js +2 -1
- package/dist/keyboard-dock.js.map +1 -1
- package/dist/keyboard-taps.d.ts +5 -3
- package/dist/keyboard-taps.js +21 -16
- package/dist/keyboard-taps.js.map +1 -1
- package/dist/safe-area-provider.js +12 -3
- package/dist/safe-area-provider.js.map +1 -1
- package/dist/scroll-view-props.d.ts +1 -1
- package/dist/stand-ins/animations.d.ts +20 -0
- package/dist/stand-ins/animations.js +36 -0
- package/dist/stand-ins/animations.js.map +1 -0
- package/dist/text-input.d.ts +31 -4
- package/dist/text-input.js +86 -26
- package/dist/text-input.js.map +1 -1
- package/dist/touchable-opacity.d.ts +11 -19
- package/dist/touchable-opacity.js +17 -50
- package/dist/touchable-opacity.js.map +1 -1
- package/package.json +8 -4
package/dist/text-input.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SimpleChanges } from '@angular/core';
|
|
2
2
|
import type { NativeSyntheticEvent } from '@ng-native/fabric';
|
|
3
|
-
import type { TextInputChangePayload } from './events.ts';
|
|
3
|
+
import type { SelectionChangePayload, TextInputChangePayload } from './events.ts';
|
|
4
4
|
import { ViewBase } from './view-base.ts';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
export type KeyboardType = 'default' | 'number-pad' | 'decimal-pad' | 'numeric' | 'email-address' | 'phone-pad' | 'url' | 'ascii-capable' | 'numbers-and-punctuation' | 'name-phone-pad' | 'twitter' | 'web-search' | 'visible-password';
|
|
@@ -79,7 +79,10 @@ export declare class TextInput extends ViewBase {
|
|
|
79
79
|
* as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.
|
|
80
80
|
*/
|
|
81
81
|
readonly rows: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
82
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* The selected range, or the caret when `end` is left out or equals `start`. Sent to native
|
|
84
|
+
* whenever it differs from what native last had, so a caret the user moves goes back to it.
|
|
85
|
+
*/
|
|
83
86
|
readonly selection: import("@angular/core").InputSignal<{
|
|
84
87
|
readonly start: number;
|
|
85
88
|
readonly end?: number;
|
|
@@ -125,9 +128,9 @@ export declare class TextInput extends ViewBase {
|
|
|
125
128
|
* Ignored on iOS, where the native field has no such chrome.
|
|
126
129
|
*/
|
|
127
130
|
readonly underlineColorAndroid: import("@angular/core").InputSignal<string>;
|
|
128
|
-
/** Android: the caret colour. */
|
|
131
|
+
/** Android: the caret colour. Follows `selectionColor` by default, as RN's does. */
|
|
129
132
|
readonly cursorColor: import("@angular/core").InputSignal<string | undefined>;
|
|
130
|
-
/** Android: the selection handle colour. */
|
|
133
|
+
/** Android: the selection handle colour. Follows `selectionColor` by default, as RN's does. */
|
|
131
134
|
readonly selectionHandleColor: import("@angular/core").InputSignal<string | undefined>;
|
|
132
135
|
/** Android: where text sits in a tall field. */
|
|
133
136
|
readonly textAlignVertical: import("@angular/core").InputSignal<"auto" | "top" | "bottom" | "center" | undefined>;
|
|
@@ -143,12 +146,26 @@ export declare class TextInput extends ViewBase {
|
|
|
143
146
|
/** Android: the line-breaking strategy. */
|
|
144
147
|
readonly textBreakStrategy: import("@angular/core").InputSignal<"simple" | "highQuality" | "balanced" | undefined>;
|
|
145
148
|
protected readonly eventCount: import("@angular/core").WritableSignal<number>;
|
|
149
|
+
/** RN's normalised selection: an `end` left out is `start`, where iOS would read 0. */
|
|
150
|
+
protected readonly resolvedSelection: import("@angular/core").Signal<{
|
|
151
|
+
start: number;
|
|
152
|
+
end: number;
|
|
153
|
+
} | undefined>;
|
|
154
|
+
protected readonly resolvedCursorColor: import("@angular/core").Signal<string | undefined>;
|
|
155
|
+
protected readonly resolvedSelectionHandleColor: import("@angular/core").Signal<string | undefined>;
|
|
146
156
|
protected readonly resolvedEditable: import("@angular/core").Signal<boolean | undefined>;
|
|
147
157
|
protected disabledForAccessibility(): boolean | undefined;
|
|
148
158
|
protected readonly resolvedSubmitBehavior: import("@angular/core").Signal<SubmitBehavior>;
|
|
149
159
|
private readonly keyboard;
|
|
150
160
|
/** What native last reported, so a value set from code can be told from an echo. */
|
|
151
161
|
private lastNativeText;
|
|
162
|
+
/**
|
|
163
|
+
* The selection native last had, sent or reported, so a bound one is sent only when it differs.
|
|
164
|
+
* Unset to start with, so the first bound selection goes out too.
|
|
165
|
+
*/
|
|
166
|
+
private lastSelection;
|
|
167
|
+
/** Moved on every reported selection, so the bound one is compared with it again. */
|
|
168
|
+
private readonly selectionReports;
|
|
152
169
|
private readonly control;
|
|
153
170
|
constructor();
|
|
154
171
|
ngOnChanges(changes: SimpleChanges): void;
|
|
@@ -168,6 +185,16 @@ export declare class TextInput extends ViewBase {
|
|
|
168
185
|
/** Whether this field currently has the keyboard. */
|
|
169
186
|
isFocused(): boolean;
|
|
170
187
|
protected onNativeChange(event: NativeSyntheticEvent<Partial<TextInputChangePayload>>): void;
|
|
188
|
+
/** Send native the text and selection it does not have, as one `setTextAndSelection`. */
|
|
189
|
+
private syncWithNative;
|
|
190
|
+
/**
|
|
191
|
+
* Whether a bound selection is not the one native last had. The prop alone does not move the
|
|
192
|
+
* caret: Android has no `selection` prop, and iOS reads it only as the field appears or its
|
|
193
|
+
* text is replaced.
|
|
194
|
+
*/
|
|
195
|
+
private differsFromNative;
|
|
196
|
+
/** What native now has selected, which a bound selection that differs is sent over again. */
|
|
197
|
+
protected onNativeSelectionChange(event: NativeSyntheticEvent<Partial<SelectionChangePayload>>): void;
|
|
171
198
|
static ɵfac: i0.ɵɵFactoryDeclaration<TextInput, never>;
|
|
172
199
|
static ɵdir: i0.ɵɵDirectiveDeclaration<TextInput, "text-input", ["textInput"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "scrollEnabled": { "alias": "scrollEnabled"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "placeholderTextColor": { "alias": "placeholderTextColor"; "required": false; "isSignal": true; }; "keyboardType": { "alias": "keyboardType"; "required": false; "isSignal": true; }; "returnKeyType": { "alias": "returnKeyType"; "required": false; "isSignal": true; }; "submitBehavior": { "alias": "submitBehavior"; "required": false; "isSignal": true; }; "secureTextEntry": { "alias": "secureTextEntry"; "required": false; "isSignal": true; }; "autoCapitalize": { "alias": "autoCapitalize"; "required": false; "isSignal": true; }; "autoCorrect": { "alias": "autoCorrect"; "required": false; "isSignal": true; }; "autoFocus": { "alias": "autoFocus"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "numberOfLines": { "alias": "numberOfLines"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "selectionColor": { "alias": "selectionColor"; "required": false; "isSignal": true; }; "selectTextOnFocus": { "alias": "selectTextOnFocus"; "required": false; "isSignal": true; }; "caretHidden": { "alias": "caretHidden"; "required": false; "isSignal": true; }; "contextMenuHidden": { "alias": "contextMenuHidden"; "required": false; "isSignal": true; }; "textAlign": { "alias": "textAlign"; "required": false; "isSignal": true; }; "allowFontScaling": { "alias": "allowFontScaling"; "required": false; "isSignal": true; }; "maxFontSizeMultiplier": { "alias": "maxFontSizeMultiplier"; "required": false; "isSignal": true; }; "inputAccessoryViewID": { "alias": "inputAccessoryViewID"; "required": false; "isSignal": true; }; "clearButtonMode": { "alias": "clearButtonMode"; "required": false; "isSignal": true; }; "clearTextOnFocus": { "alias": "clearTextOnFocus"; "required": false; "isSignal": true; }; "enablesReturnKeyAutomatically": { "alias": "enablesReturnKeyAutomatically"; "required": false; "isSignal": true; }; "keyboardAppearance": { "alias": "keyboardAppearance"; "required": false; "isSignal": true; }; "passwordRules": { "alias": "passwordRules"; "required": false; "isSignal": true; }; "spellCheck": { "alias": "spellCheck"; "required": false; "isSignal": true; }; "smartInsertDelete": { "alias": "smartInsertDelete"; "required": false; "isSignal": true; }; "dataDetectorTypes": { "alias": "dataDetectorTypes"; "required": false; "isSignal": true; }; "textContentType": { "alias": "textContentType"; "required": false; "isSignal": true; }; "autoComplete": { "alias": "autoComplete"; "required": false; "isSignal": true; }; "underlineColorAndroid": { "alias": "underlineColorAndroid"; "required": false; "isSignal": true; }; "cursorColor": { "alias": "cursorColor"; "required": false; "isSignal": true; }; "selectionHandleColor": { "alias": "selectionHandleColor"; "required": false; "isSignal": true; }; "textAlignVertical": { "alias": "textAlignVertical"; "required": false; "isSignal": true; }; "importantForAutofill": { "alias": "importantForAutofill"; "required": false; "isSignal": true; }; "showSoftInputOnFocus": { "alias": "showSoftInputOnFocus"; "required": false; "isSignal": true; }; "disableFullscreenUI": { "alias": "disableFullscreenUI"; "required": false; "isSignal": true; }; "inlineImageLeft": { "alias": "inlineImageLeft"; "required": false; "isSignal": true; }; "inlineImagePadding": { "alias": "inlineImagePadding"; "required": false; "isSignal": true; }; "textBreakStrategy": { "alias": "textBreakStrategy"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "changeText": "changeText"; "touch": "touch"; }, never, never, true, never>;
|
|
173
200
|
}
|
package/dist/text-input.js
CHANGED
|
@@ -84,7 +84,10 @@ export class TextInput extends ViewBase {
|
|
|
84
84
|
* as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.
|
|
85
85
|
*/
|
|
86
86
|
rows = input(undefined, { ...(ngDevMode ? { debugName: "rows" } : /* istanbul ignore next */ {}), transform: optionalNumber });
|
|
87
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* The selected range, or the caret when `end` is left out or equals `start`. Sent to native
|
|
89
|
+
* whenever it differs from what native last had, so a caret the user moves goes back to it.
|
|
90
|
+
*/
|
|
88
91
|
selection = input(/* @ts-ignore */
|
|
89
92
|
...(ngDevMode ? [undefined, { debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
90
93
|
selectionColor = input(/* @ts-ignore */
|
|
@@ -138,10 +141,10 @@ export class TextInput extends ViewBase {
|
|
|
138
141
|
*/
|
|
139
142
|
underlineColorAndroid = input('transparent', /* @ts-ignore */
|
|
140
143
|
...(ngDevMode ? [{ debugName: "underlineColorAndroid" }] : /* istanbul ignore next */ []));
|
|
141
|
-
/** Android: the caret colour. */
|
|
144
|
+
/** Android: the caret colour. Follows `selectionColor` by default, as RN's does. */
|
|
142
145
|
cursorColor = input(/* @ts-ignore */
|
|
143
146
|
...(ngDevMode ? [undefined, { debugName: "cursorColor" }] : /* istanbul ignore next */ []));
|
|
144
|
-
/** Android: the selection handle colour. */
|
|
147
|
+
/** Android: the selection handle colour. Follows `selectionColor` by default, as RN's does. */
|
|
145
148
|
selectionHandleColor = input(/* @ts-ignore */
|
|
146
149
|
...(ngDevMode ? [undefined, { debugName: "selectionHandleColor" }] : /* istanbul ignore next */ []));
|
|
147
150
|
/** Android: where text sits in a tall field. */
|
|
@@ -163,6 +166,25 @@ export class TextInput extends ViewBase {
|
|
|
163
166
|
...(ngDevMode ? [undefined, { debugName: "textBreakStrategy" }] : /* istanbul ignore next */ []));
|
|
164
167
|
eventCount = signal(0, /* @ts-ignore */
|
|
165
168
|
...(ngDevMode ? [{ debugName: "eventCount" }] : /* istanbul ignore next */ []));
|
|
169
|
+
/** RN's normalised selection: an `end` left out is `start`, where iOS would read 0. */
|
|
170
|
+
resolvedSelection = computed(() => {
|
|
171
|
+
const selection = this.selection();
|
|
172
|
+
return selection
|
|
173
|
+
? { start: selection.start, end: selection.end ?? selection.start }
|
|
174
|
+
: undefined;
|
|
175
|
+
}, /* @ts-ignore */
|
|
176
|
+
...(ngDevMode ? [{ debugName: "resolvedSelection" }] : /* istanbul ignore next */ []));
|
|
177
|
+
// RN's Android defaults, checked against `undefined` as RN does rather than with `??`.
|
|
178
|
+
resolvedCursorColor = computed(() => {
|
|
179
|
+
const color = this.cursorColor();
|
|
180
|
+
return color === undefined ? this.selectionColor() : color;
|
|
181
|
+
}, /* @ts-ignore */
|
|
182
|
+
...(ngDevMode ? [{ debugName: "resolvedCursorColor" }] : /* istanbul ignore next */ []));
|
|
183
|
+
resolvedSelectionHandleColor = computed(() => {
|
|
184
|
+
const color = this.selectionHandleColor();
|
|
185
|
+
return color === undefined ? this.selectionColor() : color;
|
|
186
|
+
}, /* @ts-ignore */
|
|
187
|
+
...(ngDevMode ? [{ debugName: "resolvedSelectionHandleColor" }] : /* istanbul ignore next */ []));
|
|
166
188
|
resolvedEditable = computed(() => this.disabled() || this.readonly() ? false : this.editable(), /* @ts-ignore */
|
|
167
189
|
...(ngDevMode ? [{ debugName: "resolvedEditable" }] : /* istanbul ignore next */ []));
|
|
168
190
|
disabledForAccessibility() {
|
|
@@ -179,27 +201,22 @@ export class TextInput extends ViewBase {
|
|
|
179
201
|
keyboard = inject(Keyboard);
|
|
180
202
|
/** What native last reported, so a value set from code can be told from an echo. */
|
|
181
203
|
lastNativeText = null;
|
|
204
|
+
/**
|
|
205
|
+
* The selection native last had, sent or reported, so a bound one is sent only when it differs.
|
|
206
|
+
* Unset to start with, so the first bound selection goes out too.
|
|
207
|
+
*/
|
|
208
|
+
lastSelection = { start: -1, end: -1 };
|
|
209
|
+
/** Moved on every reported selection, so the bound one is compared with it again. */
|
|
210
|
+
selectionReports = signal(0, /* @ts-ignore */
|
|
211
|
+
...(ngDevMode ? [{ debugName: "selectionReports" }] : /* istanbul ignore next */ []));
|
|
182
212
|
control = new ControlledModel(this.value, 'value');
|
|
183
213
|
constructor() {
|
|
184
214
|
super();
|
|
185
|
-
// RN's layout effect, keyed as RN keys it: the value, and the count every
|
|
186
|
-
// moves on, so a refusal that leaves the value where it was is compared all the
|
|
187
|
-
// render rather than as an ordinary effect, because an accepted edit only reaches
|
|
188
|
-
// during change detection, and comparing before it has would send the old text back.
|
|
189
|
-
afterRenderEffect({
|
|
190
|
-
write: () => {
|
|
191
|
-
const desired = this.value();
|
|
192
|
-
const count = this.eventCount();
|
|
193
|
-
if (this.lastNativeText === null || this.lastNativeText === desired)
|
|
194
|
-
return;
|
|
195
|
-
// The `text` prop alone may be ignored as stale, so send it as a command with the count
|
|
196
|
-
// native expects.
|
|
197
|
-
this.lastNativeText = desired;
|
|
198
|
-
this.engine.dispatchCommand(this.node, 'setTextAndSelection', [count, desired, -1, -1]);
|
|
199
|
-
// Fabric sized the field for the text it had; see `HostEngine.remeasure`.
|
|
200
|
-
this.engine.remeasure(this.node);
|
|
201
|
-
},
|
|
202
|
-
});
|
|
215
|
+
// RN's layout effect, keyed as RN keys it: the value, the selection, and the count every
|
|
216
|
+
// native change moves on, so a refusal that leaves the value where it was is compared all the
|
|
217
|
+
// same. After render rather than as an ordinary effect, because an accepted edit only reaches
|
|
218
|
+
// the model during change detection, and comparing before it has would send the old text back.
|
|
219
|
+
afterRenderEffect({ write: () => this.syncWithNative() });
|
|
203
220
|
}
|
|
204
221
|
ngOnChanges(changes) {
|
|
205
222
|
super.ngOnChanges(changes);
|
|
@@ -213,7 +230,7 @@ export class TextInput extends ViewBase {
|
|
|
213
230
|
onFocus() {
|
|
214
231
|
const { height, screenY } = this.keyboard.metrics();
|
|
215
232
|
if (height > 0 && screenY !== undefined)
|
|
216
|
-
this.engine.reveal(this.node, { visibleBottom: screenY });
|
|
233
|
+
this.engine.reveal(this.node, { visibleBottom: screenY - this.keyboard.windowTop });
|
|
217
234
|
}
|
|
218
235
|
/** Bring the keyboard up on this field. A view command, so it reaches native directly. */
|
|
219
236
|
focus() {
|
|
@@ -248,8 +265,50 @@ export class TextInput extends ViewBase {
|
|
|
248
265
|
this.eventCount.set(native?.eventCount ?? this.eventCount() + 1);
|
|
249
266
|
this.changeText.emit(text);
|
|
250
267
|
}
|
|
268
|
+
/** Send native the text and selection it does not have, as one `setTextAndSelection`. */
|
|
269
|
+
syncWithNative() {
|
|
270
|
+
const desired = this.value();
|
|
271
|
+
const count = this.eventCount();
|
|
272
|
+
const selection = this.resolvedSelection();
|
|
273
|
+
this.selectionReports();
|
|
274
|
+
const textChanged = this.lastNativeText !== null && this.lastNativeText !== desired;
|
|
275
|
+
if (!textChanged && !this.differsFromNative(selection))
|
|
276
|
+
return;
|
|
277
|
+
if (textChanged)
|
|
278
|
+
this.lastNativeText = desired;
|
|
279
|
+
if (selection)
|
|
280
|
+
this.lastSelection = selection;
|
|
281
|
+
// The `text` prop alone may be ignored as stale, so send it as a command with the count
|
|
282
|
+
// native expects, and the text and bound selection as RN does whichever of them changed.
|
|
283
|
+
this.engine.dispatchCommand(this.node, 'setTextAndSelection', [
|
|
284
|
+
count,
|
|
285
|
+
desired,
|
|
286
|
+
selection?.start ?? -1,
|
|
287
|
+
selection?.end ?? -1,
|
|
288
|
+
]);
|
|
289
|
+
// Fabric sized the field for the text it had; see `HostEngine.remeasure`.
|
|
290
|
+
if (textChanged)
|
|
291
|
+
this.engine.remeasure(this.node);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Whether a bound selection is not the one native last had. The prop alone does not move the
|
|
295
|
+
* caret: Android has no `selection` prop, and iOS reads it only as the field appears or its
|
|
296
|
+
* text is replaced.
|
|
297
|
+
*/
|
|
298
|
+
differsFromNative(selection) {
|
|
299
|
+
return (selection !== undefined &&
|
|
300
|
+
(selection.start !== this.lastSelection.start || selection.end !== this.lastSelection.end));
|
|
301
|
+
}
|
|
302
|
+
/** What native now has selected, which a bound selection that differs is sent over again. */
|
|
303
|
+
onNativeSelectionChange(event) {
|
|
304
|
+
const selection = event.nativeEvent?.selection;
|
|
305
|
+
if (!selection)
|
|
306
|
+
return;
|
|
307
|
+
this.lastSelection = { start: selection.start, end: selection.end };
|
|
308
|
+
this.selectionReports.update((n) => n + 1);
|
|
309
|
+
}
|
|
251
310
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TextInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
252
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: TextInput, isStandalone: true, selector: "text-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, scrollEnabled: { classPropertyName: "scrollEnabled", publicName: "scrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placeholderTextColor: { classPropertyName: "placeholderTextColor", publicName: "placeholderTextColor", isSignal: true, isRequired: false, transformFunction: null }, keyboardType: { classPropertyName: "keyboardType", publicName: "keyboardType", isSignal: true, isRequired: false, transformFunction: null }, returnKeyType: { classPropertyName: "returnKeyType", publicName: "returnKeyType", isSignal: true, isRequired: false, transformFunction: null }, submitBehavior: { classPropertyName: "submitBehavior", publicName: "submitBehavior", isSignal: true, isRequired: false, transformFunction: null }, secureTextEntry: { classPropertyName: "secureTextEntry", publicName: "secureTextEntry", isSignal: true, isRequired: false, transformFunction: null }, autoCapitalize: { classPropertyName: "autoCapitalize", publicName: "autoCapitalize", isSignal: true, isRequired: false, transformFunction: null }, autoCorrect: { classPropertyName: "autoCorrect", publicName: "autoCorrect", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, numberOfLines: { classPropertyName: "numberOfLines", publicName: "numberOfLines", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, selectTextOnFocus: { classPropertyName: "selectTextOnFocus", publicName: "selectTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, caretHidden: { classPropertyName: "caretHidden", publicName: "caretHidden", isSignal: true, isRequired: false, transformFunction: null }, contextMenuHidden: { classPropertyName: "contextMenuHidden", publicName: "contextMenuHidden", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null }, allowFontScaling: { classPropertyName: "allowFontScaling", publicName: "allowFontScaling", isSignal: true, isRequired: false, transformFunction: null }, maxFontSizeMultiplier: { classPropertyName: "maxFontSizeMultiplier", publicName: "maxFontSizeMultiplier", isSignal: true, isRequired: false, transformFunction: null }, inputAccessoryViewID: { classPropertyName: "inputAccessoryViewID", publicName: "inputAccessoryViewID", isSignal: true, isRequired: false, transformFunction: null }, clearButtonMode: { classPropertyName: "clearButtonMode", publicName: "clearButtonMode", isSignal: true, isRequired: false, transformFunction: null }, clearTextOnFocus: { classPropertyName: "clearTextOnFocus", publicName: "clearTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, enablesReturnKeyAutomatically: { classPropertyName: "enablesReturnKeyAutomatically", publicName: "enablesReturnKeyAutomatically", isSignal: true, isRequired: false, transformFunction: null }, keyboardAppearance: { classPropertyName: "keyboardAppearance", publicName: "keyboardAppearance", isSignal: true, isRequired: false, transformFunction: null }, passwordRules: { classPropertyName: "passwordRules", publicName: "passwordRules", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, smartInsertDelete: { classPropertyName: "smartInsertDelete", publicName: "smartInsertDelete", isSignal: true, isRequired: false, transformFunction: null }, dataDetectorTypes: { classPropertyName: "dataDetectorTypes", publicName: "dataDetectorTypes", isSignal: true, isRequired: false, transformFunction: null }, textContentType: { classPropertyName: "textContentType", publicName: "textContentType", isSignal: true, isRequired: false, transformFunction: null }, autoComplete: { classPropertyName: "autoComplete", publicName: "autoComplete", isSignal: true, isRequired: false, transformFunction: null }, underlineColorAndroid: { classPropertyName: "underlineColorAndroid", publicName: "underlineColorAndroid", isSignal: true, isRequired: false, transformFunction: null }, cursorColor: { classPropertyName: "cursorColor", publicName: "cursorColor", isSignal: true, isRequired: false, transformFunction: null }, selectionHandleColor: { classPropertyName: "selectionHandleColor", publicName: "selectionHandleColor", isSignal: true, isRequired: false, transformFunction: null }, textAlignVertical: { classPropertyName: "textAlignVertical", publicName: "textAlignVertical", isSignal: true, isRequired: false, transformFunction: null }, importantForAutofill: { classPropertyName: "importantForAutofill", publicName: "importantForAutofill", isSignal: true, isRequired: false, transformFunction: null }, showSoftInputOnFocus: { classPropertyName: "showSoftInputOnFocus", publicName: "showSoftInputOnFocus", isSignal: true, isRequired: false, transformFunction: null }, disableFullscreenUI: { classPropertyName: "disableFullscreenUI", publicName: "disableFullscreenUI", isSignal: true, isRequired: false, transformFunction: null }, inlineImageLeft: { classPropertyName: "inlineImageLeft", publicName: "inlineImageLeft", isSignal: true, isRequired: false, transformFunction: null }, inlineImagePadding: { classPropertyName: "inlineImagePadding", publicName: "inlineImagePadding", isSignal: true, isRequired: false, transformFunction: null }, textBreakStrategy: { classPropertyName: "textBreakStrategy", publicName: "textBreakStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changeText: "changeText", touch: "touch" }, host: { listeners: { "blur": "touch.emit()", "focus": "onFocus()", "change": "onNativeChange($event)" }, properties: { "text": "value()", "mostRecentEventCount": "eventCount()", "multiline": "multiline()", "scrollEnabled": "scrollEnabled()", "editable": "resolvedEditable()", "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "disabled() ? '' : null", "attr.data-invalid": "invalid() ? '' : null", "attr.data-touched": "touched() ? '' : null", "placeholder": "placeholder()", "placeholderTextColor": "placeholderTextColor()", "keyboardType": "keyboardType()", "returnKeyType": "returnKeyType()", "submitBehavior": "resolvedSubmitBehavior()", "secureTextEntry": "secureTextEntry()", "autoCapitalize": "autoCapitalize()", "autoCorrect": "autoCorrect()", "autoFocus": "autoFocus()", "maxLength": "maxLength()", "numberOfLines": "numberOfLines()", "rows": "rows()", "selection": "
|
|
311
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: TextInput, isStandalone: true, selector: "text-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, scrollEnabled: { classPropertyName: "scrollEnabled", publicName: "scrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placeholderTextColor: { classPropertyName: "placeholderTextColor", publicName: "placeholderTextColor", isSignal: true, isRequired: false, transformFunction: null }, keyboardType: { classPropertyName: "keyboardType", publicName: "keyboardType", isSignal: true, isRequired: false, transformFunction: null }, returnKeyType: { classPropertyName: "returnKeyType", publicName: "returnKeyType", isSignal: true, isRequired: false, transformFunction: null }, submitBehavior: { classPropertyName: "submitBehavior", publicName: "submitBehavior", isSignal: true, isRequired: false, transformFunction: null }, secureTextEntry: { classPropertyName: "secureTextEntry", publicName: "secureTextEntry", isSignal: true, isRequired: false, transformFunction: null }, autoCapitalize: { classPropertyName: "autoCapitalize", publicName: "autoCapitalize", isSignal: true, isRequired: false, transformFunction: null }, autoCorrect: { classPropertyName: "autoCorrect", publicName: "autoCorrect", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, numberOfLines: { classPropertyName: "numberOfLines", publicName: "numberOfLines", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, selectTextOnFocus: { classPropertyName: "selectTextOnFocus", publicName: "selectTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, caretHidden: { classPropertyName: "caretHidden", publicName: "caretHidden", isSignal: true, isRequired: false, transformFunction: null }, contextMenuHidden: { classPropertyName: "contextMenuHidden", publicName: "contextMenuHidden", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null }, allowFontScaling: { classPropertyName: "allowFontScaling", publicName: "allowFontScaling", isSignal: true, isRequired: false, transformFunction: null }, maxFontSizeMultiplier: { classPropertyName: "maxFontSizeMultiplier", publicName: "maxFontSizeMultiplier", isSignal: true, isRequired: false, transformFunction: null }, inputAccessoryViewID: { classPropertyName: "inputAccessoryViewID", publicName: "inputAccessoryViewID", isSignal: true, isRequired: false, transformFunction: null }, clearButtonMode: { classPropertyName: "clearButtonMode", publicName: "clearButtonMode", isSignal: true, isRequired: false, transformFunction: null }, clearTextOnFocus: { classPropertyName: "clearTextOnFocus", publicName: "clearTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, enablesReturnKeyAutomatically: { classPropertyName: "enablesReturnKeyAutomatically", publicName: "enablesReturnKeyAutomatically", isSignal: true, isRequired: false, transformFunction: null }, keyboardAppearance: { classPropertyName: "keyboardAppearance", publicName: "keyboardAppearance", isSignal: true, isRequired: false, transformFunction: null }, passwordRules: { classPropertyName: "passwordRules", publicName: "passwordRules", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, smartInsertDelete: { classPropertyName: "smartInsertDelete", publicName: "smartInsertDelete", isSignal: true, isRequired: false, transformFunction: null }, dataDetectorTypes: { classPropertyName: "dataDetectorTypes", publicName: "dataDetectorTypes", isSignal: true, isRequired: false, transformFunction: null }, textContentType: { classPropertyName: "textContentType", publicName: "textContentType", isSignal: true, isRequired: false, transformFunction: null }, autoComplete: { classPropertyName: "autoComplete", publicName: "autoComplete", isSignal: true, isRequired: false, transformFunction: null }, underlineColorAndroid: { classPropertyName: "underlineColorAndroid", publicName: "underlineColorAndroid", isSignal: true, isRequired: false, transformFunction: null }, cursorColor: { classPropertyName: "cursorColor", publicName: "cursorColor", isSignal: true, isRequired: false, transformFunction: null }, selectionHandleColor: { classPropertyName: "selectionHandleColor", publicName: "selectionHandleColor", isSignal: true, isRequired: false, transformFunction: null }, textAlignVertical: { classPropertyName: "textAlignVertical", publicName: "textAlignVertical", isSignal: true, isRequired: false, transformFunction: null }, importantForAutofill: { classPropertyName: "importantForAutofill", publicName: "importantForAutofill", isSignal: true, isRequired: false, transformFunction: null }, showSoftInputOnFocus: { classPropertyName: "showSoftInputOnFocus", publicName: "showSoftInputOnFocus", isSignal: true, isRequired: false, transformFunction: null }, disableFullscreenUI: { classPropertyName: "disableFullscreenUI", publicName: "disableFullscreenUI", isSignal: true, isRequired: false, transformFunction: null }, inlineImageLeft: { classPropertyName: "inlineImageLeft", publicName: "inlineImageLeft", isSignal: true, isRequired: false, transformFunction: null }, inlineImagePadding: { classPropertyName: "inlineImagePadding", publicName: "inlineImagePadding", isSignal: true, isRequired: false, transformFunction: null }, textBreakStrategy: { classPropertyName: "textBreakStrategy", publicName: "textBreakStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changeText: "changeText", touch: "touch" }, host: { listeners: { "blur": "touch.emit()", "focus": "onFocus()", "change": "onNativeChange($event)", "selectionChange": "onNativeSelectionChange($event)" }, properties: { "text": "value()", "mostRecentEventCount": "eventCount()", "multiline": "multiline()", "scrollEnabled": "scrollEnabled()", "editable": "resolvedEditable()", "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "disabled() ? '' : null", "attr.data-invalid": "invalid() ? '' : null", "attr.data-touched": "touched() ? '' : null", "placeholder": "placeholder()", "placeholderTextColor": "placeholderTextColor()", "keyboardType": "keyboardType()", "returnKeyType": "returnKeyType()", "submitBehavior": "resolvedSubmitBehavior()", "secureTextEntry": "secureTextEntry()", "autoCapitalize": "autoCapitalize()", "autoCorrect": "autoCorrect()", "autoFocus": "autoFocus()", "maxLength": "maxLength()", "numberOfLines": "numberOfLines()", "rows": "rows()", "selection": "resolvedSelection()", "selectionColor": "selectionColor()", "selectTextOnFocus": "selectTextOnFocus()", "caretHidden": "caretHidden()", "contextMenuHidden": "contextMenuHidden()", "textAlign": "textAlign()", "allowFontScaling": "allowFontScaling()", "maxFontSizeMultiplier": "maxFontSizeMultiplier()", "inputAccessoryViewID": "inputAccessoryViewID()", "clearButtonMode": "clearButtonMode()", "clearTextOnFocus": "clearTextOnFocus()", "enablesReturnKeyAutomatically": "enablesReturnKeyAutomatically()", "keyboardAppearance": "keyboardAppearance()", "passwordRules": "passwordRules()", "spellCheck": "spellCheck()", "smartInsertDelete": "smartInsertDelete()", "dataDetectorTypes": "dataDetectorTypes()", "textContentType": "textContentType()", "autoComplete": "autoComplete()", "underlineColorAndroid": "underlineColorAndroid()", "cursorColor": "resolvedCursorColor()", "selectionHandleColor": "resolvedSelectionHandleColor()", "textAlignVertical": "textAlignVertical()", "importantForAutofill": "importantForAutofill()", "showSoftInputOnFocus": "showSoftInputOnFocus()", "disableFullscreenUI": "disableFullscreenUI()", "inlineImageLeft": "inlineImageLeft()", "inlineImagePadding": "inlineImagePadding()", "textBreakStrategy": "textBreakStrategy()" } }, exportAs: ["textInput"], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
|
|
253
312
|
}
|
|
254
313
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TextInput, decorators: [{
|
|
255
314
|
type: Directive,
|
|
@@ -282,7 +341,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
282
341
|
'[maxLength]': 'maxLength()',
|
|
283
342
|
'[numberOfLines]': 'numberOfLines()',
|
|
284
343
|
'[rows]': 'rows()',
|
|
285
|
-
'[selection]': '
|
|
344
|
+
'[selection]': 'resolvedSelection()',
|
|
286
345
|
'[selectionColor]': 'selectionColor()',
|
|
287
346
|
'[selectTextOnFocus]': 'selectTextOnFocus()',
|
|
288
347
|
'[caretHidden]': 'caretHidden()',
|
|
@@ -302,8 +361,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
302
361
|
'[textContentType]': 'textContentType()',
|
|
303
362
|
'[autoComplete]': 'autoComplete()',
|
|
304
363
|
'[underlineColorAndroid]': 'underlineColorAndroid()',
|
|
305
|
-
'[cursorColor]': '
|
|
306
|
-
'[selectionHandleColor]': '
|
|
364
|
+
'[cursorColor]': 'resolvedCursorColor()',
|
|
365
|
+
'[selectionHandleColor]': 'resolvedSelectionHandleColor()',
|
|
307
366
|
'[textAlignVertical]': 'textAlignVertical()',
|
|
308
367
|
'[importantForAutofill]': 'importantForAutofill()',
|
|
309
368
|
'[showSoftInputOnFocus]': 'showSoftInputOnFocus()',
|
|
@@ -312,6 +371,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
312
371
|
'[inlineImagePadding]': 'inlineImagePadding()',
|
|
313
372
|
'[textBreakStrategy]': 'textBreakStrategy()',
|
|
314
373
|
'(change)': 'onNativeChange($event)',
|
|
374
|
+
'(selectionChange)': 'onNativeSelectionChange($event)',
|
|
315
375
|
},
|
|
316
376
|
}]
|
|
317
377
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], changeText: [{ type: i0.Output, args: ["changeText"] }], touch: [{ type: i0.Output, args: ["touch"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], scrollEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollEnabled", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], placeholderTextColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderTextColor", required: false }] }], keyboardType: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardType", required: false }] }], returnKeyType: [{ type: i0.Input, args: [{ isSignal: true, alias: "returnKeyType", required: false }] }], submitBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitBehavior", required: false }] }], secureTextEntry: [{ type: i0.Input, args: [{ isSignal: true, alias: "secureTextEntry", required: false }] }], autoCapitalize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCapitalize", required: false }] }], autoCorrect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCorrect", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], numberOfLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "numberOfLines", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], selectionColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionColor", required: false }] }], selectTextOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectTextOnFocus", required: false }] }], caretHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "caretHidden", required: false }] }], contextMenuHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenuHidden", required: false }] }], textAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "textAlign", required: false }] }], allowFontScaling: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFontScaling", required: false }] }], maxFontSizeMultiplier: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFontSizeMultiplier", required: false }] }], inputAccessoryViewID: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputAccessoryViewID", required: false }] }], clearButtonMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearButtonMode", required: false }] }], clearTextOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTextOnFocus", required: false }] }], enablesReturnKeyAutomatically: [{ type: i0.Input, args: [{ isSignal: true, alias: "enablesReturnKeyAutomatically", required: false }] }], keyboardAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardAppearance", required: false }] }], passwordRules: [{ type: i0.Input, args: [{ isSignal: true, alias: "passwordRules", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], smartInsertDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartInsertDelete", required: false }] }], dataDetectorTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataDetectorTypes", required: false }] }], textContentType: [{ type: i0.Input, args: [{ isSignal: true, alias: "textContentType", required: false }] }], autoComplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoComplete", required: false }] }], underlineColorAndroid: [{ type: i0.Input, args: [{ isSignal: true, alias: "underlineColorAndroid", required: false }] }], cursorColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "cursorColor", required: false }] }], selectionHandleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionHandleColor", required: false }] }], textAlignVertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "textAlignVertical", required: false }] }], importantForAutofill: [{ type: i0.Input, args: [{ isSignal: true, alias: "importantForAutofill", required: false }] }], showSoftInputOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSoftInputOnFocus", required: false }] }], disableFullscreenUI: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableFullscreenUI", required: false }] }], inlineImageLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineImageLeft", required: false }] }], inlineImagePadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineImagePadding", required: false }] }], textBreakStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "textBreakStrategy", required: false }] }] } });
|
package/dist/text-input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-input.js","sourceRoot":"","sources":["../src/text-input.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n type SimpleChanges,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { Keyboard } from '@ng-native/device';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ControlledModel } from './controlled-model.ts';\nimport type { TextInputChangePayload } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\nexport type KeyboardType =\n | 'default'\n | 'number-pad'\n | 'decimal-pad'\n | 'numeric'\n | 'email-address'\n | 'phone-pad'\n | 'url'\n | 'ascii-capable'\n | 'numbers-and-punctuation'\n | 'name-phone-pad'\n | 'twitter'\n | 'web-search'\n | 'visible-password';\nexport type ReturnKeyType =\n | 'done'\n | 'go'\n | 'next'\n | 'search'\n | 'send'\n | 'none'\n | 'previous'\n | 'default'\n | 'emergency-call'\n | 'google'\n | 'join'\n | 'route'\n | 'yahoo';\nexport type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';\n\n/**\n * A text field, wired for signal forms. Commits as `TextInput`, single or multi line by prop.\n *\n * `value` is a `model()`, which is all `FormValueControl<string>` requires, so binding it into a\n * form is `<text-input [formField]=\"f.name\" />` with no adapter class. The rest of the contract is\n * declared too, because Signal Forms only writes to inputs of those names: `disabled` and\n * `readonly` turn `editable` off, `invalid` and `touched` come out as `data-invalid` and\n * `data-touched` for a stylesheet, and `touch` fires from the native blur - there is no DOM one\n * for the form to hear instead. `(changeText)` carries\n * the new string alone, as RN's `onChangeText` does; the raw `(change)`, `(focus)`, `(blur)`,\n * `(submitEditing)`, `(endEditing)`, `(selectionChange)`, `(keyPress)`, `(contentSizeChange)`\n * and `(scroll)` are element events typed in `events.ts`.\n *\n * The interesting part is the echo. A native text field owns state the user is actively\n * changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`\n * with every change, JS passes the most recent one back as a prop, and native ignores a `text`\n * update whose count is stale, meaning the user has typed since. Without it, a controlled input\n * fights the cursor and drops characters under fast typing.\n *\n * The other direction is native holding text the app does not: a value set from code after the\n * user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -\n * bind `value` and the app's value is what the field shows - so once each pass has rendered, the\n * field compares the model with the text native last reported and sends the difference as the\n * `setTextAndSelection` command. See `ControlledModel` for how a refusal reaches the model.\n * A value set that way is also measured again, since Fabric sizes the field from native state\n * that takes the new text only after measuring it: a composer cleared after sending shrinks.\n */\n@Directive({\n selector: 'text-input',\n exportAs: 'textInput',\n host: {\n '[text]': 'value()',\n '[mostRecentEventCount]': 'eventCount()',\n '[multiline]': 'multiline()',\n '[scrollEnabled]': 'scrollEnabled()',\n '[editable]': 'resolvedEditable()',\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[attr.data-invalid]': \"invalid() ? '' : null\",\n '[attr.data-touched]': \"touched() ? '' : null\",\n '(blur)': 'touch.emit()',\n '(focus)': 'onFocus()',\n '[placeholder]': 'placeholder()',\n '[placeholderTextColor]': 'placeholderTextColor()',\n '[keyboardType]': 'keyboardType()',\n '[returnKeyType]': 'returnKeyType()',\n '[submitBehavior]': 'resolvedSubmitBehavior()',\n '[secureTextEntry]': 'secureTextEntry()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[autoCorrect]': 'autoCorrect()',\n '[autoFocus]': 'autoFocus()',\n '[maxLength]': 'maxLength()',\n '[numberOfLines]': 'numberOfLines()',\n '[rows]': 'rows()',\n '[selection]': 'selection()',\n '[selectionColor]': 'selectionColor()',\n '[selectTextOnFocus]': 'selectTextOnFocus()',\n '[caretHidden]': 'caretHidden()',\n '[contextMenuHidden]': 'contextMenuHidden()',\n '[textAlign]': 'textAlign()',\n '[allowFontScaling]': 'allowFontScaling()',\n '[maxFontSizeMultiplier]': 'maxFontSizeMultiplier()',\n '[inputAccessoryViewID]': 'inputAccessoryViewID()',\n '[clearButtonMode]': 'clearButtonMode()',\n '[clearTextOnFocus]': 'clearTextOnFocus()',\n '[enablesReturnKeyAutomatically]': 'enablesReturnKeyAutomatically()',\n '[keyboardAppearance]': 'keyboardAppearance()',\n '[passwordRules]': 'passwordRules()',\n '[spellCheck]': 'spellCheck()',\n '[smartInsertDelete]': 'smartInsertDelete()',\n '[dataDetectorTypes]': 'dataDetectorTypes()',\n '[textContentType]': 'textContentType()',\n '[autoComplete]': 'autoComplete()',\n '[underlineColorAndroid]': 'underlineColorAndroid()',\n '[cursorColor]': 'cursorColor()',\n '[selectionHandleColor]': 'selectionHandleColor()',\n '[textAlignVertical]': 'textAlignVertical()',\n '[importantForAutofill]': 'importantForAutofill()',\n '[showSoftInputOnFocus]': 'showSoftInputOnFocus()',\n '[disableFullscreenUI]': 'disableFullscreenUI()',\n '[inlineImageLeft]': 'inlineImageLeft()',\n '[inlineImagePadding]': 'inlineImagePadding()',\n '[textBreakStrategy]': 'textBreakStrategy()',\n '(change)': 'onNativeChange($event)',\n },\n})\nexport class TextInput extends ViewBase {\n readonly value = model<string>('');\n /** The new text alone, on every native change. */\n readonly changeText = output<string>();\n /** Focus left the field. What Signal Forms marks a field touched from. */\n readonly touch = output<void>();\n\n /** Refuse input and announce as disabled. Wins over `editable`. */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n /** Refuse input, though still announced as enabled. Wins over `editable`. */\n readonly readonly = input(undefined, { transform: optionalBoolean });\n /** Published as `data-invalid`; nothing native reads it. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Published as `data-touched`; nothing native reads it. */\n readonly touched = input(false, { transform: booleanAttribute });\n\n /** Allow more than one line. */\n readonly multiline = input(undefined, { transform: optionalBoolean });\n /** iOS: whether a multiline field scrolls its text; off, it grows with it instead. */\n readonly scrollEnabled = input(undefined, { transform: optionalBoolean });\n /** Set to false to make the field read-only. */\n readonly editable = input(undefined, { transform: optionalBoolean });\n /** Shown while the field is empty. */\n readonly placeholder = input<string>();\n readonly placeholderTextColor = input<string>();\n /** Which keyboard to show. */\n readonly keyboardType = input<KeyboardType>();\n /** The label on the return key. */\n readonly returnKeyType = input<ReturnKeyType>();\n /** What return does. Defaults to `blurAndSubmit` on one line and `newline` on many. */\n readonly submitBehavior = input<SubmitBehavior>();\n /** Hide what is typed, for passwords. */\n readonly secureTextEntry = input(undefined, { transform: optionalBoolean });\n /** When the keyboard capitalises. Defaults to `sentences`. */\n readonly autoCapitalize = input<'none' | 'sentences' | 'words' | 'characters'>();\n /** Auto-correct while typing. Defaults to true. */\n readonly autoCorrect = input(undefined, { transform: optionalBoolean });\n /** Focus the field as soon as it mounts. */\n readonly autoFocus = input(undefined, { transform: optionalBoolean });\n /** The most characters allowed, enforced natively so nothing flickers. */\n readonly maxLength = input(undefined, { transform: optionalNumber });\n /** Android: the height of a multiline field, in lines. */\n readonly numberOfLines = input(undefined, { transform: optionalNumber });\n /**\n * How many lines of its `line-height` a multiline field is tall, where nothing sets its height,\n * as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.\n */\n readonly rows = input(undefined, { transform: optionalNumber });\n /** The selected range, or the caret when `start` equals `end`. */\n readonly selection = input<{ readonly start: number; readonly end?: number }>();\n readonly selectionColor = input<string>();\n /** Select everything on focus. */\n readonly selectTextOnFocus = input(undefined, { transform: optionalBoolean });\n readonly caretHidden = input(undefined, { transform: optionalBoolean });\n /** Disable the copy, paste and share menu. */\n readonly contextMenuHidden = input(undefined, { transform: optionalBoolean });\n readonly textAlign = input<'left' | 'center' | 'right'>();\n readonly allowFontScaling = input(undefined, { transform: optionalBoolean });\n readonly maxFontSizeMultiplier = input(undefined, { transform: optionalNumber });\n /** iOS: the `nativeID` of an `<input-accessory-view>` to dock above the keyboard. */\n readonly inputAccessoryViewID = input<string>();\n /** iOS: when the clear button shows. */\n readonly clearButtonMode = input<'never' | 'while-editing' | 'unless-editing' | 'always'>();\n /** iOS: empty the field on focus. */\n readonly clearTextOnFocus = input(undefined, { transform: optionalBoolean });\n /** iOS: disable the return key while the field is empty. */\n readonly enablesReturnKeyAutomatically = input(undefined, { transform: optionalBoolean });\n /** iOS: the keyboard's colour scheme. */\n readonly keyboardAppearance = input<'default' | 'light' | 'dark'>();\n /** iOS: rules for a generated password, in Apple's Password Rules syntax. */\n readonly passwordRules = input<string>();\n /** iOS: underline misspellings. Follows `autoCorrect` by default. */\n readonly spellCheck = input(undefined, { transform: optionalBoolean });\n /** iOS: add and remove spaces around pasted and deleted words. */\n readonly smartInsertDelete = input(undefined, { transform: optionalBoolean });\n /** iOS, multiline: turn phone numbers, links and addresses into taps. */\n readonly dataDetectorTypes = input<string | readonly string[]>();\n /** iOS: what the field holds, so the system can autofill it. */\n readonly textContentType = input<string>();\n /** Android: the autofill hint. */\n readonly autoComplete = input<string>();\n /**\n * Android: the underline colour, transparent by default.\n *\n * Not a taste call. Android's `EditText` carries the platform's own underline in its background\n * drawable, so a field with a border of its own draws two: the app's box, and a grey line\n * through it that turns blue on focus. React Native's `TextInput` defaults this prop to\n * `'transparent'` for exactly that reason, and this is that default rather than a new opinion.\n * Ignored on iOS, where the native field has no such chrome.\n */\n readonly underlineColorAndroid = input<string>('transparent');\n /** Android: the caret colour. */\n readonly cursorColor = input<string>();\n /** Android: the selection handle colour. */\n readonly selectionHandleColor = input<string>();\n /** Android: where text sits in a tall field. */\n readonly textAlignVertical = input<'auto' | 'top' | 'bottom' | 'center'>();\n /** Android: whether autofill may fill this field. */\n readonly importantForAutofill = input<\n 'auto' | 'no' | 'noExcludeDescendants' | 'yes' | 'yesExcludeDescendants'\n >();\n /** Android: set to false to focus without raising the keyboard. */\n readonly showSoftInputOnFocus = input(undefined, { transform: optionalBoolean });\n /** Android: keep the field in place in landscape rather than going full screen. */\n readonly disableFullscreenUI = input(undefined, { transform: optionalBoolean });\n /** Android: a drawable resource shown at the left of the field. */\n readonly inlineImageLeft = input<string>();\n readonly inlineImagePadding = input(undefined, { transform: optionalNumber });\n /** Android: the line-breaking strategy. */\n readonly textBreakStrategy = input<'simple' | 'highQuality' | 'balanced'>();\n\n protected readonly eventCount = signal(0);\n\n protected readonly resolvedEditable = computed(() =>\n this.disabled() || this.readonly() ? false : this.editable(),\n );\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n\n protected readonly resolvedSubmitBehavior = computed(() => {\n const explicit = this.submitBehavior();\n // A single-line field has no line to add, so `newline` collapses to the default.\n if (explicit && (this.multiline() || explicit !== 'newline')) return explicit;\n return this.multiline() ? 'newline' : 'blurAndSubmit';\n });\n\n private readonly keyboard = inject(Keyboard);\n /** What native last reported, so a value set from code can be told from an echo. */\n private lastNativeText: string | null = null;\n private readonly control = new ControlledModel(this.value, 'value');\n\n constructor() {\n super();\n // RN's layout effect, keyed as RN keys it: the value, and the count every native change\n // moves on, so a refusal that leaves the value where it was is compared all the same. After\n // render rather than as an ordinary effect, because an accepted edit only reaches the model\n // during change detection, and comparing before it has would send the old text back.\n afterRenderEffect({\n write: () => {\n const desired = this.value();\n const count = this.eventCount();\n if (this.lastNativeText === null || this.lastNativeText === desired) return;\n // The `text` prop alone may be ignored as stale, so send it as a command with the count\n // native expects.\n this.lastNativeText = desired;\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [count, desired, -1, -1]);\n // Fabric sized the field for the text it had; see `HostEngine.remeasure`.\n this.engine.remeasure(this.node);\n },\n });\n }\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n this.control.noteChanges(changes);\n }\n\n /**\n * With the keyboard already up, keep the field clear of it. UIKit scrolls a field clear as the\n * keyboard rises, not when focus moves from one field to another beneath it, which is what a\n * form's Next key does; native form screens keep the new field on screen either way.\n */\n protected onFocus(): void {\n const { height, screenY } = this.keyboard.metrics();\n if (height > 0 && screenY !== undefined)\n this.engine.reveal(this.node, { visibleBottom: screenY });\n }\n\n /** Bring the keyboard up on this field. A view command, so it reaches native directly. */\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field. */\n clear(): void {\n this.value.set('');\n }\n\n /** Move the caret, or select a range. */\n setSelection(start: number, end = start): void {\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n this.eventCount(),\n null,\n start,\n end,\n ]);\n }\n\n /** Whether this field currently has the keyboard. */\n isFocused(): boolean {\n return this.engine.focused === this.node;\n }\n\n protected onNativeChange(event: NativeSyntheticEvent<Partial<TextInputChangePayload>>): void {\n const native = event.nativeEvent;\n const text = native?.text ?? '';\n // Order matters, as it does in RN: the value first, the count last.\n this.lastNativeText = text;\n this.control.propose(text);\n this.eventCount.set(native?.eventCount ?? this.eventCount() + 1);\n this.changeText.emit(text);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"text-input.js","sourceRoot":"","sources":["../src/text-input.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n type SimpleChanges,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { Keyboard } from '@ng-native/device';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ControlledModel } from './controlled-model.ts';\nimport type { SelectionChangePayload, TextInputChangePayload } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\nexport type KeyboardType =\n | 'default'\n | 'number-pad'\n | 'decimal-pad'\n | 'numeric'\n | 'email-address'\n | 'phone-pad'\n | 'url'\n | 'ascii-capable'\n | 'numbers-and-punctuation'\n | 'name-phone-pad'\n | 'twitter'\n | 'web-search'\n | 'visible-password';\nexport type ReturnKeyType =\n | 'done'\n | 'go'\n | 'next'\n | 'search'\n | 'send'\n | 'none'\n | 'previous'\n | 'default'\n | 'emergency-call'\n | 'google'\n | 'join'\n | 'route'\n | 'yahoo';\nexport type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';\n\n/**\n * A text field, wired for signal forms. Commits as `TextInput`, single or multi line by prop.\n *\n * `value` is a `model()`, which is all `FormValueControl<string>` requires, so binding it into a\n * form is `<text-input [formField]=\"f.name\" />` with no adapter class. The rest of the contract is\n * declared too, because Signal Forms only writes to inputs of those names: `disabled` and\n * `readonly` turn `editable` off, `invalid` and `touched` come out as `data-invalid` and\n * `data-touched` for a stylesheet, and `touch` fires from the native blur - there is no DOM one\n * for the form to hear instead. `(changeText)` carries\n * the new string alone, as RN's `onChangeText` does; the raw `(change)`, `(focus)`, `(blur)`,\n * `(submitEditing)`, `(endEditing)`, `(selectionChange)`, `(keyPress)`, `(contentSizeChange)`\n * and `(scroll)` are element events typed in `events.ts`.\n *\n * The interesting part is the echo. A native text field owns state the user is actively\n * changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`\n * with every change, JS passes the most recent one back as a prop, and native ignores a `text`\n * update whose count is stale, meaning the user has typed since. Without it, a controlled input\n * fights the cursor and drops characters under fast typing.\n *\n * The other direction is native holding text the app does not: a value set from code after the\n * user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -\n * bind `value` and the app's value is what the field shows - so once each pass has rendered, the\n * field compares the model with the text native last reported and sends the difference as the\n * `setTextAndSelection` command. See `ControlledModel` for how a refusal reaches the model.\n * A value set that way is also measured again, since Fabric sizes the field from native state\n * that takes the new text only after measuring it: a composer cleared after sending shrinks.\n */\n@Directive({\n selector: 'text-input',\n exportAs: 'textInput',\n host: {\n '[text]': 'value()',\n '[mostRecentEventCount]': 'eventCount()',\n '[multiline]': 'multiline()',\n '[scrollEnabled]': 'scrollEnabled()',\n '[editable]': 'resolvedEditable()',\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[attr.data-invalid]': \"invalid() ? '' : null\",\n '[attr.data-touched]': \"touched() ? '' : null\",\n '(blur)': 'touch.emit()',\n '(focus)': 'onFocus()',\n '[placeholder]': 'placeholder()',\n '[placeholderTextColor]': 'placeholderTextColor()',\n '[keyboardType]': 'keyboardType()',\n '[returnKeyType]': 'returnKeyType()',\n '[submitBehavior]': 'resolvedSubmitBehavior()',\n '[secureTextEntry]': 'secureTextEntry()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[autoCorrect]': 'autoCorrect()',\n '[autoFocus]': 'autoFocus()',\n '[maxLength]': 'maxLength()',\n '[numberOfLines]': 'numberOfLines()',\n '[rows]': 'rows()',\n '[selection]': 'resolvedSelection()',\n '[selectionColor]': 'selectionColor()',\n '[selectTextOnFocus]': 'selectTextOnFocus()',\n '[caretHidden]': 'caretHidden()',\n '[contextMenuHidden]': 'contextMenuHidden()',\n '[textAlign]': 'textAlign()',\n '[allowFontScaling]': 'allowFontScaling()',\n '[maxFontSizeMultiplier]': 'maxFontSizeMultiplier()',\n '[inputAccessoryViewID]': 'inputAccessoryViewID()',\n '[clearButtonMode]': 'clearButtonMode()',\n '[clearTextOnFocus]': 'clearTextOnFocus()',\n '[enablesReturnKeyAutomatically]': 'enablesReturnKeyAutomatically()',\n '[keyboardAppearance]': 'keyboardAppearance()',\n '[passwordRules]': 'passwordRules()',\n '[spellCheck]': 'spellCheck()',\n '[smartInsertDelete]': 'smartInsertDelete()',\n '[dataDetectorTypes]': 'dataDetectorTypes()',\n '[textContentType]': 'textContentType()',\n '[autoComplete]': 'autoComplete()',\n '[underlineColorAndroid]': 'underlineColorAndroid()',\n '[cursorColor]': 'resolvedCursorColor()',\n '[selectionHandleColor]': 'resolvedSelectionHandleColor()',\n '[textAlignVertical]': 'textAlignVertical()',\n '[importantForAutofill]': 'importantForAutofill()',\n '[showSoftInputOnFocus]': 'showSoftInputOnFocus()',\n '[disableFullscreenUI]': 'disableFullscreenUI()',\n '[inlineImageLeft]': 'inlineImageLeft()',\n '[inlineImagePadding]': 'inlineImagePadding()',\n '[textBreakStrategy]': 'textBreakStrategy()',\n '(change)': 'onNativeChange($event)',\n '(selectionChange)': 'onNativeSelectionChange($event)',\n },\n})\nexport class TextInput extends ViewBase {\n readonly value = model<string>('');\n /** The new text alone, on every native change. */\n readonly changeText = output<string>();\n /** Focus left the field. What Signal Forms marks a field touched from. */\n readonly touch = output<void>();\n\n /** Refuse input and announce as disabled. Wins over `editable`. */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n /** Refuse input, though still announced as enabled. Wins over `editable`. */\n readonly readonly = input(undefined, { transform: optionalBoolean });\n /** Published as `data-invalid`; nothing native reads it. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Published as `data-touched`; nothing native reads it. */\n readonly touched = input(false, { transform: booleanAttribute });\n\n /** Allow more than one line. */\n readonly multiline = input(undefined, { transform: optionalBoolean });\n /** iOS: whether a multiline field scrolls its text; off, it grows with it instead. */\n readonly scrollEnabled = input(undefined, { transform: optionalBoolean });\n /** Set to false to make the field read-only. */\n readonly editable = input(undefined, { transform: optionalBoolean });\n /** Shown while the field is empty. */\n readonly placeholder = input<string>();\n readonly placeholderTextColor = input<string>();\n /** Which keyboard to show. */\n readonly keyboardType = input<KeyboardType>();\n /** The label on the return key. */\n readonly returnKeyType = input<ReturnKeyType>();\n /** What return does. Defaults to `blurAndSubmit` on one line and `newline` on many. */\n readonly submitBehavior = input<SubmitBehavior>();\n /** Hide what is typed, for passwords. */\n readonly secureTextEntry = input(undefined, { transform: optionalBoolean });\n /** When the keyboard capitalises. Defaults to `sentences`. */\n readonly autoCapitalize = input<'none' | 'sentences' | 'words' | 'characters'>();\n /** Auto-correct while typing. Defaults to true. */\n readonly autoCorrect = input(undefined, { transform: optionalBoolean });\n /** Focus the field as soon as it mounts. */\n readonly autoFocus = input(undefined, { transform: optionalBoolean });\n /** The most characters allowed, enforced natively so nothing flickers. */\n readonly maxLength = input(undefined, { transform: optionalNumber });\n /** Android: the height of a multiline field, in lines. */\n readonly numberOfLines = input(undefined, { transform: optionalNumber });\n /**\n * How many lines of its `line-height` a multiline field is tall, where nothing sets its height,\n * as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.\n */\n readonly rows = input(undefined, { transform: optionalNumber });\n /**\n * The selected range, or the caret when `end` is left out or equals `start`. Sent to native\n * whenever it differs from what native last had, so a caret the user moves goes back to it.\n */\n readonly selection = input<{ readonly start: number; readonly end?: number }>();\n readonly selectionColor = input<string>();\n /** Select everything on focus. */\n readonly selectTextOnFocus = input(undefined, { transform: optionalBoolean });\n readonly caretHidden = input(undefined, { transform: optionalBoolean });\n /** Disable the copy, paste and share menu. */\n readonly contextMenuHidden = input(undefined, { transform: optionalBoolean });\n readonly textAlign = input<'left' | 'center' | 'right'>();\n readonly allowFontScaling = input(undefined, { transform: optionalBoolean });\n readonly maxFontSizeMultiplier = input(undefined, { transform: optionalNumber });\n /** iOS: the `nativeID` of an `<input-accessory-view>` to dock above the keyboard. */\n readonly inputAccessoryViewID = input<string>();\n /** iOS: when the clear button shows. */\n readonly clearButtonMode = input<'never' | 'while-editing' | 'unless-editing' | 'always'>();\n /** iOS: empty the field on focus. */\n readonly clearTextOnFocus = input(undefined, { transform: optionalBoolean });\n /** iOS: disable the return key while the field is empty. */\n readonly enablesReturnKeyAutomatically = input(undefined, { transform: optionalBoolean });\n /** iOS: the keyboard's colour scheme. */\n readonly keyboardAppearance = input<'default' | 'light' | 'dark'>();\n /** iOS: rules for a generated password, in Apple's Password Rules syntax. */\n readonly passwordRules = input<string>();\n /** iOS: underline misspellings. Follows `autoCorrect` by default. */\n readonly spellCheck = input(undefined, { transform: optionalBoolean });\n /** iOS: add and remove spaces around pasted and deleted words. */\n readonly smartInsertDelete = input(undefined, { transform: optionalBoolean });\n /** iOS, multiline: turn phone numbers, links and addresses into taps. */\n readonly dataDetectorTypes = input<string | readonly string[]>();\n /** iOS: what the field holds, so the system can autofill it. */\n readonly textContentType = input<string>();\n /** Android: the autofill hint. */\n readonly autoComplete = input<string>();\n /**\n * Android: the underline colour, transparent by default.\n *\n * Not a taste call. Android's `EditText` carries the platform's own underline in its background\n * drawable, so a field with a border of its own draws two: the app's box, and a grey line\n * through it that turns blue on focus. React Native's `TextInput` defaults this prop to\n * `'transparent'` for exactly that reason, and this is that default rather than a new opinion.\n * Ignored on iOS, where the native field has no such chrome.\n */\n readonly underlineColorAndroid = input<string>('transparent');\n /** Android: the caret colour. Follows `selectionColor` by default, as RN's does. */\n readonly cursorColor = input<string>();\n /** Android: the selection handle colour. Follows `selectionColor` by default, as RN's does. */\n readonly selectionHandleColor = input<string>();\n /** Android: where text sits in a tall field. */\n readonly textAlignVertical = input<'auto' | 'top' | 'bottom' | 'center'>();\n /** Android: whether autofill may fill this field. */\n readonly importantForAutofill = input<\n 'auto' | 'no' | 'noExcludeDescendants' | 'yes' | 'yesExcludeDescendants'\n >();\n /** Android: set to false to focus without raising the keyboard. */\n readonly showSoftInputOnFocus = input(undefined, { transform: optionalBoolean });\n /** Android: keep the field in place in landscape rather than going full screen. */\n readonly disableFullscreenUI = input(undefined, { transform: optionalBoolean });\n /** Android: a drawable resource shown at the left of the field. */\n readonly inlineImageLeft = input<string>();\n readonly inlineImagePadding = input(undefined, { transform: optionalNumber });\n /** Android: the line-breaking strategy. */\n readonly textBreakStrategy = input<'simple' | 'highQuality' | 'balanced'>();\n\n protected readonly eventCount = signal(0);\n\n /** RN's normalised selection: an `end` left out is `start`, where iOS would read 0. */\n protected readonly resolvedSelection = computed(() => {\n const selection = this.selection();\n return selection\n ? { start: selection.start, end: selection.end ?? selection.start }\n : undefined;\n });\n\n // RN's Android defaults, checked against `undefined` as RN does rather than with `??`.\n protected readonly resolvedCursorColor = computed(() => {\n const color = this.cursorColor();\n return color === undefined ? this.selectionColor() : color;\n });\n protected readonly resolvedSelectionHandleColor = computed(() => {\n const color = this.selectionHandleColor();\n return color === undefined ? this.selectionColor() : color;\n });\n\n protected readonly resolvedEditable = computed(() =>\n this.disabled() || this.readonly() ? false : this.editable(),\n );\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n\n protected readonly resolvedSubmitBehavior = computed(() => {\n const explicit = this.submitBehavior();\n // A single-line field has no line to add, so `newline` collapses to the default.\n if (explicit && (this.multiline() || explicit !== 'newline')) return explicit;\n return this.multiline() ? 'newline' : 'blurAndSubmit';\n });\n\n private readonly keyboard = inject(Keyboard);\n /** What native last reported, so a value set from code can be told from an echo. */\n private lastNativeText: string | null = null;\n /**\n * The selection native last had, sent or reported, so a bound one is sent only when it differs.\n * Unset to start with, so the first bound selection goes out too.\n */\n private lastSelection = { start: -1, end: -1 };\n /** Moved on every reported selection, so the bound one is compared with it again. */\n private readonly selectionReports = signal(0);\n private readonly control = new ControlledModel(this.value, 'value');\n\n constructor() {\n super();\n // RN's layout effect, keyed as RN keys it: the value, the selection, and the count every\n // native change moves on, so a refusal that leaves the value where it was is compared all the\n // same. After render rather than as an ordinary effect, because an accepted edit only reaches\n // the model during change detection, and comparing before it has would send the old text back.\n afterRenderEffect({ write: () => this.syncWithNative() });\n }\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n this.control.noteChanges(changes);\n }\n\n /**\n * With the keyboard already up, keep the field clear of it. UIKit scrolls a field clear as the\n * keyboard rises, not when focus moves from one field to another beneath it, which is what a\n * form's Next key does; native form screens keep the new field on screen either way.\n */\n protected onFocus(): void {\n const { height, screenY } = this.keyboard.metrics();\n if (height > 0 && screenY !== undefined)\n this.engine.reveal(this.node, { visibleBottom: screenY - this.keyboard.windowTop });\n }\n\n /** Bring the keyboard up on this field. A view command, so it reaches native directly. */\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field. */\n clear(): void {\n this.value.set('');\n }\n\n /** Move the caret, or select a range. */\n setSelection(start: number, end = start): void {\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n this.eventCount(),\n null,\n start,\n end,\n ]);\n }\n\n /** Whether this field currently has the keyboard. */\n isFocused(): boolean {\n return this.engine.focused === this.node;\n }\n\n protected onNativeChange(event: NativeSyntheticEvent<Partial<TextInputChangePayload>>): void {\n const native = event.nativeEvent;\n const text = native?.text ?? '';\n // Order matters, as it does in RN: the value first, the count last.\n this.lastNativeText = text;\n this.control.propose(text);\n this.eventCount.set(native?.eventCount ?? this.eventCount() + 1);\n this.changeText.emit(text);\n }\n\n /** Send native the text and selection it does not have, as one `setTextAndSelection`. */\n private syncWithNative(): void {\n const desired = this.value();\n const count = this.eventCount();\n const selection = this.resolvedSelection();\n this.selectionReports();\n const textChanged = this.lastNativeText !== null && this.lastNativeText !== desired;\n if (!textChanged && !this.differsFromNative(selection)) return;\n if (textChanged) this.lastNativeText = desired;\n if (selection) this.lastSelection = selection;\n // The `text` prop alone may be ignored as stale, so send it as a command with the count\n // native expects, and the text and bound selection as RN does whichever of them changed.\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n count,\n desired,\n selection?.start ?? -1,\n selection?.end ?? -1,\n ]);\n // Fabric sized the field for the text it had; see `HostEngine.remeasure`.\n if (textChanged) this.engine.remeasure(this.node);\n }\n\n /**\n * Whether a bound selection is not the one native last had. The prop alone does not move the\n * caret: Android has no `selection` prop, and iOS reads it only as the field appears or its\n * text is replaced.\n */\n private differsFromNative(selection: { start: number; end: number } | undefined): boolean {\n return (\n selection !== undefined &&\n (selection.start !== this.lastSelection.start || selection.end !== this.lastSelection.end)\n );\n }\n\n /** What native now has selected, which a bound selection that differs is sent over again. */\n protected onNativeSelectionChange(\n event: NativeSyntheticEvent<Partial<SelectionChangePayload>>,\n ): void {\n const selection = event.nativeEvent?.selection;\n if (!selection) return;\n this.lastSelection = { start: selection.start, end: selection.end };\n this.selectionReports.update((n) => n + 1);\n }\n}\n"]}
|
|
@@ -3,15 +3,18 @@ import * as i0 from "@angular/core";
|
|
|
3
3
|
/**
|
|
4
4
|
* A pressable that dims while pressed, as RN's `TouchableOpacity` does.
|
|
5
5
|
*
|
|
6
|
-
* The fade is a CSS transition rather than a JavaScript tween:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* The fade is a CSS transition rather than a JavaScript tween: a rule sets the pressed opacity and
|
|
7
|
+
* the engine eases to it. React Native's own timings are asymmetric - 150ms in, 250ms out - which
|
|
8
|
+
* is a thing CSS expresses exactly, because the duration in force is the one on the state being
|
|
9
|
+
* entered. That is what the two rules below are.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Nothing here states the resting opacity, so whatever the cascade gives the host is what a press
|
|
12
|
+
* eases back to: a class, Tailwind's, an inline `[style]` or a bound `[style.opacity]`, read when
|
|
13
|
+
* the press ends as `TouchableOpacity.js` reads its style, and followed as it changes. An opacity
|
|
14
|
+
* nothing sets is still 1 to ease from and to. The pressed rule is `!important` because a
|
|
15
|
+
* caller's inline opacity outranks this component's host bindings and plain rules alike, and
|
|
16
|
+
* would otherwise keep it from dimming at all; `activeOpacity` reaches it as a custom property,
|
|
17
|
+
* which no caller's style sets.
|
|
15
18
|
*/
|
|
16
19
|
export declare class TouchableOpacity extends ControlBase {
|
|
17
20
|
/** `TouchableOpacity.js`: `accessible={this.props.accessible !== false}`, and focusable too. */
|
|
@@ -21,17 +24,6 @@ export declare class TouchableOpacity extends ControlBase {
|
|
|
21
24
|
protected pressDisabled(): boolean;
|
|
22
25
|
/** The opacity while pressed. */
|
|
23
26
|
readonly activeOpacity: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
24
|
-
/** Undefined at rest, so the caller's own `[style]` opacity shows through. */
|
|
25
|
-
protected readonly opacity: import("@angular/core").WritableSignal<number | undefined>;
|
|
26
|
-
/** What to ease back to: whatever the caller had before the press. */
|
|
27
|
-
private resting;
|
|
28
|
-
constructor();
|
|
29
|
-
/**
|
|
30
|
-
* The fade is over. Letting go of the value hands the opacity back to whatever the caller's own
|
|
31
|
-
* style says, which is the same number we just eased to - so nothing moves, and a caller who
|
|
32
|
-
* changes it later is not fighting a binding of ours.
|
|
33
|
-
*/
|
|
34
|
-
protected settle(): void;
|
|
35
27
|
static ɵfac: i0.ɵɵFactoryDeclaration<TouchableOpacity, never>;
|
|
36
28
|
static ɵcmp: i0.ɵɵComponentDeclaration<TouchableOpacity, "touchable-opacity", ["touchableOpacity"], { "activeOpacity": { "alias": "activeOpacity"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
37
29
|
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { Component,
|
|
1
|
+
import { Component, input } from '@angular/core';
|
|
2
2
|
import { ControlBase } from "./pressable.js";
|
|
3
3
|
import { numberOr } from "./transforms.js";
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
/**
|
|
6
6
|
* A pressable that dims while pressed, as RN's `TouchableOpacity` does.
|
|
7
7
|
*
|
|
8
|
-
* The fade is a CSS transition rather than a JavaScript tween:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* The fade is a CSS transition rather than a JavaScript tween: a rule sets the pressed opacity and
|
|
9
|
+
* the engine eases to it. React Native's own timings are asymmetric - 150ms in, 250ms out - which
|
|
10
|
+
* is a thing CSS expresses exactly, because the duration in force is the one on the state being
|
|
11
|
+
* entered. That is what the two rules below are.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Nothing here states the resting opacity, so whatever the cascade gives the host is what a press
|
|
14
|
+
* eases back to: a class, Tailwind's, an inline `[style]` or a bound `[style.opacity]`, read when
|
|
15
|
+
* the press ends as `TouchableOpacity.js` reads its style, and followed as it changes. An opacity
|
|
16
|
+
* nothing sets is still 1 to ease from and to. The pressed rule is `!important` because a
|
|
17
|
+
* caller's inline opacity outranks this component's host bindings and plain rules alike, and
|
|
18
|
+
* would otherwise keep it from dimming at all; `activeOpacity` reaches it as a custom property,
|
|
19
|
+
* which no caller's style sets.
|
|
17
20
|
*/
|
|
18
21
|
export class TouchableOpacity extends ControlBase {
|
|
19
22
|
/** `TouchableOpacity.js`: `accessible={this.props.accessible !== false}`, and focusable too. */
|
|
@@ -31,50 +34,14 @@ export class TouchableOpacity extends ControlBase {
|
|
|
31
34
|
}
|
|
32
35
|
/** The opacity while pressed. */
|
|
33
36
|
activeOpacity = input(0.2, { ...(ngDevMode ? { debugName: "activeOpacity" } : /* istanbul ignore next */ {}), transform: numberOr(0.2) });
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
...(ngDevMode ? [{ debugName: "opacity" }] : /* istanbul ignore next */ []));
|
|
37
|
-
/** What to ease back to: whatever the caller had before the press. */
|
|
38
|
-
resting = 1;
|
|
39
|
-
constructor() {
|
|
40
|
-
super();
|
|
41
|
-
// Reacts to `pressed` alone. Reading `opacity` here would re-run the effect on the value it
|
|
42
|
-
// just wrote, and a press that arrives mid-fade would restart from the wrong end.
|
|
43
|
-
effect(() => {
|
|
44
|
-
const pressed = this.pressed();
|
|
45
|
-
untracked(() => {
|
|
46
|
-
if (pressed) {
|
|
47
|
-
// Remembered on the way in, so the fade out returns to it rather than to 1.
|
|
48
|
-
const style = this.node.props['style'];
|
|
49
|
-
this.resting = this.opacity() ?? style?.opacity ?? 1;
|
|
50
|
-
this.opacity.set(this.activeOpacity());
|
|
51
|
-
}
|
|
52
|
-
else if (this.opacity() !== undefined) {
|
|
53
|
-
this.opacity.set(this.resting);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
// A component destroyed mid-fade leaves a transition the engine would go on advancing.
|
|
58
|
-
inject(DestroyRef).onDestroy(() => this.opacity.set(undefined));
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* The fade is over. Letting go of the value hands the opacity back to whatever the caller's own
|
|
62
|
-
* style says, which is the same number we just eased to - so nothing moves, and a caller who
|
|
63
|
-
* changes it later is not fighting a binding of ours.
|
|
64
|
-
*/
|
|
65
|
-
settle() {
|
|
66
|
-
if (!this.pressed())
|
|
67
|
-
this.opacity.set(undefined);
|
|
68
|
-
}
|
|
69
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TouchableOpacity, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
70
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: TouchableOpacity, isStandalone: true, selector: "touchable-opacity", inputs: { activeOpacity: { classPropertyName: "activeOpacity", publicName: "activeOpacity", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "transitionend": "settle()" }, properties: { "style.opacity": "opacity()", "class.pressed": "pressed()" } }, exportAs: ["touchableOpacity"], usesInheritance: true, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["\n /*\n * The resting opacity is stated rather than left out, because a transition needs a value to\n * ease *from*: a property appearing for the first time is recorded and left alone, which is\n * CSS's own rule and would make every fade in a snap. Inline style still wins over this, so a\n * caller's own opacity is untouched.\n */\n :host {\n opacity: 1;\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n transition: opacity 150ms ease-in-out;\n }\n "] });
|
|
37
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TouchableOpacity, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
38
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: TouchableOpacity, isStandalone: true, selector: "touchable-opacity", inputs: { activeOpacity: { classPropertyName: "activeOpacity", publicName: "activeOpacity", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--touchable-active-opacity": "activeOpacity()", "class.pressed": "pressed()" } }, exportAs: ["touchableOpacity"], usesInheritance: true, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["\n :host {\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n opacity: var(--touchable-active-opacity, 0.2) !important;\n transition: opacity 150ms ease-in-out;\n }\n "] });
|
|
71
39
|
}
|
|
72
40
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TouchableOpacity, decorators: [{
|
|
73
41
|
type: Component,
|
|
74
42
|
args: [{ selector: 'touchable-opacity', template: `<ng-content />`, exportAs: 'touchableOpacity', host: {
|
|
75
|
-
'[style
|
|
43
|
+
'[style.--touchable-active-opacity]': 'activeOpacity()',
|
|
76
44
|
'[class.pressed]': 'pressed()',
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}], ctorParameters: () => [], propDecorators: { activeOpacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeOpacity", required: false }] }] } });
|
|
45
|
+
}, styles: ["\n :host {\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n opacity: var(--touchable-active-opacity, 0.2) !important;\n transition: opacity 150ms ease-in-out;\n }\n "] }]
|
|
46
|
+
}], propDecorators: { activeOpacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeOpacity", required: false }] }] } });
|
|
80
47
|
//# sourceMappingURL=touchable-opacity.js.map
|