@symbiote-native/react 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 +149 -0
- package/build/components/activity-indicator/index.android.d.ts +2 -0
- package/build/components/activity-indicator/index.android.js +13 -0
- package/build/components/activity-indicator/index.d.ts +1 -0
- package/build/components/activity-indicator/index.ios.d.ts +2 -0
- package/build/components/activity-indicator/index.ios.js +10 -0
- package/build/components/activity-indicator/index.js +4 -0
- package/build/components/activity-indicator/shared.d.ts +7 -0
- package/build/components/activity-indicator/shared.js +20 -0
- package/build/components/button.d.ts +6 -0
- package/build/components/button.js +42 -0
- package/build/components/drawer-layout-android/index.android.d.ts +3 -0
- package/build/components/drawer-layout-android/index.android.js +93 -0
- package/build/components/drawer-layout-android/index.d.ts +3 -0
- package/build/components/drawer-layout-android/index.js +19 -0
- package/build/components/drawer-layout-android/shared.d.ts +19 -0
- package/build/components/drawer-layout-android/shared.js +7 -0
- package/build/components/flat-list/index.d.ts +73 -0
- package/build/components/flat-list/index.js +86 -0
- package/build/components/image/index.d.ts +9 -0
- package/build/components/image/index.js +28 -0
- package/build/components/image-background/index.d.ts +10 -0
- package/build/components/image-background/index.js +46 -0
- package/build/components/input-accessory-view/index.d.ts +11 -0
- package/build/components/input-accessory-view/index.js +14 -0
- package/build/components/keyboard-avoiding-view/index.d.ts +17 -0
- package/build/components/keyboard-avoiding-view/index.js +85 -0
- package/build/components/modal/index.d.ts +24 -0
- package/build/components/modal/index.js +56 -0
- package/build/components/pressable/index.d.ts +30 -0
- package/build/components/pressable/index.js +100 -0
- package/build/components/refresh-control/index.d.ts +17 -0
- package/build/components/refresh-control/index.js +21 -0
- package/build/components/safe-area-view/index.d.ts +11 -0
- package/build/components/safe-area-view/index.js +18 -0
- package/build/components/scroll-view/index.android.d.ts +3 -0
- package/build/components/scroll-view/index.android.js +53 -0
- package/build/components/scroll-view/index.d.ts +1 -0
- package/build/components/scroll-view/index.ios.d.ts +3 -0
- package/build/components/scroll-view/index.ios.js +27 -0
- package/build/components/scroll-view/index.js +4 -0
- package/build/components/scroll-view/shared.d.ts +98 -0
- package/build/components/scroll-view/shared.js +195 -0
- package/build/components/scroll-view/sticky-header.d.ts +9 -0
- package/build/components/scroll-view/sticky-header.js +161 -0
- package/build/components/section-list/index.d.ts +8 -0
- package/build/components/section-list/index.js +12 -0
- package/build/components/switch/index.android.d.ts +2 -0
- package/build/components/switch/index.android.js +12 -0
- package/build/components/switch/index.d.ts +1 -0
- package/build/components/switch/index.ios.d.ts +2 -0
- package/build/components/switch/index.ios.js +10 -0
- package/build/components/switch/index.js +6 -0
- package/build/components/switch/shared.d.ts +10 -0
- package/build/components/switch/shared.js +59 -0
- package/build/components/text-input/index.d.ts +50 -0
- package/build/components/text-input/index.js +167 -0
- package/build/components/touchable/index.d.ts +20 -0
- package/build/components/touchable/index.js +95 -0
- package/build/components/touchable-native-feedback/index.d.ts +18 -0
- package/build/components/touchable-native-feedback/index.js +32 -0
- package/build/components/virtualized-list/index.d.ts +73 -0
- package/build/components/virtualized-list/index.js +552 -0
- package/build/components/virtualized-section-list/index.d.ts +66 -0
- package/build/components/virtualized-section-list/index.js +99 -0
- package/build/components.d.ts +54 -0
- package/build/components.js +17 -0
- package/build/create-portal.d.ts +4 -0
- package/build/create-portal.js +23 -0
- package/build/create-tunnel.d.ts +12 -0
- package/build/create-tunnel.js +60 -0
- package/build/descriptor-to-react/index.d.ts +3 -0
- package/build/descriptor-to-react/index.js +15 -0
- package/build/hooks/use-color-scheme.d.ts +2 -0
- package/build/hooks/use-color-scheme.js +13 -0
- package/build/hooks/use-window-dimensions.d.ts +2 -0
- package/build/hooks/use-window-dimensions.js +30 -0
- package/build/host-config.d.ts +7 -0
- package/build/host-config.js +169 -0
- package/build/host-instance.d.ts +3 -0
- package/build/host-instance.js +20 -0
- package/build/index.d.ts +98 -0
- package/build/index.js +85 -0
- package/build/modules/accessibility-info/index.android.d.ts +2 -0
- package/build/modules/accessibility-info/index.android.js +4 -0
- package/build/modules/accessibility-info/index.d.ts +1 -0
- package/build/modules/accessibility-info/index.ios.d.ts +2 -0
- package/build/modules/accessibility-info/index.ios.js +3 -0
- package/build/modules/accessibility-info/index.js +5 -0
- package/build/modules/accessibility-info/shared.d.ts +1 -0
- package/build/modules/accessibility-info/shared.js +1 -0
- package/build/modules/action-sheet-ios.d.ts +2 -0
- package/build/modules/action-sheet-ios.js +4 -0
- package/build/modules/alert.d.ts +2 -0
- package/build/modules/alert.js +5 -0
- package/build/modules/animated/create-animated-component.d.ts +12 -0
- package/build/modules/animated/create-animated-component.js +125 -0
- package/build/modules/animated/index.d.ts +52 -0
- package/build/modules/animated/index.js +84 -0
- package/build/modules/app-registry/index.d.ts +7 -0
- package/build/modules/app-registry/index.js +26 -0
- package/build/modules/app-state.d.ts +2 -0
- package/build/modules/app-state.js +3 -0
- package/build/modules/appearance.d.ts +2 -0
- package/build/modules/appearance.js +3 -0
- package/build/modules/back-handler.d.ts +2 -0
- package/build/modules/back-handler.js +3 -0
- package/build/modules/dimensions.d.ts +2 -0
- package/build/modules/dimensions.js +3 -0
- package/build/modules/i18n-manager.d.ts +2 -0
- package/build/modules/i18n-manager.js +4 -0
- package/build/modules/keyboard.d.ts +2 -0
- package/build/modules/keyboard.js +3 -0
- package/build/modules/layout-animation.d.ts +2 -0
- package/build/modules/layout-animation.js +3 -0
- package/build/modules/linking.d.ts +2 -0
- package/build/modules/linking.js +4 -0
- package/build/modules/permissions-android.d.ts +2 -0
- package/build/modules/permissions-android.js +3 -0
- package/build/modules/settings.d.ts +1 -0
- package/build/modules/settings.js +4 -0
- package/build/modules/share.d.ts +2 -0
- package/build/modules/share.js +4 -0
- package/build/modules/status-bar/index.android.d.ts +3 -0
- package/build/modules/status-bar/index.android.js +89 -0
- package/build/modules/status-bar/index.d.ts +1 -0
- package/build/modules/status-bar/index.ios.d.ts +3 -0
- package/build/modules/status-bar/index.ios.js +64 -0
- package/build/modules/status-bar/index.js +4 -0
- package/build/modules/status-bar/shared.d.ts +6 -0
- package/build/modules/status-bar/shared.js +6 -0
- package/build/modules/text-input-state.d.ts +1 -0
- package/build/modules/text-input-state.js +3 -0
- package/build/modules/toast-android.d.ts +1 -0
- package/build/modules/toast-android.js +4 -0
- package/build/modules/vibration.d.ts +1 -0
- package/build/modules/vibration.js +4 -0
- package/build/reconciler-constants.d.ts +7 -0
- package/build/reconciler-constants.js +12 -0
- package/build/render.d.ts +7 -0
- package/build/render.js +60 -0
- package/build/utils/responder-props.d.ts +1 -0
- package/build/utils/responder-props.js +1 -0
- package/build/utils/styles.d.ts +1 -0
- package/build/utils/styles.js +1 -0
- package/metro-css-parser.cjs +11 -0
- package/package.json +53 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Linking now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
|
+
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
+
// platform split (linking.ios/linking.android) lives inside engine. See ADR 0019.
|
|
4
|
+
export { Linking } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// PermissionsAndroid moved to @symbiote-native/engine (a framework-agnostic device-state module
|
|
2
|
+
// re-exported by every adapter). This thin re-export keeps @symbiote-native/react's surface identical.
|
|
3
|
+
export { PermissionsAndroid, PERMISSIONS, RESULTS } from '@symbiote-native/engine';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Settings } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Settings now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
|
+
// module, no visual, no lifecycle). The React adapter re-exports it verbatim so the
|
|
3
|
+
// public surface is unchanged. See ADR 0019.
|
|
4
|
+
export { Settings } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Share now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
|
+
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
+
// platform split (share.ios/share.android) lives inside engine. See ADR 0019.
|
|
4
|
+
export { Share } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// StatusBar on Android: drives the Android StatusBarManager from props (and from the
|
|
2
|
+
// static methods). Android's native module is a DIFFERENT shape from iOS: single-arg
|
|
3
|
+
// setHidden(hidden) / setStyle(style) plus setColor/setTranslucent, same module name
|
|
4
|
+
// ('StatusBarManager'). Metro picks this on an Android host; iOS keeps its own shape.
|
|
5
|
+
//
|
|
6
|
+
// The native-call logic stays in the adapter (not the engine): the platform module shape
|
|
7
|
+
// diverges iOS/Android and the headless smokes import this file by name (tsx has no platform
|
|
8
|
+
// picker, so routing through the engine barrel would resolve the iOS base on every platform).
|
|
9
|
+
// The engine owns only the pure shared contract: types, constants, hideTransition.
|
|
10
|
+
//
|
|
11
|
+
// History: this used to be a no-op. Driving the window flags from the bridgeless surface
|
|
12
|
+
// blanked the app: a status-bar relayout triggered stopSurface, which threw "Global was
|
|
13
|
+
// not installed" because RN installs global.RN$stopSurface from its own renderer, which this
|
|
14
|
+
// renderer replaces. Now that render.ts installs RN$stopSurface and tears surfaces down cleanly, the
|
|
15
|
+
// relayout survives and the bar updates without blanking (verified on device: show/hide +
|
|
16
|
+
// light/dark text). See render.ts installStopSurfaceGlobal + native-module-platform-routing.
|
|
17
|
+
import { useEffect } from 'react';
|
|
18
|
+
import { dlog, getNativeModule, processColor, STATUS_BAR_MANAGER, } from '@symbiote-native/engine';
|
|
19
|
+
// processColor returns `unknown` (its result is platform-dependent); narrow to the
|
|
20
|
+
// number Fabric/native expects, like RN's invariant before setColor. A non-number
|
|
21
|
+
// (null for an unparseable color, headless identity passthrough of a string) is dropped.
|
|
22
|
+
function applyBackgroundColor(manager, color, animated) {
|
|
23
|
+
const processed = processColor(color);
|
|
24
|
+
if (typeof processed !== 'number') {
|
|
25
|
+
dlog(`StatusBar android: backgroundColor ${String(color)} did not process to an int — skipping`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// RISK: driving the window background flag once blanked the bridgeless surface
|
|
29
|
+
// (see header). Routed cleanly here but DEVICE-VERIFY-PENDING.
|
|
30
|
+
dlog(`StatusBar android setColor -> ${processed} animated=${animated}`);
|
|
31
|
+
manager.setColor(processed, animated);
|
|
32
|
+
}
|
|
33
|
+
// Renders null and applies its props to the native module in an effect, on mount and on
|
|
34
|
+
// every prop change, same contract as iOS, with the single-arg Android setters.
|
|
35
|
+
const StatusBarAndroid = props => {
|
|
36
|
+
const { barStyle, hidden, animated = false, backgroundColor, translucent } = props;
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const manager = getNativeModule(STATUS_BAR_MANAGER);
|
|
39
|
+
if (manager === null) {
|
|
40
|
+
dlog('StatusBar android: StatusBarManager not resolvable — skipping');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
dlog(`StatusBar android -> barStyle=${barStyle} hidden=${hidden} translucent=${translucent} bg=${String(backgroundColor)}`);
|
|
44
|
+
if (barStyle !== undefined)
|
|
45
|
+
manager.setStyle(barStyle);
|
|
46
|
+
if (hidden !== undefined)
|
|
47
|
+
manager.setHidden(hidden);
|
|
48
|
+
if (translucent !== undefined)
|
|
49
|
+
manager.setTranslucent(translucent);
|
|
50
|
+
if (backgroundColor !== undefined)
|
|
51
|
+
applyBackgroundColor(manager, backgroundColor, animated);
|
|
52
|
+
}, [barStyle, hidden, animated, backgroundColor, translucent]);
|
|
53
|
+
return null;
|
|
54
|
+
};
|
|
55
|
+
StatusBarAndroid.setBarStyle = style => {
|
|
56
|
+
dlog(`StatusBar.setBarStyle android ${style}`);
|
|
57
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setStyle(style);
|
|
58
|
+
};
|
|
59
|
+
StatusBarAndroid.setHidden = hidden => {
|
|
60
|
+
dlog(`StatusBar.setHidden android ${hidden}`);
|
|
61
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setHidden(hidden);
|
|
62
|
+
};
|
|
63
|
+
StatusBarAndroid.setNetworkActivityIndicatorVisible = () => {
|
|
64
|
+
// No Android equivalent, an iOS-only concept.
|
|
65
|
+
dlog('StatusBar.setNetworkActivityIndicatorVisible (android no-op)');
|
|
66
|
+
};
|
|
67
|
+
StatusBarAndroid.setBackgroundColor = (color, animated = false) => {
|
|
68
|
+
dlog(`StatusBar.setBackgroundColor android ${String(color)}`);
|
|
69
|
+
const manager = getNativeModule(STATUS_BAR_MANAGER);
|
|
70
|
+
if (manager === null)
|
|
71
|
+
return;
|
|
72
|
+
applyBackgroundColor(manager, color, animated);
|
|
73
|
+
};
|
|
74
|
+
StatusBarAndroid.setTranslucent = translucent => {
|
|
75
|
+
// RISK: window translucent flag is device-verify-pending (may blank the surface).
|
|
76
|
+
dlog(`StatusBar.setTranslucent android ${translucent}`);
|
|
77
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setTranslucent(translucent);
|
|
78
|
+
};
|
|
79
|
+
// Android exposes the bar height as a native constant; undefined if the module or the
|
|
80
|
+
// constant is absent (older RN, or a fake that doesn't define getConstants). Read lazily
|
|
81
|
+
// (getter, not a value) so nothing touches native at import time.
|
|
82
|
+
Object.defineProperty(StatusBarAndroid, 'currentHeight', {
|
|
83
|
+
get() {
|
|
84
|
+
return getNativeModule(STATUS_BAR_MANAGER)?.getConstants?.()
|
|
85
|
+
.HEIGHT;
|
|
86
|
+
},
|
|
87
|
+
enumerable: true,
|
|
88
|
+
});
|
|
89
|
+
export const StatusBar = StatusBarAndroid;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.ios';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// StatusBar on iOS: drives the iOS `StatusBarManager` TurboModule from its props
|
|
2
|
+
// (and from static methods). The native contract is RN's spec at
|
|
3
|
+
// .vendors/react-native/.../src/private/specs_DEPRECATED/modules/NativeStatusBarManagerIOS.js:
|
|
4
|
+
// setStyle(statusBarStyle?: string, animated: boolean)
|
|
5
|
+
// setHidden(hidden: boolean, withAnimation: 'none' | 'fade' | 'slide')
|
|
6
|
+
// setNetworkActivityIndicatorVisible(visible: boolean)
|
|
7
|
+
// Only those three setters are mirrored as the hand-written interface, the typed trust
|
|
8
|
+
// boundary getNativeModule<T> resolves against. Metro picks this on an iOS host.
|
|
9
|
+
//
|
|
10
|
+
// The native-call logic stays in the adapter (not the engine): the platform module shape
|
|
11
|
+
// diverges iOS/Android and the headless smokes import this file by name (tsx has no
|
|
12
|
+
// platform picker, so routing through the engine barrel would resolve the iOS base on every
|
|
13
|
+
// platform). The engine owns only the pure shared contract: types, constants, hideTransition.
|
|
14
|
+
import { useEffect } from 'react';
|
|
15
|
+
import { dlog, getNativeModule, STATUS_BAR_MANAGER, STATIC_HIDE_TRANSITION, hideTransition, } from '@symbiote-native/engine';
|
|
16
|
+
// StatusBar renders null and applies its props to the native module in an effect,
|
|
17
|
+
// on mount and on every prop change. Simplification vs RN: RN maintains a
|
|
18
|
+
// prop-merge stack so nested StatusBars compose (deepest/last wins). This module
|
|
19
|
+
// direct-applies a single component's props, which is correct for one StatusBar.
|
|
20
|
+
export const StatusBar = props => {
|
|
21
|
+
const { barStyle, hidden, animated = false, networkActivityIndicatorVisible } = props;
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
// Resolve lazily inside the effect, not at import, keeps this module importable
|
|
24
|
+
// headless before a fake __turboModuleProxy is installed. Non-enforcing: a
|
|
25
|
+
// declarative StatusBar must NOT crash the whole render if the module can't resolve.
|
|
26
|
+
const manager = getNativeModule(STATUS_BAR_MANAGER);
|
|
27
|
+
if (manager === null) {
|
|
28
|
+
dlog('StatusBar: StatusBarManager not resolvable via __turboModuleProxy — skipping');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
dlog('StatusBar -> applying props to StatusBarManager');
|
|
32
|
+
if (barStyle !== undefined)
|
|
33
|
+
manager.setStyle(barStyle, animated);
|
|
34
|
+
if (hidden !== undefined)
|
|
35
|
+
manager.setHidden(hidden, hideTransition(animated));
|
|
36
|
+
if (networkActivityIndicatorVisible !== undefined) {
|
|
37
|
+
manager.setNetworkActivityIndicatorVisible(networkActivityIndicatorVisible);
|
|
38
|
+
}
|
|
39
|
+
}, [barStyle, hidden, animated, networkActivityIndicatorVisible]);
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
// The static API mirrors the declarative component: non-throwing. A missing optional
|
|
43
|
+
// native module is a no-op.
|
|
44
|
+
StatusBar.setBarStyle = (style, animated = false) => {
|
|
45
|
+
dlog('StatusBar.setBarStyle');
|
|
46
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setStyle(style, animated);
|
|
47
|
+
};
|
|
48
|
+
StatusBar.setHidden = (hidden, animation = STATIC_HIDE_TRANSITION) => {
|
|
49
|
+
dlog('StatusBar.setHidden');
|
|
50
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setHidden(hidden, animation);
|
|
51
|
+
};
|
|
52
|
+
StatusBar.setNetworkActivityIndicatorVisible = visible => {
|
|
53
|
+
dlog('StatusBar.setNetworkActivityIndicatorVisible');
|
|
54
|
+
getNativeModule(STATUS_BAR_MANAGER)?.setNetworkActivityIndicatorVisible(visible);
|
|
55
|
+
};
|
|
56
|
+
// Android-only on RN, inert on iOS (the iOS status bar has no background color and
|
|
57
|
+
// is never translucent in RN's sense). Present so the contract is platform-uniform.
|
|
58
|
+
StatusBar.setBackgroundColor = () => {
|
|
59
|
+
dlog('StatusBar.setBackgroundColor (ios no-op)');
|
|
60
|
+
};
|
|
61
|
+
StatusBar.setTranslucent = () => {
|
|
62
|
+
dlog('StatusBar.setTranslucent (ios no-op)');
|
|
63
|
+
};
|
|
64
|
+
// currentHeight is Android-only; absent on iOS (RN sets it to null on iOS).
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Base / default StatusBar: re-exports the iOS build. Metro overrides this with
|
|
2
|
+
// status-bar.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. See status-bar-shared.ts.
|
|
4
|
+
export * from './index.ios';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { IStatusBarImperative, IStatusBarProps } from '@symbiote-native/engine';
|
|
3
|
+
export type { IStatusBarProps, IStatusBarStyle, IStatusBarAnimation, } from '@symbiote-native/engine';
|
|
4
|
+
export interface IStatusBarComponent extends FC<IStatusBarProps>, IStatusBarImperative {
|
|
5
|
+
currentHeight?: number;
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// StatusBar is the React-side contract. The pure types + the imperative API + applyStatusBarProps
|
|
2
|
+
// live in @symbiote-native/engine (shared verbatim with every adapter); React supplies only the
|
|
3
|
+
// declarative component shape: an FC that renders null and applies the props in an effect, with
|
|
4
|
+
// the imperative statics attached to the function object (RN's StatusBar). IStatusBarComponent
|
|
5
|
+
// is the one React-coupled type (it names React's FC), so it stays here, not in the engine.
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// TextInputState moved to @symbiote-native/engine (a framework-agnostic module: Keyboard.dismiss
|
|
2
|
+
// and TextInput both reach it). This thin re-export keeps the adapter's import path stable.
|
|
3
|
+
export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from '@symbiote-native/engine';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ToastAndroid } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// ToastAndroid now lives framework-agnostic in @symbiote-native/engine (imperative
|
|
2
|
+
// native-bridge module, no visual, no lifecycle). The React adapter re-exports it
|
|
3
|
+
// verbatim so the public surface is unchanged. See ADR 0019.
|
|
4
|
+
export { ToastAndroid } from '@symbiote-native/engine';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Vibration } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Vibration now lives framework-agnostic in @symbiote-native/engine (imperative native-bridge
|
|
2
|
+
// module, no visual, no lifecycle). The React adapter re-exports it verbatim; the
|
|
3
|
+
// platform split (vibration.ios/vibration.android) lives inside engine. See ADR 0019.
|
|
4
|
+
export { Vibration } from '@symbiote-native/engine';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const LegacyRoot = 0;
|
|
2
|
+
export declare const ConcurrentRoot = 1;
|
|
3
|
+
export declare const NoEventPriority = 0;
|
|
4
|
+
export declare const DiscreteEventPriority = 2;
|
|
5
|
+
export declare const ContinuousEventPriority = 8;
|
|
6
|
+
export declare const DefaultEventPriority = 32;
|
|
7
|
+
export declare const IdleEventPriority = 268435456;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Inlined from react-reconciler/constants. The package ships CommonJS only, so
|
|
2
|
+
// importing the subpath under ESM/bundler resolution is fragile; these values
|
|
3
|
+
// are stable.
|
|
4
|
+
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactRootTags.js
|
|
5
|
+
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactEventPriorities.js
|
|
6
|
+
export const LegacyRoot = 0;
|
|
7
|
+
export const ConcurrentRoot = 1;
|
|
8
|
+
export const NoEventPriority = 0;
|
|
9
|
+
export const DiscreteEventPriority = 2;
|
|
10
|
+
export const ContinuousEventPriority = 8;
|
|
11
|
+
export const DefaultEventPriority = 32;
|
|
12
|
+
export const IdleEventPriority = 268435456;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type IRootTag, type SymbioteSurface } from '@symbiote-native/engine';
|
|
3
|
+
export declare function mount(rootTag: IRootTag, element: ReactNode): SymbioteSurface;
|
|
4
|
+
export declare function unmount(rootTag: IRootTag): void;
|
|
5
|
+
declare global {
|
|
6
|
+
var RN$stopSurface: ((surfaceId: number) => void) | undefined;
|
|
7
|
+
}
|
package/build/render.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Mount a React element tree onto a Fabric surface. The native host hands us a
|
|
2
|
+
// rootTag (via AppRegistry.registerRunnable); we create a surface for it and let
|
|
3
|
+
// the reconciler drive shared, which commits into nativeFabricUIManager.
|
|
4
|
+
import { createSurface, disposeRoot, setEventDispatcher, dlog, } from '@symbiote-native/engine';
|
|
5
|
+
import reconciler, { withDiscretePriority } from './host-config';
|
|
6
|
+
import { LegacyRoot } from './reconciler-constants';
|
|
7
|
+
const noop = () => { };
|
|
8
|
+
// A native event runs the listener (which may call setState) outside React's
|
|
9
|
+
// loop. Run it at discrete priority so the update takes the sync lane, then
|
|
10
|
+
// flush that work synchronously to paint the result.
|
|
11
|
+
setEventDispatcher(run => {
|
|
12
|
+
withDiscretePriority(run);
|
|
13
|
+
// @ts-expect-error flushSyncWork exists at runtime in react-reconciler 0.33
|
|
14
|
+
reconciler.flushSyncWork();
|
|
15
|
+
});
|
|
16
|
+
const containers = new Map();
|
|
17
|
+
// Unmount a surface's React tree (render null → empty completeRoot, clearing the
|
|
18
|
+
// native views) and drop its shared root container so a later mount on the same
|
|
19
|
+
// rootTag rebuilds from scratch instead of cloning the stopped surface's dead handles.
|
|
20
|
+
function teardown(rootTag) {
|
|
21
|
+
const container = containers.get(rootTag);
|
|
22
|
+
if (container === undefined)
|
|
23
|
+
return;
|
|
24
|
+
// @ts-expect-error updateContainerSync exists at runtime in react-reconciler 0.33
|
|
25
|
+
reconciler.updateContainerSync(null, container, null, noop);
|
|
26
|
+
// @ts-expect-error flushSyncWork exists at runtime in react-reconciler 0.33
|
|
27
|
+
reconciler.flushSyncWork();
|
|
28
|
+
containers.delete(rootTag);
|
|
29
|
+
disposeRoot(rootTag);
|
|
30
|
+
}
|
|
31
|
+
export function mount(rootTag, element) {
|
|
32
|
+
// A re-mount on a live rootTag (host restarted the surface without stopping it
|
|
33
|
+
// first) starts clean. Otherwise the stale container double-drives the surface.
|
|
34
|
+
teardown(rootTag);
|
|
35
|
+
const surface = createSurface(rootTag);
|
|
36
|
+
const container = reconciler.createContainer(surface, LegacyRoot, null, false, null, 'symbiote', noop, noop, noop, noop, null);
|
|
37
|
+
containers.set(rootTag, container);
|
|
38
|
+
// react-reconciler 0.33 exposes updateContainerSync + flushSyncWork for an
|
|
39
|
+
// immediate render/commit; @types 0.32 still lists the older updateContainer /
|
|
40
|
+
// flushSync names, so these calls are type-suppressed until the types catch up.
|
|
41
|
+
// @ts-expect-error updateContainerSync exists at runtime in react-reconciler 0.33
|
|
42
|
+
reconciler.updateContainerSync(element, container, null, noop);
|
|
43
|
+
// @ts-expect-error flushSyncWork exists at runtime in react-reconciler 0.33
|
|
44
|
+
reconciler.flushSyncWork();
|
|
45
|
+
return surface;
|
|
46
|
+
}
|
|
47
|
+
// Tear down a surface by rootTag, the public pair of `mount`. This is also the JS half of
|
|
48
|
+
// the bridgeless `RN$stopSurface` contract (see installStopSurfaceGlobal): the native
|
|
49
|
+
// AppRegistryBinding calls our global to stop a surface; we unmount its tree and dispose its root.
|
|
50
|
+
export function unmount(rootTag) {
|
|
51
|
+
dlog(`unmount root=${rootTag}`);
|
|
52
|
+
teardown(rootTag);
|
|
53
|
+
}
|
|
54
|
+
function installStopSurfaceGlobal() {
|
|
55
|
+
globalThis.RN$stopSurface = (surfaceId) => {
|
|
56
|
+
unmount(surfaceId);
|
|
57
|
+
};
|
|
58
|
+
dlog('installed global.RN$stopSurface');
|
|
59
|
+
}
|
|
60
|
+
installStopSurfaceGlobal();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { IResponderProps } from '@symbiote-native/components';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { IViewStyle, ITextStyle, IStyleProp, IDimensionValue, IFlexAlign, IFlexJustify, ITransformProp, IBoxShadowValue, IDropShadowValue, IFilterFunction, IBlendMode, } from '@symbiote-native/engine';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Re-exports @symbiote-native/css-parser verbatim from INSIDE this package, so a consuming app's own
|
|
2
|
+
// require('@symbiote-native/react/metro-css-parser') resolves css-parser relative to THIS file's
|
|
3
|
+
// location (adapters/react/node_modules, where css-parser IS a real dependency — see
|
|
4
|
+
// package.json), not relative to the app's own node_modules, which does not and should not
|
|
5
|
+
// need to declare @symbiote-native/css-parser itself. Node resolves each require() relative to the
|
|
6
|
+
// requiring FILE's own location, so this indirection is what actually removes the extra install
|
|
7
|
+
// step, not pnpm hoisting (which does not propagate this transitively across workspace packages
|
|
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. See the
|
|
10
|
+
// symbiote-sfc-style-compiler skill.
|
|
11
|
+
module.exports = require('@symbiote-native/css-parser');
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@symbiote-native/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SymbioteJS's React adapter — a react-reconciler host config (mutation mode) driving real native iOS/Android views through stock React Native Fabric.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/OneEyed1366/symbiote-native.git",
|
|
8
|
+
"directory": "adapters/react"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/OneEyed1366/symbiote-native/tree/master/adapters/react#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/OneEyed1366/symbiote-native/issues"
|
|
13
|
+
},
|
|
14
|
+
"author": "Andrey Prokopenko <psevdoproger@gmail.com>",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./build/index.js",
|
|
17
|
+
"module": "./build/index.js",
|
|
18
|
+
"types": "./build/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./build/index.d.ts",
|
|
22
|
+
"default": "./build/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./metro-css-parser": "./metro-css-parser.cjs"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"build",
|
|
28
|
+
"metro-css-parser.cjs"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"react-reconciler": "^0.33.0",
|
|
35
|
+
"@symbiote-native/components": "0.1.0",
|
|
36
|
+
"@symbiote-native/engine": "0.1.0",
|
|
37
|
+
"@symbiote-native/css-parser": "0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"react": ">=19.0.0",
|
|
41
|
+
"react-native": ">=0.86"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/react": "^19.2.0",
|
|
45
|
+
"@types/react-reconciler": "^0.32.2",
|
|
46
|
+
"react": "19.2.3",
|
|
47
|
+
"@symbiote-native/test-utils": "0.0.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"typecheck": "tsc --build",
|
|
51
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\""
|
|
52
|
+
}
|
|
53
|
+
}
|