@symbiote-native/angular 0.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/babel-register-composed.cjs +58 -18
- package/bin/symbiote-angular-dev.cjs +16 -4
- package/build/angular/anchor-host-registry.js +1 -15
- package/build/angular/anchor-host-registry.js.map +1 -1
- package/build/angular/change-detection-flush.d.ts +31 -0
- package/build/angular/change-detection-flush.js +110 -0
- package/build/angular/change-detection-flush.js.map +1 -0
- package/build/angular/components/activity-indicator-props.d.ts +2 -0
- package/build/angular/components/activity-indicator-props.js +2 -0
- package/build/angular/components/activity-indicator-props.js.map +1 -0
- package/build/angular/components/button-props.d.ts +2 -0
- package/build/angular/components/button-props.js +2 -0
- package/build/angular/components/button-props.js.map +1 -0
- package/build/angular/components/flat-list/index.d.ts +2 -1
- package/build/angular/components/flat-list/index.js +22 -10
- package/build/angular/components/flat-list/index.js.map +1 -1
- package/build/angular/components/image-background-props.d.ts +6 -0
- package/build/angular/components/image-background-props.js +2 -0
- package/build/angular/components/image-background-props.js.map +1 -0
- package/build/angular/components/{image/shared.d.ts → image-shared.d.ts} +4 -4
- package/build/angular/components/{image/shared.js → image-shared.js} +39 -28
- package/build/angular/components/image-shared.js.map +1 -0
- package/build/angular/components/input-accessory-view-props.d.ts +7 -0
- package/build/angular/components/input-accessory-view-props.js +9 -0
- package/build/angular/components/input-accessory-view-props.js.map +1 -0
- package/build/angular/components/keyboard-avoiding-view/index.d.ts +2 -1
- package/build/angular/components/keyboard-avoiding-view/index.js +28 -27
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
- package/build/angular/components/modal/index.d.ts +2 -0
- package/build/angular/components/modal/index.js +33 -20
- package/build/angular/components/modal/index.js.map +1 -1
- package/build/angular/components/pressable-props.d.ts +32 -0
- package/build/angular/components/pressable-props.js +11 -0
- package/build/angular/components/pressable-props.js.map +1 -0
- package/build/angular/components/refresh-control-props.d.ts +16 -0
- package/build/angular/components/refresh-control-props.js +14 -0
- package/build/angular/components/refresh-control-props.js.map +1 -0
- package/build/angular/components/safe-area-view-props.d.ts +7 -0
- package/build/angular/components/safe-area-view-props.js +11 -0
- package/build/angular/components/safe-area-view-props.js.map +1 -0
- package/build/angular/components/scroll-view-props.d.ts +76 -0
- package/build/angular/components/scroll-view-props.js +18 -0
- package/build/angular/components/scroll-view-props.js.map +1 -0
- package/build/angular/components/section-list/index.d.ts +3 -0
- package/build/angular/components/section-list/index.js +10 -1
- package/build/angular/components/section-list/index.js.map +1 -1
- package/build/angular/components/text-input-props.d.ts +45 -0
- package/build/angular/components/text-input-props.js +18 -0
- package/build/angular/components/text-input-props.js.map +1 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +6 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js +2 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js.map +1 -0
- package/build/angular/components/touchable-props.d.ts +14 -0
- package/build/angular/components/touchable-props.js +13 -0
- package/build/angular/components/touchable-props.js.map +1 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +3 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js +2 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js.map +1 -0
- package/build/angular/components/virtualized-list/index.d.ts +8 -1
- package/build/angular/components/virtualized-list/index.js +373 -278
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/index.d.ts +3 -0
- package/build/angular/components/virtualized-section-list/index.js +10 -1
- package/build/angular/components/virtualized-section-list/index.js.map +1 -1
- package/build/angular/components.d.ts +21 -27
- package/build/angular/components.js +13 -15
- package/build/angular/components.js.map +1 -1
- package/build/angular/create-portal/index.d.ts +11 -2
- package/build/angular/create-portal/index.js +37 -11
- package/build/angular/create-portal/index.js.map +1 -1
- package/build/angular/create-tunnel/index.js +1 -1
- package/build/angular/element-props.d.ts +53 -0
- package/build/angular/element-props.js +2 -0
- package/build/angular/element-props.js.map +1 -0
- package/build/angular/elements.d.ts +528 -0
- package/build/angular/elements.js +1444 -0
- package/build/angular/elements.js.map +1 -0
- package/build/angular/gate-demand.d.ts +37 -0
- package/build/angular/gate-demand.js +84 -0
- package/build/angular/gate-demand.js.map +1 -0
- package/build/angular/host-instance/index.js +1 -1
- package/build/angular/index.d.ts +5 -2
- package/build/angular/index.js +16 -1
- package/build/angular/index.js.map +1 -1
- package/build/angular/modules/animated/create-animated-component.d.ts +6 -6
- package/build/angular/modules/animated/create-animated-component.js +73 -81
- package/build/angular/modules/animated/create-animated-component.js.map +1 -1
- package/build/angular/modules/animated/index.js +1 -1
- package/build/angular/modules/animated/index.js.map +1 -1
- package/build/angular/modules/image/index.d.ts +3 -0
- package/build/angular/modules/image/index.js +16 -0
- package/build/angular/modules/image/index.js.map +1 -0
- package/build/angular/primitives/index.d.ts +28 -16
- package/build/angular/primitives/index.js +77 -31
- package/build/angular/primitives/index.js.map +1 -1
- package/build/angular/primitives/shared.d.ts +2 -3
- package/build/angular/primitives/shared.js +8 -53
- package/build/angular/primitives/shared.js.map +1 -1
- package/build/angular/register.d.ts +1 -0
- package/build/angular/register.js +16 -0
- package/build/angular/register.js.map +1 -0
- package/build/angular/render/index.js +4 -2
- package/build/angular/render/index.js.map +1 -1
- package/build/angular/renderer/index.js +207 -60
- package/build/angular/renderer/index.js.map +1 -1
- package/build/angular/renderer/value-change.d.ts +2 -0
- package/build/angular/renderer/value-change.js +9 -0
- package/build/angular/renderer/value-change.js.map +1 -0
- package/metro-config.cjs +23 -5
- package/metro-css-parser.cjs +2 -1
- package/package.json +17 -7
- package/src/anchor-host-registry.ts +1 -15
- package/src/change-detection-flush.ts +120 -0
- package/src/components/activity-indicator-props.ts +21 -0
- package/src/components/button-props.ts +26 -0
- package/src/components/flat-list/index.ts +12 -4
- package/src/components/image-background-props.ts +24 -0
- package/src/components/{image/shared.ts → image-shared.ts} +57 -26
- package/src/components/input-accessory-view-props.ts +21 -0
- package/src/components/keyboard-avoiding-view/index.ts +27 -16
- package/src/components/modal/index.ts +32 -11
- package/src/components/pressable-props.ts +73 -0
- package/src/components/refresh-control-props.ts +43 -0
- package/src/components/safe-area-view-props.ts +28 -0
- package/src/components/scroll-view-props.ts +109 -0
- package/src/components/section-list/index.ts +18 -0
- package/src/components/text-input-props.ts +72 -0
- package/src/components/touchable-native-feedback/touchable-native-feedback-props.ts +23 -0
- package/src/components/touchable-props.ts +30 -0
- package/src/components/touchable-without-feedback/touchable-without-feedback-props.ts +21 -0
- package/src/components/virtualized-list/index.ts +254 -153
- package/src/components/virtualized-section-list/index.ts +18 -0
- package/src/components.ts +86 -35
- package/src/create-portal/index.ts +39 -9
- package/src/create-tunnel/index.ts +1 -1
- package/src/diagnostics.ts +1 -1
- package/src/element-props.ts +90 -0
- package/src/elements.ts +919 -0
- package/src/gate-demand.ts +109 -0
- package/src/host-instance/index.ts +1 -1
- package/src/index.ts +54 -15
- package/src/modules/animated/create-animated-component.ts +73 -59
- package/src/modules/animated/index.ts +1 -1
- package/src/modules/image/index.ts +18 -0
- package/src/primitives/index.ts +47 -16
- package/src/primitives/shared.ts +11 -44
- package/src/register.ts +15 -0
- package/src/render/index.ts +4 -2
- package/src/renderer/index.ts +239 -80
- package/src/renderer/value-change.ts +8 -0
- package/build/angular/components/activity-indicator/index.android.d.ts +0 -13
- package/build/angular/components/activity-indicator/index.android.js +0 -29
- package/build/angular/components/activity-indicator/index.android.js.map +0 -1
- package/build/angular/components/activity-indicator/index.d.ts +0 -1
- package/build/angular/components/activity-indicator/index.ios.d.ts +0 -9
- package/build/angular/components/activity-indicator/index.ios.js +0 -26
- package/build/angular/components/activity-indicator/index.ios.js.map +0 -1
- package/build/angular/components/activity-indicator/index.js +0 -4
- package/build/angular/components/activity-indicator/index.js.map +0 -1
- package/build/angular/components/activity-indicator/shared.d.ts +0 -67
- package/build/angular/components/activity-indicator/shared.js +0 -260
- package/build/angular/components/activity-indicator/shared.js.map +0 -1
- package/build/angular/components/button.d.ts +0 -65
- package/build/angular/components/button.js +0 -351
- package/build/angular/components/button.js.map +0 -1
- package/build/angular/components/image/index.android.d.ts +0 -15
- package/build/angular/components/image/index.android.js +0 -91
- package/build/angular/components/image/index.android.js.map +0 -1
- package/build/angular/components/image/index.d.ts +0 -1
- package/build/angular/components/image/index.ios.d.ts +0 -15
- package/build/angular/components/image/index.ios.js +0 -91
- package/build/angular/components/image/index.ios.js.map +0 -1
- package/build/angular/components/image/index.js +0 -3
- package/build/angular/components/image/index.js.map +0 -1
- package/build/angular/components/image/shared.js.map +0 -1
- package/build/angular/components/image-background.d.ts +0 -82
- package/build/angular/components/image-background.js +0 -434
- package/build/angular/components/image-background.js.map +0 -1
- package/build/angular/components/input-accessory-view/index.d.ts +0 -65
- package/build/angular/components/input-accessory-view/index.js +0 -290
- package/build/angular/components/input-accessory-view/index.js.map +0 -1
- package/build/angular/components/pressable/index.d.ts +0 -129
- package/build/angular/components/pressable/index.js +0 -473
- package/build/angular/components/pressable/index.js.map +0 -1
- package/build/angular/components/refresh-control/index.d.ts +0 -90
- package/build/angular/components/refresh-control/index.js +0 -380
- package/build/angular/components/refresh-control/index.js.map +0 -1
- package/build/angular/components/safe-area-view/index.d.ts +0 -62
- package/build/angular/components/safe-area-view/index.js +0 -287
- package/build/angular/components/safe-area-view/index.js.map +0 -1
- package/build/angular/components/scroll-view/index.android.d.ts +0 -20
- package/build/angular/components/scroll-view/index.android.js +0 -262
- package/build/angular/components/scroll-view/index.android.js.map +0 -1
- package/build/angular/components/scroll-view/index.d.ts +0 -3
- package/build/angular/components/scroll-view/index.ios.d.ts +0 -8
- package/build/angular/components/scroll-view/index.ios.js +0 -92
- package/build/angular/components/scroll-view/index.ios.js.map +0 -1
- package/build/angular/components/scroll-view/index.js +0 -6
- package/build/angular/components/scroll-view/index.js.map +0 -1
- package/build/angular/components/scroll-view/projection.d.ts +0 -67
- package/build/angular/components/scroll-view/projection.js +0 -560
- package/build/angular/components/scroll-view/projection.js.map +0 -1
- package/build/angular/components/scroll-view/shared.d.ts +0 -239
- package/build/angular/components/scroll-view/shared.js +0 -832
- package/build/angular/components/scroll-view/shared.js.map +0 -1
- package/build/angular/components/scroll-view/sticky-header.d.ts +0 -40
- package/build/angular/components/scroll-view/sticky-header.js +0 -224
- package/build/angular/components/scroll-view/sticky-header.js.map +0 -1
- package/build/angular/components/switch/index.android.d.ts +0 -24
- package/build/angular/components/switch/index.android.js +0 -112
- package/build/angular/components/switch/index.android.js.map +0 -1
- package/build/angular/components/switch/index.d.ts +0 -1
- package/build/angular/components/switch/index.ios.d.ts +0 -23
- package/build/angular/components/switch/index.ios.js +0 -111
- package/build/angular/components/switch/index.ios.js.map +0 -1
- package/build/angular/components/switch/index.js +0 -4
- package/build/angular/components/switch/index.js.map +0 -1
- package/build/angular/components/switch/shared.d.ts +0 -49
- package/build/angular/components/switch/shared.js +0 -191
- package/build/angular/components/switch/shared.js.map +0 -1
- package/build/angular/components/text-input.d.ts +0 -161
- package/build/angular/components/text-input.js +0 -659
- package/build/angular/components/text-input.js.map +0 -1
- package/build/angular/components/touchable/index.d.ts +0 -276
- package/build/angular/components/touchable/index.js +0 -1422
- package/build/angular/components/touchable/index.js.map +0 -1
- package/build/angular/components/touchable-native-feedback/index.d.ts +0 -86
- package/build/angular/components/touchable-native-feedback/index.js +0 -407
- package/build/angular/components/touchable-native-feedback/index.js.map +0 -1
- package/src/components/activity-indicator/index.android.ts +0 -23
- package/src/components/activity-indicator/index.ios.ts +0 -21
- package/src/components/activity-indicator/index.ts +0 -4
- package/src/components/activity-indicator/shared.ts +0 -225
- package/src/components/button.ts +0 -220
- package/src/components/image/index.android.ts +0 -99
- package/src/components/image/index.ios.ts +0 -99
- package/src/components/image/index.ts +0 -3
- package/src/components/image-background.ts +0 -290
- package/src/components/input-accessory-view/index.ts +0 -240
- package/src/components/pressable/index.ts +0 -462
- package/src/components/refresh-control/index.ts +0 -340
- package/src/components/safe-area-view/index.ts +0 -231
- package/src/components/scroll-view/index.android.ts +0 -205
- package/src/components/scroll-view/index.ios.ts +0 -81
- package/src/components/scroll-view/index.ts +0 -7
- package/src/components/scroll-view/projection.ts +0 -713
- package/src/components/scroll-view/shared.ts +0 -1066
- package/src/components/scroll-view/sticky-header.ts +0 -267
- package/src/components/switch/index.android.ts +0 -113
- package/src/components/switch/index.ios.ts +0 -112
- package/src/components/switch/index.ts +0 -4
- package/src/components/switch/shared.ts +0 -284
- package/src/components/text-input.ts +0 -613
- package/src/components/touchable/index.ts +0 -913
- package/src/components/touchable-native-feedback/index.ts +0 -317
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Whether anything downstream actually wants a gated accessibility event, passed from a wrapper
|
|
2
|
+
// component to the inner component that owns the gate.
|
|
3
|
+
//
|
|
4
|
+
// THE PROBLEM. Six Fabric events fire only if a BOOLEAN prop reaches the payload
|
|
5
|
+
// (`.claude/rules/fabric-boolean-event-gates.md`), and the flag follows the VALUE: a handler
|
|
6
|
+
// present means `true`, absent means the key is deleted. Every component that owns such a gate
|
|
7
|
+
// therefore writes it only while its own `@Output()` is `.observed`.
|
|
8
|
+
//
|
|
9
|
+
// Angular has no conditional template binding, so a wrapper rendering an inner component must write
|
|
10
|
+
// `(accessibilityAction)="accessibilityAction.emit($event)"` unconditionally — which subscribes,
|
|
11
|
+
// which makes the inner's `.observed` permanently true, which lights the flag on EVERY instance
|
|
12
|
+
// whether or not any app listens. Fixing the inner component does nothing: the wrapper is the
|
|
13
|
+
// subscriber. The chain is up to four deep here (SectionList -> VirtualizedSectionList ->
|
|
14
|
+
// VirtualizedList -> ScrollView), and every middle link has the same problem for the same reason.
|
|
15
|
+
//
|
|
16
|
+
// WHY THIS IS DI AND NOT AN `@Input`. An input is public API. An app could write
|
|
17
|
+
// `[gatedEvents]="…"` on a `Pressable` and silently switch its accessibility events OFF — a change
|
|
18
|
+
// nothing in this repo could detect and nothing on screen would show. A `viewProviders` entry is
|
|
19
|
+
// not part of the component's binding surface, so an app cannot reach it by accident.
|
|
20
|
+
//
|
|
21
|
+
// WHY `viewProviders` AND NOT `providers` — measured, both arms, 2026-09-02:
|
|
22
|
+
//
|
|
23
|
+
// viewProviders the wrapper's OWN template sees it, projected content does NOT
|
|
24
|
+
// providers both see it
|
|
25
|
+
//
|
|
26
|
+
// The second half is what matters: an app writing `<TouchableOpacity><Pressable/></TouchableOpacity>`
|
|
27
|
+
// projects its own Pressable INTO the wrapper, and that Pressable must behave exactly as it would
|
|
28
|
+
// standing alone. Under `providers` it would inherit the wrapper's demand and the debt would just
|
|
29
|
+
// move one level down.
|
|
30
|
+
//
|
|
31
|
+
// Verified on both rungs — JIT through `mount()`, and again by executing the artifact from a real
|
|
32
|
+
// `ngc --compilationMode partial` + `babel-linker.cjs` chain, because `viewProviders` compiles into
|
|
33
|
+
// the component definition (`ɵɵProvidersFeature`) and this repo has a recorded case of JIT and AOT
|
|
34
|
+
// disagreeing on a compiled binding (`.claude/rules/test-harness-false-greens.md` §21/§21a). Both
|
|
35
|
+
// arms reported the same four cells.
|
|
36
|
+
import {
|
|
37
|
+
EventEmitter,
|
|
38
|
+
InjectionToken,
|
|
39
|
+
forwardRef,
|
|
40
|
+
inject,
|
|
41
|
+
} from '@angular/core';
|
|
42
|
+
import type { Provider, Type } from '@angular/core';
|
|
43
|
+
import type { ISymbioteEvent } from '@symbiote-native/engine';
|
|
44
|
+
|
|
45
|
+
// The four `on*`-gated accessibility events every wrapper forwards. Not the full gate list from the
|
|
46
|
+
// engine: `layout` and `textLayout` are never forwarded wrapper-to-wrapper, and
|
|
47
|
+
// KeyboardAvoidingView READS its own `onLayout` internally, so gating that one on a subscriber
|
|
48
|
+
// would break inset-following (`.claude/rules/keyboard-avoiding-view-rn-contract.md`).
|
|
49
|
+
export const GATED_ACCESSIBILITY_EVENTS = [
|
|
50
|
+
'accessibilityAction',
|
|
51
|
+
'accessibilityTap',
|
|
52
|
+
'magicTap',
|
|
53
|
+
'accessibilityEscape',
|
|
54
|
+
] as const;
|
|
55
|
+
|
|
56
|
+
export type IGatedAccessibilityEvent =
|
|
57
|
+
(typeof GATED_ACCESSIBILITY_EVENTS)[number];
|
|
58
|
+
|
|
59
|
+
export interface IGateDemand {
|
|
60
|
+
wantsGate(name: IGatedAccessibilityEvent): boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const GATE_DEMAND = new InjectionToken<IGateDemand>(
|
|
64
|
+
'symbiote.gate-demand',
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Declare a wrapper as the demand for everything in its own template.
|
|
69
|
+
*
|
|
70
|
+
* Takes a THUNK rather than the class: the entry sits in the decorator of the very class it names,
|
|
71
|
+
* so the reference has to be late.
|
|
72
|
+
*/
|
|
73
|
+
export function provideGateDemand(get: () => Type<IGateDemand>): Provider {
|
|
74
|
+
return { provide: GATE_DEMAND, useExisting: forwardRef(get) };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* For a component that OWNS a gate — the innermost one, which writes the flag.
|
|
79
|
+
*/
|
|
80
|
+
export function injectGateDemand(): IGateDemand | null {
|
|
81
|
+
return inject(GATE_DEMAND, { optional: true });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* For a component that PROVIDES demand and is itself wrapped.
|
|
86
|
+
*
|
|
87
|
+
* `skipSelf` is not optional here: a component resolves its own `viewProviders`, so without it the
|
|
88
|
+
* lookup reaches this class's own `useExisting` entry and Angular throws NG0200 at construction.
|
|
89
|
+
* Loud rather than silent, but the shape is easy to get wrong, which is why the two lookups are
|
|
90
|
+
* separate functions instead of one with a flag.
|
|
91
|
+
*/
|
|
92
|
+
export function injectGateDemandAbove(): IGateDemand | null {
|
|
93
|
+
return inject(GATE_DEMAND, { optional: true, skipSelf: true });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The one expression both roles evaluate.
|
|
98
|
+
*
|
|
99
|
+
* A demand from above OVERRIDES the local emitter, and that override is the whole mechanism: a
|
|
100
|
+
* middle link's own emitter is `.observed` precisely because the level above bound it, so answering
|
|
101
|
+
* from it would report "wanted" for a chain nobody subscribed to.
|
|
102
|
+
*/
|
|
103
|
+
export function gateWanted(
|
|
104
|
+
above: IGateDemand | null,
|
|
105
|
+
name: IGatedAccessibilityEvent,
|
|
106
|
+
own: EventEmitter<ISymbioteEvent>,
|
|
107
|
+
): boolean {
|
|
108
|
+
return above !== null ? above.wantsGate(name) : own.observed;
|
|
109
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// adapters/vue/src/host-instance/index.ts. RN's "ref/instance -> native reactTag" lookup,
|
|
3
3
|
// the seam imperative-interop libraries reach through.
|
|
4
4
|
//
|
|
5
|
-
// Angular template refs on a primitive host (`<
|
|
5
|
+
// Angular template refs on a primitive host (`<view #myView>`) receive the component instance,
|
|
6
6
|
// not the raw engine node. SymbiotePrimitiveHost exposes `nativeElement`, which holds the
|
|
7
7
|
// engine host node that `getNativeTag` is keyed on. This adapter accepts:
|
|
8
8
|
// - a bare number (idempotent)
|
package/src/index.ts
CHANGED
|
@@ -5,35 +5,23 @@
|
|
|
5
5
|
// SEAM SCAFFOLD: mount/unmount + the renderer seam + host intrinsic selectors. Full RN-like
|
|
6
6
|
// composed components still flow through the shared @symbiote-native/components bridge.
|
|
7
7
|
|
|
8
|
+
import './register';
|
|
9
|
+
|
|
8
10
|
export {
|
|
9
|
-
ActivityIndicator,
|
|
10
11
|
anchorHostStyle,
|
|
11
|
-
Button,
|
|
12
12
|
FlatList,
|
|
13
13
|
HorizontalScrollContentView,
|
|
14
14
|
HorizontalScrollView,
|
|
15
15
|
Image,
|
|
16
|
-
ImageBackground,
|
|
17
|
-
InputAccessoryView,
|
|
18
16
|
KeyboardAvoidingView,
|
|
19
17
|
Modal,
|
|
20
|
-
Pressable,
|
|
21
|
-
RefreshControl,
|
|
22
|
-
SafeAreaView,
|
|
23
18
|
ScrollContentView,
|
|
24
|
-
ScrollView,
|
|
25
|
-
ScrollViewStickyHeader,
|
|
26
19
|
SectionList,
|
|
27
20
|
stableAnchorStyle,
|
|
28
|
-
Switch,
|
|
29
21
|
SymbioteHostPropsDirective,
|
|
30
22
|
SymbioteStyleInputDirective,
|
|
31
23
|
Text,
|
|
32
|
-
TextInput,
|
|
33
|
-
TouchableHighlight,
|
|
34
24
|
TouchableNativeFeedback,
|
|
35
|
-
TouchableOpacity,
|
|
36
|
-
TouchableWithoutFeedback,
|
|
37
25
|
View,
|
|
38
26
|
VirtualizedList,
|
|
39
27
|
VirtualizedSectionList,
|
|
@@ -73,6 +61,7 @@ export {
|
|
|
73
61
|
export { createAnimatedComponent } from './modules/animated';
|
|
74
62
|
export type {
|
|
75
63
|
IActivityIndicatorProps,
|
|
64
|
+
IAngularPressableInputs,
|
|
76
65
|
IAngularImageBackgroundProps,
|
|
77
66
|
IAngularInputAccessoryViewProps,
|
|
78
67
|
IAngularKeyboardAvoidingViewProps,
|
|
@@ -110,7 +99,6 @@ export type {
|
|
|
110
99
|
ISectionListProps,
|
|
111
100
|
ISeparatorProps,
|
|
112
101
|
ISeparators,
|
|
113
|
-
IStickyHeaderComponentType,
|
|
114
102
|
ISubmitBehavior,
|
|
115
103
|
IThemeAttrBackground,
|
|
116
104
|
IViewabilityConfig,
|
|
@@ -128,10 +116,61 @@ export type {
|
|
|
128
116
|
ISection,
|
|
129
117
|
ISwitchProps,
|
|
130
118
|
ISwitchTrackColor,
|
|
119
|
+
ISwitchChangeEvent,
|
|
131
120
|
ITextInputHandle,
|
|
132
121
|
ITextInputSelection,
|
|
122
|
+
ITextInputChangeEvent,
|
|
133
123
|
} from './components';
|
|
134
124
|
export { setImageSourceResolver } from './components';
|
|
125
|
+
// The element directives that make a HAND-WRITTEN intrinsic tag (`<view>`, `<text-input>`, ...)
|
|
126
|
+
// compile under ngtsc with no schema, and with a real type on every declared prop. `imports:
|
|
127
|
+
// [SYMBIOTE_ELEMENTS]` is the whole app-facing surface; the individual classes are exported for an
|
|
128
|
+
// app that wants a narrower import. See `elements.ts`'s header for why a directive rather than
|
|
129
|
+
// `CUSTOM_ELEMENTS_SCHEMA`/`NO_ERRORS_SCHEMA`.
|
|
130
|
+
export {
|
|
131
|
+
SYMBIOTE_ELEMENTS,
|
|
132
|
+
SymbioteElement,
|
|
133
|
+
ActivityIndicatorElement,
|
|
134
|
+
ActivityIndicatorSpinnerElement,
|
|
135
|
+
ButtonElement,
|
|
136
|
+
HorizontalScrollContentElement,
|
|
137
|
+
HorizontalScrollViewElement,
|
|
138
|
+
ImageBackgroundElement,
|
|
139
|
+
ImageElement,
|
|
140
|
+
InputAccessoryViewElement,
|
|
141
|
+
ManagedMultilineTextInputElement,
|
|
142
|
+
ManagedSwitchElement,
|
|
143
|
+
ManagedTextInputElement,
|
|
144
|
+
ModalElement,
|
|
145
|
+
MultilineTextInputElement,
|
|
146
|
+
PressableElement,
|
|
147
|
+
RefreshControlElement,
|
|
148
|
+
SafeAreaViewElement,
|
|
149
|
+
ScrollContentElement,
|
|
150
|
+
ScrollViewElement,
|
|
151
|
+
StickyHeaderElement,
|
|
152
|
+
SwitchElement,
|
|
153
|
+
TextElement,
|
|
154
|
+
TextInputElement,
|
|
155
|
+
// The `[(ngModel)]` / `formControl*` accessors for the two controlled tags — where the deleted
|
|
156
|
+
// wrappers' `NG_VALUE_ACCESSOR` went. Both ride `SYMBIOTE_ELEMENTS`; named separately for an app
|
|
157
|
+
// that imports narrowly.
|
|
158
|
+
SwitchValueAccessor,
|
|
159
|
+
TextInputValueAccessor,
|
|
160
|
+
// The three the list omitted while their components still existed. These are now the ONLY
|
|
161
|
+
// replacements for their deleted components in an app's `imports`, so a narrower import has to be
|
|
162
|
+
// able to name them.
|
|
163
|
+
TouchableHighlightElement,
|
|
164
|
+
TouchableNativeFeedbackElement,
|
|
165
|
+
TouchableOpacityElement,
|
|
166
|
+
TouchableWithoutFeedbackElement,
|
|
167
|
+
ViewElement,
|
|
168
|
+
} from './elements';
|
|
169
|
+
export type {
|
|
170
|
+
IElementProps,
|
|
171
|
+
IStickyHeaderElementProps,
|
|
172
|
+
ITextElementProps,
|
|
173
|
+
} from './element-props';
|
|
135
174
|
export { mount, unmount } from './render';
|
|
136
175
|
// The generic Descriptor→Angular bridge, the twin of descriptorToReact/descriptorToVue.
|
|
137
176
|
// Exported so a component defined OUTSIDE this package (e.g.
|
|
@@ -37,12 +37,10 @@ import {
|
|
|
37
37
|
resolveHostNode,
|
|
38
38
|
type ISymbioteNode,
|
|
39
39
|
} from '@symbiote-native/engine';
|
|
40
|
-
import {
|
|
41
|
-
import { Image, ScrollView, Text, View } from '../../components';
|
|
40
|
+
import { Text, View } from '../../components';
|
|
42
41
|
import {
|
|
43
42
|
anchorHostStyle,
|
|
44
43
|
ImageHost,
|
|
45
|
-
ScrollViewHost,
|
|
46
44
|
SymbioteHostPropsDirective,
|
|
47
45
|
SymbioteStyleInputDirective,
|
|
48
46
|
TextHost,
|
|
@@ -53,11 +51,19 @@ import {
|
|
|
53
51
|
IMAGE_INPUTS,
|
|
54
52
|
IMAGE_OUTPUTS,
|
|
55
53
|
ImageBase,
|
|
54
|
+
isImageEventCallback,
|
|
56
55
|
resolveImageProps,
|
|
57
|
-
} from '../../components/image
|
|
56
|
+
} from '../../components/image-shared';
|
|
57
|
+
import type { IGatedAccessibilityEvent } from '../../gate-demand';
|
|
58
58
|
import { SectionList } from '../../components/section-list';
|
|
59
59
|
import { AnimatedLeafBinder } from './animated-leaf-binder';
|
|
60
60
|
|
|
61
|
+
// The intrinsic `createAnimatedComponent` accepts in place of the deleted `Image` component.
|
|
62
|
+
const IMAGE_TAG = 'image';
|
|
63
|
+
// Same move for the deleted `ScrollView` component — the vertical axis's own tag stands in for
|
|
64
|
+
// the class identity the generic dispatcher used to compare against.
|
|
65
|
+
const SCROLL_VIEW_TAG = 'scroll-view';
|
|
66
|
+
|
|
61
67
|
// RN's prop carrying explicit (already-rasterized) values that override the animated prop in
|
|
62
68
|
// the COMMITTED props (sticky-header passthrough). Named once so the directive input and the
|
|
63
69
|
// reconcile agree.
|
|
@@ -68,7 +74,17 @@ const PASSTHROUGH_PROP = 'passthroughAnimatedPropExplicitValues';
|
|
|
68
74
|
// escape hatch for any OTHER prop that may hold an AnimatedNode or an Animated.event handler,
|
|
69
75
|
// plus static host props to forward (the React/Vue `rest`). Each concrete @Component re-lists
|
|
70
76
|
// these (Angular's inputs-on-base convention, mirroring Switch/Image).
|
|
71
|
-
|
|
77
|
+
// `testID` is listed alongside them rather than left to `animatedProps`, which is the documented
|
|
78
|
+
// escape hatch for everything else. Every other component in this adapter takes it as an ordinary
|
|
79
|
+
// input, and React's `createAnimatedComponent` spreads `...props`, so `<AnimatedView testID="x">`
|
|
80
|
+
// is what an app writes — it compiled (a static attribute on a component tag is never checked),
|
|
81
|
+
// landed on the non-painting anchor host and committed nowhere.
|
|
82
|
+
export const ANIMATED_INPUTS = [
|
|
83
|
+
'style',
|
|
84
|
+
'testID',
|
|
85
|
+
'animatedProps',
|
|
86
|
+
PASSTHROUGH_PROP,
|
|
87
|
+
];
|
|
72
88
|
export const ANIMATED_IMAGE_INPUTS = [
|
|
73
89
|
...IMAGE_INPUTS,
|
|
74
90
|
'animatedProps',
|
|
@@ -85,6 +101,7 @@ export abstract class AnimatedComponentBase
|
|
|
85
101
|
implements AfterViewInit, DoCheck, OnChanges, OnDestroy
|
|
86
102
|
{
|
|
87
103
|
style: unknown;
|
|
104
|
+
testID: string | undefined;
|
|
88
105
|
animatedProps: Record<string, unknown> | undefined;
|
|
89
106
|
passthroughAnimatedPropExplicitValues: unknown;
|
|
90
107
|
|
|
@@ -181,9 +198,11 @@ export abstract class AnimatedComponentBase
|
|
|
181
198
|
// never disagree.
|
|
182
199
|
private mergedProps(): Record<string, unknown> {
|
|
183
200
|
const base = this.animatedProps ?? {};
|
|
184
|
-
|
|
185
|
-
? { ...base }
|
|
186
|
-
|
|
201
|
+
const merged: Record<string, unknown> =
|
|
202
|
+
this.style === undefined ? { ...base } : { ...base, style: this.style };
|
|
203
|
+
// Only when set, so an unset input cannot clear a `testID` the app put in `animatedProps`.
|
|
204
|
+
if (this.testID !== undefined) merged.testID = this.testID;
|
|
205
|
+
return merged;
|
|
187
206
|
}
|
|
188
207
|
|
|
189
208
|
// The committed host node held by IDENTITY. resolveHostNode unwraps an imperative scroll
|
|
@@ -205,9 +224,9 @@ export abstract class AnimatedComponentBase
|
|
|
205
224
|
imports: [SymbioteHostPropsDirective, ViewHost],
|
|
206
225
|
inputs: ANIMATED_INPUTS,
|
|
207
226
|
template: `
|
|
208
|
-
<
|
|
227
|
+
<view [symbioteHostProps]="reducedProps">
|
|
209
228
|
<ng-content></ng-content>
|
|
210
|
-
</
|
|
229
|
+
</view>
|
|
211
230
|
`,
|
|
212
231
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
213
232
|
})
|
|
@@ -223,9 +242,9 @@ export class AnimatedView extends AnimatedComponentBase {}
|
|
|
223
242
|
imports: [SymbioteHostPropsDirective, TextHost],
|
|
224
243
|
inputs: ANIMATED_INPUTS,
|
|
225
244
|
template: `
|
|
226
|
-
<
|
|
245
|
+
<text [symbioteHostProps]="reducedProps">
|
|
227
246
|
<ng-content></ng-content>
|
|
228
|
-
</
|
|
247
|
+
</text>
|
|
229
248
|
`,
|
|
230
249
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
231
250
|
})
|
|
@@ -242,12 +261,8 @@ export class AnimatedText extends AnimatedComponentBase {}
|
|
|
242
261
|
inputs: ANIMATED_IMAGE_INPUTS,
|
|
243
262
|
outputs: IMAGE_OUTPUTS,
|
|
244
263
|
template: `
|
|
245
|
-
<
|
|
264
|
+
<image
|
|
246
265
|
[symbioteHostProps]="animatedImageProps"
|
|
247
|
-
(accessibilityAction)="handleAccessibilityAction($event)"
|
|
248
|
-
(accessibilityTap)="handleAccessibilityTap($event)"
|
|
249
|
-
(magicTap)="handleMagicTap($event)"
|
|
250
|
-
(accessibilityEscape)="handleAccessibilityEscape($event)"
|
|
251
266
|
(loadStart)="handleLoadStart($event)"
|
|
252
267
|
(load)="handleLoad($event)"
|
|
253
268
|
(loadEnd)="handleLoadEnd($event)"
|
|
@@ -256,7 +271,7 @@ export class AnimatedText extends AnimatedComponentBase {}
|
|
|
256
271
|
(partialLoad)="handlePartialLoad($event)"
|
|
257
272
|
>
|
|
258
273
|
<ng-content></ng-content>
|
|
259
|
-
</
|
|
274
|
+
</image>
|
|
260
275
|
`,
|
|
261
276
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
262
277
|
})
|
|
@@ -283,6 +298,18 @@ export class AnimatedImage
|
|
|
283
298
|
);
|
|
284
299
|
private viewReady = false;
|
|
285
300
|
|
|
301
|
+
private gateInto(
|
|
302
|
+
props: Record<string, unknown>,
|
|
303
|
+
name: IGatedAccessibilityEvent,
|
|
304
|
+
key: string,
|
|
305
|
+
): void {
|
|
306
|
+
const carried = props[key];
|
|
307
|
+
props[key] = this.gatedAccessibilityHandler(
|
|
308
|
+
name,
|
|
309
|
+
isImageEventCallback(carried) ? carried : undefined,
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
286
313
|
get animatedImageProps(): Record<string, unknown> {
|
|
287
314
|
const reduced = reduceProps(this.mergedProps());
|
|
288
315
|
const passthroughStyle = readPassthroughStyle(
|
|
@@ -296,6 +323,15 @@ export class AnimatedImage
|
|
|
296
323
|
}
|
|
297
324
|
const resolved = resolveImageProps(reduced);
|
|
298
325
|
resolved['style'] = [anchorHostStyle(this.elementRef), resolved['style']];
|
|
326
|
+
// The four gated accessibility events, which used to be template bindings on the host tag and
|
|
327
|
+
// therefore lit their Fabric flags on every AnimatedImage in the app
|
|
328
|
+
// (`.claude/rules/fabric-boolean-event-gates.md`). Routed through the base's gate instead, so
|
|
329
|
+
// both channels still reach the app — the `onX` callback carried in the animated prop bag, and
|
|
330
|
+
// the `@Output()` an app may bind on <AnimatedImage> (IMAGE_OUTPUTS declares all four).
|
|
331
|
+
this.gateInto(resolved, 'accessibilityAction', 'onAccessibilityAction');
|
|
332
|
+
this.gateInto(resolved, 'accessibilityTap', 'onAccessibilityTap');
|
|
333
|
+
this.gateInto(resolved, 'magicTap', 'onMagicTap');
|
|
334
|
+
this.gateInto(resolved, 'accessibilityEscape', 'onAccessibilityEscape');
|
|
299
335
|
return resolved;
|
|
300
336
|
}
|
|
301
337
|
|
|
@@ -363,49 +399,23 @@ export class AnimatedImage
|
|
|
363
399
|
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
364
400
|
],
|
|
365
401
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
366
|
-
imports: [SymbioteHostPropsDirective
|
|
402
|
+
imports: [SymbioteHostPropsDirective],
|
|
367
403
|
inputs: ANIMATED_INPUTS,
|
|
368
404
|
template: `
|
|
369
|
-
<
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
</symbiote-scroll-content>
|
|
373
|
-
</symbiote-scroll-view>
|
|
405
|
+
<scroll-view [symbioteHostProps]="reducedProps">
|
|
406
|
+
<ng-content></ng-content>
|
|
407
|
+
</scroll-view>
|
|
374
408
|
`,
|
|
375
409
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
376
410
|
})
|
|
377
411
|
export class AnimatedScrollView extends AnimatedComponentBase {
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
384
|
-
//
|
|
385
|
-
// real ScrollView applies that this bespoke template used to skip — without it, iOS Fabric
|
|
386
|
-
// never clips content to the scroll view's frame (invisible on Android, whose native ViewGroup
|
|
387
|
-
// clips regardless of style). This wrapper has no `horizontal` input and its template is
|
|
388
|
-
// hardcoded to the vertical intrinsics, so selectScrollIntrinsics is always called with
|
|
389
|
-
// isHorizontal=false here, matching what the template can actually render.
|
|
390
|
-
override get reducedProps(): Record<string, unknown> {
|
|
391
|
-
const reduced = super.reducedProps;
|
|
392
|
-
const { scrollViewBaseStyle } = selectScrollIntrinsics(false, undefined);
|
|
393
|
-
const withScrollBase: Record<string, unknown> = {
|
|
394
|
-
...reduced,
|
|
395
|
-
style: [scrollViewBaseStyle, reduced.style],
|
|
396
|
-
};
|
|
397
|
-
return withScrollBase.nestedScrollEnabled === undefined
|
|
398
|
-
? { ...withScrollBase, nestedScrollEnabled: true }
|
|
399
|
-
: withScrollBase;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// The content (inner) view's props: contentStyle from the same intrinsics selection, plus
|
|
403
|
-
// `collapsable: false` (the Android multi-child fix this file's tests already cover) — mirrors
|
|
404
|
-
// the real ScrollView's own `contentProps` getter (scroll-view/shared.ts).
|
|
405
|
-
get contentProps(): Record<string, unknown> {
|
|
406
|
-
const { contentStyle } = selectScrollIntrinsics(false, undefined);
|
|
407
|
-
return { style: contentStyle, collapsable: false };
|
|
408
|
-
}
|
|
412
|
+
// Nothing left to override: `registerScrollViewBehavior()` (`../../register.ts`) now owns the
|
|
413
|
+
// content node, `scrollViewBaseStyle`/`nestedScrollEnabled` defaults, and the sticky seam for
|
|
414
|
+
// this SAME `scroll-view` tag. This class used to build its own `<scroll-content>` child by
|
|
415
|
+
// hand — deleted 2026-09-11, since that made TWO owners of the content node the moment the
|
|
416
|
+
// behavior registered on this tag: the engine's own `buildStructure` and this template both
|
|
417
|
+
// creating one. `<ng-content>` now lands directly under the owner and the behavior redirects it
|
|
418
|
+
// into the content node it builds, same as every other `<scroll-view>` in the app.
|
|
409
419
|
}
|
|
410
420
|
|
|
411
421
|
// List components are already explicit AOT-compiled Angular components with their own full input
|
|
@@ -422,12 +432,16 @@ export const AnimatedSectionList = SectionList;
|
|
|
422
432
|
export function createAnimatedComponent(base: unknown): Type<unknown> {
|
|
423
433
|
if (base === View) return AnimatedView;
|
|
424
434
|
if (base === Text) return AnimatedText;
|
|
425
|
-
|
|
426
|
-
|
|
435
|
+
// The TAG, not a component identity: `ScrollView`/`Image` are gone as classes now
|
|
436
|
+
// (`components/scroll-view-props.ts`, `modules/image`), so there is no class to compare
|
|
437
|
+
// against — the same move React made (`createAnimatedComponent('image')`). A tag string is also
|
|
438
|
+
// what portable app code can pass on every adapter.
|
|
439
|
+
if (base === SCROLL_VIEW_TAG) return AnimatedScrollView;
|
|
440
|
+
if (base === IMAGE_TAG) return AnimatedImage;
|
|
427
441
|
throw new Error(
|
|
428
442
|
'createAnimatedComponent: Angular cannot synthesize a component at runtime (no JIT compiler ' +
|
|
429
443
|
'under AOT/Metro). Author an explicit standalone @Component extending AnimatedComponentBase ' +
|
|
430
|
-
|
|
431
|
-
'AnimatedView / AnimatedText /
|
|
444
|
+
"instead. The built-in primitives View / Text and the tags 'scroll-view' / 'image' map to " +
|
|
445
|
+
'AnimatedView / AnimatedText / AnimatedScrollView / AnimatedImage.',
|
|
432
446
|
);
|
|
433
447
|
}
|
|
@@ -55,7 +55,7 @@ export {
|
|
|
55
55
|
// getter only exists to defer a RUNTIME createAnimatedComponent(ScrollView) past module init so
|
|
56
56
|
// it cannot read ScrollView inside its own TDZ during an import cycle. AnimatedScrollView here is
|
|
57
57
|
// a statically-declared component that never reads the ScrollView class at init (it targets the
|
|
58
|
-
// `
|
|
58
|
+
// `scroll-view` host by string), so there is no cycle to defer.
|
|
59
59
|
//
|
|
60
60
|
// FlatList / SectionList are exposed as explicit AOT-safe list entries now that the Angular list
|
|
61
61
|
// components exist. Angular still cannot synthesize arbitrary animated wrappers at runtime; custom
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// RN's Image STATICS — `getSize`, `getSizeWithHeaders`, `prefetch`, `abortPrefetch`, `queryCache`,
|
|
2
|
+
// `resolveAssetSource`.
|
|
3
|
+
//
|
|
4
|
+
// IN `modules/`, NOT `components/`. The primitive is the `<image>` tag matched by `ImageElement`,
|
|
5
|
+
// and its fold runs in the engine (`behaviors/image.ts`); what is left under the name `Image` is an
|
|
6
|
+
// imperative API with no view, which is what this bucket is for
|
|
7
|
+
// (<adapter_src_follows_framework_idioms>). Sitting in `components/` was what made a statics object
|
|
8
|
+
// read as a component.
|
|
9
|
+
//
|
|
10
|
+
// A NAMESPACE OBJECT rather than six bare functions, deliberately: `Alert`, `Share`, `Linking` and
|
|
11
|
+
// `AppState` all take that shape, and an app porting from RN writes `Image.getSize(...)` verbatim.
|
|
12
|
+
//
|
|
13
|
+
// Shared verbatim via `imageStatics`, the same source every other adapter's Image uses.
|
|
14
|
+
import { imageStatics, type IImageStatics } from '@symbiote-native/components';
|
|
15
|
+
|
|
16
|
+
export type { IImageStatics };
|
|
17
|
+
|
|
18
|
+
export const Image: IImageStatics = imageStatics;
|
package/src/primitives/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ export {
|
|
|
24
24
|
} from './shared';
|
|
25
25
|
|
|
26
26
|
@Component({
|
|
27
|
-
selector: '
|
|
27
|
+
selector: 'view',
|
|
28
28
|
standalone: true,
|
|
29
29
|
template: '<ng-content></ng-content>',
|
|
30
30
|
})
|
|
@@ -32,7 +32,7 @@ export class ViewHost extends SymbiotePrimitiveHost {}
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Text carries the two defaults RN's Text.js applies unconditionally (`ellipsizeMode ?? 'tail'`,
|
|
35
|
-
* `allowFontScaling !== false`, Text.js:
|
|
35
|
+
* `allowFontScaling !== false`, Text.js:289 and :291). Without them native falls back to `clip` and a
|
|
36
36
|
* clamped Text cuts mid-word with no ellipsis — device-observed on the other adapters 2026-08-19.
|
|
37
37
|
*
|
|
38
38
|
* They are declared as real `@Input()`s, unlike the pass-through props the base's comment
|
|
@@ -41,7 +41,7 @@ export class ViewHost extends SymbiotePrimitiveHost {}
|
|
|
41
41
|
* 'tail' would silently overwrite an explicit `ellipsizeMode="clip"`.
|
|
42
42
|
*/
|
|
43
43
|
@Component({
|
|
44
|
-
selector: '
|
|
44
|
+
selector: 'text',
|
|
45
45
|
standalone: true,
|
|
46
46
|
template: '<ng-content></ng-content>',
|
|
47
47
|
})
|
|
@@ -73,91 +73,122 @@ export class TextHost extends SymbiotePrimitiveHost implements OnInit {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
@Component({
|
|
76
|
-
selector: '
|
|
76
|
+
selector: 'image',
|
|
77
77
|
standalone: true,
|
|
78
78
|
template: '<ng-content></ng-content>',
|
|
79
79
|
})
|
|
80
80
|
export class ImageHost extends SymbiotePrimitiveHost {}
|
|
81
81
|
|
|
82
82
|
@Component({
|
|
83
|
-
selector: '
|
|
83
|
+
selector: 'scroll-view',
|
|
84
84
|
standalone: true,
|
|
85
85
|
template: '<ng-content></ng-content>',
|
|
86
86
|
})
|
|
87
87
|
export class ScrollViewHost extends SymbiotePrimitiveHost {}
|
|
88
88
|
|
|
89
89
|
@Component({
|
|
90
|
-
selector: '
|
|
90
|
+
selector: 'scroll-content',
|
|
91
91
|
standalone: true,
|
|
92
92
|
template: '<ng-content></ng-content>',
|
|
93
93
|
})
|
|
94
94
|
export class ScrollContentView extends SymbiotePrimitiveHost {}
|
|
95
95
|
|
|
96
96
|
@Component({
|
|
97
|
-
selector: '
|
|
97
|
+
selector: 'horizontal-scroll-view',
|
|
98
98
|
standalone: true,
|
|
99
99
|
template: '<ng-content></ng-content>',
|
|
100
100
|
})
|
|
101
101
|
export class HorizontalScrollView extends SymbiotePrimitiveHost {}
|
|
102
102
|
|
|
103
103
|
@Component({
|
|
104
|
-
selector: '
|
|
104
|
+
selector: 'horizontal-scroll-content',
|
|
105
105
|
standalone: true,
|
|
106
106
|
template: '<ng-content></ng-content>',
|
|
107
107
|
})
|
|
108
108
|
export class HorizontalScrollContentView extends SymbiotePrimitiveHost {}
|
|
109
109
|
|
|
110
|
+
// The pair the LOWERED path commits — declared so the tag alphabet stays complete, though no
|
|
111
|
+
// Angular template renders them: this adapter has no lowering transform. The `-managed` pair below
|
|
112
|
+
// is what its own TextInput renders.
|
|
110
113
|
@Component({
|
|
111
|
-
selector: '
|
|
114
|
+
selector: 'text-input',
|
|
112
115
|
standalone: true,
|
|
113
116
|
template: '<ng-content></ng-content>',
|
|
114
117
|
})
|
|
115
118
|
export class TextInputHost extends SymbiotePrimitiveHost {}
|
|
116
119
|
|
|
117
120
|
@Component({
|
|
118
|
-
selector: '
|
|
121
|
+
selector: 'text-input-multiline',
|
|
119
122
|
standalone: true,
|
|
120
123
|
template: '<ng-content></ng-content>',
|
|
121
124
|
})
|
|
122
125
|
export class MultilineTextInputHost extends SymbiotePrimitiveHost {}
|
|
123
126
|
|
|
124
127
|
@Component({
|
|
125
|
-
selector: '
|
|
128
|
+
selector: 'text-input-managed',
|
|
129
|
+
standalone: true,
|
|
130
|
+
template: '<ng-content></ng-content>',
|
|
131
|
+
})
|
|
132
|
+
export class ManagedTextInputHost extends SymbiotePrimitiveHost {}
|
|
133
|
+
|
|
134
|
+
@Component({
|
|
135
|
+
selector: 'text-input-multiline-managed',
|
|
136
|
+
standalone: true,
|
|
137
|
+
template: '<ng-content></ng-content>',
|
|
138
|
+
})
|
|
139
|
+
export class ManagedMultilineTextInputHost extends SymbiotePrimitiveHost {}
|
|
140
|
+
|
|
141
|
+
@Component({
|
|
142
|
+
selector: 'switch',
|
|
126
143
|
standalone: true,
|
|
127
144
|
template: '<ng-content></ng-content>',
|
|
128
145
|
})
|
|
129
146
|
export class SwitchHost extends SymbiotePrimitiveHost {}
|
|
130
147
|
|
|
148
|
+
// The component path's spelling — same native Switch/AndroidSwitch, a tag the engine's Switch
|
|
149
|
+
// behavior does not carry. See `component-names/shared.ts` for why the wrapper may not share the
|
|
150
|
+
// lowered tag; mirrors `ManagedTextInputHost` above.
|
|
151
|
+
@Component({
|
|
152
|
+
selector: 'switch-managed',
|
|
153
|
+
standalone: true,
|
|
154
|
+
template: '<ng-content></ng-content>',
|
|
155
|
+
})
|
|
156
|
+
export class ManagedSwitchHost extends SymbiotePrimitiveHost {}
|
|
157
|
+
|
|
158
|
+
// The centering RCTView RN wraps the spinner in (ActivityIndicator.js:112), not the spinner —
|
|
159
|
+
// which is what this tag resolved to until 2026-09-09. The native view moved to
|
|
160
|
+
// `activity-indicator-spinner`, built by the engine's ActivityIndicator behavior, so nothing writes
|
|
161
|
+
// it in a template and it needs no host here.
|
|
131
162
|
@Component({
|
|
132
|
-
selector: '
|
|
163
|
+
selector: 'activity-indicator',
|
|
133
164
|
standalone: true,
|
|
134
165
|
template: '<ng-content></ng-content>',
|
|
135
166
|
})
|
|
136
167
|
export class ActivityIndicatorHost extends SymbiotePrimitiveHost {}
|
|
137
168
|
|
|
138
169
|
@Component({
|
|
139
|
-
selector: '
|
|
170
|
+
selector: 'safe-area-view',
|
|
140
171
|
standalone: true,
|
|
141
172
|
template: '<ng-content></ng-content>',
|
|
142
173
|
})
|
|
143
174
|
export class SafeAreaViewHost extends SymbiotePrimitiveHost {}
|
|
144
175
|
|
|
145
176
|
@Component({
|
|
146
|
-
selector: '
|
|
177
|
+
selector: 'modal',
|
|
147
178
|
standalone: true,
|
|
148
179
|
template: '<ng-content></ng-content>',
|
|
149
180
|
})
|
|
150
181
|
export class ModalHost extends SymbiotePrimitiveHost {}
|
|
151
182
|
|
|
152
183
|
@Component({
|
|
153
|
-
selector: '
|
|
184
|
+
selector: 'refresh-control',
|
|
154
185
|
standalone: true,
|
|
155
186
|
template: '<ng-content></ng-content>',
|
|
156
187
|
})
|
|
157
188
|
export class RefreshControlHost extends SymbiotePrimitiveHost {}
|
|
158
189
|
|
|
159
190
|
@Component({
|
|
160
|
-
selector: '
|
|
191
|
+
selector: 'input-accessory-view',
|
|
161
192
|
standalone: true,
|
|
162
193
|
template: '<ng-content></ng-content>',
|
|
163
194
|
})
|