@symbiote-native/engine 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 +124 -0
- package/build/accessibility-info/index.android.d.ts +3 -0
- package/build/accessibility-info/index.android.js +166 -0
- package/build/accessibility-info/index.d.ts +1 -0
- package/build/accessibility-info/index.ios.d.ts +3 -0
- package/build/accessibility-info/index.ios.js +219 -0
- package/build/accessibility-info/index.js +5 -0
- package/build/accessibility-info/shared.d.ts +34 -0
- package/build/accessibility-info/shared.js +13 -0
- package/build/action-sheet-ios/index.d.ts +36 -0
- package/build/action-sheet-ios/index.js +74 -0
- package/build/alert/index.android.d.ts +5 -0
- package/build/alert/index.android.js +117 -0
- package/build/alert/index.d.ts +1 -0
- package/build/alert/index.ios.d.ts +7 -0
- package/build/alert/index.ios.js +83 -0
- package/build/alert/index.js +8 -0
- package/build/alert/shared.d.ts +19 -0
- package/build/alert/shared.js +17 -0
- package/build/animated/animated-component-shared.d.ts +5 -0
- package/build/animated/animated-component-shared.js +54 -0
- package/build/animated/animation.d.ts +9 -0
- package/build/animated/animation.js +6 -0
- package/build/animated/animations/base.d.ts +27 -0
- package/build/animated/animations/base.js +90 -0
- package/build/animated/animations/composition.d.ts +38 -0
- package/build/animated/animations/composition.js +236 -0
- package/build/animated/animations/decay.d.ts +22 -0
- package/build/animated/animations/decay.js +65 -0
- package/build/animated/animations/raf.d.ts +5 -0
- package/build/animated/animations/raf.js +39 -0
- package/build/animated/animations/spring-config.d.ts +6 -0
- package/build/animated/animations/spring-config.js +55 -0
- package/build/animated/animations/spring.d.ts +50 -0
- package/build/animated/animations/spring.js +207 -0
- package/build/animated/animations/timing.d.ts +27 -0
- package/build/animated/animations/timing.js +101 -0
- package/build/animated/animations/tracking.d.ts +14 -0
- package/build/animated/animations/tracking.js +43 -0
- package/build/animated/bezier.d.ts +1 -0
- package/build/animated/bezier.js +101 -0
- package/build/animated/color.d.ts +37 -0
- package/build/animated/color.js +183 -0
- package/build/animated/easing.d.ts +20 -0
- package/build/animated/easing.js +96 -0
- package/build/animated/event.d.ts +36 -0
- package/build/animated/event.js +252 -0
- package/build/animated/graph.d.ts +38 -0
- package/build/animated/graph.js +227 -0
- package/build/animated/index.d.ts +20 -0
- package/build/animated/index.js +28 -0
- package/build/animated/interpolation-node.d.ts +16 -0
- package/build/animated/interpolation-node.js +57 -0
- package/build/animated/interpolation.d.ts +22 -0
- package/build/animated/interpolation.js +199 -0
- package/build/animated/mock.d.ts +56 -0
- package/build/animated/mock.js +127 -0
- package/build/animated/native/native-animated.d.ts +43 -0
- package/build/animated/native/native-animated.js +146 -0
- package/build/animated/operators.d.ts +80 -0
- package/build/animated/operators.js +266 -0
- package/build/animated/props.d.ts +20 -0
- package/build/animated/props.js +187 -0
- package/build/animated/style.d.ts +26 -0
- package/build/animated/style.js +187 -0
- package/build/animated/value-xy.d.ts +35 -0
- package/build/animated/value-xy.js +106 -0
- package/build/animated/value.d.ts +36 -0
- package/build/animated/value.js +185 -0
- package/build/app-registry/index.d.ts +40 -0
- package/build/app-registry/index.js +144 -0
- package/build/app-state/index.d.ts +16 -0
- package/build/app-state/index.js +105 -0
- package/build/appearance/index.d.ts +12 -0
- package/build/appearance/index.js +84 -0
- package/build/back-handler/index.d.ts +14 -0
- package/build/back-handler/index.js +106 -0
- package/build/commit.d.ts +16 -0
- package/build/commit.js +678 -0
- package/build/debug.d.ts +5 -0
- package/build/debug.js +18 -0
- package/build/dimensions/index.d.ts +28 -0
- package/build/dimensions/index.js +148 -0
- package/build/dispatch.d.ts +2 -0
- package/build/dispatch.js +18 -0
- package/build/events/index.d.ts +1 -0
- package/build/events/index.js +691 -0
- package/build/fabric.d.ts +32 -0
- package/build/fabric.js +59 -0
- package/build/host-instance/index.d.ts +11 -0
- package/build/host-instance/index.js +49 -0
- package/build/i18n-manager/index.d.ts +13 -0
- package/build/i18n-manager/index.js +91 -0
- package/build/index.d.ts +80 -0
- package/build/index.js +72 -0
- package/build/interaction-manager/index.d.ts +45 -0
- package/build/interaction-manager/index.js +222 -0
- package/build/keyboard/index.d.ts +31 -0
- package/build/keyboard/index.js +142 -0
- package/build/layout-animation/index.d.ts +66 -0
- package/build/layout-animation/index.js +183 -0
- package/build/linking/index.android.d.ts +2 -0
- package/build/linking/index.android.js +18 -0
- package/build/linking/index.d.ts +1 -0
- package/build/linking/index.ios.d.ts +2 -0
- package/build/linking/index.ios.js +9 -0
- package/build/linking/index.js +6 -0
- package/build/linking/shared.d.ts +32 -0
- package/build/linking/shared.js +98 -0
- package/build/native-events.d.ts +24 -0
- package/build/native-events.js +129 -0
- package/build/native-modules.d.ts +6 -0
- package/build/native-modules.js +57 -0
- package/build/node.d.ts +36 -0
- package/build/node.js +194 -0
- package/build/pan-responder/index.d.ts +53 -0
- package/build/pan-responder/index.js +353 -0
- package/build/permissions-android/index.d.ts +115 -0
- package/build/permissions-android/index.js +185 -0
- package/build/pixel-ratio/index.d.ts +8 -0
- package/build/pixel-ratio/index.js +27 -0
- package/build/platform/index.android.d.ts +22 -0
- package/build/platform/index.android.js +60 -0
- package/build/platform/index.d.ts +1 -0
- package/build/platform/index.ios.d.ts +18 -0
- package/build/platform/index.ios.js +62 -0
- package/build/platform/index.js +5 -0
- package/build/platform/shared.d.ts +25 -0
- package/build/platform/shared.js +41 -0
- package/build/platform-color.d.ts +19 -0
- package/build/platform-color.js +25 -0
- package/build/post-commit.d.ts +4 -0
- package/build/post-commit.js +16 -0
- package/build/process-aspect-ratio.d.ts +1 -0
- package/build/process-aspect-ratio.js +34 -0
- package/build/process-background-image/index.d.ts +28 -0
- package/build/process-background-image/index.js +557 -0
- package/build/process-box-shadow/index.d.ts +11 -0
- package/build/process-box-shadow/index.js +193 -0
- package/build/process-filter.d.ts +31 -0
- package/build/process-filter.js +304 -0
- package/build/process-font-variant.d.ts +1 -0
- package/build/process-font-variant.js +17 -0
- package/build/process-transform/index.d.ts +5 -0
- package/build/process-transform/index.js +120 -0
- package/build/process-transform-origin/index.d.ts +3 -0
- package/build/process-transform-origin/index.js +108 -0
- package/build/registry.d.ts +31 -0
- package/build/registry.js +145 -0
- package/build/settings/index.d.ts +8 -0
- package/build/settings/index.js +126 -0
- package/build/share/index.android.d.ts +3 -0
- package/build/share/index.android.js +56 -0
- package/build/share/index.d.ts +1 -0
- package/build/share/index.ios.d.ts +3 -0
- package/build/share/index.ios.js +47 -0
- package/build/share/index.js +6 -0
- package/build/share/shared.d.ts +32 -0
- package/build/share/shared.js +32 -0
- package/build/status-bar/index.android.d.ts +5 -0
- package/build/status-bar/index.android.js +83 -0
- package/build/status-bar/index.d.ts +1 -0
- package/build/status-bar/index.ios.d.ts +5 -0
- package/build/status-bar/index.ios.js +66 -0
- package/build/status-bar/index.js +4 -0
- package/build/status-bar/shared.d.ts +22 -0
- package/build/status-bar/shared.js +22 -0
- package/build/style/index.d.ts +1 -0
- package/build/style/index.js +30 -0
- package/build/style-registry/index.d.ts +11 -0
- package/build/style-registry/index.js +165 -0
- package/build/style-sheet/index.d.ts +20 -0
- package/build/style-sheet/index.js +121 -0
- package/build/styles.d.ts +220 -0
- package/build/styles.js +7 -0
- package/build/surface.d.ts +16 -0
- package/build/surface.js +67 -0
- package/build/tags.d.ts +1 -0
- package/build/tags.js +10 -0
- package/build/text-input-state.d.ts +5 -0
- package/build/text-input-state.js +29 -0
- package/build/toast-android/index.d.ts +10 -0
- package/build/toast-android/index.js +108 -0
- package/build/vibration/index.android.d.ts +2 -0
- package/build/vibration/index.android.js +18 -0
- package/build/vibration/index.d.ts +1 -0
- package/build/vibration/index.ios.d.ts +2 -0
- package/build/vibration/index.ios.js +54 -0
- package/build/vibration/index.js +6 -0
- package/build/vibration/shared.d.ts +15 -0
- package/build/vibration/shared.js +68 -0
- package/build/view-config.d.ts +1 -0
- package/build/view-config.js +114 -0
- package/package.json +41 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// ActionSheetIOS: a JS->native imperative module, no Fabric view, no React. It
|
|
2
|
+
// drives the `ActionSheetManager` native module: `showActionSheetWithOptions`
|
|
3
|
+
// passes options straight through and the native `callback(buttonIndex)` reports
|
|
4
|
+
// the tapped row. We mirror RN faithfully.
|
|
5
|
+
//
|
|
6
|
+
// The native contract is confirmed from RN's TurboModule spec at
|
|
7
|
+
// .vendors/react-native/.../src/private/specs_DEPRECATED/modules/INativeActionSheetManager.js:
|
|
8
|
+
// showActionSheetWithOptions(options, callback: (buttonIndex: number) => void)
|
|
9
|
+
// showShareActionSheetWithOptions(options, failureCallback, successCallback)
|
|
10
|
+
// dismissActionSheet?()
|
|
11
|
+
//
|
|
12
|
+
// iOS only. Non-throwing, like StatusBar: a missing native module is a no-op,
|
|
13
|
+
// never a crash (on a device the module may be absent).
|
|
14
|
+
//
|
|
15
|
+
// Color note: RN runs `tintColor` / `cancelButtonTintColor` / `titleTextColor`
|
|
16
|
+
// through processColor before handing them to native. symbiote centralizes color
|
|
17
|
+
// processing in @symbiote-native/engine, so we do NOT process colors here; options pass
|
|
18
|
+
// through untouched. The canary needs no colors; revisit when wiring real colors.
|
|
19
|
+
import { dlog } from '../debug';
|
|
20
|
+
import { getNativeModule } from '../native-modules';
|
|
21
|
+
const ACTION_SHEET_MANAGER = 'ActionSheetManager';
|
|
22
|
+
// The static imperative API RN exposes, mirrored as a static-method object.
|
|
23
|
+
export const ActionSheetIOS = {
|
|
24
|
+
showActionSheetWithOptions(options, callback) {
|
|
25
|
+
dlog('ActionSheetIOS.showActionSheetWithOptions');
|
|
26
|
+
const manager = getNativeModule(ACTION_SHEET_MANAGER);
|
|
27
|
+
if (manager === null) {
|
|
28
|
+
dlog(`ActionSheetIOS: "${ACTION_SHEET_MANAGER}" unresolved — no-op`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Normalize the single-index legacy form to the array RN's native side expects
|
|
32
|
+
// (RN ActionSheetIOS.js ~95-101): a `destructiveButtonIndex: number` becomes
|
|
33
|
+
// `destructiveButtonIndices: [number]`; an existing array passes through. Without
|
|
34
|
+
// this the destructive row isn't highlighted on a real iOS host. Colors are still
|
|
35
|
+
// not processed here (see file header).
|
|
36
|
+
const { destructiveButtonIndex, ...remainingOptions } = options;
|
|
37
|
+
let destructiveButtonIndices = options.destructiveButtonIndices;
|
|
38
|
+
if (Array.isArray(destructiveButtonIndex)) {
|
|
39
|
+
destructiveButtonIndices = destructiveButtonIndex;
|
|
40
|
+
}
|
|
41
|
+
else if (typeof destructiveButtonIndex === 'number') {
|
|
42
|
+
destructiveButtonIndices = [destructiveButtonIndex];
|
|
43
|
+
}
|
|
44
|
+
const nativeOptions = { ...remainingOptions, destructiveButtonIndices };
|
|
45
|
+
manager.showActionSheetWithOptions(nativeOptions, buttonIndex => {
|
|
46
|
+
dlog(`ActionSheetIOS callback buttonIndex=${buttonIndex}`);
|
|
47
|
+
callback(buttonIndex);
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
showShareActionSheetWithOptions(options, failureCallback, successCallback) {
|
|
51
|
+
dlog('ActionSheetIOS.showShareActionSheetWithOptions');
|
|
52
|
+
const manager = getNativeModule(ACTION_SHEET_MANAGER);
|
|
53
|
+
if (manager === null) {
|
|
54
|
+
dlog(`ActionSheetIOS: "${ACTION_SHEET_MANAGER}" unresolved — no-op`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
manager.showShareActionSheetWithOptions(options, error => {
|
|
58
|
+
dlog('ActionSheetIOS share failure callback');
|
|
59
|
+
failureCallback(error);
|
|
60
|
+
}, (completed, activityType) => {
|
|
61
|
+
dlog(`ActionSheetIOS share success completed=${completed}`);
|
|
62
|
+
successCallback(completed, activityType);
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
dismissActionSheet() {
|
|
66
|
+
dlog('ActionSheetIOS.dismissActionSheet');
|
|
67
|
+
const manager = getNativeModule(ACTION_SHEET_MANAGER);
|
|
68
|
+
if (manager === null) {
|
|
69
|
+
dlog(`ActionSheetIOS: "${ACTION_SHEET_MANAGER}" unresolved — no-op`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
manager.dismissActionSheet?.();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Alert, Android build. The native module is `DialogManagerAndroid`
|
|
2
|
+
// (RN's TurboModuleRegistry.get('DialogManagerAndroid')): `showAlert(config, onError,
|
|
3
|
+
// onAction)` pops the native dialog, and `onAction(action, buttonKey)` reports the action
|
|
4
|
+
// plus the tapped button's key constant. At most three buttons map onto positive/negative/
|
|
5
|
+
// neutral, last-to-first as RN does. Everything platform-agnostic is the shared core.
|
|
6
|
+
// Metro picks this file on an Android host.
|
|
7
|
+
//
|
|
8
|
+
// The native contract is confirmed from RN's TurboModule spec:
|
|
9
|
+
// .vendors/.../specs_DEPRECATED/modules/INativeDialogManagerAndroid.js
|
|
10
|
+
// getConstants(): { buttonClicked, dismissed, buttonPositive, buttonNegative,
|
|
11
|
+
// buttonNeutral }
|
|
12
|
+
// showAlert(config, onError: (msg) => void, onAction: (action, buttonKey?) => void)
|
|
13
|
+
//
|
|
14
|
+
// device-verify-pending: the `DialogManagerAndroid` name and routing are confirmed from RN
|
|
15
|
+
// source but not yet exercised on a real Android host; only a bridgeless resolution log
|
|
16
|
+
// there can prove the name. See .docs/native-module-platform-routing.md.
|
|
17
|
+
//
|
|
18
|
+
// Non-throwing, like StatusBar: a missing native module is a no-op, never a crash.
|
|
19
|
+
import { dlog } from '../debug';
|
|
20
|
+
import { getNativeModule } from '../native-modules';
|
|
21
|
+
import { DEFAULT_POSITIVE_TEXT, normalizeButtons, } from './shared';
|
|
22
|
+
const DIALOG_MANAGER = 'DialogManagerAndroid';
|
|
23
|
+
// RN's hardwired Android fallbacks for the button-key constants (NativeDialogManager-
|
|
24
|
+
// Android documents buttonPositive=-1, buttonNegative=-2, buttonNeutral=-3, and the
|
|
25
|
+
// 'buttonClicked'/'dismissed' actions). Used when getConstants() omits a key.
|
|
26
|
+
const ANDROID_DIALOG_CONSTANTS = {
|
|
27
|
+
buttonClicked: 'buttonClicked',
|
|
28
|
+
dismissed: 'dismissed',
|
|
29
|
+
buttonPositive: -1,
|
|
30
|
+
buttonNegative: -2,
|
|
31
|
+
buttonNeutral: -3,
|
|
32
|
+
};
|
|
33
|
+
// The trust boundary for getConstants(): native sends an untyped HostObject. Read each key
|
|
34
|
+
// with a typeof guard and fall back to RN's documented default when it's missing.
|
|
35
|
+
function isRecord(value) {
|
|
36
|
+
return typeof value === 'object' && value !== null;
|
|
37
|
+
}
|
|
38
|
+
function readDialogConstants(raw) {
|
|
39
|
+
if (!isRecord(raw)) {
|
|
40
|
+
dlog('Alert: DialogManagerAndroid.getConstants() returned a non-object — using defaults');
|
|
41
|
+
return ANDROID_DIALOG_CONSTANTS;
|
|
42
|
+
}
|
|
43
|
+
const action = (key) => typeof raw[key] === 'string' ? raw[key] : ANDROID_DIALOG_CONSTANTS[key];
|
|
44
|
+
const buttonKey = (key) => typeof raw[key] === 'number' ? raw[key] : ANDROID_DIALOG_CONSTANTS[key];
|
|
45
|
+
return {
|
|
46
|
+
buttonClicked: action('buttonClicked'),
|
|
47
|
+
dismissed: action('dismissed'),
|
|
48
|
+
buttonPositive: buttonKey('buttonPositive'),
|
|
49
|
+
buttonNegative: buttonKey('buttonNegative'),
|
|
50
|
+
buttonNeutral: buttonKey('buttonNeutral'),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// The static imperative API RN exposes, mirrored as a static-method object. `prompt` has
|
|
54
|
+
// no Android counterpart in RN, so it is a dlog'd no-op here (documented below).
|
|
55
|
+
export const Alert = {
|
|
56
|
+
// The Android dialog path. RN keeps at most three buttons and maps them, last-to-first,
|
|
57
|
+
// onto positive/negative/neutral; onAction reads the native button-key constant back and
|
|
58
|
+
// fires that button's onPress. Non-throwing: no module -> no-op.
|
|
59
|
+
alert(title, message, buttons, options) {
|
|
60
|
+
dlog('Alert.alert (android)');
|
|
61
|
+
const manager = getNativeModule(DIALOG_MANAGER);
|
|
62
|
+
if (manager === null) {
|
|
63
|
+
dlog(`Alert.alert: "${DIALOG_MANAGER}" unresolved — no-op`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const constants = readDialogConstants(manager.getConstants());
|
|
67
|
+
const config = {
|
|
68
|
+
title: title || '',
|
|
69
|
+
message: message || '',
|
|
70
|
+
cancelable: options?.cancelable ?? false,
|
|
71
|
+
};
|
|
72
|
+
// At most three buttons (neutral, negative, positive). Ignore the rest. RN pops
|
|
73
|
+
// last-to-first, so the LAST button becomes positive and the FIRST neutral.
|
|
74
|
+
const validButtons = normalizeButtons(buttons).slice(0, 3);
|
|
75
|
+
const buttonPositive = validButtons.pop();
|
|
76
|
+
const buttonNegative = validButtons.pop();
|
|
77
|
+
const buttonNeutral = validButtons.pop();
|
|
78
|
+
if (buttonNeutral) {
|
|
79
|
+
config.buttonNeutral = buttonNeutral.text || '';
|
|
80
|
+
}
|
|
81
|
+
if (buttonNegative) {
|
|
82
|
+
config.buttonNegative = buttonNegative.text || '';
|
|
83
|
+
}
|
|
84
|
+
if (buttonPositive) {
|
|
85
|
+
config.buttonPositive = buttonPositive.text || DEFAULT_POSITIVE_TEXT;
|
|
86
|
+
}
|
|
87
|
+
// onAction maps the returned button-key constant back to the matching button's onPress;
|
|
88
|
+
// the dismiss action fires options.onDismiss.
|
|
89
|
+
const onAction = (action, buttonKey) => {
|
|
90
|
+
dlog(`Alert onAction action=${action} buttonKey=${String(buttonKey)}`);
|
|
91
|
+
if (action === constants.buttonClicked) {
|
|
92
|
+
if (buttonKey === constants.buttonNeutral) {
|
|
93
|
+
buttonNeutral?.onPress?.();
|
|
94
|
+
}
|
|
95
|
+
else if (buttonKey === constants.buttonNegative) {
|
|
96
|
+
buttonNegative?.onPress?.();
|
|
97
|
+
}
|
|
98
|
+
else if (buttonKey === constants.buttonPositive) {
|
|
99
|
+
buttonPositive?.onPress?.();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (action === constants.dismissed) {
|
|
103
|
+
options?.onDismiss?.();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const onError = (errorMessage) => {
|
|
107
|
+
dlog(`Alert onError: ${errorMessage}`);
|
|
108
|
+
};
|
|
109
|
+
manager.showAlert(config, onError, onAction);
|
|
110
|
+
},
|
|
111
|
+
// Android has no native `prompt` (RN's Alert.prompt is iOS-only; there is no
|
|
112
|
+
// DialogManagerAndroid equivalent). Keep the symbol so the surface matches, but no-op
|
|
113
|
+
// with a dlog rather than route to a single-input dialog.
|
|
114
|
+
prompt() {
|
|
115
|
+
dlog('Alert.prompt: no Android equivalent — no-op');
|
|
116
|
+
},
|
|
117
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.ios';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IAlertButtons, IAlertOptions, IAlertStatic, IAlertType } from './shared';
|
|
2
|
+
export type { IAlertButton, IAlertButtonStyle, IAlertButtons, IAlertOptions, IAlertType, } from './shared';
|
|
3
|
+
type IPromptCallbackOrButtons = ((text: string) => void) | IAlertButtons;
|
|
4
|
+
declare function prompt(title?: string, message?: string, callbackOrButtons?: IPromptCallbackOrButtons, type?: IAlertType, defaultValue?: string, keyboardType?: string, options?: IAlertOptions): void;
|
|
5
|
+
export declare const Alert: IAlertStatic & {
|
|
6
|
+
prompt: typeof prompt;
|
|
7
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Alert: iOS build. The native module is `AlertManager`
|
|
2
|
+
// (RN's TurboModuleRegistry.get('AlertManager')); `alertWithArgs(args, callback)` pops the
|
|
3
|
+
// native alert, and the native `callback(id, value)` reports which button (by numeric id)
|
|
4
|
+
// the user tapped plus any text-input value. `alert` delegates to `prompt`, the same
|
|
5
|
+
// AlertManager path RN uses. Metro picks this file on an iOS host; the base alert.ts
|
|
6
|
+
// re-exports it for web/headless.
|
|
7
|
+
//
|
|
8
|
+
// The native contract is confirmed from RN's TurboModule spec:
|
|
9
|
+
// .vendors/.../specs_DEPRECATED/modules/INativeAlertManager.js
|
|
10
|
+
// alertWithArgs(args: Args, callback: (id: number, value: string) => void)
|
|
11
|
+
//
|
|
12
|
+
// Non-throwing, like StatusBar: a missing native module is a no-op, never a crash (on a
|
|
13
|
+
// device the module may be absent).
|
|
14
|
+
import { dlog } from '../debug';
|
|
15
|
+
import { getNativeModule } from '../native-modules';
|
|
16
|
+
const ALERT_MANAGER = 'AlertManager';
|
|
17
|
+
// prompt builds the native args, assigns each button its array index as id, and dispatches
|
|
18
|
+
// the matching button's onPress when the native callback returns that id. Non-throwing: no
|
|
19
|
+
// native module -> dlog + no-op.
|
|
20
|
+
function prompt(title, message, callbackOrButtons, type = 'plain-text', defaultValue, keyboardType, options) {
|
|
21
|
+
dlog('Alert.prompt');
|
|
22
|
+
// callbacks[id] is the onPress for the button at that index: the id->onPress map the
|
|
23
|
+
// native callback indexes into. The native always supplies a real string value, so the
|
|
24
|
+
// element accepts `string`; a button's `onPress` (`value?: string`) is contravariantly
|
|
25
|
+
// assignable to it.
|
|
26
|
+
let callbacks = [];
|
|
27
|
+
const buttons = [];
|
|
28
|
+
let cancelButtonKey;
|
|
29
|
+
let destructiveButtonKey;
|
|
30
|
+
let preferredButtonKey;
|
|
31
|
+
if (typeof callbackOrButtons === 'function') {
|
|
32
|
+
callbacks = [callbackOrButtons];
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(callbackOrButtons)) {
|
|
35
|
+
callbackOrButtons.forEach((btn, index) => {
|
|
36
|
+
callbacks[index] = btn.onPress;
|
|
37
|
+
if (btn.style === 'cancel') {
|
|
38
|
+
cancelButtonKey = String(index);
|
|
39
|
+
}
|
|
40
|
+
else if (btn.style === 'destructive') {
|
|
41
|
+
destructiveButtonKey = String(index);
|
|
42
|
+
}
|
|
43
|
+
if (btn.isPreferred) {
|
|
44
|
+
preferredButtonKey = String(index);
|
|
45
|
+
}
|
|
46
|
+
if (btn.text !== undefined || index < callbackOrButtons.length - 1) {
|
|
47
|
+
buttons.push({ [index]: btn.text ?? '' });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const manager = getNativeModule(ALERT_MANAGER);
|
|
52
|
+
if (manager === null) {
|
|
53
|
+
dlog(`Alert.prompt: "${ALERT_MANAGER}" unresolved — no-op`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
manager.alertWithArgs({
|
|
57
|
+
title: title ?? '',
|
|
58
|
+
message: message || undefined,
|
|
59
|
+
buttons,
|
|
60
|
+
type: type || undefined,
|
|
61
|
+
defaultValue,
|
|
62
|
+
cancelButtonKey,
|
|
63
|
+
destructiveButtonKey,
|
|
64
|
+
preferredButtonKey,
|
|
65
|
+
keyboardType,
|
|
66
|
+
userInterfaceStyle: options?.userInterfaceStyle || undefined,
|
|
67
|
+
},
|
|
68
|
+
// The native callback crossing back: `id` is the tapped button's index, `value` the
|
|
69
|
+
// text-input contents. Index into callbacks and fire onPress.
|
|
70
|
+
(id, value) => {
|
|
71
|
+
dlog(`Alert callback id=${id}`);
|
|
72
|
+
callbacks[id]?.(value);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// The static imperative API RN exposes, mirrored as a static-method object. `prompt` is
|
|
76
|
+
// iOS-only, so it lives beyond IAlertStatic on this build.
|
|
77
|
+
export const Alert = {
|
|
78
|
+
// alert delegates to prompt (same AlertManager path), exactly as RN does on iOS.
|
|
79
|
+
alert(title, message, buttons, options) {
|
|
80
|
+
prompt(title, message, buttons, 'default', undefined, undefined, options);
|
|
81
|
+
},
|
|
82
|
+
prompt,
|
|
83
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Alert: base / default build (web, headless tsx, any target without a dedicated platform
|
|
2
|
+
// file). Metro overrides this with alert.ios.ts / alert.android.ts on a real iOS/Android
|
|
3
|
+
// host; off those, the iOS build is the fallback (its AlertManager resolves null elsewhere
|
|
4
|
+
// → graceful no-op). The barrel imports './alert', which resolves here under tsc/tsx and to
|
|
5
|
+
// the platform file under Metro. The `export *` re-exports the public type names
|
|
6
|
+
// (AlertType, AlertButtonStyle, AlertButton, AlertButtons, AlertOptions) so the barrel's
|
|
7
|
+
// `export type { ... } from '../alert'` still resolves. See ADR 0019.
|
|
8
|
+
export * from './index.ios';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type IAlertType = 'default' | 'plain-text' | 'secure-text' | 'login-password';
|
|
2
|
+
export type IAlertButtonStyle = 'default' | 'cancel' | 'destructive';
|
|
3
|
+
export interface IAlertButton {
|
|
4
|
+
text?: string;
|
|
5
|
+
onPress?: (value?: string) => void;
|
|
6
|
+
isPreferred?: boolean;
|
|
7
|
+
style?: IAlertButtonStyle;
|
|
8
|
+
}
|
|
9
|
+
export type IAlertButtons = IAlertButton[];
|
|
10
|
+
export interface IAlertOptions {
|
|
11
|
+
cancelable?: boolean;
|
|
12
|
+
userInterfaceStyle?: 'unspecified' | 'light' | 'dark';
|
|
13
|
+
onDismiss?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface IAlertStatic {
|
|
16
|
+
alert(title?: string, message?: string, buttons?: IAlertButtons, options?: IAlertOptions): void;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_POSITIVE_TEXT = "OK";
|
|
19
|
+
export declare function normalizeButtons(buttons?: IAlertButtons): IAlertButtons;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Shared core of the Alert module, everything that does NOT differ by platform: the
|
|
2
|
+
// public contract (the type union, button shapes, IAlertStatic), the Android button-key
|
|
3
|
+
// constant defaults, and the button-normalization helper. The per-platform files
|
|
4
|
+
// (alert.ios.ts / alert.android.ts) implement `alert()` fully against their own native
|
|
5
|
+
// module (iOS keeps `prompt` too); the two native call shapes are too divergent to share
|
|
6
|
+
// a factory. No native, no `Platform.OS` read here. See ADR 0019.
|
|
7
|
+
// The default positive label RN uses when a button carries no text.
|
|
8
|
+
export const DEFAULT_POSITIVE_TEXT = 'OK';
|
|
9
|
+
// Normalize the `buttons` arg into a consistent list: undefined/empty becomes a single
|
|
10
|
+
// default "OK" button, exactly as RN does before handing the list to native. Both
|
|
11
|
+
// platform files start from this so the no-buttons case behaves identically.
|
|
12
|
+
export function normalizeButtons(buttons) {
|
|
13
|
+
if (buttons === undefined || buttons.length === 0) {
|
|
14
|
+
return [{ text: DEFAULT_POSITIVE_TEXT }];
|
|
15
|
+
}
|
|
16
|
+
return buttons;
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AnimatedNode } from './graph';
|
|
2
|
+
export declare function isAnimatedNode(value: unknown): value is AnimatedNode;
|
|
3
|
+
export declare function readPassthroughStyle(passthrough: unknown): unknown;
|
|
4
|
+
export declare function reduceProps(props: Record<string, unknown>): Record<string, unknown>;
|
|
5
|
+
export declare function resolveHostNode(instance: unknown): unknown;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Framework-agnostic helpers for createAnimatedComponent. Both the React and Vue
|
|
2
|
+
// adapters wrap a base component so it accepts AnimatedNodes in its props; the wrap
|
|
3
|
+
// mechanism (capture the host node, build an AnimatedProps leaf, reduce animated
|
|
4
|
+
// props to their current values, override with the passthrough style) is pure JS,
|
|
5
|
+
// identical across frameworks. Only `assignRef` is framework-ref-specific and stays
|
|
6
|
+
// per-adapter; everything here is shared. Extracted from the React wrapper (ADR
|
|
7
|
+
// 0016/0017) so a new adapter reuses it verbatim.
|
|
8
|
+
import { AnimatedNode } from './graph';
|
|
9
|
+
import { AnimatedStyle } from './style';
|
|
10
|
+
export function isAnimatedNode(value) {
|
|
11
|
+
return value instanceof AnimatedNode;
|
|
12
|
+
}
|
|
13
|
+
// RN's `passthroughAnimatedPropExplicitValues` carries explicit (already-rasterized) prop
|
|
14
|
+
// values (e.g. a sticky header's debounced `{style:{transform:[{translateY}]}}`) that must
|
|
15
|
+
// override the animated prop in the COMMITTED props so the Fabric ShadowTree (hit-testing)
|
|
16
|
+
// stays current while the native driver animates. Read its `style` without a cast.
|
|
17
|
+
export function readPassthroughStyle(passthrough) {
|
|
18
|
+
if (typeof passthrough !== 'object' || passthrough === null)
|
|
19
|
+
return undefined;
|
|
20
|
+
return Reflect.get(passthrough, 'style');
|
|
21
|
+
}
|
|
22
|
+
// Replace animated entries in a props map with their current rasterized values so the
|
|
23
|
+
// first paint (and every re-render) carries concrete props. `style` is run through
|
|
24
|
+
// AnimatedStyle so an animated style key resolves to its current number.
|
|
25
|
+
export function reduceProps(props) {
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const key of Object.keys(props)) {
|
|
28
|
+
const value = props[key];
|
|
29
|
+
if (key === 'style') {
|
|
30
|
+
const styleNode = AnimatedStyle.from(value);
|
|
31
|
+
out[key] = styleNode !== undefined ? styleNode.__getValue() : value;
|
|
32
|
+
}
|
|
33
|
+
else if (isAnimatedNode(value)) {
|
|
34
|
+
out[key] = value.__getValue();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
out[key] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
// A ScrollView / FlatList / SectionList ref captures an imperative handle (RN's
|
|
43
|
+
// getScrollableNode pattern), NOT the raw host node, so a native event or animated
|
|
44
|
+
// props have nothing to bind to. Unwrap it via getScrollNode() to the underlying
|
|
45
|
+
// SymbioteNode; View / Text / Image already hand back the node directly, so they fall
|
|
46
|
+
// through unchanged.
|
|
47
|
+
export function resolveHostNode(instance) {
|
|
48
|
+
if (instance !== null && typeof instance === 'object') {
|
|
49
|
+
const getScrollNode = Reflect.get(instance, 'getScrollNode');
|
|
50
|
+
if (typeof getScrollNode === 'function')
|
|
51
|
+
return getScrollNode.call(instance);
|
|
52
|
+
}
|
|
53
|
+
return instance;
|
|
54
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AnimatedValue } from './value';
|
|
2
|
+
export interface IEndResult {
|
|
3
|
+
finished: boolean;
|
|
4
|
+
}
|
|
5
|
+
export type IEndCallback = (result: IEndResult) => void;
|
|
6
|
+
export interface IAnimation {
|
|
7
|
+
start(fromValue: number, onUpdate: (value: number) => void, onEnd: IEndCallback, previousAnimation: IAnimation | null, animatedValue: AnimatedValue): void;
|
|
8
|
+
stop(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The driver contract. A concrete animation (timing / spring / decay, all
|
|
2
|
+
// Phase 2) is a number -> number machine: `start` is handed the value's current
|
|
3
|
+
// number and an `onUpdate` it calls each frame with the next number; `onEnd`
|
|
4
|
+
// fires exactly once. This interface is the seam between AnimatedValue and the
|
|
5
|
+
// drivers, so it lives here, free of any concrete driver.
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IAnimation, IEndCallback, IEndResult } from '../animation';
|
|
2
|
+
import type { AnimatedValue } from '../value';
|
|
3
|
+
import { type INativeAnimationConfig, type IPlatformConfig } from '../native/native-animated';
|
|
4
|
+
export interface IAnimationConfig {
|
|
5
|
+
isInteraction?: boolean;
|
|
6
|
+
iterations?: number;
|
|
7
|
+
useNativeDriver?: boolean;
|
|
8
|
+
platformConfig?: IPlatformConfig;
|
|
9
|
+
debugID?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare abstract class BaseAnimation implements IAnimation {
|
|
12
|
+
protected __active: boolean;
|
|
13
|
+
protected __iterations: number;
|
|
14
|
+
protected readonly __platformConfig: IPlatformConfig | undefined;
|
|
15
|
+
private readonly __debugID;
|
|
16
|
+
private onEndCallback;
|
|
17
|
+
private readonly nativeDriverRequested;
|
|
18
|
+
private nativeId;
|
|
19
|
+
constructor(config: IAnimationConfig);
|
|
20
|
+
protected __getDebugID(): string | undefined;
|
|
21
|
+
abstract start(fromValue: number, onUpdate: (value: number) => void, onEnd: IEndCallback, previousAnimation: IAnimation | null, animatedValue: AnimatedValue): void;
|
|
22
|
+
protected begin(onEnd: IEndCallback): void;
|
|
23
|
+
protected getNativeAnimationConfig(): INativeAnimationConfig;
|
|
24
|
+
protected startNativeIfNeeded(animatedValue: AnimatedValue): boolean;
|
|
25
|
+
stop(): void;
|
|
26
|
+
protected __notifyAnimationEnd(result: IEndResult): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Minimal driver base, ported from RN's animations/Animation.js with every
|
|
2
|
+
// native path removed (ADR 0016): no NativeAnimatedHelper, no
|
|
3
|
+
// __startAnimationIfNative, no shouldUseNativeDriver, no FeatureFlags. What
|
|
4
|
+
// remains is the JS-only contract: hold the end callback, track whether the
|
|
5
|
+
// animation is still active, and fire onEnd at most once.
|
|
6
|
+
//
|
|
7
|
+
// start() / stop() are abstract: each concrete driver (timing / spring / decay)
|
|
8
|
+
// owns its own requestAnimationFrame loop. They are declared as methods (not
|
|
9
|
+
// class fields) so a subclass override is not shadowed under
|
|
10
|
+
// useDefineForClassFields.
|
|
11
|
+
import { flushValue } from '../graph';
|
|
12
|
+
import { dlog, isDebug } from '../../debug';
|
|
13
|
+
import { generateNativeAnimationId, isNativeAnimatedAvailable, nativeAnimated, } from '../native/native-animated';
|
|
14
|
+
export class BaseAnimation {
|
|
15
|
+
// `protected` so subclasses read it inside their rAF loop to decide whether to
|
|
16
|
+
// schedule the next frame; cleared by stop().
|
|
17
|
+
__active = false;
|
|
18
|
+
__iterations;
|
|
19
|
+
// RN's Animation holds `_platformConfig` / `__debugID` and folds them into the
|
|
20
|
+
// native config (Animation.js:60-62). Subclasses read them via the protected
|
|
21
|
+
// accessors below so every driver's config carries them uniformly.
|
|
22
|
+
__platformConfig;
|
|
23
|
+
__debugID;
|
|
24
|
+
onEndCallback = null;
|
|
25
|
+
nativeDriverRequested;
|
|
26
|
+
nativeId;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.__iterations = config.iterations ?? 1;
|
|
29
|
+
this.nativeDriverRequested = config.useNativeDriver === true;
|
|
30
|
+
this.__platformConfig = config.platformConfig;
|
|
31
|
+
this.__debugID = config.debugID;
|
|
32
|
+
}
|
|
33
|
+
// Mirrors RN's Animation.__getDebugID (Animation.js:192). Returns the label only
|
|
34
|
+
// under DEBUG so production native configs stay lean, undefined otherwise.
|
|
35
|
+
__getDebugID() {
|
|
36
|
+
return isDebug() ? this.__debugID : undefined;
|
|
37
|
+
}
|
|
38
|
+
// Subclasses call super.start(...) shape via this helper to wire the end
|
|
39
|
+
// callback and arm the active flag before launching their loop.
|
|
40
|
+
begin(onEnd) {
|
|
41
|
+
this.onEndCallback = onEnd;
|
|
42
|
+
this.__active = true;
|
|
43
|
+
}
|
|
44
|
+
// A native driver overrides this with its curve config (`{type:'frames'|'spring'|'decay', …}`).
|
|
45
|
+
getNativeAnimationConfig() {
|
|
46
|
+
throw new Error('This animation type cannot be offloaded to the native driver');
|
|
47
|
+
}
|
|
48
|
+
// If useNativeDriver was requested and the module is present, mirror the value
|
|
49
|
+
// graph into native and hand the curve to native. The JS rAF loop is then
|
|
50
|
+
// skipped entirely. Returns true when native took over. Falls back to JS (false)
|
|
51
|
+
// when the module is missing (ADR 0016 path), so an app without RCTAnimation
|
|
52
|
+
// still animates.
|
|
53
|
+
startNativeIfNeeded(animatedValue) {
|
|
54
|
+
if (!this.nativeDriverRequested)
|
|
55
|
+
return false;
|
|
56
|
+
if (!isNativeAnimatedAvailable()) {
|
|
57
|
+
dlog('useNativeDriver requested but native animated module is missing; using JS driver');
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const config = this.getNativeAnimationConfig();
|
|
61
|
+
// RN hands the curve's platform bag down to the value node (Animation.js:137)
|
|
62
|
+
// so the node's create config carries it too.
|
|
63
|
+
animatedValue.__makeNative(this.__platformConfig);
|
|
64
|
+
this.nativeId = generateNativeAnimationId();
|
|
65
|
+
nativeAnimated.startAnimatingNode(this.nativeId, animatedValue.__getNativeTag(), config, result => {
|
|
66
|
+
this.__notifyAnimationEnd({ finished: result.finished });
|
|
67
|
+
// Sync the JS value to native's final value, then run leaf callbacks once.
|
|
68
|
+
if (result.value !== undefined) {
|
|
69
|
+
animatedValue.__onNativeUpdate(result.value, result.offset);
|
|
70
|
+
flushValue(animatedValue);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
stop() {
|
|
76
|
+
if (this.nativeId !== undefined) {
|
|
77
|
+
nativeAnimated.stopAnimation(this.nativeId);
|
|
78
|
+
}
|
|
79
|
+
this.__active = false;
|
|
80
|
+
}
|
|
81
|
+
// Fire the completion callback at most once. start() and stop() each run at
|
|
82
|
+
// most once over an animation's life, and so does this.
|
|
83
|
+
__notifyAnimationEnd(result) {
|
|
84
|
+
const callback = this.onEndCallback;
|
|
85
|
+
if (callback !== null) {
|
|
86
|
+
this.onEndCallback = null;
|
|
87
|
+
callback(result);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { IEndCallback } from '../animation';
|
|
2
|
+
import { AnimatedNode } from '../graph';
|
|
3
|
+
import { AnimatedValue } from '../value';
|
|
4
|
+
import { type ITimingAnimationConfig } from './timing';
|
|
5
|
+
import { type ISpringAnimationConfig } from './spring';
|
|
6
|
+
import { type IDecayAnimationConfig } from './decay';
|
|
7
|
+
export interface ICompositeAnimation {
|
|
8
|
+
start(callback?: IEndCallback, isLooping?: boolean): void;
|
|
9
|
+
stop(): void;
|
|
10
|
+
reset(): void;
|
|
11
|
+
_nativeLoop?(iterations: number, callback?: IEndCallback): boolean;
|
|
12
|
+
}
|
|
13
|
+
interface IWithOnComplete {
|
|
14
|
+
onComplete?: IEndCallback;
|
|
15
|
+
}
|
|
16
|
+
export type ITimingConfig = Omit<ITimingAnimationConfig, 'toValue'> & {
|
|
17
|
+
toValue: number | AnimatedNode;
|
|
18
|
+
} & IWithOnComplete;
|
|
19
|
+
export type ISpringConfig = Omit<ISpringAnimationConfig, 'toValue'> & {
|
|
20
|
+
toValue: number | AnimatedNode;
|
|
21
|
+
} & IWithOnComplete;
|
|
22
|
+
export type IDecayConfig = IDecayAnimationConfig & IWithOnComplete;
|
|
23
|
+
export declare function timing(value: AnimatedValue, config: ITimingConfig): ICompositeAnimation;
|
|
24
|
+
export declare function spring(value: AnimatedValue, config: ISpringConfig): ICompositeAnimation;
|
|
25
|
+
export declare function decay(value: AnimatedValue, config: IDecayConfig): ICompositeAnimation;
|
|
26
|
+
export interface IParallelConfig {
|
|
27
|
+
stopTogether?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function parallel(animations: ICompositeAnimation[], config?: IParallelConfig): ICompositeAnimation;
|
|
30
|
+
export declare function sequence(animations: ICompositeAnimation[]): ICompositeAnimation;
|
|
31
|
+
export declare function delay(time: number): ICompositeAnimation;
|
|
32
|
+
export declare function stagger(time: number, animations: ICompositeAnimation[]): ICompositeAnimation;
|
|
33
|
+
export interface ILoopAnimationConfig {
|
|
34
|
+
iterations?: number;
|
|
35
|
+
resetBeforeIteration?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare function loop(animation: ICompositeAnimation, config?: ILoopAnimationConfig): ICompositeAnimation;
|
|
38
|
+
export {};
|