@symbiote-native/react 2.0.0 → 3.0.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/README.md +3 -3
- package/build/components/flat-list/index.js +1 -1
- package/build/components/keyboard-avoiding-view/index.js +6 -1
- package/build/components/pressable/pressable-props.d.ts +2 -0
- package/build/components/touchable/touchable-props.d.ts +2 -0
- package/build/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +1 -0
- package/build/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +1 -0
- package/build/components/virtualized-list/index.js +8 -4
- package/build/host-config.js +5 -12
- package/build/modules/animated/index.d.ts +29 -19
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -27,9 +27,9 @@ npm install @symbiote-native/react react-native react
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
`react-native` and `react` stay your app's own top-level dependencies — SymbioteNative doesn't hide
|
|
30
|
-
them, it only replaces the JS renderer that drives them.
|
|
31
|
-
|
|
32
|
-
[`examples/react`](../../examples/react) rather than a generator.
|
|
30
|
+
them, it only replaces the JS renderer that drives them. `npx @symbiote-native/cli new --framework react`
|
|
31
|
+
scaffolds the Metro config and the `index.js` entry seam below for a new app; wiring them into an
|
|
32
|
+
existing one still follows [`examples/react`](../../examples/react) rather than a generator.
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
@@ -80,7 +80,7 @@ export function FlatList(props) {
|
|
|
80
80
|
getItem: (_source, index) => rows[index],
|
|
81
81
|
getItemCount: () => rows.length,
|
|
82
82
|
renderItem: renderRow,
|
|
83
|
-
keyExtractor: rowKeyExtractor,
|
|
83
|
+
keyExtractor: (row) => rowKeyExtractor(row, keyExtractor),
|
|
84
84
|
onViewableItemsChanged: rowOnViewableItemsChanged,
|
|
85
85
|
viewabilityConfigCallbackPairs: rowViewabilityPairs,
|
|
86
86
|
ItemSeparatorComponent: rowSeparatorComponent,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// around its children.
|
|
11
11
|
import { createElement, useEffect, useRef, useState, } from 'react';
|
|
12
12
|
import { dlog, Keyboard, Platform, } from '@symbiote-native/engine';
|
|
13
|
-
import { computeInset, keyboardAvoidingEventNamesFor, readKeyboardFrame, readLayoutFrame, readPrefersCrossFadeTransitions, resolveKeyboardAvoidingLayout, DEFAULT_VERTICAL_OFFSET, } from '@symbiote-native/components';
|
|
13
|
+
import { computeInset, configureKeyboardAvoidingAnimation, keyboardAvoidingEventNamesFor, readKeyboardAnimationTiming, readKeyboardFrame, readLayoutFrame, readPrefersCrossFadeTransitions, resolveKeyboardAvoidingLayout, DEFAULT_VERTICAL_OFFSET, } from '@symbiote-native/components';
|
|
14
14
|
import {} from '../../components.js';
|
|
15
15
|
// The two notifications to subscribe to, per host (iOS takes the `will` pair so the view rides
|
|
16
16
|
// up with the keyboard animation; Android has no will-notifications). Resolved ONCE at module
|
|
@@ -47,6 +47,11 @@ export const KeyboardAvoidingView = props => {
|
|
|
47
47
|
previousInset,
|
|
48
48
|
prefersCrossFadeTransitions: prefersCrossFadeRef.current,
|
|
49
49
|
});
|
|
50
|
+
// RN's `_updateBottomIfNecessary` skips the animation entirely when the inset did not
|
|
51
|
+
// change (`if (this._bottom === height) return;`) — arming a transition for a value that
|
|
52
|
+
// moves nowhere would only ever animate other props the app changed this frame.
|
|
53
|
+
if (next !== previousInset)
|
|
54
|
+
configureKeyboardAvoidingAnimation(readKeyboardAnimationTiming(payload), enabled);
|
|
50
55
|
dlog(`KeyboardAvoidingView show -> inset ${next}`);
|
|
51
56
|
return next;
|
|
52
57
|
});
|
|
@@ -14,7 +14,9 @@ export interface IPressableProps extends IAccessibilityProps, IAriaProps {
|
|
|
14
14
|
disabled?: boolean;
|
|
15
15
|
focusable?: boolean;
|
|
16
16
|
cancelable?: boolean;
|
|
17
|
+
blockNativeResponder?: boolean;
|
|
17
18
|
hitSlop?: IRectOffset;
|
|
19
|
+
testOnly_pressed?: boolean;
|
|
18
20
|
pressRetentionOffset?: IRectOffset;
|
|
19
21
|
unstable_pressDelay?: number;
|
|
20
22
|
minPressDuration?: number;
|
|
@@ -12,6 +12,8 @@ export interface ITouchableOpacityProps extends ITouchableBaseProps {
|
|
|
12
12
|
export interface ITouchableHighlightProps extends ITouchableBaseProps {
|
|
13
13
|
activeOpacity?: number;
|
|
14
14
|
underlayColor?: string;
|
|
15
|
+
touchSoundDisabled?: boolean;
|
|
16
|
+
testOnly_pressed?: boolean;
|
|
15
17
|
onShowUnderlay?: () => void;
|
|
16
18
|
onHideUnderlay?: () => void;
|
|
17
19
|
}
|
|
@@ -3,4 +3,5 @@ import type { IPressTimingProps } from '@symbiote-native/components';
|
|
|
3
3
|
import type { IPressableProps } from '../pressable/pressable-props';
|
|
4
4
|
export type ITouchableWithoutFeedbackProps = Omit<IPressableProps, 'style' | 'children'> & IPressTimingProps & {
|
|
5
5
|
children?: ReactNode;
|
|
6
|
+
touchSoundDisabled?: boolean;
|
|
6
7
|
};
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
// nothing else about it.
|
|
39
39
|
import { createElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, } from 'react';
|
|
40
40
|
import { dlog, } from '@symbiote-native/engine';
|
|
41
|
-
import {
|
|
41
|
+
import { DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_WINDOW_SIZE, EMPTY_OFFSET, FIRST_INDEX, INVERTED_X_STYLE, INVERTED_Y_STYLE, buildListPlan, buildScrollViewHandle, buildViewabilityPairs, createInitialListState, isSeparatorGapInRange, listEffectSignature, readLayoutLength, readLayoutOffset, readScrollOffset, reduceList, resolveItemKey, } from '@symbiote-native/components';
|
|
42
42
|
function resolveElement(component) {
|
|
43
43
|
if (component === undefined)
|
|
44
44
|
return undefined;
|
|
@@ -65,7 +65,7 @@ function renderSeparatorElement(component, leadingItem, trailingItem, overrides)
|
|
|
65
65
|
// generic). The ref is destructured here and wired through useImperativeHandle.
|
|
66
66
|
export function VirtualizedList(props) {
|
|
67
67
|
const forwardedRef = props.ref;
|
|
68
|
-
const { data, getItem, getItemCount, renderItem, keyExtractor, getItemLayout, ItemSeparatorComponent, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, horizontal = false, inverted = false, extraData, onEndReached, onEndReachedThreshold
|
|
68
|
+
const { data, getItem, getItemCount, renderItem, keyExtractor, getItemLayout, ItemSeparatorComponent, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, horizontal = false, inverted = false, extraData, onEndReached, onEndReachedThreshold, onStartReached, onStartReachedThreshold, onRefresh, refreshing, progressViewOffset, onViewableItemsChanged, viewabilityConfig, viewabilityConfigCallbackPairs, onScrollToIndexFailed, initialNumToRender = DEFAULT_INITIAL_NUM_TO_RENDER, initialScrollIndex, maxToRenderPerBatch = DEFAULT_MAX_TO_RENDER_PER_BATCH, updateCellsBatchingPeriod = DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, windowSize = DEFAULT_WINDOW_SIZE, stickyHeaderIndices, maintainVisibleContentPosition, style, contentContainerStyle,
|
|
69
69
|
// Pulled out of the rest so the user's onScroll does NOT arrive raw via
|
|
70
70
|
// ...accessibilityRest and overwrite the internal windowing handler. Composed below.
|
|
71
71
|
onScroll: userOnScroll, onScrollBeginDrag, onScrollEndDrag, onMomentumScrollBegin, onMomentumScrollEnd, scrollEventThrottle, keyboardShouldPersistTaps, keyboardDismissMode,
|
|
@@ -188,8 +188,12 @@ export function VirtualizedList(props) {
|
|
|
188
188
|
const info = effect.info;
|
|
189
189
|
const map = effect.map;
|
|
190
190
|
const fire = () => {
|
|
191
|
-
for (const pair of pairs)
|
|
192
|
-
pair.onViewableItemsChanged(
|
|
191
|
+
for (const pair of pairs) {
|
|
192
|
+
pair.onViewableItemsChanged({
|
|
193
|
+
...info,
|
|
194
|
+
viewabilityConfig: pair.viewabilityConfig,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
193
197
|
dispatchRef.current({ kind: 'viewable-fired', map });
|
|
194
198
|
};
|
|
195
199
|
if (viewableTimerRef.current !== null) {
|
package/build/host-config.js
CHANGED
|
@@ -16,10 +16,9 @@ import { descriptorFor } from '@symbiote-native/components';
|
|
|
16
16
|
// A bare intrinsic tag has no wrapper to apply RN's per-primitive prop folds (id -> nativeID,
|
|
17
17
|
// Text's ellipsizeMode / allowFontScaling defaults), so the renderer is the layer that must.
|
|
18
18
|
// Shared with every other adapter, driven by the same HOST_PRIMITIVES spec.
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// where the runtime value is known. Identity for every primitive that declares no alternative.
|
|
19
|
+
// WHICH native view a primitive commits can depend on a prop (TextInput's `multiline`), and that
|
|
20
|
+
// prop can be a runtime value — so the choice is made here, where it is known. Identity for every
|
|
21
|
+
// primitive that declares no alternative.
|
|
23
22
|
import { resolveIntrinsicTag } from '@symbiote-native/components/resolve-intrinsic';
|
|
24
23
|
// React-reserved prop keys that must never reach Fabric. `children` is the element
|
|
25
24
|
// tree (handled via appendChild). `ref`/`key` are React 19 plain props: the reconciler
|
|
@@ -117,12 +116,8 @@ const reconciler = createReconciler({
|
|
|
117
116
|
// other four adapters all pass it (vue `renderer/index.ts`, svelte `dom-shim/element.ts`,
|
|
118
117
|
// solid `renderer.ts`, angular `renderer/index.ts`), and React is the one that did not.
|
|
119
118
|
//
|
|
120
|
-
// Inert on landing and deliberately so — nothing registers a behavior under a tag React emits.
|
|
121
|
-
// The `-managed` split is what keeps it inert once something does: React's TextInput and
|
|
122
|
-
// Switch wrappers emit `text-input-managed` / `switch-managed`, so a machine
|
|
123
|
-
// registered on the lowered tag cannot also attach to a wrapper-built node and run twice.
|
|
124
119
|
const node = createElement(descriptor.component, descriptor.isText, tag);
|
|
125
|
-
applyProps(node,
|
|
120
|
+
applyProps(node, props);
|
|
126
121
|
return node;
|
|
127
122
|
},
|
|
128
123
|
createTextInstance(text, _container, hostContext) {
|
|
@@ -159,9 +154,7 @@ const reconciler = createReconciler({
|
|
|
159
154
|
// an update. The node keeps its identity — an app's ref stays live — and the commit walk
|
|
160
155
|
// re-creates the Fabric node because its viewName no longer matches the committed one.
|
|
161
156
|
setNodeComponent(node, descriptorFor(resolveIntrinsicTag(type, newProps)).component);
|
|
162
|
-
|
|
163
|
-
// the alias twice while never clearing the raw key.
|
|
164
|
-
applyUpdate(node, foldHostBag(type, oldProps), foldHostBag(type, newProps));
|
|
157
|
+
applyUpdate(node, oldProps, newProps);
|
|
165
158
|
},
|
|
166
159
|
commitTextUpdate(node, _oldText, newText) {
|
|
167
160
|
setText(node, newText);
|
|
@@ -6,25 +6,7 @@ export declare const Animated: {
|
|
|
6
6
|
Value: typeof AnimatedValue;
|
|
7
7
|
ValueXY: typeof AnimatedValueXY;
|
|
8
8
|
Color: typeof AnimatedColor;
|
|
9
|
-
Easing:
|
|
10
|
-
step0(n: number): number;
|
|
11
|
-
step1(n: number): number;
|
|
12
|
-
linear(t: number): number;
|
|
13
|
-
ease(t: number): number;
|
|
14
|
-
quad(t: number): number;
|
|
15
|
-
cubic(t: number): number;
|
|
16
|
-
poly(n: number): import("@symbiote-native/engine").IEasingFunction;
|
|
17
|
-
sin(t: number): number;
|
|
18
|
-
circle(t: number): number;
|
|
19
|
-
exp(t: number): number;
|
|
20
|
-
elastic(bounciness?: number): import("@symbiote-native/engine").IEasingFunction;
|
|
21
|
-
back(s?: number): import("@symbiote-native/engine").IEasingFunction;
|
|
22
|
-
bounce(t: number): number;
|
|
23
|
-
bezier(x1: number, y1: number, x2: number, y2: number): import("@symbiote-native/engine").IEasingFunction;
|
|
24
|
-
in(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
|
|
25
|
-
out(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
|
|
26
|
-
inOut(easing: import("@symbiote-native/engine").IEasingFunction): import("@symbiote-native/engine").IEasingFunction;
|
|
27
|
-
};
|
|
9
|
+
Easing: import("@symbiote-native/engine").IEasing;
|
|
28
10
|
timing: typeof timing;
|
|
29
11
|
spring: typeof spring;
|
|
30
12
|
decay: typeof decay;
|
|
@@ -48,4 +30,32 @@ export declare const Animated: {
|
|
|
48
30
|
FlatList: ReturnType<typeof createAnimatedComponent>;
|
|
49
31
|
SectionList: ReturnType<typeof createAnimatedComponent>;
|
|
50
32
|
createAnimatedComponent: typeof createAnimatedComponent;
|
|
33
|
+
} | {
|
|
34
|
+
Value: typeof AnimatedValue;
|
|
35
|
+
ValueXY: typeof AnimatedValueXY;
|
|
36
|
+
Color: typeof AnimatedColor;
|
|
37
|
+
Easing: import("@symbiote-native/engine").IEasing;
|
|
38
|
+
timing: (value: AnimatedValue, config: import("@symbiote-native/engine").ITimingConfig) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
39
|
+
spring: (value: AnimatedValue, config: import("@symbiote-native/engine").ISpringConfig) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
40
|
+
decay: (_value: AnimatedValue, _config: import("@symbiote-native/engine").IDecayConfig) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
41
|
+
parallel: (animations: import("@symbiote-native/engine").ICompositeAnimation[], _config?: import("@symbiote-native/engine").IParallelConfig) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
42
|
+
sequence: (animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
43
|
+
stagger: (_time: number, animations: import("@symbiote-native/engine").ICompositeAnimation[]) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
44
|
+
loop: (_animation: import("@symbiote-native/engine").ICompositeAnimation) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
45
|
+
delay: (_time: number) => import("@symbiote-native/engine").ICompositeAnimation;
|
|
46
|
+
add: typeof add;
|
|
47
|
+
subtract: typeof subtract;
|
|
48
|
+
multiply: typeof multiply;
|
|
49
|
+
divide: typeof divide;
|
|
50
|
+
modulo: typeof modulo;
|
|
51
|
+
diffClamp: typeof diffClamp;
|
|
52
|
+
event: typeof event;
|
|
53
|
+
forkEvent: typeof forkEvent;
|
|
54
|
+
unforkEvent: typeof unforkEvent;
|
|
55
|
+
View: import("react").ComponentType<import("./create-animated-component").IAnimatedComponentProps>;
|
|
56
|
+
Text: import("react").ComponentType<import("./create-animated-component").IAnimatedComponentProps>;
|
|
57
|
+
Image: import("react").ComponentType<import("./create-animated-component").IAnimatedComponentProps>;
|
|
58
|
+
FlatList: ReturnType<typeof createAnimatedComponent>;
|
|
59
|
+
SectionList: ReturnType<typeof createAnimatedComponent>;
|
|
60
|
+
createAnimatedComponent: typeof createAnimatedComponent;
|
|
51
61
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "SymbioteNative's React adapter — a react-reconciler host config (mutation mode) driving real native iOS/Android views through stock React Native Fabric.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -57,20 +57,20 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"react-reconciler": "^0.33.0",
|
|
60
|
-
"@symbiote-native/components": "
|
|
60
|
+
"@symbiote-native/components": "3.0.0",
|
|
61
61
|
"@symbiote-native/css-parser": "0.5.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"react": ">=19.0.0",
|
|
65
65
|
"react-native": ">=0.86",
|
|
66
|
-
"@symbiote-native/engine": "^0.
|
|
66
|
+
"@symbiote-native/engine": "^1.0.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@types/react": "^19.2.0",
|
|
70
70
|
"@types/react-reconciler": "^0.32.2",
|
|
71
71
|
"react": "19.2.3",
|
|
72
|
-
"@symbiote-native/engine": "0.
|
|
73
|
-
"@symbiote-native/test-utils": "0.3.
|
|
72
|
+
"@symbiote-native/engine": "1.0.0",
|
|
73
|
+
"@symbiote-native/test-utils": "0.3.1"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"typecheck": "tsc --build",
|