@symbiote-native/react 0.2.2 → 0.2.4
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 +2 -2
- package/build/components/activity-indicator/index.android.js +1 -1
- package/build/components/activity-indicator/index.ios.js +1 -1
- package/build/components/activity-indicator/index.js +1 -1
- package/build/components/scroll-view/index.android.js +2 -2
- package/build/components/scroll-view/index.ios.js +2 -2
- package/build/components/scroll-view/index.js +1 -1
- package/build/components/scroll-view/shared.js +2 -2
- package/build/components/scroll-view/sticky-header.js +1 -1
- package/build/components/switch/index.js +3 -3
- package/build/components/virtualized-list/index.js +2 -2
- package/build/create-tunnel.js +2 -2
- package/build/descriptor-to-react/index.js +1 -1
- package/build/host-config.js +2 -2
- package/build/index.js +14 -12
- package/build/modules/accessibility-info/index.js +1 -1
- package/build/modules/action-sheet-ios.js +2 -2
- package/build/modules/alert.js +2 -2
- package/build/modules/animated/create-animated-component.js +2 -2
- package/build/modules/animated/index.js +3 -3
- package/build/modules/i18n-manager.js +1 -1
- package/build/modules/linking.js +1 -1
- package/build/modules/settings.js +1 -1
- package/build/modules/share.js +1 -1
- package/build/modules/status-bar/index.android.js +1 -1
- package/build/modules/status-bar/index.ios.js +2 -2
- package/build/modules/toast-android.js +2 -2
- package/build/modules/vibration.js +2 -2
- package/metro-css-parser.cjs +1 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ canary ([`App.tsx`](../../examples/react/App.tsx)) exercises every block of the
|
|
|
85
85
|
## Surface — verified on device, iOS + Android
|
|
86
86
|
|
|
87
87
|
Every interaction commits through `@symbiote-native/engine` into Fabric, with RN's renderer never in the
|
|
88
|
-
path
|
|
88
|
+
path:
|
|
89
89
|
|
|
90
90
|
- **Primitives** — `View` · `Text` · `Image` · `ImageBackground` · `ScrollView` · `TextInput` ·
|
|
91
91
|
`Pressable` · `Touchable*` · `Button` · `Switch` · `Modal` · `ActivityIndicator` ·
|
|
@@ -96,7 +96,7 @@ path (R1 + R2 + R3 — decision record 0009):
|
|
|
96
96
|
bridgeless host.
|
|
97
97
|
- **`Animated`, both drivers** — JS *and* native driver side by side (`timing` · `spring` · `loop` ·
|
|
98
98
|
`interpolate` · `ValueXY` · tracking · `diffClamp`). Native offload is proven by jamming the JS
|
|
99
|
-
thread 1.5 s: the native-driven animations keep moving, the JS-driven one stalls
|
|
99
|
+
thread 1.5 s: the native-driven animations keep moving, the JS-driven one stalls.
|
|
100
100
|
- **Third-party native views** — `@react-native-community/slider` used straight from the package
|
|
101
101
|
with zero SymbioteNative metadata; the engine derives its events and prop processors from the library's
|
|
102
102
|
own ViewConfig at runtime — the "install the package, use its component" path.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// ProgressBar's setStyle(); without it the view throws "setStyle() not called") and
|
|
3
3
|
// `indeterminate: true`, and its default color is the theme (null), per RN's
|
|
4
4
|
// ActivityIndicator.js android branch ({styleAttr:'Normal', indeterminate:true}). Metro
|
|
5
|
-
// picks this on an Android host; no Platform.OS read.
|
|
5
|
+
// picks this on an Android host; no Platform.OS read.
|
|
6
6
|
// device-verify-pending: prop names mirror RN's AndroidProgressBar, proven on a real
|
|
7
7
|
// host by the absence of the "setStyle() not called" red box.
|
|
8
8
|
import { createActivityIndicator } from './shared.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ActivityIndicator on iOS: RCTActivityIndicatorView takes the size enum + a GRAY
|
|
2
2
|
// default color and no extra native props. Also the base (activity-indicator.ts
|
|
3
|
-
// re-exports it) for headless / web.
|
|
3
|
+
// re-exports it) for headless / web.
|
|
4
4
|
import { createActivityIndicator } from './shared.js';
|
|
5
5
|
// RN's iOS default spinner color (Libraries/.../ActivityIndicator.js GRAY).
|
|
6
6
|
const IOS_DEFAULT_COLOR = '#999999';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Base / default ActivityIndicator: re-exports the iOS build. Metro overrides this with
|
|
2
2
|
// activity-indicator.ios.ts / .android.ts on a real host; under tsx / tsc / web the host
|
|
3
|
-
// config resolves here. Filename is the selector, no Platform.OS read.
|
|
3
|
+
// config resolves here. Filename is the selector, no Platform.OS read.
|
|
4
4
|
export * from './index.ios.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// scroll handles the gesture before the refresh parent, which mirrors RN's ScrollView.js
|
|
6
6
|
// android branch (cloneElement(refreshControl, {style}, <ScrollView nestedScrollEnabled
|
|
7
7
|
// style={flex:1}>{content}</ScrollView>)). Metro picks this on an Android host; no
|
|
8
|
-
// Platform.OS read.
|
|
8
|
+
// Platform.OS read.
|
|
9
9
|
// device-verify-pending: the wrap shape mirrors RN, proven on a real host by the absence
|
|
10
10
|
// of the "addViewAt: failed to insert" crash.
|
|
11
11
|
import { cloneElement, createElement, forwardRef, useImperativeHandle, useRef } from 'react';
|
|
@@ -18,7 +18,7 @@ export const ScrollView = forwardRef((props, forwardedRef) => {
|
|
|
18
18
|
// (the wrap shape leaves the scroll view as the command target, not the RefreshControl).
|
|
19
19
|
const ref = useRef(null);
|
|
20
20
|
// Lazy getter, not the ref itself: the node is null until the element commits, so the handle
|
|
21
|
-
// must read ref.current on each command
|
|
21
|
+
// must read ref.current on each command, an eager capture would freeze null.
|
|
22
22
|
useImperativeHandle(forwardedRef, () => buildScrollViewHandle(() => ref.current), []);
|
|
23
23
|
// Drive the sticky scroll value on the native UI thread (RN attachNativeEvent). No-op on a
|
|
24
24
|
// host without the native animated module. The JS sticky path stays in effect.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ScrollView on iOS: the RefreshControl is a CHILD of the scroll view, rendered as a
|
|
2
2
|
// sibling BEFORE the content container (RN ScrollView.js: {refreshControl}{contentContainer}).
|
|
3
|
-
// Also the base (scroll-view.ts re-exports it) for headless / web.
|
|
3
|
+
// Also the base (scroll-view.ts re-exports it) for headless / web.
|
|
4
4
|
import { createElement, forwardRef, useImperativeHandle, useRef } from 'react';
|
|
5
5
|
import { buildScrollViewHandle } from '@symbiote-native/components';
|
|
6
6
|
import { usePreparedScrollView, useNativeStickyScrollAttach, } from './shared.js';
|
|
@@ -10,7 +10,7 @@ export const ScrollView = forwardRef((props, forwardedRef) => {
|
|
|
10
10
|
// (passing `ref` through createElement props binds it to the SymbioteNode, as TextInput does).
|
|
11
11
|
const ref = useRef(null);
|
|
12
12
|
// Lazy getter, not the ref itself: the node is null until the element commits, so the handle
|
|
13
|
-
// must read ref.current on each command
|
|
13
|
+
// must read ref.current on each command, an eager capture would freeze null.
|
|
14
14
|
useImperativeHandle(forwardedRef, () => buildScrollViewHandle(() => ref.current), []);
|
|
15
15
|
// Drive the sticky scroll value on the native UI thread (RN attachNativeEvent). No-op on a
|
|
16
16
|
// host without the native animated module. The JS sticky path stays in effect.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Base / default ScrollView: re-exports the iOS build. Metro overrides this with
|
|
2
2
|
// scroll-view.ios.ts / .android.ts on a real host; under tsx / tsc / web the host config
|
|
3
|
-
// resolves here. Filename is the selector, no Platform.OS read.
|
|
3
|
+
// resolves here. Filename is the selector, no Platform.OS read.
|
|
4
4
|
export * from './index.ios.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// ScrollView: shared core. The Fabric tree is nested: the scroll view wraps a content
|
|
2
2
|
// view that holds the children (RN's own ScrollView.js shape). Building that content
|
|
3
3
|
// node, resolving decelerationRate, and the prop plumbing are platform-invariant and
|
|
4
|
-
// live here. What diverges
|
|
4
|
+
// live here. What diverges is how a RefreshControl integrates: on iOS it is a
|
|
5
5
|
// CHILD of the scroll view (sibling of the content), on Android it WRAPS the scroll view
|
|
6
6
|
// (AndroidSwipeRefreshLayout is the parent, ScrollView nested inside). So the .ios/.android
|
|
7
7
|
// files assemble the final element; the filename selects, no Platform.OS read.
|
|
8
8
|
//
|
|
9
9
|
// The framework-agnostic pieces (decelerationRate, the per-axis intrinsics/base style, the
|
|
10
10
|
// content-size dedupe, the imperative handle, splitLayoutProps, the sticky math, the native
|
|
11
|
-
// scroll-attach) live in @symbiote-native/components
|
|
11
|
+
// scroll-attach) live in @symbiote-native/components; this file holds only the React
|
|
12
12
|
// lifecycle (refs/state/effects) and the element assembly that consumes them.
|
|
13
13
|
import { createElement, useEffect, useRef, useState, } from 'react';
|
|
14
14
|
import { AnimatedValue, dlog, event as animatedEvent, isClassNameValue, isNativeAnimatedAvailable, resolveClassName, } from '@symbiote-native/engine';
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// its own. Forwarding `stickyHeaderIndices` to native is a silent no-op. So we replicate the
|
|
8
8
|
// JS layer: subscribe each flagged child to the scroll offset and translate it to stay pinned.
|
|
9
9
|
// The interpolation mirrors ScrollViewStickyHeader.js (non-inverted + inverted branches) and now
|
|
10
|
-
// lives, framework-agnostic, in @symbiote-native/components (computeStickyInterpolation
|
|
10
|
+
// lives, framework-agnostic, in @symbiote-native/components (computeStickyInterpolation); this
|
|
11
11
|
// file holds the React component shell, the layout state, and the child-wrapping.
|
|
12
12
|
import { Children, createElement, isValidElement, useCallback, useEffect, useRef, useState, } from 'react';
|
|
13
13
|
import { AnimatedInterpolation, AnimatedValue, Platform, dlog, } from '@symbiote-native/engine';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Base / default Switch: re-exports the iOS build. Metro overrides this with switch.ios.ts /
|
|
2
2
|
// switch.android.ts on a real host; under tsx / tsc / web the host config resolves here.
|
|
3
|
-
// Filename is the selector, no Platform.OS read.
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Filename is the selector, no Platform.OS read. The logic lives in
|
|
4
|
+
// @symbiote-native/components/state, the render in @symbiote-native/components/view, and the
|
|
5
|
+
// hook in switch-shared.
|
|
6
6
|
export * from './index.ios.js';
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// viewability bug is fixed once for all adapters (<adapters_reach_full_feature_parity>).
|
|
11
11
|
// React supplies only its lifecycle (state/refs/effects), the imperative-handle wiring,
|
|
12
12
|
// and the per-cell element creation (createElement). Lists have no Descriptor render fn
|
|
13
|
-
// (the cell content is React's own children)
|
|
13
|
+
// (the cell content is React's own children).
|
|
14
14
|
//
|
|
15
15
|
// Imperative scrolling (scrollToIndex / scrollToOffset / scrollToItem / scrollToEnd)
|
|
16
16
|
// resolves to an offset and rides the ScrollView's native scrollTo command via its handle
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { createElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
20
20
|
import { dlog } from '@symbiote-native/engine';
|
|
21
21
|
import { DEFAULT_END_REACHED_THRESHOLD, DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_START_REACHED_THRESHOLD, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_WINDOW_SIZE, EMPTY_OFFSET, FIRST_INDEX, INVERTED_X_STYLE, INVERTED_Y_STYLE, NO_CONTENT_LENGTH_SENT, averageMeasuredLength, buildListPlan, buildOffsets, buildViewabilityPairs, computeEndReached, computeStartReached, computeViewableSet, computeWindow, diffViewable, highestMeasuredIndex as findHighestMeasuredIndex, maxMinimumViewTime, offsetForIndex as resolveOffsetForIndex, readLayoutLength, readScrollOffset, throttleWindow, } from '@symbiote-native/components';
|
|
22
|
-
import { ScrollView } from '../scroll-view
|
|
22
|
+
import { ScrollView } from '../scroll-view';
|
|
23
23
|
import { RefreshControl } from '../refresh-control/index.js';
|
|
24
24
|
function resolveElement(component) {
|
|
25
25
|
if (component === undefined)
|
package/build/create-tunnel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// createTunnel — the cross-surface answer to createPortal's same-surface-only
|
|
3
|
-
//
|
|
2
|
+
// createTunnel — the cross-surface answer to createPortal's same-surface-only scope.
|
|
3
|
+
// Prior art: pmndrs/tunnel-rat exists precisely because a real
|
|
4
4
|
// createPortal cannot reach across two genuinely separate reconciler roots — see
|
|
5
5
|
// github.com/facebook/react/issues/17147 ("react-reconciler & portals: missing root
|
|
6
6
|
// instance"). The fix is the one the ecosystem already settled on: don't reach into a
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// framework-agnostic `Descriptor` tree; this maps it onto React elements. The resulting
|
|
3
3
|
// host element (`symbiote-view`, `symbiote-activity-indicator`, …) flows on through the
|
|
4
4
|
// react-reconciler host config → engine → Fabric, exactly like a hand-written JSX host
|
|
5
|
-
// element.
|
|
5
|
+
// element.
|
|
6
6
|
import { createElement } from 'react';
|
|
7
7
|
export function descriptorToReact(node, index) {
|
|
8
8
|
const children = node.children.map(toChild);
|
package/build/host-config.js
CHANGED
|
@@ -9,8 +9,8 @@ import { DefaultEventPriority, DiscreteEventPriority, NoEventPriority, } from '.
|
|
|
9
9
|
import { toPublicInstance } from './host-instance.js';
|
|
10
10
|
// Intrinsic JSX type -> Fabric component name. The name table + resolver live once in
|
|
11
11
|
// @symbiote-native/components, shared by every adapter so the names can't drift (one engine, one
|
|
12
|
-
// Fabric). The table is Metro-split (.ios/.android, filename selects, no Platform.OS read
|
|
13
|
-
//
|
|
12
|
+
// Fabric). The table is Metro-split (.ios/.android, filename selects, no Platform.OS read).
|
|
13
|
+
// Adding a primitive is one entry in each name table there, plus its thin
|
|
14
14
|
// component in components.ts: no host-config logic per primitive.
|
|
15
15
|
import { descriptorFor } from '@symbiote-native/components';
|
|
16
16
|
// React-reserved prop keys that must never reach Fabric. `children` is the element
|
package/build/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// @symbiote-native/react: a react-reconciler host config (mutation mode) over
|
|
2
2
|
// @symbiote-native/engine. React is a known-good driver: it proves the native pipe
|
|
3
|
-
//
|
|
3
|
+
// and the shared clone-on-write engine before any non-React adapter has to.
|
|
4
4
|
export { View, Text } from './components.js';
|
|
5
5
|
export { Image, setImageSourceResolver } from './components/image/index.js';
|
|
6
6
|
export { ImageBackground } from './components/image-background/index.js';
|
|
7
|
-
export { ScrollView } from './components/scroll-view
|
|
7
|
+
export { ScrollView } from './components/scroll-view';
|
|
8
8
|
export { TextInput } from './components/text-input/index.js';
|
|
9
9
|
export { InputAccessoryView } from './components/input-accessory-view/index.js';
|
|
10
10
|
export { Keyboard, KEYBOARD_EVENT } from './modules/keyboard.js';
|
|
11
11
|
export { KeyboardAvoidingView } from './components/keyboard-avoiding-view/index.js';
|
|
12
|
-
export { StatusBar } from './modules/status-bar
|
|
13
|
-
export { Switch } from './components/switch
|
|
14
|
-
export { ActivityIndicator } from './components/activity-indicator
|
|
12
|
+
export { StatusBar } from './modules/status-bar';
|
|
13
|
+
export { Switch } from './components/switch';
|
|
14
|
+
export { ActivityIndicator } from './components/activity-indicator';
|
|
15
15
|
export { SafeAreaView } from './components/safe-area-view/index.js';
|
|
16
16
|
export { RefreshControl } from './components/refresh-control/index.js';
|
|
17
17
|
export { Modal } from './components/modal/index.js';
|
|
@@ -27,8 +27,10 @@ export { mount, unmount } from './render.js';
|
|
|
27
27
|
// mutation-mode (unlike stock RN's persistent-mode Fabric renderer, which doesn't support it —
|
|
28
28
|
// see create-portal.ts). v1 scope: target must be an already-mounted node in the SAME surface.
|
|
29
29
|
export { createPortal } from './create-portal.js';
|
|
30
|
-
// createTunnel: cross-surface content sharing
|
|
31
|
-
// by design —
|
|
30
|
+
// createTunnel: cross-surface content sharing. createPortal/Teleport stay same-surface-only
|
|
31
|
+
// by design — a real React portal can't reach across two separate reconciler roots either
|
|
32
|
+
// (see github.com/facebook/react/issues/17147), so reaching a different surface means letting
|
|
33
|
+
// that surface commit its own content by reading from a shared store instead.
|
|
32
34
|
export { createTunnel } from './create-tunnel.js';
|
|
33
35
|
// descriptorToReact: the @symbiote-native/components Descriptor → React.createElement bridge. Exported so
|
|
34
36
|
// an external wrapper package (e.g. @symbiote-native/slider/react over a third-party native view) can map
|
|
@@ -39,8 +41,8 @@ export { findNodeHandle } from './host-instance.js';
|
|
|
39
41
|
// registrar so the native Fabric host finds our runnable by app key.
|
|
40
42
|
export { AppRegistry, setHostRegistrar } from './modules/app-registry/index.js';
|
|
41
43
|
// Animated bridge: createAnimatedComponent + Animated.View/Text/Image, driving the
|
|
42
|
-
// shared JS Animated engine
|
|
43
|
-
//
|
|
44
|
+
// shared JS Animated engine. Imperative timing/spring drivers merge into this
|
|
45
|
+
// namespace once they land in shared.
|
|
44
46
|
export { Animated, createAnimatedComponent } from './modules/animated/index.js';
|
|
45
47
|
// Framework-agnostic runtime utilities live in shared; the adapter re-exports them
|
|
46
48
|
// so app code names only @symbiote-native/react (RN's surface, one import root).
|
|
@@ -66,7 +68,7 @@ export { ActionSheetIOS } from './modules/action-sheet-ios.js';
|
|
|
66
68
|
export { Linking } from './modules/linking.js';
|
|
67
69
|
export { Vibration } from './modules/vibration.js';
|
|
68
70
|
export { Share } from './modules/share.js';
|
|
69
|
-
export { AccessibilityInfo } from './modules/accessibility-info
|
|
71
|
+
export { AccessibilityInfo } from './modules/accessibility-info';
|
|
70
72
|
export { I18nManager } from './modules/i18n-manager.js';
|
|
71
73
|
export { Settings } from './modules/settings.js';
|
|
72
74
|
// Interaction subsystems: gestures, deferred work, and layout transitions.
|
|
@@ -77,8 +79,8 @@ export { LayoutAnimation } from './modules/layout-animation.js';
|
|
|
77
79
|
export { InteractionManager } from '@symbiote-native/engine';
|
|
78
80
|
// Android-only surface (the second-platform pass). Each is a thin JS shim over an
|
|
79
81
|
// Android native module / Fabric view, inert on iOS (no module → graceful no-op,
|
|
80
|
-
// no native view → degrade to a plain container). Native module
|
|
81
|
-
// device
|
|
82
|
+
// no native view → degrade to a plain container). Native module name correctness
|
|
83
|
+
// can only be confirmed on a real device/simulator, not headless tests.
|
|
82
84
|
export { BackHandler } from './modules/back-handler.js';
|
|
83
85
|
export { ToastAndroid } from './modules/toast-android.js';
|
|
84
86
|
export { PermissionsAndroid, PERMISSIONS, RESULTS } from './modules/permissions-android.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Base / default AccessibilityInfo: re-exports the iOS build. Metro overrides this with
|
|
2
2
|
// accessibility-info.ios.ts / .android.ts on a real host; under tsx / tsc / web the host
|
|
3
3
|
// config resolves here. Filename is the selector, no Platform.OS read. See
|
|
4
|
-
//
|
|
4
|
+
// shared.ts.
|
|
5
5
|
export * from './index.ios.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ActionSheetIOS
|
|
1
|
+
// ActionSheetIOS lives framework-agnostic in @symbiote-native/engine (imperative
|
|
2
2
|
// native-bridge module, no visual, no lifecycle). The React adapter re-exports it
|
|
3
|
-
// verbatim so the public surface is unchanged.
|
|
3
|
+
// verbatim so the public surface is unchanged.
|
|
4
4
|
export { ActionSheetIOS } from '@symbiote-native/engine';
|
package/build/modules/alert.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Alert
|
|
1
|
+
// Alert lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
2
|
// module, no visual, no lifecycle). The React adapter re-exports it verbatim so the
|
|
3
3
|
// public surface is unchanged; the platform split (alert.ios/alert.android) lives
|
|
4
|
-
// inside engine.
|
|
4
|
+
// inside engine.
|
|
5
5
|
export { Alert } from '@symbiote-native/engine';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// createAnimatedComponent wraps a base component (View / Text / Image / any) so
|
|
2
2
|
// it can take AnimatedNodes in its props. Reimplemented thin against symbiote's
|
|
3
3
|
// shared primitive: NO native driver, NO scheduleUpdate fallback. A frame is the
|
|
4
|
-
// scoped commit setNativeProps drives from the AnimatedProps leaf
|
|
4
|
+
// scoped commit setNativeProps drives from the AnimatedProps leaf. RN's
|
|
5
5
|
// createAnimatedComponent + useAnimatedProps + createAnimatedPropsHook are the
|
|
6
6
|
// structural reference, but their native helpers are deliberately not imported.
|
|
7
7
|
//
|
|
@@ -58,7 +58,7 @@ export function createAnimatedComponent(Component) {
|
|
|
58
58
|
previous.__detach();
|
|
59
59
|
}
|
|
60
60
|
}, [animatedProps]);
|
|
61
|
-
// Native-driver trigger
|
|
61
|
+
// Native-driver trigger. Runs after attach: push the leaf -> style -> transform
|
|
62
62
|
// -> interpolation -> value chain native so the props animate on the UI thread (no JS lag).
|
|
63
63
|
// Cascades down to the source value; the scroll event attaches to that same value
|
|
64
64
|
// (idempotent). __makeNative is idempotent, so re-firing on a leaf swap is safe.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// The Animated namespace for @symbiote-native/react. createAnimatedComponent applied to
|
|
2
2
|
// the adapter's primitives gives Animated.View / Text / Image; the value graph,
|
|
3
3
|
// easing and imperative drivers come from @symbiote-native/engine (framework-agnostic,
|
|
4
|
-
// JS-driven
|
|
4
|
+
// JS-driven). Both halves meet here in one `Animated` object so the
|
|
5
5
|
// familiar surface (`Animated.timing(new Animated.Value(0), …).start()`) works.
|
|
6
6
|
import { AnimatedValue, AnimatedValueXY, AnimatedColor, Easing, Platform, timing, spring, decay, parallel, sequence, stagger, loop, delay, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, } from '@symbiote-native/engine';
|
|
7
7
|
import { View, Text } from '../../components.js';
|
|
8
8
|
import { Image } from '../../components/image/index.js';
|
|
9
|
-
import { ScrollView } from '../../components/scroll-view
|
|
9
|
+
import { ScrollView } from '../../components/scroll-view';
|
|
10
10
|
import { FlatList } from '../../components/flat-list/index.js';
|
|
11
11
|
import { SectionList } from '../../components/section-list/index.js';
|
|
12
12
|
import { createAnimatedComponent } from './create-animated-component.js';
|
|
@@ -26,7 +26,7 @@ const AnimatedImage = createAnimatedComponent(Image);
|
|
|
26
26
|
// back, and a static `createAnimatedComponent(ScrollView)` at init would read ScrollView
|
|
27
27
|
// inside its own TDZ. A memoized getter defers the wrap past module init, so the
|
|
28
28
|
// cycle never fires. The wrappers carry no per-component animation logic; they only
|
|
29
|
-
// add animated-prop support,
|
|
29
|
+
// add animated-prop support, keeping the adapter a thin layer over the engine.
|
|
30
30
|
// The native scroll-event attach (Animated.event onto contentOffset) is owned by
|
|
31
31
|
// ScrollView itself.
|
|
32
32
|
let animatedScrollView;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// I18nManager now lives framework-agnostic in @symbiote-native/engine (imperative
|
|
2
2
|
// native-bridge module, no visual, no lifecycle). The React adapter re-exports it
|
|
3
|
-
// verbatim so the public surface is unchanged.
|
|
3
|
+
// verbatim so the public surface is unchanged.
|
|
4
4
|
export { I18nManager } from '@symbiote-native/engine';
|
package/build/modules/linking.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Linking now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
2
|
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
-
// platform split (linking.ios/linking.android) lives inside engine.
|
|
3
|
+
// platform split (linking.ios/linking.android) lives inside engine.
|
|
4
4
|
export { Linking } from '@symbiote-native/engine';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Settings now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
2
|
// module, no visual, no lifecycle). The React adapter re-exports it verbatim so the
|
|
3
|
-
// public surface is unchanged.
|
|
3
|
+
// public surface is unchanged.
|
|
4
4
|
export { Settings } from '@symbiote-native/engine';
|
package/build/modules/share.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Share now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
2
|
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
-
// platform split (share.ios/share.android) lives inside engine.
|
|
3
|
+
// platform split (share.ios/share.android) lives inside engine.
|
|
4
4
|
export { Share } from '@symbiote-native/engine';
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// not installed" because RN installs global.RN$stopSurface from its own renderer, which this
|
|
14
14
|
// renderer replaces. Now that render.ts installs RN$stopSurface and tears surfaces down cleanly, the
|
|
15
15
|
// relayout survives and the bar updates without blanking (verified on device: show/hide +
|
|
16
|
-
// light/dark text).
|
|
16
|
+
// light/dark text).
|
|
17
17
|
import { useEffect } from 'react';
|
|
18
18
|
import { dlog, getNativeModule, processColor, STATUS_BAR_MANAGER, } from '@symbiote-native/engine';
|
|
19
19
|
// processColor returns `unknown` (its result is platform-dependent); narrow to the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// StatusBar on iOS: drives the iOS `StatusBarManager` TurboModule from its props
|
|
2
|
-
// (and from static methods). The native contract
|
|
3
|
-
//
|
|
2
|
+
// (and from static methods). The native contract matches React Native's own
|
|
3
|
+
// NativeStatusBarManagerIOS spec:
|
|
4
4
|
// setStyle(statusBarStyle?: string, animated: boolean)
|
|
5
5
|
// setHidden(hidden: boolean, withAnimation: 'none' | 'fade' | 'slide')
|
|
6
6
|
// setNetworkActivityIndicatorVisible(visible: boolean)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ToastAndroid
|
|
1
|
+
// ToastAndroid lives framework-agnostic in @symbiote-native/engine (imperative
|
|
2
2
|
// native-bridge module, no visual, no lifecycle). The React adapter re-exports it
|
|
3
|
-
// verbatim so the public surface is unchanged.
|
|
3
|
+
// verbatim so the public surface is unchanged.
|
|
4
4
|
export { ToastAndroid } from '@symbiote-native/engine';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Vibration
|
|
1
|
+
// Vibration lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
2
|
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
-
// platform split (vibration.ios/vibration.android) lives inside engine.
|
|
3
|
+
// platform split (vibration.ios/vibration.android) lives inside the engine.
|
|
4
4
|
export { Vibration } from '@symbiote-native/engine';
|
package/metro-css-parser.cjs
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
// requiring FILE's own location, so this indirection is what actually removes the extra install
|
|
7
7
|
// step, not pnpm hoisting (which does not propagate this transitively across workspace packages
|
|
8
8
|
// the way a flat classic node_modules would). .cjs, not .js: this package is "type": "module",
|
|
9
|
-
// and Metro's babelTransformerPath loading expects a require()-able module.
|
|
10
|
-
// symbiote-sfc-style-compiler skill.
|
|
9
|
+
// and Metro's babelTransformerPath loading expects a require()-able module.
|
|
11
10
|
// createCssMetroTransformer is a factory, not a ready transformer — Metro's
|
|
12
11
|
// babelTransformerPath needs the actual {transform, getCacheKey} object it returns,
|
|
13
12
|
// not the css-parser package barrel.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
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
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"react-reconciler": "^0.33.0",
|
|
39
|
-
"@symbiote-native/components": "0.2.
|
|
40
|
-
"@symbiote-native/css-parser": "0.2.
|
|
41
|
-
"@symbiote-native/engine": "0.1.
|
|
39
|
+
"@symbiote-native/components": "0.2.3",
|
|
40
|
+
"@symbiote-native/css-parser": "0.2.1",
|
|
41
|
+
"@symbiote-native/engine": "0.1.4"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": ">=19.0.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@types/react": "^19.2.0",
|
|
49
49
|
"@types/react-reconciler": "^0.32.2",
|
|
50
50
|
"react": "19.2.3",
|
|
51
|
-
"@symbiote-native/test-utils": "0.1.
|
|
51
|
+
"@symbiote-native/test-utils": "0.1.5"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"typecheck": "tsc --build",
|