@symbiote-native/angular 0.3.3 → 0.5.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/babel-register-composed.cjs +119 -0
- package/bin/symbiote-angular-dev.cjs +43 -1
- package/build/angular/components/image/shared.d.ts +4 -4
- package/build/angular/components/image/shared.js +1 -3
- package/build/angular/components/image/shared.js.map +1 -1
- package/build/angular/components/{input-accessory-view.d.ts → input-accessory-view/index.d.ts} +1 -1
- package/build/angular/components/{input-accessory-view.js → input-accessory-view/index.js} +3 -7
- package/build/angular/components/input-accessory-view/index.js.map +1 -0
- package/build/angular/components/{keyboard-avoiding-view.js → keyboard-avoiding-view/index.js} +3 -8
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -0
- package/build/angular/components/{modal.js → modal/index.js} +3 -8
- package/build/angular/components/modal/index.js.map +1 -0
- package/build/angular/components/pressable/index.js +13 -14
- package/build/angular/components/pressable/index.js.map +1 -1
- package/build/angular/components/{refresh-control.js → refresh-control/index.js} +3 -8
- package/build/angular/components/refresh-control/index.js.map +1 -0
- package/build/angular/components/{safe-area-view.d.ts → safe-area-view/index.d.ts} +1 -1
- package/build/angular/components/{safe-area-view.js → safe-area-view/index.js} +3 -7
- package/build/angular/components/safe-area-view/index.js.map +1 -0
- package/build/angular/components/text-input.js +1 -6
- package/build/angular/components/text-input.js.map +1 -1
- package/build/angular/components/{touchable.d.ts → touchable/index.d.ts} +1 -1
- package/build/angular/components/{touchable.js → touchable/index.js} +4 -4
- package/build/angular/components/touchable/index.js.map +1 -0
- package/build/angular/components/{touchable-native-feedback.d.ts → touchable-native-feedback/index.d.ts} +1 -1
- package/build/angular/components/{touchable-native-feedback.js → touchable-native-feedback/index.js} +4 -9
- package/build/angular/components/touchable-native-feedback/index.js.map +1 -0
- package/build/angular/{create-portal.js → create-portal/index.js} +1 -1
- package/build/angular/create-portal/index.js.map +1 -0
- package/build/angular/{create-tunnel.js → create-tunnel/index.js} +1 -1
- package/build/angular/create-tunnel/index.js.map +1 -0
- package/build/angular/index.d.ts +1 -1
- package/build/angular/index.js +1 -1
- package/build/angular/index.js.map +1 -1
- package/build/angular/modules/animated/animated-leaf-binder/index.d.ts +14 -0
- package/build/angular/modules/animated/animated-leaf-binder/index.js +91 -0
- package/build/angular/modules/animated/animated-leaf-binder/index.js.map +1 -0
- package/build/angular/modules/animated/animated-leaf-binder.d.ts +14 -0
- package/build/angular/modules/animated/animated-leaf-binder.js +91 -0
- package/build/angular/modules/animated/animated-leaf-binder.js.map +1 -0
- package/build/angular/modules/animated/create-animated-component.d.ts +3 -12
- package/build/angular/modules/animated/create-animated-component.js +48 -113
- package/build/angular/modules/animated/create-animated-component.js.map +1 -1
- package/build/angular/modules/{status-bar.js → status-bar/index.js} +1 -1
- package/build/angular/modules/status-bar/index.js.map +1 -0
- package/build/angular/{render.js → render/index.js} +15 -4
- package/build/angular/render/index.js.map +1 -0
- package/build/{renderer.js → angular/renderer/index.js} +17 -18
- package/build/angular/renderer/index.js.map +1 -0
- package/build/components/image/shared.d.ts +4 -4
- package/build/components/image/shared.js +1 -3
- package/build/components/{input-accessory-view.d.ts → input-accessory-view/index.d.ts} +1 -1
- package/build/components/{input-accessory-view.js → input-accessory-view/index.js} +2 -6
- package/build/components/{keyboard-avoiding-view.js → keyboard-avoiding-view/index.js} +2 -7
- package/build/components/{modal.js → modal/index.js} +2 -7
- package/build/components/pressable/index.js +13 -14
- package/build/components/{refresh-control.js → refresh-control/index.js} +2 -7
- package/build/components/{safe-area-view.d.ts → safe-area-view/index.d.ts} +1 -1
- package/build/components/{safe-area-view.js → safe-area-view/index.js} +2 -6
- package/build/components/text-input.js +1 -6
- package/build/components/{touchable.d.ts → touchable/index.d.ts} +1 -1
- package/build/components/{touchable.js → touchable/index.js} +3 -3
- package/build/components/{touchable-native-feedback.d.ts → touchable-native-feedback/index.d.ts} +1 -1
- package/build/components/{touchable-native-feedback.js → touchable-native-feedback/index.js} +3 -8
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/modules/animated/animated-leaf-binder/index.d.ts +14 -0
- package/build/modules/animated/animated-leaf-binder/index.js +90 -0
- package/build/modules/animated/animated-leaf-binder.d.ts +14 -0
- package/build/modules/animated/animated-leaf-binder.js +90 -0
- package/build/modules/animated/create-animated-component.d.ts +3 -12
- package/build/modules/animated/create-animated-component.js +47 -112
- package/build/{render.js → render/index.js} +14 -3
- package/build/{angular/renderer.js → renderer/index.js} +16 -19
- package/package.json +10 -5
- package/src/angular-gaps.test.ts +1 -1
- package/src/components/image/shared.ts +6 -5
- package/src/components/{input-accessory-view.ts → input-accessory-view/index.ts} +11 -8
- package/src/components/{input-accessory-view.test.ts → input-accessory-view/input-accessory-view.test.ts} +2 -2
- package/src/components/{keyboard-avoiding-view.ts → keyboard-avoiding-view/index.ts} +2 -7
- package/src/components/{keyboard-avoiding-view.test.ts → keyboard-avoiding-view/keyboard-avoiding-view.test.ts} +2 -2
- package/src/components/{modal.ts → modal/index.ts} +2 -7
- package/src/components/{modal.test.ts → modal/modal.test.ts} +2 -2
- package/src/components/pressable/index.ts +17 -15
- package/src/components/{refresh-control.ts → refresh-control/index.ts} +2 -7
- package/src/components/{refresh-control.test.ts → refresh-control/refresh-control.test.ts} +2 -2
- package/src/components/{safe-area-view.ts → safe-area-view/index.ts} +7 -8
- package/src/components/{safe-area-view.test.ts → safe-area-view/safe-area-view.test.ts} +2 -2
- package/src/components/text-input.ts +1 -6
- package/src/components/{touchable.ts → touchable/index.ts} +3 -3
- package/src/components/{touchable.test.ts → touchable/touchable.test.ts} +2 -2
- package/src/components/{touchable-native-feedback.ts → touchable-native-feedback/index.ts} +3 -9
- package/src/components/{touchable-native-feedback.test.ts → touchable-native-feedback/touchable-native-feedback.test.ts} +2 -2
- package/src/{create-portal.test.ts → create-portal/create-portal.test.ts} +3 -3
- package/src/{create-tunnel.test.ts → create-tunnel/create-tunnel.test.ts} +3 -3
- package/src/index.ts +1 -1
- package/src/modules/animated/animated-leaf-binder/animated-leaf-binder.test.ts +116 -0
- package/src/modules/animated/animated-leaf-binder/index.ts +101 -0
- package/src/modules/animated/animated-leaf-binder.test.ts +116 -0
- package/src/modules/animated/animated-leaf-binder.ts +101 -0
- package/src/modules/animated/animated-scroll-view.test.ts +17 -0
- package/src/modules/animated/create-animated-component.ts +53 -123
- package/src/modules/{status-bar.test.ts → status-bar/status-bar.test.ts} +2 -2
- package/src/{render.ts → render/index.ts} +14 -2
- package/src/{render.test.ts → render/render.test.ts} +1 -1
- package/src/{renderer.ts → renderer/index.ts} +58 -58
- package/src/{renderer.test.ts → renderer/renderer.test.ts} +24 -1
- package/build/angular/components/input-accessory-view.js.map +0 -1
- package/build/angular/components/keyboard-avoiding-view.js.map +0 -1
- package/build/angular/components/modal.js.map +0 -1
- package/build/angular/components/refresh-control.js.map +0 -1
- package/build/angular/components/safe-area-view.js.map +0 -1
- package/build/angular/components/touchable-native-feedback.js.map +0 -1
- package/build/angular/components/touchable.js.map +0 -1
- package/build/angular/create-portal.js.map +0 -1
- package/build/angular/create-tunnel.js.map +0 -1
- package/build/angular/modules/status-bar.js.map +0 -1
- package/build/angular/render.js.map +0 -1
- package/build/angular/renderer.js.map +0 -1
- /package/build/angular/components/{keyboard-avoiding-view.d.ts → keyboard-avoiding-view/index.d.ts} +0 -0
- /package/build/angular/components/{modal.d.ts → modal/index.d.ts} +0 -0
- /package/build/angular/components/{refresh-control.d.ts → refresh-control/index.d.ts} +0 -0
- /package/build/angular/{create-portal.d.ts → create-portal/index.d.ts} +0 -0
- /package/build/angular/{create-tunnel.d.ts → create-tunnel/index.d.ts} +0 -0
- /package/build/angular/modules/{status-bar.d.ts → status-bar/index.d.ts} +0 -0
- /package/build/angular/{render.d.ts → render/index.d.ts} +0 -0
- /package/build/angular/{renderer.d.ts → renderer/index.d.ts} +0 -0
- /package/build/components/{keyboard-avoiding-view.d.ts → keyboard-avoiding-view/index.d.ts} +0 -0
- /package/build/components/{modal.d.ts → modal/index.d.ts} +0 -0
- /package/build/components/{refresh-control.d.ts → refresh-control/index.d.ts} +0 -0
- /package/build/{create-portal.d.ts → create-portal/index.d.ts} +0 -0
- /package/build/{create-portal.js → create-portal/index.js} +0 -0
- /package/build/{create-tunnel.d.ts → create-tunnel/index.d.ts} +0 -0
- /package/build/{create-tunnel.js → create-tunnel/index.js} +0 -0
- /package/build/modules/{status-bar.d.ts → status-bar/index.d.ts} +0 -0
- /package/build/modules/{status-bar.js → status-bar/index.js} +0 -0
- /package/build/{render.d.ts → render/index.d.ts} +0 -0
- /package/build/{renderer.d.ts → renderer/index.d.ts} +0 -0
- /package/src/{create-portal.ts → create-portal/index.ts} +0 -0
- /package/src/{create-tunnel.ts → create-tunnel/index.ts} +0 -0
- /package/src/modules/{status-bar.ts → status-bar/index.ts} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Pure Fabrication (GRASP): the leaf-lifecycle orchestration shared by every Animated*
|
|
2
|
+
// wrapper, extracted out of AnimatedComponentBase so AnimatedImage — which cannot extend
|
|
3
|
+
// AnimatedComponentBase, since it must extend ImageBase for TS's-native image handling —
|
|
4
|
+
// gets the SAME logic via composition instead of copy-pasting it. Framework-thin on
|
|
5
|
+
// purpose: it knows nothing about Angular (@ViewChild, DI, change detection), only the
|
|
6
|
+
// engine's Animated leaf + commit primitives, so it stays testable without any Angular
|
|
7
|
+
// bootstrap. NOTE: react/vue drive this same dance through their own runtime HOC
|
|
8
|
+
// (createAnimatedComponent) rather than a class, so there is no cross-adapter dedup
|
|
9
|
+
// opportunity here yet — this Pure Fabrication is local to the angular adapter.
|
|
10
|
+
import {
|
|
11
|
+
AnimatedProps,
|
|
12
|
+
attachNativeEventHandler,
|
|
13
|
+
dlog,
|
|
14
|
+
whenCommitted,
|
|
15
|
+
type ISymbioteNode,
|
|
16
|
+
} from '@symbiote-native/engine';
|
|
17
|
+
|
|
18
|
+
export class AnimatedLeafBinder {
|
|
19
|
+
// The leaf currently wired into the value graph. Null until the first reconcile.
|
|
20
|
+
private attached: AnimatedProps | null = null;
|
|
21
|
+
// The whenCommitted waiter for the current leaf's node binding, cancelled before the next.
|
|
22
|
+
private cancelBind: (() => void) | undefined;
|
|
23
|
+
// Detachers for any Animated.event prop bound natively to the committed node (JS path: none).
|
|
24
|
+
private eventDetachers: Array<() => void> = [];
|
|
25
|
+
|
|
26
|
+
// `resolveNode` stays a caller-supplied resolver (not a constructor-captured node) so this
|
|
27
|
+
// class never needs to know HOW the host node is found — AnimatedComponentBase and
|
|
28
|
+
// AnimatedImage both resolve it the same way (resolveHostNode + isSymbioteNode over their
|
|
29
|
+
// own @ViewChild), but that's Angular DI state this binder has no business touching.
|
|
30
|
+
// `label` is purely diagnostic (dlog), mirroring the constructor.name the pre-extraction
|
|
31
|
+
// dlog call used.
|
|
32
|
+
constructor(
|
|
33
|
+
private readonly resolveNode: () => ISymbioteNode | null,
|
|
34
|
+
private readonly label: string,
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
// Build a fresh AnimatedProps leaf from the current props (the React/Vue per-render
|
|
38
|
+
// useMemo(rest)), wire it into the graph, and swap the previous one out. Attach the NEW leaf
|
|
39
|
+
// BEFORE detaching the OLD one: a shared Value self-detaches (dropping its native node) the
|
|
40
|
+
// instant its child count hits zero, so detaching first would kill a running native animation
|
|
41
|
+
// on any unrelated re-render (mirrors RN's AnimatedComponent._attachProps). Then bind the
|
|
42
|
+
// committed node, go native if wanted, and rebind native events.
|
|
43
|
+
reconcile(props: Record<string, unknown>, wantsNative: boolean): void {
|
|
44
|
+
dlog(`${this.label} reconcile`);
|
|
45
|
+
const newLeaf = new AnimatedProps(props);
|
|
46
|
+
newLeaf.__attach();
|
|
47
|
+
if (this.attached !== null && this.attached !== newLeaf) this.attached.__detach();
|
|
48
|
+
this.attached = newLeaf;
|
|
49
|
+
|
|
50
|
+
this.bindNode(newLeaf, props, wantsNative);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Bind the leaf to the host's Fabric node THROUGH whenCommitted: under Angular's zoneless
|
|
54
|
+
// batched change detection the inner host's tag does not exist yet at ngAfterViewInit time
|
|
55
|
+
// (the same async-commit gotcha Vue documents), so binding eagerly would no-op. whenCommitted
|
|
56
|
+
// runs the action now if already committed, else after the commit that assigns the tag.
|
|
57
|
+
private bindNode(
|
|
58
|
+
leaf: AnimatedProps,
|
|
59
|
+
props: Record<string, unknown>,
|
|
60
|
+
wantsNative: boolean,
|
|
61
|
+
): void {
|
|
62
|
+
this.cancelBind?.();
|
|
63
|
+
this.cancelBind = undefined;
|
|
64
|
+
const node = this.resolveNode();
|
|
65
|
+
if (node === null) return;
|
|
66
|
+
this.cancelBind = whenCommitted(node, () => {
|
|
67
|
+
leaf.setNativeView(node);
|
|
68
|
+
if (wantsNative) leaf.__makeNative();
|
|
69
|
+
this.attachEvents(node, props);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Native-attach any Animated.event prop (e.g. onScroll={Animated.event(…,{useNativeDriver:true})})
|
|
74
|
+
// to the committed node. attachNativeEventHandler no-ops (returns undefined) unless the prop is a
|
|
75
|
+
// native event handler with a committed tag, so the JS path stays the fallback. Rebound each
|
|
76
|
+
// reconcile so a new inline event re-attaches; detached first to avoid leaking the prior binding.
|
|
77
|
+
private attachEvents(node: ISymbioteNode, props: Record<string, unknown>): void {
|
|
78
|
+
this.detachEvents();
|
|
79
|
+
for (const key of Object.keys(props)) {
|
|
80
|
+
const attachment = attachNativeEventHandler(node, key, props[key]);
|
|
81
|
+
if (attachment !== undefined) this.eventDetachers.push(attachment.detach);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private detachEvents(): void {
|
|
86
|
+
for (const detach of this.eventDetachers) detach();
|
|
87
|
+
this.eventDetachers = [];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Tear down everything: cancel a still-pending bind, drop native event listeners, detach the
|
|
91
|
+
// current leaf from the value graph. Safe to call even if reconcile() was never called.
|
|
92
|
+
destroy(): void {
|
|
93
|
+
this.cancelBind?.();
|
|
94
|
+
this.cancelBind = undefined;
|
|
95
|
+
this.detachEvents();
|
|
96
|
+
if (this.attached !== null) {
|
|
97
|
+
this.attached.__detach();
|
|
98
|
+
this.attached = null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -75,6 +75,23 @@ describe('AnimatedScrollView', () => {
|
|
|
75
75
|
expect(content?.children.map(child => child.props.testID)).toEqual(['a', 'b']);
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
+
// Regression test for a THIRD bug in this same bespoke-template class, this one iOS-only (the
|
|
79
|
+
// inverse of the two Android bugs above): AnimatedScrollView never applied
|
|
80
|
+
// selectScrollIntrinsics' scrollViewBaseStyle (overflow: 'scroll') to its host node, unlike the
|
|
81
|
+
// real ScrollView component. On iOS Fabric a scroll view only clips its content to its own
|
|
82
|
+
// frame when `overflow: 'scroll'` is set; without it, content taller than the frame bleeds out
|
|
83
|
+
// over sibling views instead of scrolling clipped (Android's native ViewGroup clips regardless
|
|
84
|
+
// of the style prop, which is why this was invisible there). See
|
|
85
|
+
// core/components/src/view/render-scroll-view.ts's SCROLL_VIEW_BASE_VERTICAL comment.
|
|
86
|
+
it('applies the scroll-view base style (overflow: scroll) so content clips to the frame', async () => {
|
|
87
|
+
mount(ROOT_TAG, AnimatedScrollViewApp);
|
|
88
|
+
await tick();
|
|
89
|
+
|
|
90
|
+
const scrollView = fabric.find(node => node.viewName === 'RCTScrollView');
|
|
91
|
+
expect(scrollView?.props.overflow).toBe('scroll');
|
|
92
|
+
expect(scrollView?.props.flexDirection).toBe('column');
|
|
93
|
+
});
|
|
94
|
+
|
|
78
95
|
it('lets an explicit nestedScrollEnabled in animatedProps override the default', async () => {
|
|
79
96
|
mount(OVERRIDE_ROOT_TAG, AnimatedScrollViewOverrideApp);
|
|
80
97
|
await tick();
|
|
@@ -32,17 +32,14 @@ import {
|
|
|
32
32
|
type Type,
|
|
33
33
|
} from '@angular/core';
|
|
34
34
|
import {
|
|
35
|
-
AnimatedProps,
|
|
36
|
-
attachNativeEventHandler,
|
|
37
|
-
dlog,
|
|
38
35
|
isNativeAnimatedAvailable,
|
|
39
36
|
isSymbioteNode,
|
|
40
37
|
reduceProps,
|
|
41
38
|
readPassthroughStyle,
|
|
42
39
|
resolveHostNode,
|
|
43
|
-
whenCommitted,
|
|
44
40
|
type ISymbioteNode,
|
|
45
41
|
} from '@symbiote-native/engine';
|
|
42
|
+
import { selectScrollIntrinsics } from '@symbiote-native/components';
|
|
46
43
|
import { Image, ScrollView, Text, View } from '../../components';
|
|
47
44
|
import {
|
|
48
45
|
anchorHostStyle,
|
|
@@ -60,6 +57,7 @@ import {
|
|
|
60
57
|
resolveImageProps,
|
|
61
58
|
} from '../../components/image/shared';
|
|
62
59
|
import { SectionList } from '../../components/section-list';
|
|
60
|
+
import { AnimatedLeafBinder } from './animated-leaf-binder';
|
|
63
61
|
|
|
64
62
|
// RN's prop carrying explicit (already-rasterized) values that override the animated prop in
|
|
65
63
|
// the COMMITTED props (sticky-header passthrough). Named once so the directive input and the
|
|
@@ -96,12 +94,14 @@ export abstract class AnimatedComponentBase implements AfterViewInit, OnChanges,
|
|
|
96
94
|
// the leaf binds to. Inherited by the decorated subclass (Angular collects base-class queries).
|
|
97
95
|
@ViewChild(SymbioteHostPropsDirective) private hostDirective?: SymbioteHostPropsDirective;
|
|
98
96
|
|
|
99
|
-
// The leaf
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
// The leaf-lifecycle orchestration (build/attach/swap/bind/detach an AnimatedProps leaf) is a
|
|
98
|
+
// Pure Fabrication shared with AnimatedImage, which cannot extend this class (it must extend
|
|
99
|
+
// ImageBase — see the file header). `resolveNode` stays a resolver, not a captured node: the
|
|
100
|
+
// committed node only exists after `hostDirective` is populated post-view-init.
|
|
101
|
+
private readonly leafBinder = new AnimatedLeafBinder(
|
|
102
|
+
() => this.hostNode(),
|
|
103
|
+
this.constructor.name,
|
|
104
|
+
);
|
|
105
105
|
// Set once the view (and the inner host directive) exists; ngOnChanges before then is a no-op.
|
|
106
106
|
private viewReady = false;
|
|
107
107
|
|
|
@@ -129,78 +129,22 @@ export abstract class AnimatedComponentBase implements AfterViewInit, OnChanges,
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
ngOnDestroy(): void {
|
|
132
|
-
this.
|
|
133
|
-
this.cancelBind = undefined;
|
|
134
|
-
this.detachEvents();
|
|
135
|
-
if (this.attached !== null) {
|
|
136
|
-
this.attached.__detach();
|
|
137
|
-
this.attached = null;
|
|
138
|
-
}
|
|
132
|
+
this.leafBinder.destroy();
|
|
139
133
|
}
|
|
140
134
|
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
// committed node, go native if wanted, and rebind native events.
|
|
135
|
+
// A non-stable [animatedProps]/[style] input (a fresh object literal in the template) pushes
|
|
136
|
+
// a new reference on every change-detection pass of the HOST view, re-triggering this on every
|
|
137
|
+
// unrelated interaction elsewhere in the app — DEBUG=1 turns this into a visible tick count in
|
|
138
|
+
// AnimatedLeafBinder.reconcile, so an unexpectedly high rate for a component nobody is
|
|
139
|
+
// animating is the tell (see AnimatedScrollView's stable-reference fix in examples/angular/App.ts).
|
|
147
140
|
private reconcile(): void {
|
|
148
141
|
if (!this.viewReady) return;
|
|
149
|
-
// A non-stable [animatedProps]/[style] input (a fresh object literal in the template)
|
|
150
|
-
// pushes a new reference on every change-detection pass of the HOST view, re-triggering
|
|
151
|
-
// this on every unrelated interaction elsewhere in the app — DEBUG=1 turns this into a
|
|
152
|
-
// visible tick count, so an unexpectedly high rate for a component nobody is animating
|
|
153
|
-
// is the tell (see AnimatedScrollView's stable-reference fix in examples/angular/App.ts).
|
|
154
|
-
dlog(`AnimatedComponentBase reconcile (${this.constructor.name})`);
|
|
155
142
|
const props = this.mergedProps();
|
|
156
143
|
const hasPassthroughAnimatedValues =
|
|
157
144
|
this.passthroughAnimatedPropExplicitValues !== null &&
|
|
158
145
|
this.passthroughAnimatedPropExplicitValues !== undefined;
|
|
159
146
|
const wantsNative = hasPassthroughAnimatedValues && isNativeAnimatedAvailable();
|
|
160
|
-
|
|
161
|
-
const newLeaf = new AnimatedProps(props);
|
|
162
|
-
newLeaf.__attach();
|
|
163
|
-
if (this.attached !== null && this.attached !== newLeaf) this.attached.__detach();
|
|
164
|
-
this.attached = newLeaf;
|
|
165
|
-
|
|
166
|
-
this.bindNode(newLeaf, props, wantsNative);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Bind the leaf to the host's Fabric node THROUGH whenCommitted: under Angular's zoneless
|
|
170
|
-
// batched change detection the inner host's tag does not exist yet at ngAfterViewInit time
|
|
171
|
-
// (the same async-commit gotcha Vue documents), so binding eagerly would no-op. whenCommitted
|
|
172
|
-
// runs the action now if already committed, else after the commit that assigns the tag.
|
|
173
|
-
private bindNode(
|
|
174
|
-
leaf: AnimatedProps,
|
|
175
|
-
props: Record<string, unknown>,
|
|
176
|
-
wantsNative: boolean,
|
|
177
|
-
): void {
|
|
178
|
-
this.cancelBind?.();
|
|
179
|
-
this.cancelBind = undefined;
|
|
180
|
-
const node = this.hostNode();
|
|
181
|
-
if (node === null) return;
|
|
182
|
-
this.cancelBind = whenCommitted(node, () => {
|
|
183
|
-
leaf.setNativeView(node);
|
|
184
|
-
if (wantsNative) leaf.__makeNative();
|
|
185
|
-
this.attachEvents(node, props);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Native-attach any Animated.event prop (e.g. onScroll={Animated.event(…,{useNativeDriver:true})})
|
|
190
|
-
// to the committed node. attachNativeEventHandler no-ops (returns undefined) unless the prop is a
|
|
191
|
-
// native event handler with a committed tag, so the JS path stays the fallback. Rebound each
|
|
192
|
-
// reconcile so a new inline event re-attaches; detached first to avoid leaking the prior binding.
|
|
193
|
-
private attachEvents(node: ISymbioteNode, props: Record<string, unknown>): void {
|
|
194
|
-
this.detachEvents();
|
|
195
|
-
for (const key of Object.keys(props)) {
|
|
196
|
-
const attachment = attachNativeEventHandler(node, key, props[key]);
|
|
197
|
-
if (attachment !== undefined) this.eventDetachers.push(attachment.detach);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private detachEvents(): void {
|
|
202
|
-
for (const detach of this.eventDetachers) detach();
|
|
203
|
-
this.eventDetachers = [];
|
|
147
|
+
this.leafBinder.reconcile(props, wantsNative);
|
|
204
148
|
}
|
|
205
149
|
|
|
206
150
|
// Merge the dedicated `style` input over the generic `animatedProps` bag into one props map —
|
|
@@ -286,9 +230,13 @@ export class AnimatedImage extends ImageBase implements AfterViewInit, OnChanges
|
|
|
286
230
|
|
|
287
231
|
@ViewChild(SymbioteHostPropsDirective) private hostDirective?: SymbioteHostPropsDirective;
|
|
288
232
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
233
|
+
// Same Pure Fabrication AnimatedComponentBase holds — see its matching comment. AnimatedImage
|
|
234
|
+
// can't extend AnimatedComponentBase (it must extend ImageBase, see the file header), so it
|
|
235
|
+
// gets the leaf-lifecycle via composition instead of duplicating it.
|
|
236
|
+
private readonly leafBinder = new AnimatedLeafBinder(
|
|
237
|
+
() => this.hostNode(),
|
|
238
|
+
this.constructor.name,
|
|
239
|
+
);
|
|
292
240
|
private viewReady = false;
|
|
293
241
|
|
|
294
242
|
get animatedImageProps(): Record<string, unknown> {
|
|
@@ -313,13 +261,7 @@ export class AnimatedImage extends ImageBase implements AfterViewInit, OnChanges
|
|
|
313
261
|
}
|
|
314
262
|
|
|
315
263
|
ngOnDestroy(): void {
|
|
316
|
-
this.
|
|
317
|
-
this.cancelBind = undefined;
|
|
318
|
-
this.detachEvents();
|
|
319
|
-
if (this.attached !== null) {
|
|
320
|
-
this.attached.__detach();
|
|
321
|
-
this.attached = null;
|
|
322
|
-
}
|
|
264
|
+
this.leafBinder.destroy();
|
|
323
265
|
}
|
|
324
266
|
|
|
325
267
|
private reconcile(): void {
|
|
@@ -329,42 +271,7 @@ export class AnimatedImage extends ImageBase implements AfterViewInit, OnChanges
|
|
|
329
271
|
this.passthroughAnimatedPropExplicitValues !== null &&
|
|
330
272
|
this.passthroughAnimatedPropExplicitValues !== undefined;
|
|
331
273
|
const wantsNative = hasPassthroughAnimatedValues && isNativeAnimatedAvailable();
|
|
332
|
-
|
|
333
|
-
const newLeaf = new AnimatedProps(props);
|
|
334
|
-
newLeaf.__attach();
|
|
335
|
-
if (this.attached !== null && this.attached !== newLeaf) this.attached.__detach();
|
|
336
|
-
this.attached = newLeaf;
|
|
337
|
-
|
|
338
|
-
this.bindNode(newLeaf, props, wantsNative);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
private bindNode(
|
|
342
|
-
leaf: AnimatedProps,
|
|
343
|
-
props: Record<string, unknown>,
|
|
344
|
-
wantsNative: boolean,
|
|
345
|
-
): void {
|
|
346
|
-
this.cancelBind?.();
|
|
347
|
-
this.cancelBind = undefined;
|
|
348
|
-
const node = this.hostNode();
|
|
349
|
-
if (node === null) return;
|
|
350
|
-
this.cancelBind = whenCommitted(node, () => {
|
|
351
|
-
leaf.setNativeView(node);
|
|
352
|
-
if (wantsNative) leaf.__makeNative();
|
|
353
|
-
this.attachEvents(node, props);
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
private attachEvents(node: ISymbioteNode, props: Record<string, unknown>): void {
|
|
358
|
-
this.detachEvents();
|
|
359
|
-
for (const key of Object.keys(props)) {
|
|
360
|
-
const attachment = attachNativeEventHandler(node, key, props[key]);
|
|
361
|
-
if (attachment !== undefined) this.eventDetachers.push(attachment.detach);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
private detachEvents(): void {
|
|
366
|
-
for (const detach of this.eventDetachers) detach();
|
|
367
|
-
this.eventDetachers = [];
|
|
274
|
+
this.leafBinder.reconcile(props, wantsNative);
|
|
368
275
|
}
|
|
369
276
|
|
|
370
277
|
private mergedProps(): Record<string, unknown> {
|
|
@@ -389,7 +296,7 @@ export class AnimatedImage extends ImageBase implements AfterViewInit, OnChanges
|
|
|
389
296
|
inputs: ANIMATED_INPUTS,
|
|
390
297
|
template: `
|
|
391
298
|
<symbiote-scroll-view [symbioteHostProps]="reducedProps">
|
|
392
|
-
<symbiote-scroll-content [
|
|
299
|
+
<symbiote-scroll-content [symbioteHostProps]="contentProps">
|
|
393
300
|
<ng-content></ng-content>
|
|
394
301
|
</symbiote-scroll-content>
|
|
395
302
|
</symbiote-scroll-view>
|
|
@@ -402,11 +309,34 @@ export class AnimatedScrollView extends AnimatedComponentBase {
|
|
|
402
309
|
// receives touch (swallowed by the outer scroll view; iOS doesn't gate on this). The real
|
|
403
310
|
// ScrollView component already defaults this (scroll-view/shared.ts), but AnimatedScrollView
|
|
404
311
|
// talks to the raw primitive directly and has no such defaulting, so it must apply it too.
|
|
312
|
+
//
|
|
313
|
+
// scrollViewBaseStyle (overflow: 'scroll' + the per-axis flexDirection) is the OTHER thing
|
|
314
|
+
// the real ScrollView applies that this bespoke template used to skip entirely — without it,
|
|
315
|
+
// iOS Fabric never clips the scroll view's content to its own frame (Android's native
|
|
316
|
+
// ViewGroup clips regardless of the style prop, which is why this was invisible there). This
|
|
317
|
+
// wrapper has no dedicated `horizontal` input (only the generic `animatedProps`/`style`
|
|
318
|
+
// surface), and its template is hardcoded to the vertical intrinsics
|
|
319
|
+
// (symbiote-scroll-view/symbiote-scroll-content, not the horizontal variants), so
|
|
320
|
+
// selectScrollIntrinsics is always called with isHorizontal=false here — matching what the
|
|
321
|
+
// template can actually render.
|
|
405
322
|
override get reducedProps(): Record<string, unknown> {
|
|
406
323
|
const reduced = super.reducedProps;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
324
|
+
const { scrollViewBaseStyle } = selectScrollIntrinsics(false, undefined);
|
|
325
|
+
const withScrollBase: Record<string, unknown> = {
|
|
326
|
+
...reduced,
|
|
327
|
+
style: [scrollViewBaseStyle, reduced.style],
|
|
328
|
+
};
|
|
329
|
+
return withScrollBase.nestedScrollEnabled === undefined
|
|
330
|
+
? { ...withScrollBase, nestedScrollEnabled: true }
|
|
331
|
+
: withScrollBase;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// The content (inner) view's props: contentStyle from the same intrinsics selection, plus
|
|
335
|
+
// `collapsable: false` (the Android multi-child fix this file's tests already cover) — mirrors
|
|
336
|
+
// the real ScrollView's own `contentProps` getter (scroll-view/shared.ts).
|
|
337
|
+
get contentProps(): Record<string, unknown> {
|
|
338
|
+
const { contentStyle } = selectScrollIntrinsics(false, undefined);
|
|
339
|
+
return { style: contentStyle, collapsable: false };
|
|
410
340
|
}
|
|
411
341
|
}
|
|
412
342
|
|
|
@@ -4,8 +4,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
4
4
|
import * as engine from '@symbiote-native/engine';
|
|
5
5
|
import { installFabric } from '@symbiote-native/test-utils';
|
|
6
6
|
|
|
7
|
-
import { mount, unmount } from '
|
|
8
|
-
import { StatusBar } from './
|
|
7
|
+
import { mount, unmount } from '../../render';
|
|
8
|
+
import { StatusBar } from './index';
|
|
9
9
|
|
|
10
10
|
const ROOT_TAG = 901;
|
|
11
11
|
const fabric = installFabric();
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
createComponent,
|
|
22
22
|
createEnvironmentInjector,
|
|
23
23
|
DOCUMENT,
|
|
24
|
+
ErrorHandler,
|
|
24
25
|
RendererFactory2,
|
|
25
26
|
ɵINJECTOR_SCOPE as INJECTOR_SCOPE,
|
|
26
27
|
ɵprovideZonelessChangeDetectionInternal as provideZonelessChangeDetectionInternal,
|
|
@@ -28,8 +29,8 @@ import {
|
|
|
28
29
|
type EnvironmentInjector,
|
|
29
30
|
type Type,
|
|
30
31
|
} from '@angular/core';
|
|
31
|
-
import { SymbioteRendererFactory } from '
|
|
32
|
-
import { ColorSchemeService, WindowDimensionsService } from '
|
|
32
|
+
import { SymbioteRendererFactory } from '../renderer';
|
|
33
|
+
import { ColorSchemeService, WindowDimensionsService } from '../services';
|
|
33
34
|
|
|
34
35
|
// The two FFI-edge casts of this adapter, both confined here to bootstrap. Angular's core
|
|
35
36
|
// types model a browser: the injector parent is a non-null EnvironmentInjector, the host is
|
|
@@ -145,6 +146,17 @@ export function mount(
|
|
|
145
146
|
// `@Component` boundary — SignalView-compiled children are skip-eligible regardless of
|
|
146
147
|
// this scheduler.
|
|
147
148
|
...provideZonelessChangeDetectionInternal(),
|
|
149
|
+
// Angular's own INTERNAL_APPLICATION_ERROR_HANDLER (core.mjs) reports a tick()
|
|
150
|
+
// exception by calling `injector.get(ErrorHandler)` — a normal `bootstrapApplication`
|
|
151
|
+
// registers this token by default (platform-browser's BROWSER_MODULE_PROVIDERS), but
|
|
152
|
+
// our from-scratch environment injector never did, so that lookup itself threw
|
|
153
|
+
// NG0201 and REPLACED whatever the real error was with an unrelated "No provider
|
|
154
|
+
// found for ErrorHandler" — the real exception never got logged, and the NG0201 itself
|
|
155
|
+
// propagated out of a bare Timeout callback uncaught (nothing above it in the stack to
|
|
156
|
+
// catch it), i.e. any async tick() exception, anywhere in the app, crashed hard instead
|
|
157
|
+
// of being reported. Providing the default `ErrorHandler` (same one bootstrapApplication
|
|
158
|
+
// ships) restores the intended behavior: `console.error('ERROR', e)` and keep running.
|
|
159
|
+
{ provide: ErrorHandler, useClass: ErrorHandler },
|
|
148
160
|
ColorSchemeService,
|
|
149
161
|
WindowDimensionsService,
|
|
150
162
|
],
|
|
@@ -7,7 +7,7 @@ import '@angular/compiler';
|
|
|
7
7
|
import { Component } from '@angular/core';
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
9
9
|
import { installFabric } from '@symbiote-native/test-utils';
|
|
10
|
-
import { mount, unmount } from './
|
|
10
|
+
import { mount, unmount } from './index';
|
|
11
11
|
|
|
12
12
|
const ROOT_TAG = 808;
|
|
13
13
|
|
|
@@ -29,7 +29,7 @@ import type { Renderer2, RendererFactory2, RendererType2 } from '@angular/core';
|
|
|
29
29
|
import {
|
|
30
30
|
getScrollViewProjection,
|
|
31
31
|
removeScrollViewProjectedChild,
|
|
32
|
-
} from '
|
|
32
|
+
} from '../components/scroll-view/projection';
|
|
33
33
|
|
|
34
34
|
// Angular host nodes are all SymbioteNode (elements, raw text, anchors). The mount
|
|
35
35
|
// container is the surface, so a parent can be either a node or the surface root.
|
|
@@ -80,64 +80,64 @@ const PRIMITIVE_SELECTOR_ALIAS: Record<string, string> = {
|
|
|
80
80
|
// anchor host (see the set comment below). Tests register their own child-component selectors
|
|
81
81
|
// through this at module load; app-authored composed components can too.
|
|
82
82
|
export function registerComposedComponent(selector: string): void {
|
|
83
|
-
ANCHOR_HOST_COMPONENTS.add(selector);
|
|
83
|
+
ANCHOR_HOST_COMPONENTS.add(selector.toLowerCase());
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
86
|
+
// Lowercased at construction — createElement's lookup and registerComposedComponent's insert
|
|
87
|
+
// both normalize to lowercase (Angular lowercases a dynamically-mounted component's selector at
|
|
88
|
+
// runtime, see §11a), so the literal entries below must match that or every capitalized one
|
|
89
|
+
// (all but the handful already written lowercase) silently never matches .has() and falls
|
|
90
|
+
// through to a real Fabric createNode — the exact "Unimplemented component" / extra-wrapper-node
|
|
91
|
+
// bug this Set exists to prevent.
|
|
92
|
+
const ANCHOR_HOST_COMPONENTS: Set<string> = new Set(
|
|
93
|
+
[
|
|
94
|
+
// Composed Angular components render their real Fabric descriptor tree from the template;
|
|
95
|
+
// their Angular host element is only a framework bookkeeping node and must not paint. This
|
|
96
|
+
// is NOT limited to adapter-authored components — ANY custom composed @Component used as a
|
|
97
|
+
// plain <Tag> inside another template needs its selector listed here too, or Angular's
|
|
98
|
+
// automatic host-element creation for it falls through to a raw Fabric createNode call with
|
|
99
|
+
// an unrecognized view name, which paints RN's own "Unimplemented component: <Tag>" fallback
|
|
100
|
+
// view instead (a real device-visible bug, not a silent no-op). This Set holds only
|
|
101
|
+
// adapter/engine-owned selectors; app code and third-party packages self-register their own
|
|
102
|
+
// composed components through registerComposedComponent instead of being hardcoded here.
|
|
103
|
+
'ActivityIndicator',
|
|
104
|
+
'Button',
|
|
105
|
+
'FlatList',
|
|
106
|
+
'AnimatedView',
|
|
107
|
+
'symbiote-animated-view',
|
|
108
|
+
'AnimatedText',
|
|
109
|
+
'symbiote-animated-text',
|
|
110
|
+
'AnimatedImage',
|
|
111
|
+
'symbiote-animated-image',
|
|
112
|
+
'AnimatedScrollView',
|
|
113
|
+
'symbiote-animated-scroll-view',
|
|
114
|
+
'symbiote-descriptor-outlet',
|
|
115
|
+
'tunnel-out',
|
|
116
|
+
'Image',
|
|
117
|
+
'ImageBackground',
|
|
118
|
+
'InputAccessoryView',
|
|
119
|
+
'KeyboardAvoidingView',
|
|
120
|
+
'Modal',
|
|
121
|
+
'Pressable',
|
|
122
|
+
'RefreshControl',
|
|
123
|
+
'SafeAreaView',
|
|
124
|
+
'ScrollView',
|
|
125
|
+
'ScrollViewStickyHeader',
|
|
126
|
+
'SectionList',
|
|
127
|
+
'symbiote-sticky-header',
|
|
128
|
+
'StatusBar',
|
|
129
|
+
'Switch',
|
|
130
|
+
'Text',
|
|
131
|
+
'TextInput',
|
|
132
|
+
'TouchableHighlight',
|
|
133
|
+
'TouchableNativeFeedback',
|
|
134
|
+
'TouchableOpacity',
|
|
135
|
+
'TouchableWithoutFeedback',
|
|
136
|
+
'VirtualizedList',
|
|
137
|
+
'VirtualizedSectionList',
|
|
138
|
+
'symbiote-pressable',
|
|
139
|
+
].map(selector => selector.toLowerCase()),
|
|
140
|
+
);
|
|
141
141
|
|
|
142
142
|
// Inserting a bare raw-text node anywhere but inside a <Text> is invalid in Fabric (a
|
|
143
143
|
// stray RCTRawText would paint). Angular's ɵɵtext only ever lands text inside a <Text>,
|
|
@@ -170,7 +170,7 @@ export class SymbioteRenderer implements Renderer2 {
|
|
|
170
170
|
// ViewConfig). toPublicInstance grafts the imperative API (measure / setNativeProps /
|
|
171
171
|
// focus) onto the raw node in place, returning the SAME identity the commit mirror keys on.
|
|
172
172
|
const engineName = PRIMITIVE_SELECTOR_ALIAS[name] ?? name;
|
|
173
|
-
if (ANCHOR_HOST_COMPONENTS.has(engineName)) {
|
|
173
|
+
if (ANCHOR_HOST_COMPONENTS.has(engineName.toLowerCase())) {
|
|
174
174
|
const anchor = tagAnchorForDebug(createAnchor());
|
|
175
175
|
dlog(`angular createElement ${name} -> anchor host ${describeHost(anchor)}`);
|
|
176
176
|
return anchor;
|
|
@@ -9,11 +9,12 @@ import {
|
|
|
9
9
|
clearGlobalStyles,
|
|
10
10
|
createSurface,
|
|
11
11
|
disposeRoot,
|
|
12
|
+
isAnchor,
|
|
12
13
|
isSymbioteNode,
|
|
13
14
|
registerStyles,
|
|
14
15
|
} from '@symbiote-native/engine';
|
|
15
16
|
import { installFabric } from '@symbiote-native/test-utils';
|
|
16
|
-
import { SymbioteRenderer, SymbioteRendererFactory } from './
|
|
17
|
+
import { registerComposedComponent, SymbioteRenderer, SymbioteRendererFactory } from './index';
|
|
17
18
|
|
|
18
19
|
const ROOT_TAG = 707;
|
|
19
20
|
const PROBE_ID = 'probe';
|
|
@@ -176,4 +177,26 @@ describe('Angular SymbioteRenderer drives the engine', () => {
|
|
|
176
177
|
const { renderer } = setup();
|
|
177
178
|
expect(() => renderer.listen('window', 'resize', () => {})()).not.toThrow();
|
|
178
179
|
});
|
|
180
|
+
|
|
181
|
+
// App/third-party selectors must not be hardcoded into ANCHOR_HOST_COMPONENTS — the owning
|
|
182
|
+
// package registers itself via registerComposedComponent, same as an adapter-owned composed
|
|
183
|
+
// component. 'RefApiDemo' names examples/angular's demo component; this test never imports
|
|
184
|
+
// it, it only proves the renderer treats an unregistered selector as a raw Fabric view name,
|
|
185
|
+
// not a hardcoded anchor host. MUST run before the registration test below, since
|
|
186
|
+
// registerComposedComponent mutates the module-level Set for the rest of the file.
|
|
187
|
+
it('does not anchor-host an app-owned selector unless it self-registers', () => {
|
|
188
|
+
const { renderer } = setup();
|
|
189
|
+
const node = renderer.createElement('RefApiDemo');
|
|
190
|
+
if (!isSymbioteNode(node)) throw new Error('unreachable: createElement returns a node');
|
|
191
|
+
expect(isAnchor(node), 'falls through to a raw Fabric view, not an anchor').toBe(false);
|
|
192
|
+
expect(node.component).toBe('RefApiDemo');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('anchor-hosts an app-owned selector once it self-registers via registerComposedComponent', () => {
|
|
196
|
+
registerComposedComponent('RefApiDemo');
|
|
197
|
+
const { renderer } = setup();
|
|
198
|
+
const node = renderer.createElement('RefApiDemo');
|
|
199
|
+
if (!isSymbioteNode(node)) throw new Error('unreachable: createElement returns a node');
|
|
200
|
+
expect(isAnchor(node)).toBe(true);
|
|
201
|
+
});
|
|
179
202
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input-accessory-view.js","sourceRoot":"","sources":["../../../src/components/input-accessory-view.ts"],"names":[],"mappings":"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"}
|