@symbiote-native/components 0.1.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/LICENSE +21 -0
- package/README.md +110 -0
- package/build/accessibility-props.d.ts +64 -0
- package/build/accessibility-props.js +150 -0
- package/build/component-names/index.android.d.ts +3 -0
- package/build/component-names/index.android.js +32 -0
- package/build/component-names/index.d.ts +1 -0
- package/build/component-names/index.ios.d.ts +3 -0
- package/build/component-names/index.ios.js +26 -0
- package/build/component-names/index.js +5 -0
- package/build/component-names/shared.d.ts +7 -0
- package/build/component-names/shared.js +36 -0
- package/build/descriptor.d.ts +11 -0
- package/build/descriptor.js +17 -0
- package/build/index.d.ts +51 -0
- package/build/index.js +63 -0
- package/build/responder-props.d.ts +18 -0
- package/build/responder-props.js +9 -0
- package/build/scroll-view-commands.d.ts +23 -0
- package/build/scroll-view-commands.js +123 -0
- package/build/state/drawer-layout-android.d.ts +22 -0
- package/build/state/drawer-layout-android.js +53 -0
- package/build/state/flat-list.d.ts +12 -0
- package/build/state/flat-list.js +40 -0
- package/build/state/modal.d.ts +11 -0
- package/build/state/modal.js +28 -0
- package/build/state/pressable.d.ts +90 -0
- package/build/state/pressable.js +236 -0
- package/build/state/section-list.d.ts +46 -0
- package/build/state/section-list.js +51 -0
- package/build/state/switch.d.ts +12 -0
- package/build/state/switch.js +31 -0
- package/build/state/text-input.d.ts +103 -0
- package/build/state/text-input.js +205 -0
- package/build/state/touchable.d.ts +15 -0
- package/build/state/touchable.js +22 -0
- package/build/state/virtualized-list.d.ts +161 -0
- package/build/state/virtualized-list.js +306 -0
- package/build/view/render-activity-indicator.d.ts +25 -0
- package/build/view/render-activity-indicator.js +54 -0
- package/build/view/render-button.d.ts +19 -0
- package/build/view/render-button.js +24 -0
- package/build/view/render-drawer-layout-android.d.ts +23 -0
- package/build/view/render-drawer-layout-android.js +56 -0
- package/build/view/render-image-background.d.ts +9 -0
- package/build/view/render-image-background.js +48 -0
- package/build/view/render-image.d.ts +86 -0
- package/build/view/render-image.js +298 -0
- package/build/view/render-input-accessory-view.d.ts +9 -0
- package/build/view/render-input-accessory-view.js +18 -0
- package/build/view/render-keyboard-avoiding-view.d.ts +30 -0
- package/build/view/render-keyboard-avoiding-view.js +75 -0
- package/build/view/render-modal.d.ts +23 -0
- package/build/view/render-modal.js +70 -0
- package/build/view/render-pressable.d.ts +8 -0
- package/build/view/render-pressable.js +42 -0
- package/build/view/render-scroll-sticky.d.ts +24 -0
- package/build/view/render-scroll-sticky.js +81 -0
- package/build/view/render-scroll-view.d.ts +18 -0
- package/build/view/render-scroll-view.js +85 -0
- package/build/view/render-switch.d.ts +29 -0
- package/build/view/render-switch.js +33 -0
- package/build/view/render-text-input.d.ts +11 -0
- package/build/view/render-text-input.js +35 -0
- package/build/view/render-touchable-native-feedback.d.ts +17 -0
- package/build/view/render-touchable-native-feedback.js +39 -0
- package/package.json +38 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// TextInput: the logic half (framework-agnostic, zero render). TextInput is the controlled-
|
|
2
|
+
// value / event-count handshake primitive. There is NO `value` Fabric prop: JS folds
|
|
3
|
+
// value/defaultValue into a single private `text` prop plus a `mostRecentEventCount` counter.
|
|
4
|
+
// Native increments its own counter per keystroke and rejects stale writes by
|
|
5
|
+
// eventLag = nativeCount - mostRecentEventCount, so a controlled JS write must push the
|
|
6
|
+
// ACKNOWLEDGED count (the one native last reported) through the setTextAndSelection view
|
|
7
|
+
// command, never a plain prop re-push, which would fight the cursor.
|
|
8
|
+
//
|
|
9
|
+
// Unlike Switch this is NOT a single reducer: the handshake holds two pieces with different
|
|
10
|
+
// reactivity needs: `mostRecentEventCount` must re-render so the imperative handle echoes the
|
|
11
|
+
// latest count, while `lastNativeText` is bookkeeping the controlled-write effect mutates
|
|
12
|
+
// without a render. So the logic layer is the pure folds/maps + the controlled-write predicate;
|
|
13
|
+
// each adapter holds the two pieces in ITS own primitives (React useState/useRef, Vue ref/let).
|
|
14
|
+
// The acknowledged count starts at 0, native has reported nothing yet, so the first
|
|
15
|
+
// controlled write echoes 0 and lands on eventLag 0.
|
|
16
|
+
export const INITIAL_EVENT_COUNT = 0;
|
|
17
|
+
// RN's "no selection" sentinel for setTextAndSelection: a negative index tells native to
|
|
18
|
+
// leave the caret where it is rather than move it (used on a controlled write with no
|
|
19
|
+
// explicit selection).
|
|
20
|
+
export const SELECTION_NONE = -1;
|
|
21
|
+
// The W3C/alias → native lookup tables. Typed Record<string, string> (not Record<IInputMode,
|
|
22
|
+
// string>) so the one safe-lookup helper (mapAutoComplete) serves every map without a cast;
|
|
23
|
+
// the union types above still guard the app-facing prop contract.
|
|
24
|
+
// RN's inputMode -> keyboardType map (TextInput.js:815). `search` is platform-split (iOS
|
|
25
|
+
// 'web-search', else 'default'); we use the Android/default branch since the folded prop is
|
|
26
|
+
// forwarded verbatim and the safe default avoids an unknown keyboardType on Android.
|
|
27
|
+
const inputModeToKeyboardType = {
|
|
28
|
+
decimal: 'decimal-pad',
|
|
29
|
+
email: 'email-address',
|
|
30
|
+
none: 'default',
|
|
31
|
+
numeric: 'number-pad',
|
|
32
|
+
search: 'default',
|
|
33
|
+
tel: 'phone-pad',
|
|
34
|
+
text: 'default',
|
|
35
|
+
url: 'url',
|
|
36
|
+
};
|
|
37
|
+
// RN's enterKeyHint -> returnKeyType map (TextInput.js:805). Note `enter` -> 'default'.
|
|
38
|
+
const enterKeyHintToReturnKeyType = {
|
|
39
|
+
done: 'done',
|
|
40
|
+
enter: 'default',
|
|
41
|
+
go: 'go',
|
|
42
|
+
next: 'next',
|
|
43
|
+
previous: 'previous',
|
|
44
|
+
search: 'search',
|
|
45
|
+
send: 'send',
|
|
46
|
+
};
|
|
47
|
+
// RN's W3C autocomplete -> Android `autoComplete` map (TextInput.js:828). A token with no
|
|
48
|
+
// native equivalent passes through unchanged (RN's `?? autoComplete`).
|
|
49
|
+
const autoCompleteWebToAndroid = {
|
|
50
|
+
'additional-name': 'name-middle',
|
|
51
|
+
'address-line1': 'postal-address-region',
|
|
52
|
+
'address-line2': 'postal-address-locality',
|
|
53
|
+
bday: 'birthdate-full',
|
|
54
|
+
'bday-day': 'birthdate-day',
|
|
55
|
+
'bday-month': 'birthdate-month',
|
|
56
|
+
'bday-year': 'birthdate-year',
|
|
57
|
+
'cc-csc': 'cc-csc',
|
|
58
|
+
'cc-exp': 'cc-exp',
|
|
59
|
+
'cc-exp-month': 'cc-exp-month',
|
|
60
|
+
'cc-exp-year': 'cc-exp-year',
|
|
61
|
+
'cc-number': 'cc-number',
|
|
62
|
+
country: 'postal-address-country',
|
|
63
|
+
'current-password': 'password',
|
|
64
|
+
email: 'email',
|
|
65
|
+
'family-name': 'name-family',
|
|
66
|
+
'given-name': 'name-given',
|
|
67
|
+
'honorific-prefix': 'name-prefix',
|
|
68
|
+
'honorific-suffix': 'name-suffix',
|
|
69
|
+
name: 'name',
|
|
70
|
+
'new-password': 'password-new',
|
|
71
|
+
off: 'off',
|
|
72
|
+
'one-time-code': 'sms-otp',
|
|
73
|
+
'postal-code': 'postal-code',
|
|
74
|
+
sex: 'gender',
|
|
75
|
+
'street-address': 'street-address',
|
|
76
|
+
tel: 'tel',
|
|
77
|
+
'tel-country-code': 'tel-country-code',
|
|
78
|
+
'tel-national': 'tel-national',
|
|
79
|
+
username: 'username',
|
|
80
|
+
};
|
|
81
|
+
// RN's W3C autocomplete -> iOS `textContentType` map (TextInput.js:862). A token absent here
|
|
82
|
+
// leaves textContentType undefined on iOS (RN's `autoComplete in map` guard).
|
|
83
|
+
const autoCompleteWebToTextContentType = {
|
|
84
|
+
'additional-name': 'middleName',
|
|
85
|
+
'address-line1': 'streetAddressLine1',
|
|
86
|
+
'address-line2': 'streetAddressLine2',
|
|
87
|
+
bday: 'birthdate',
|
|
88
|
+
'bday-day': 'birthdateDay',
|
|
89
|
+
'bday-month': 'birthdateMonth',
|
|
90
|
+
'bday-year': 'birthdateYear',
|
|
91
|
+
'cc-additional-name': 'creditCardMiddleName',
|
|
92
|
+
'cc-csc': 'creditCardSecurityCode',
|
|
93
|
+
'cc-exp': 'creditCardExpiration',
|
|
94
|
+
'cc-exp-month': 'creditCardExpirationMonth',
|
|
95
|
+
'cc-exp-year': 'creditCardExpirationYear',
|
|
96
|
+
'cc-family-name': 'creditCardFamilyName',
|
|
97
|
+
'cc-given-name': 'creditCardGivenName',
|
|
98
|
+
'cc-name': 'creditCardName',
|
|
99
|
+
'cc-number': 'creditCardNumber',
|
|
100
|
+
'cc-type': 'creditCardType',
|
|
101
|
+
country: 'countryName',
|
|
102
|
+
'current-password': 'password',
|
|
103
|
+
email: 'emailAddress',
|
|
104
|
+
'family-name': 'familyName',
|
|
105
|
+
'given-name': 'givenName',
|
|
106
|
+
'honorific-prefix': 'namePrefix',
|
|
107
|
+
'honorific-suffix': 'nameSuffix',
|
|
108
|
+
name: 'name',
|
|
109
|
+
'new-password': 'newPassword',
|
|
110
|
+
nickname: 'nickname',
|
|
111
|
+
off: 'none',
|
|
112
|
+
'one-time-code': 'oneTimeCode',
|
|
113
|
+
organization: 'organizationName',
|
|
114
|
+
'organization-title': 'jobTitle',
|
|
115
|
+
'postal-code': 'postalCode',
|
|
116
|
+
'street-address': 'fullStreetAddress',
|
|
117
|
+
tel: 'telephoneNumber',
|
|
118
|
+
url: 'URL',
|
|
119
|
+
username: 'username',
|
|
120
|
+
};
|
|
121
|
+
// Safe lookup into a W3C->native / alias->native map (no `as`): own-property guard, undefined
|
|
122
|
+
// if the token has no native equivalent. The caller decides the per-platform fallback. Named
|
|
123
|
+
// for its first user (autoComplete), but it is the one generic safe lookup every map shares.
|
|
124
|
+
export function mapAutoComplete(map, token) {
|
|
125
|
+
return Object.prototype.hasOwnProperty.call(map, token) ? map[token] : undefined;
|
|
126
|
+
}
|
|
127
|
+
// RN folds W3C `autoComplete` per platform (TextInput.js:938): Android takes the mapped
|
|
128
|
+
// `autoComplete` token (falling back to the raw token), iOS takes the mapped `textContentType`
|
|
129
|
+
// (only when the token is in the map, else leaves it untouched). Symbiote is Metro-built per
|
|
130
|
+
// platform but folds platform-agnostically, resolving BOTH native props from the one token:
|
|
131
|
+
// the iOS-only `textContentType` is inert on Android and the Android `autoComplete` token is
|
|
132
|
+
// inert on iOS, so emitting both is safe: same shape as the dual-keyed events.
|
|
133
|
+
export function foldAutoComplete(token) {
|
|
134
|
+
if (token === undefined)
|
|
135
|
+
return { autoComplete: undefined, textContentType: undefined };
|
|
136
|
+
return {
|
|
137
|
+
autoComplete: mapAutoComplete(autoCompleteWebToAndroid, token) ?? token,
|
|
138
|
+
textContentType: mapAutoComplete(autoCompleteWebToTextContentType, token),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// RN's submitBehavior reconciliation (TextInput.js:559). Explicit submitBehavior wins (with
|
|
142
|
+
// single-line 'newline' coerced to 'blurAndSubmit'); else it is derived from the legacy
|
|
143
|
+
// blurOnSubmit per multiline. Input/output are plain strings: the result is forwarded to the
|
|
144
|
+
// native prop verbatim, so no ISubmitBehavior union is needed at the seam.
|
|
145
|
+
export function foldSubmitBehavior(submitBehavior, blurOnSubmit, multiline) {
|
|
146
|
+
if (submitBehavior !== undefined) {
|
|
147
|
+
if (!multiline && submitBehavior === 'newline')
|
|
148
|
+
return 'blurAndSubmit';
|
|
149
|
+
return submitBehavior;
|
|
150
|
+
}
|
|
151
|
+
if (multiline)
|
|
152
|
+
return blurOnSubmit === true ? 'blurAndSubmit' : 'newline';
|
|
153
|
+
return blurOnSubmit !== false ? 'blurAndSubmit' : 'submit';
|
|
154
|
+
}
|
|
155
|
+
// RN's fold: value wins, else defaultValue, else leave undefined (uncontrolled).
|
|
156
|
+
export function foldText(value, defaultValue) {
|
|
157
|
+
if (typeof value === 'string')
|
|
158
|
+
return value;
|
|
159
|
+
if (typeof defaultValue === 'string')
|
|
160
|
+
return defaultValue;
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
// The change payload carries the new text + native event counter. nativeEvent is an untyped
|
|
164
|
+
// Record, so narrow each.
|
|
165
|
+
export function textFromChange(event) {
|
|
166
|
+
const text = event.nativeEvent.text;
|
|
167
|
+
return typeof text === 'string' ? text : undefined;
|
|
168
|
+
}
|
|
169
|
+
export function eventCountFromChange(event) {
|
|
170
|
+
const count = event.nativeEvent.eventCount;
|
|
171
|
+
return typeof count === 'number' ? count : undefined;
|
|
172
|
+
}
|
|
173
|
+
// Controlled-write decision: command native back only when JS-side `value` is a string that
|
|
174
|
+
// diverges from what native last reported. A plain prop re-push would race the user's
|
|
175
|
+
// keystrokes; the setTextAndSelection command is the only stale-safe path. The guard narrows
|
|
176
|
+
// `value` to string so the caller can build the command args without re-checking.
|
|
177
|
+
export function shouldCommandText(lastNativeText, value) {
|
|
178
|
+
return typeof value === 'string' && lastNativeText !== value;
|
|
179
|
+
}
|
|
180
|
+
// The whole per-platform-agnostic prop fold in one place (TextInput.js:928-946), shared by every
|
|
181
|
+
// adapter: inputMode wins over keyboardType, enterKeyHint over returnKeyType, readOnly over
|
|
182
|
+
// editable (inverted), the cursor/selection-handle colors default from selectionColor, the W3C
|
|
183
|
+
// autoComplete token folds to the per-platform native prop (an explicit textContentType still
|
|
184
|
+
// wins), inputMode forces softInput visibility, and underlineColorAndroid defaults to
|
|
185
|
+
// 'transparent' to hide the Material EditText bar.
|
|
186
|
+
export function resolveTextInputProps(input) {
|
|
187
|
+
const folded = foldAutoComplete(input.autoComplete);
|
|
188
|
+
return {
|
|
189
|
+
keyboardType: input.inputMode !== undefined
|
|
190
|
+
? mapAutoComplete(inputModeToKeyboardType, input.inputMode)
|
|
191
|
+
: input.keyboardType,
|
|
192
|
+
returnKeyType: input.enterKeyHint !== undefined
|
|
193
|
+
? mapAutoComplete(enterKeyHintToReturnKeyType, input.enterKeyHint)
|
|
194
|
+
: input.returnKeyType,
|
|
195
|
+
editable: input.readOnly !== undefined ? !input.readOnly : input.editable,
|
|
196
|
+
submitBehavior: foldSubmitBehavior(input.submitBehavior, input.blurOnSubmit, input.multiline),
|
|
197
|
+
selectionColor: input.selectionColor,
|
|
198
|
+
cursorColor: input.cursorColor !== undefined ? input.cursorColor : input.selectionColor,
|
|
199
|
+
selectionHandleColor: input.selectionHandleColor !== undefined ? input.selectionHandleColor : input.selectionColor,
|
|
200
|
+
underlineColorAndroid: input.underlineColorAndroid !== undefined ? input.underlineColorAndroid : 'transparent',
|
|
201
|
+
autoComplete: folded.autoComplete,
|
|
202
|
+
textContentType: input.textContentType !== undefined ? input.textContentType : folded.textContentType,
|
|
203
|
+
showSoftInputOnFocus: input.inputMode !== undefined ? input.inputMode !== 'none' : input.showSoftInputOnFocus,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ISymbioteEvent } from '@symbiote-native/engine';
|
|
2
|
+
export declare const DEFAULT_ACTIVE_OPACITY = 0.2;
|
|
3
|
+
export declare const OPACITY_ACTIVE_DURATION_MS = 150;
|
|
4
|
+
export declare const OPACITY_INACTIVE_DURATION_MS = 250;
|
|
5
|
+
export declare const RESTING_OPACITY = 1;
|
|
6
|
+
export declare const DEFAULT_HIGHLIGHT_CHILD_OPACITY = 0.85;
|
|
7
|
+
export declare const DEFAULT_UNDERLAY_COLOR = "black";
|
|
8
|
+
export declare const DEFAULT_MIN_PRESS_DURATION_MS = 130;
|
|
9
|
+
export type ITouchableHandler = (event: ISymbioteEvent) => void;
|
|
10
|
+
export interface IPressTimingProps {
|
|
11
|
+
delayPressIn?: number;
|
|
12
|
+
delayPressOut?: number;
|
|
13
|
+
minPressDuration?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function computePressOutWait(heldFor: number, minPressDuration: number, delayPressOut: number): number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Touchable*: the shared logic half (framework-agnostic). The Touchable family is built on
|
|
2
|
+
// Pressable; what is identical across adapters is the press-timing config RN's Pressability reads
|
|
3
|
+
// (delayPressIn/delayPressOut/minPressDuration) and the deactivation floor math. The Animated
|
|
4
|
+
// feedback itself is framework (each adapter's Animated namespace), so it stays in the adapter;
|
|
5
|
+
// only the timing constants + the pure wait computation live here.
|
|
6
|
+
// TouchableOpacity.js: _opacityActive(150)/_opacityInactive(250), activeOpacity 0.2.
|
|
7
|
+
export const DEFAULT_ACTIVE_OPACITY = 0.2;
|
|
8
|
+
export const OPACITY_ACTIVE_DURATION_MS = 150;
|
|
9
|
+
export const OPACITY_INACTIVE_DURATION_MS = 250;
|
|
10
|
+
export const RESTING_OPACITY = 1;
|
|
11
|
+
// TouchableHighlight.js: child opacity 0.85, underlay 'black' when unset.
|
|
12
|
+
export const DEFAULT_HIGHLIGHT_CHILD_OPACITY = 0.85;
|
|
13
|
+
export const DEFAULT_UNDERLAY_COLOR = 'black';
|
|
14
|
+
// RN's Pressability DEFAULT_MIN_PRESS_DURATION, the floor a press visual is held, so a very fast
|
|
15
|
+
// tap still flashes the active feedback (Pressability.js).
|
|
16
|
+
export const DEFAULT_MIN_PRESS_DURATION_MS = 130;
|
|
17
|
+
// RN's _deactivate floor: the press-out waits at least minPressDuration past activation (so a fast
|
|
18
|
+
// tap holds the active visual) and at least delayPressOut, whichever is longer. `heldFor` is how
|
|
19
|
+
// long the visual has already been active (0 when it never activated).
|
|
20
|
+
export function computePressOutWait(heldFor, minPressDuration, delayPressOut) {
|
|
21
|
+
return Math.max(minPressDuration - heldFor, delayPressOut);
|
|
22
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { IViewStyle } from '@symbiote-native/engine';
|
|
2
|
+
import type { ISymbioteEvent, ISymbioteNode } from '@symbiote-native/engine';
|
|
3
|
+
import type { IScrollViewHandle } from '../scroll-view-commands';
|
|
4
|
+
export declare const DEFAULT_WINDOW_SIZE = 21;
|
|
5
|
+
export declare const DEFAULT_INITIAL_NUM_TO_RENDER = 10;
|
|
6
|
+
export declare const DEFAULT_END_REACHED_THRESHOLD = 2;
|
|
7
|
+
export declare const DEFAULT_MAX_TO_RENDER_PER_BATCH = 10;
|
|
8
|
+
export declare const DEFAULT_UPDATE_CELLS_BATCHING_PERIOD = 50;
|
|
9
|
+
export declare const DEFAULT_VIEW_AREA_COVERAGE_PERCENT_THRESHOLD = 0;
|
|
10
|
+
export declare const DEFAULT_START_REACHED_THRESHOLD = 2;
|
|
11
|
+
export declare const FIRST_INDEX = 0;
|
|
12
|
+
export declare const EMPTY_OFFSET = 0;
|
|
13
|
+
export declare const NO_INDEX = -1;
|
|
14
|
+
export declare const FULLY_VISIBLE_PERCENT = 100;
|
|
15
|
+
export declare const ON_EDGE_REACHED_EPSILON = 0.001;
|
|
16
|
+
export declare const NO_CONTENT_LENGTH_SENT = -1;
|
|
17
|
+
export declare const INVERTED_Y_STYLE: IViewStyle;
|
|
18
|
+
export declare const INVERTED_X_STYLE: IViewStyle;
|
|
19
|
+
export interface ICellLayout {
|
|
20
|
+
length: number;
|
|
21
|
+
offset: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ISeparatorProps<ItemT> {
|
|
24
|
+
highlighted: boolean;
|
|
25
|
+
leadingItem?: ItemT;
|
|
26
|
+
trailingItem?: ItemT;
|
|
27
|
+
section?: unknown;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
export interface ISeparators {
|
|
31
|
+
highlight(): void;
|
|
32
|
+
unhighlight(): void;
|
|
33
|
+
updateProps(select: 'leading' | 'trailing', newProps: Record<string, unknown>): void;
|
|
34
|
+
}
|
|
35
|
+
export interface IViewToken<ItemT> {
|
|
36
|
+
item: ItemT;
|
|
37
|
+
key: string;
|
|
38
|
+
index: number;
|
|
39
|
+
isViewable: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface IViewableItemsChangedInfo<ItemT> {
|
|
42
|
+
viewableItems: IViewToken<ItemT>[];
|
|
43
|
+
changed: IViewToken<ItemT>[];
|
|
44
|
+
}
|
|
45
|
+
export interface IViewabilityConfig {
|
|
46
|
+
minimumViewTime?: number;
|
|
47
|
+
viewAreaCoveragePercentThreshold?: number;
|
|
48
|
+
itemVisiblePercentThreshold?: number;
|
|
49
|
+
waitForInteraction?: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface IViewabilityConfigCallbackPair<ItemT> {
|
|
52
|
+
viewabilityConfig: IViewabilityConfig;
|
|
53
|
+
onViewableItemsChanged: (info: IViewableItemsChangedInfo<ItemT>) => void;
|
|
54
|
+
}
|
|
55
|
+
export interface IVirtualizedListHandle {
|
|
56
|
+
scrollToOffset(params: {
|
|
57
|
+
offset: number;
|
|
58
|
+
animated?: boolean;
|
|
59
|
+
}): void;
|
|
60
|
+
scrollToIndex(params: {
|
|
61
|
+
index: number;
|
|
62
|
+
animated?: boolean;
|
|
63
|
+
viewOffset?: number;
|
|
64
|
+
viewPosition?: number;
|
|
65
|
+
}): void;
|
|
66
|
+
scrollToItem(params: {
|
|
67
|
+
item: unknown;
|
|
68
|
+
animated?: boolean;
|
|
69
|
+
viewPosition?: number;
|
|
70
|
+
}): void;
|
|
71
|
+
scrollToEnd(params?: {
|
|
72
|
+
animated?: boolean;
|
|
73
|
+
}): void;
|
|
74
|
+
flashScrollIndicators(): void;
|
|
75
|
+
getNativeScrollRef(): IScrollViewHandle | null;
|
|
76
|
+
getScrollableNode(): IScrollViewHandle | null;
|
|
77
|
+
getScrollResponder(): IScrollViewHandle | null;
|
|
78
|
+
getScrollNode(): ISymbioteNode | null;
|
|
79
|
+
recordInteraction(): void;
|
|
80
|
+
}
|
|
81
|
+
export declare function readScrollOffset(event: ISymbioteEvent, horizontal: boolean): number | undefined;
|
|
82
|
+
export declare function readLayoutLength(event: ISymbioteEvent, horizontal: boolean): number | undefined;
|
|
83
|
+
export declare function buildOffsets(count: number, measured: Map<number, number>, fixedLayout: ((index: number) => ICellLayout) | undefined, averageLength: number): {
|
|
84
|
+
offsets: number[];
|
|
85
|
+
lengths: number[];
|
|
86
|
+
total: number;
|
|
87
|
+
};
|
|
88
|
+
export declare function computeWindow(count: number, offsets: number[], lengths: number[], scrollOffset: number, viewportLength: number, windowSize: number, initialNumToRender: number): {
|
|
89
|
+
first: number;
|
|
90
|
+
last: number;
|
|
91
|
+
};
|
|
92
|
+
export declare function throttleWindow(target: {
|
|
93
|
+
first: number;
|
|
94
|
+
last: number;
|
|
95
|
+
}, previous: {
|
|
96
|
+
first: number;
|
|
97
|
+
last: number;
|
|
98
|
+
}, maxToRenderPerBatch: number): {
|
|
99
|
+
first: number;
|
|
100
|
+
last: number;
|
|
101
|
+
};
|
|
102
|
+
export declare function visiblePercent(cellOffset: number, cellLength: number, scrollOffset: number, viewportLength: number): number;
|
|
103
|
+
export declare function isCellViewable(percent: number, config: IViewabilityConfig): boolean;
|
|
104
|
+
export declare function offsetForIndex(index: number, viewPosition: number, viewOffset: number, count: number, offsets: number[], lengths: number[], viewportLength: number): number;
|
|
105
|
+
export declare function averageMeasuredLength(measured: Map<number, number>): number;
|
|
106
|
+
export declare function highestMeasuredIndex(measured: Map<number, number>): number;
|
|
107
|
+
export declare function computeEndReached(total: number, scrollOffset: number, viewportLength: number, thresholdMultiplier: number): {
|
|
108
|
+
distanceFromEnd: number;
|
|
109
|
+
withinThreshold: boolean;
|
|
110
|
+
};
|
|
111
|
+
export declare function computeStartReached(scrollOffset: number, viewportLength: number, thresholdMultiplier: number): {
|
|
112
|
+
distanceFromStart: number;
|
|
113
|
+
withinThreshold: boolean;
|
|
114
|
+
};
|
|
115
|
+
export declare function buildViewabilityPairs<ItemT>(onViewableItemsChanged: ((info: IViewableItemsChangedInfo<ItemT>) => void) | undefined, viewabilityConfig: IViewabilityConfig | undefined, pairs: IViewabilityConfigCallbackPair<ItemT>[] | undefined): IViewabilityConfigCallbackPair<ItemT>[];
|
|
116
|
+
export interface IViewableSetParams<ItemT> {
|
|
117
|
+
first: number;
|
|
118
|
+
last: number;
|
|
119
|
+
count: number;
|
|
120
|
+
offsets: number[];
|
|
121
|
+
lengths: number[];
|
|
122
|
+
scrollOffset: number;
|
|
123
|
+
viewportLength: number;
|
|
124
|
+
data: unknown;
|
|
125
|
+
getItem: (data: unknown, index: number) => ItemT;
|
|
126
|
+
keyExtractor?: (item: ItemT, index: number) => string;
|
|
127
|
+
pairs: IViewabilityConfigCallbackPair<ItemT>[];
|
|
128
|
+
hasInteracted: boolean;
|
|
129
|
+
}
|
|
130
|
+
export declare function computeViewableSet<ItemT>(params: IViewableSetParams<ItemT>): {
|
|
131
|
+
tokens: IViewToken<ItemT>[];
|
|
132
|
+
map: Map<string, IViewToken<ItemT>>;
|
|
133
|
+
};
|
|
134
|
+
export declare function diffViewable<ItemT>(previous: Map<string, IViewToken<ItemT>>, current: Map<string, IViewToken<ItemT>>, currentTokens: IViewToken<ItemT>[]): {
|
|
135
|
+
changed: IViewToken<ItemT>[];
|
|
136
|
+
hasChanged: boolean;
|
|
137
|
+
};
|
|
138
|
+
export declare function maxMinimumViewTime<ItemT>(pairs: IViewabilityConfigCallbackPair<ItemT>[]): number;
|
|
139
|
+
export interface IListCellPlan {
|
|
140
|
+
index: number;
|
|
141
|
+
key: string;
|
|
142
|
+
}
|
|
143
|
+
export interface IListPlan {
|
|
144
|
+
leadingExtent: number;
|
|
145
|
+
trailingExtent: number;
|
|
146
|
+
cells: IListCellPlan[];
|
|
147
|
+
stickyChildPositions: number[];
|
|
148
|
+
}
|
|
149
|
+
export interface IListPlanParams {
|
|
150
|
+
count: number;
|
|
151
|
+
first: number;
|
|
152
|
+
last: number;
|
|
153
|
+
offsets: number[];
|
|
154
|
+
lengths: number[];
|
|
155
|
+
total: number;
|
|
156
|
+
keyFor: (index: number) => string;
|
|
157
|
+
stickyIndices?: ReadonlySet<number>;
|
|
158
|
+
hasHeader: boolean;
|
|
159
|
+
hasSeparators: boolean;
|
|
160
|
+
}
|
|
161
|
+
export declare function buildListPlan(params: IListPlanParams): IListPlan;
|