@symbiote-native/angular 0.6.1 → 0.7.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 +1 -1
- package/bin/symbiote-angular-dev.cjs +20 -19
- package/build/angular/anchor-host-registry.js +2 -2
- package/build/angular/anchor-host-registry.js.map +1 -1
- package/build/angular/components/activity-indicator/index.android.d.ts +2 -1
- package/build/angular/components/activity-indicator/index.android.js +6 -3
- package/build/angular/components/activity-indicator/index.android.js.map +1 -1
- package/build/angular/components/activity-indicator/index.ios.d.ts +2 -1
- package/build/angular/components/activity-indicator/index.ios.js +6 -3
- package/build/angular/components/activity-indicator/index.ios.js.map +1 -1
- package/build/angular/components/activity-indicator/shared.js +3 -3
- package/build/angular/components/button.d.ts +4 -2
- package/build/angular/components/button.js +28 -17
- package/build/angular/components/button.js.map +1 -1
- package/build/angular/components/flat-list/index.d.ts +5 -3
- package/build/angular/components/flat-list/index.js +35 -38
- package/build/angular/components/flat-list/index.js.map +1 -1
- package/build/angular/components/image/index.android.d.ts +8 -3
- package/build/angular/components/image/index.android.js +39 -9
- package/build/angular/components/image/index.android.js.map +1 -1
- package/build/angular/components/image/index.ios.d.ts +8 -3
- package/build/angular/components/image/index.ios.js +39 -9
- package/build/angular/components/image/index.ios.js.map +1 -1
- package/build/angular/components/image/shared.d.ts +4 -1
- package/build/angular/components/image/shared.js +33 -2
- package/build/angular/components/image/shared.js.map +1 -1
- package/build/angular/components/image-background.d.ts +2 -1
- package/build/angular/components/image-background.js +6 -4
- package/build/angular/components/image-background.js.map +1 -1
- package/build/angular/components/input-accessory-view/index.d.ts +9 -4
- package/build/angular/components/input-accessory-view/index.js +43 -9
- package/build/angular/components/input-accessory-view/index.js.map +1 -1
- package/build/angular/components/keyboard-avoiding-view/index.d.ts +2 -1
- package/build/angular/components/keyboard-avoiding-view/index.js +6 -4
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
- package/build/angular/components/modal/index.d.ts +11 -8
- package/build/angular/components/modal/index.js +45 -28
- package/build/angular/components/modal/index.js.map +1 -1
- package/build/angular/components/pressable/index.d.ts +11 -5
- package/build/angular/components/pressable/index.js +61 -12
- package/build/angular/components/pressable/index.js.map +1 -1
- package/build/angular/components/refresh-control/index.d.ts +8 -4
- package/build/angular/components/refresh-control/index.js +52 -16
- package/build/angular/components/refresh-control/index.js.map +1 -1
- package/build/angular/components/safe-area-view/index.d.ts +9 -4
- package/build/angular/components/safe-area-view/index.js +46 -9
- package/build/angular/components/safe-area-view/index.js.map +1 -1
- package/build/angular/components/scroll-view/index.android.d.ts +2 -3
- package/build/angular/components/scroll-view/index.android.js +49 -52
- package/build/angular/components/scroll-view/index.android.js.map +1 -1
- package/build/angular/components/scroll-view/index.ios.d.ts +2 -3
- package/build/angular/components/scroll-view/index.ios.js +15 -17
- package/build/angular/components/scroll-view/index.ios.js.map +1 -1
- package/build/angular/components/scroll-view/projection.d.ts +3 -0
- package/build/angular/components/scroll-view/projection.js +68 -7
- package/build/angular/components/scroll-view/projection.js.map +1 -1
- package/build/angular/components/scroll-view/shared.d.ts +14 -5
- package/build/angular/components/scroll-view/shared.js +198 -69
- package/build/angular/components/scroll-view/shared.js.map +1 -1
- package/build/angular/components/scroll-view/sticky-header.js +14 -19
- package/build/angular/components/scroll-view/sticky-header.js.map +1 -1
- package/build/angular/components/section-list/index.d.ts +2 -1
- package/build/angular/components/section-list/index.js +31 -39
- package/build/angular/components/section-list/index.js.map +1 -1
- package/build/angular/components/switch/index.android.d.ts +7 -3
- package/build/angular/components/switch/index.android.js +38 -10
- package/build/angular/components/switch/index.android.js.map +1 -1
- package/build/angular/components/switch/index.ios.d.ts +7 -3
- package/build/angular/components/switch/index.ios.js +38 -10
- package/build/angular/components/switch/index.ios.js.map +1 -1
- package/build/angular/components/switch/shared.d.ts +12 -3
- package/build/angular/components/switch/shared.js +66 -5
- package/build/angular/components/switch/shared.js.map +1 -1
- package/build/angular/components/text-input.d.ts +10 -2
- package/build/angular/components/text-input.js +46 -6
- package/build/angular/components/text-input.js.map +1 -1
- package/build/angular/components/touchable/index.d.ts +17 -8
- package/build/angular/components/touchable/index.js +78 -19
- package/build/angular/components/touchable/index.js.map +1 -1
- package/build/angular/components/touchable-native-feedback/index.d.ts +6 -3
- package/build/angular/components/touchable-native-feedback/index.js +61 -25
- package/build/angular/components/touchable-native-feedback/index.js.map +1 -1
- package/build/angular/components/virtualized-list/directives.js +18 -18
- package/build/angular/components/virtualized-list/index.d.ts +12 -4
- package/build/angular/components/virtualized-list/index.js +163 -68
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/directives.js +12 -12
- package/build/angular/components/virtualized-section-list/index.d.ts +2 -1
- package/build/angular/components/virtualized-section-list/index.js +6 -4
- package/build/angular/components/virtualized-section-list/index.js.map +1 -1
- package/build/angular/components.d.ts +1 -1
- package/build/angular/components.js +5 -0
- package/build/angular/components.js.map +1 -1
- package/build/angular/create-portal/index.js +29 -35
- package/build/angular/create-portal/index.js.map +1 -1
- package/build/angular/create-tunnel/index.js +19 -22
- package/build/angular/create-tunnel/index.js.map +1 -1
- package/build/angular/descriptor-to-angular/index.js +3 -3
- package/build/angular/index.d.ts +4 -2
- package/build/angular/index.js +2 -2
- package/build/angular/index.js.map +1 -1
- package/build/angular/modules/animated/animated-leaf-binder.d.ts +1 -7
- package/build/angular/modules/animated/animated-leaf-binder.js +22 -72
- package/build/angular/modules/animated/animated-leaf-binder.js.map +1 -1
- package/build/angular/modules/animated/create-animated-component.d.ts +11 -6
- package/build/angular/modules/animated/create-animated-component.js +83 -50
- package/build/angular/modules/animated/create-animated-component.js.map +1 -1
- package/build/angular/modules/app-registry/index.js.map +1 -1
- package/build/angular/modules/status-bar/index.js +3 -3
- package/build/angular/primitives/index.d.ts +1 -1
- package/build/angular/primitives/index.js +46 -46
- package/build/angular/primitives/index.js.map +1 -1
- package/build/angular/primitives/shared.d.ts +39 -1
- package/build/angular/primitives/shared.js +110 -9
- package/build/angular/primitives/shared.js.map +1 -1
- package/build/angular/render/index.js +23 -35
- package/build/angular/render/index.js.map +1 -1
- package/build/angular/services/color-scheme.service.js +3 -3
- package/build/angular/services/window-dimensions.service.js +3 -3
- package/package.json +13 -8
- package/src/anchor-host-registry.ts +2 -2
- package/src/components/activity-indicator/index.android.ts +2 -0
- package/src/components/activity-indicator/index.ios.ts +2 -0
- package/src/components/button.ts +28 -14
- package/src/components/flat-list/index.ts +34 -36
- package/src/components/image/index.android.ts +50 -6
- package/src/components/image/index.ios.ts +50 -6
- package/src/components/image/shared.ts +34 -2
- package/src/components/image-background.ts +2 -1
- package/src/components/input-accessory-view/index.ts +42 -4
- package/src/components/keyboard-avoiding-view/index.ts +7 -1
- package/src/components/modal/index.ts +51 -26
- package/src/components/pressable/index.ts +67 -8
- package/src/components/refresh-control/index.ts +54 -12
- package/src/components/safe-area-view/index.ts +50 -5
- package/src/components/scroll-view/index.android.ts +34 -41
- package/src/components/scroll-view/index.ios.ts +10 -21
- package/src/components/scroll-view/projection.ts +79 -7
- package/src/components/scroll-view/shared.ts +223 -68
- package/src/components/scroll-view/sticky-header.ts +11 -16
- package/src/components/section-list/index.ts +27 -36
- package/src/components/switch/index.android.ts +48 -7
- package/src/components/switch/index.ios.ts +48 -7
- package/src/components/switch/shared.ts +79 -3
- package/src/components/text-input.ts +52 -2
- package/src/components/touchable/index.ts +76 -16
- package/src/components/touchable-native-feedback/index.ts +62 -21
- package/src/components/virtualized-list/index.ts +137 -44
- package/src/components/virtualized-section-list/index.ts +2 -1
- package/src/components.ts +5 -0
- package/src/create-portal/index.ts +23 -29
- package/src/create-tunnel/index.ts +13 -16
- package/src/index.ts +30 -1
- package/src/modules/animated/animated-leaf-binder.ts +28 -77
- package/src/modules/animated/create-animated-component.ts +75 -36
- package/src/modules/app-registry/index.ts +6 -8
- package/src/primitives/index.ts +1 -0
- package/src/primitives/shared.ts +102 -3
- package/src/render/index.ts +23 -35
- package/build/angular/modules/animated/animated-leaf-binder/index.d.ts +0 -14
- package/build/angular/modules/animated/animated-leaf-binder/index.js +0 -91
- package/build/angular/modules/animated/animated-leaf-binder/index.js.map +0 -1
- package/src/__tests__/responder-change-detection.test.ts +0 -102
- package/src/__tests__/responder-nested-cd.test.ts +0 -113
- package/src/angular-gaps.test.ts +0 -142
- package/src/angular-imports.test.ts +0 -100
- package/src/components/activity-indicator/activity-indicator-class-style.test.ts +0 -44
- package/src/components/activity-indicator/activity-indicator.test.ts +0 -131
- package/src/components/flat-list/column-wrapper-style-class.test.ts +0 -116
- package/src/components/flat-list/flat-list-array-style.test.ts +0 -131
- package/src/components/flat-list/flat-list-class-style.test.ts +0 -74
- package/src/components/flat-list/flat-list-scroll-containment.test.ts +0 -107
- package/src/components/flat-list/flat-list.test.ts +0 -99
- package/src/components/image/image-class-style.test.ts +0 -46
- package/src/components/image-background-class-style.test.ts +0 -48
- package/src/components/image-background-style-class.test.ts +0 -79
- package/src/components/input-accessory-view/input-accessory-view.test.ts +0 -43
- package/src/components/keyboard-avoiding-view/keyboard-avoiding-view.test.ts +0 -54
- package/src/components/modal/modal.test.ts +0 -43
- package/src/components/pressable/pressable.test.ts +0 -85
- package/src/components/refresh-control/refresh-control.test.ts +0 -41
- package/src/components/safe-area-view/safe-area-view.test.ts +0 -43
- package/src/components/scroll-view/android-scroll-view-axis-projection.test.ts +0 -123
- package/src/components/scroll-view/content-container-style-class.test.ts +0 -75
- package/src/components/scroll-view/scroll-view-class-style.test.ts +0 -134
- package/src/components/scroll-view/scroll-view-projection.test.ts +0 -194
- package/src/components/switch/android-switch-class.test.ts +0 -42
- package/src/components/switch/switch.test.ts +0 -92
- package/src/components/text-input-class-style.test.ts +0 -54
- package/src/components/touchable/touchable.test.ts +0 -102
- package/src/components/touchable-native-feedback/touchable-native-feedback.test.ts +0 -49
- package/src/components/virtualized-list/virtualized-list-class-style.test.ts +0 -76
- package/src/components/virtualized-section-list/virtualized-section-list-class-style.test.ts +0 -60
- package/src/create-portal/create-portal.test.ts +0 -90
- package/src/create-tunnel/create-tunnel.test.ts +0 -120
- package/src/descriptor-to-angular/descriptor-outlet.test.ts +0 -94
- package/src/host-instance/host-instance.test.ts +0 -49
- package/src/modules/animated/animated-leaf-binder/animated-leaf-binder.test.ts +0 -116
- package/src/modules/animated/animated-leaf-binder/index.ts +0 -101
- package/src/modules/animated/animated-leaf-binder.test.ts +0 -116
- package/src/modules/animated/animated-scroll-view.test.ts +0 -102
- package/src/modules/app-registry/app-registry.test.ts +0 -106
- package/src/modules/status-bar/status-bar.test.ts +0 -50
- package/src/render/render.test.ts +0 -147
- package/src/renderer/renderer.test.ts +0 -203
- package/src/services/services.test.ts +0 -163
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
// Regression test for the anchor/class bug: a composed component's own
|
|
2
|
-
// use-site `class="..."` resolves through Angular's addClass/removeClass onto the component's
|
|
3
|
-
// non-painting ANCHOR host (ANCHOR_HOST_COMPONENTS in renderer.ts), never onto the real Fabric
|
|
4
|
-
// node its own template renders — so the resolved style was silently lost. Fixed via
|
|
5
|
-
// anchorHostStyle(this.elementRef) merged into ScrollView's own scrollProps/androidWrappedScrollProps
|
|
6
|
-
// getters (see index.ios.ts / index.android.ts). Mirrors pressable.test.ts's "resolves a class=" case,
|
|
7
|
-
// covering BOTH platforms and the Android refresh-control-wrapped branch (androidWrappedScrollProps
|
|
8
|
-
// is a SEPARATE override from scrollProps, since it recomputes `style` from scratch rather than
|
|
9
|
-
// inheriting the base getter's result).
|
|
10
|
-
import '@angular/compiler';
|
|
11
|
-
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
12
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
13
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
14
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
15
|
-
|
|
16
|
-
import { mount, unmount } from '../../render';
|
|
17
|
-
import { RefreshControl } from '../refresh-control';
|
|
18
|
-
import { ScrollView as AndroidScrollView } from './index.android';
|
|
19
|
-
import { ScrollView as IOSScrollView } from './index.ios';
|
|
20
|
-
|
|
21
|
-
const ROOT_TAG = 950;
|
|
22
|
-
const fabric = installFabric();
|
|
23
|
-
const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
|
|
24
|
-
|
|
25
|
-
@Component({
|
|
26
|
-
selector: 'symbiote-scroll-ios-class-host',
|
|
27
|
-
standalone: true,
|
|
28
|
-
imports: [IOSScrollView],
|
|
29
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
30
|
-
template: `
|
|
31
|
-
<ScrollView class="card">
|
|
32
|
-
<symbiote-view testID="cell"></symbiote-view>
|
|
33
|
-
</ScrollView>
|
|
34
|
-
`,
|
|
35
|
-
})
|
|
36
|
-
class IOSScrollViewClassHost {}
|
|
37
|
-
|
|
38
|
-
@Component({
|
|
39
|
-
selector: 'symbiote-scroll-android-class-host',
|
|
40
|
-
standalone: true,
|
|
41
|
-
imports: [AndroidScrollView],
|
|
42
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
43
|
-
template: `
|
|
44
|
-
<ScrollView class="card">
|
|
45
|
-
<symbiote-view testID="cell"></symbiote-view>
|
|
46
|
-
</ScrollView>
|
|
47
|
-
`,
|
|
48
|
-
})
|
|
49
|
-
class AndroidScrollViewClassHost {}
|
|
50
|
-
|
|
51
|
-
@Component({
|
|
52
|
-
selector: 'symbiote-scroll-android-wrapped-class-host',
|
|
53
|
-
standalone: true,
|
|
54
|
-
imports: [AndroidScrollView, RefreshControl],
|
|
55
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
56
|
-
template: `
|
|
57
|
-
<ScrollView class="card">
|
|
58
|
-
<RefreshControl [refreshing]="true" (refresh)="refresh()" />
|
|
59
|
-
<symbiote-view testID="cell"></symbiote-view>
|
|
60
|
-
</ScrollView>
|
|
61
|
-
`,
|
|
62
|
-
})
|
|
63
|
-
class AndroidWrappedScrollViewClassHost {
|
|
64
|
-
refresh = (): void => undefined;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
@Component({
|
|
68
|
-
selector: 'symbiote-scroll-android-wrapped-layout-class-host',
|
|
69
|
-
standalone: true,
|
|
70
|
-
imports: [AndroidScrollView, RefreshControl],
|
|
71
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
72
|
-
template: `
|
|
73
|
-
<ScrollView class="box">
|
|
74
|
-
<RefreshControl [refreshing]="true" (refresh)="refresh()" />
|
|
75
|
-
<symbiote-view testID="cell"></symbiote-view>
|
|
76
|
-
</ScrollView>
|
|
77
|
-
`,
|
|
78
|
-
})
|
|
79
|
-
class AndroidWrappedScrollViewLayoutClassHost {
|
|
80
|
-
refresh = (): void => undefined;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
beforeEach(() => {
|
|
84
|
-
fabric.reset();
|
|
85
|
-
registerStyles({ card: { backgroundColor: 'red' }, box: { flex: 1, height: 84 } });
|
|
86
|
-
});
|
|
87
|
-
afterEach(() => {
|
|
88
|
-
unmount(ROOT_TAG);
|
|
89
|
-
clearGlobalStyles();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('ScrollView anchor class= resolution', () => {
|
|
93
|
-
it('resolves a class= on the iOS ScrollView use site onto the real committed scroll host', async () => {
|
|
94
|
-
mount(ROOT_TAG, IOSScrollViewClassHost);
|
|
95
|
-
await tick();
|
|
96
|
-
|
|
97
|
-
const node = fabric.find(n => n.props.backgroundColor === 'red');
|
|
98
|
-
expect(node, 'a real Fabric node carries the class-derived style').toBeDefined();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('resolves a class= on the Android ScrollView use site (no refresh control)', async () => {
|
|
102
|
-
mount(ROOT_TAG, AndroidScrollViewClassHost);
|
|
103
|
-
await tick();
|
|
104
|
-
|
|
105
|
-
const node = fabric.find(n => n.props.backgroundColor === 'red');
|
|
106
|
-
expect(node, 'a real Fabric node carries the class-derived style').toBeDefined();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('resolves a class= on the Android ScrollView use site wrapped by a projected RefreshControl', async () => {
|
|
110
|
-
mount(ROOT_TAG, AndroidWrappedScrollViewClassHost);
|
|
111
|
-
await tick();
|
|
112
|
-
|
|
113
|
-
const node = fabric.find(n => n.props.backgroundColor === 'red');
|
|
114
|
-
expect(node, 'a real Fabric node carries the class-derived style').toBeDefined();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Regression for a real device bug distinct from the one above: a class-derived LAYOUT
|
|
118
|
-
// property (flex/height/…) must reach the OUTER refresh-control wrapper via splitLayoutProps,
|
|
119
|
-
// not just the inner scroll view — a class carrying only a color property (the test above)
|
|
120
|
-
// never exercises this split at all, since color is never a layout key. Without
|
|
121
|
-
// `layoutSplitStyle` feeding the anchor's style INTO the split (not tacked on after), the
|
|
122
|
-
// wrapper never receives its flex/height share and collapses to zero size — the whole
|
|
123
|
-
// ScrollView renders nothing on a real Android device. Mirrors the Vue adapter's identical
|
|
124
|
-
// `layoutSplitStyle` fix (same root cause, same symptom).
|
|
125
|
-
it('resolves a class-derived LAYOUT style onto the Android outer refresh-control wrapper', async () => {
|
|
126
|
-
mount(ROOT_TAG, AndroidWrappedScrollViewLayoutClassHost);
|
|
127
|
-
await tick();
|
|
128
|
-
|
|
129
|
-
const wrapper = fabric.find(n => n.props.refreshing === true);
|
|
130
|
-
expect(wrapper, 'the outer refresh-control wrapper committed').toBeDefined();
|
|
131
|
-
expect(wrapper?.props.flex).toBe(1);
|
|
132
|
-
expect(wrapper?.props.height).toBe(84);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import '@angular/compiler';
|
|
2
|
-
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
4
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
5
|
-
import { mount, unmount } from '../../render';
|
|
6
|
-
import { RefreshControl } from '../refresh-control';
|
|
7
|
-
import { ScrollView as AndroidScrollView } from './index.android';
|
|
8
|
-
import { ScrollView } from './index.ios';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 918;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
|
|
13
|
-
|
|
14
|
-
class StickyProjectionApp {}
|
|
15
|
-
Component({
|
|
16
|
-
selector: 'symbiote-scroll-sticky-projection-test',
|
|
17
|
-
standalone: true,
|
|
18
|
-
imports: [ScrollView],
|
|
19
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
20
|
-
template: `
|
|
21
|
-
<ScrollView [stickyHeaderIndices]="[1]">
|
|
22
|
-
<symbiote-view testID="before"></symbiote-view>
|
|
23
|
-
<symbiote-view testID="sticky"></symbiote-view>
|
|
24
|
-
<symbiote-view testID="after"></symbiote-view>
|
|
25
|
-
</ScrollView>
|
|
26
|
-
`,
|
|
27
|
-
})(StickyProjectionApp);
|
|
28
|
-
|
|
29
|
-
class CustomStickyHeader {
|
|
30
|
-
static instantiated = false;
|
|
31
|
-
|
|
32
|
-
constructor() {
|
|
33
|
-
CustomStickyHeader.instantiated = true;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
Component({
|
|
37
|
-
selector: 'CustomStickyHeader',
|
|
38
|
-
standalone: true,
|
|
39
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
40
|
-
template: `
|
|
41
|
-
<symbiote-view testID="custom-sticky-wrapper">
|
|
42
|
-
<ng-content></ng-content>
|
|
43
|
-
</symbiote-view>
|
|
44
|
-
`,
|
|
45
|
-
})(CustomStickyHeader);
|
|
46
|
-
|
|
47
|
-
class CustomStickyProjectionApp {
|
|
48
|
-
CustomStickyHeader = CustomStickyHeader;
|
|
49
|
-
}
|
|
50
|
-
Component({
|
|
51
|
-
selector: 'symbiote-scroll-custom-sticky-projection-test',
|
|
52
|
-
standalone: true,
|
|
53
|
-
imports: [ScrollView],
|
|
54
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
55
|
-
template: `
|
|
56
|
-
<ScrollView [stickyHeaderIndices]="[0]" [StickyHeaderComponent]="CustomStickyHeader">
|
|
57
|
-
<symbiote-view testID="sticky"></symbiote-view>
|
|
58
|
-
<symbiote-view testID="after"></symbiote-view>
|
|
59
|
-
</ScrollView>
|
|
60
|
-
`,
|
|
61
|
-
})(CustomStickyProjectionApp);
|
|
62
|
-
|
|
63
|
-
class IOSRefreshProjectionApp {
|
|
64
|
-
static refreshes = 0;
|
|
65
|
-
|
|
66
|
-
readonly refreshing = signal(false);
|
|
67
|
-
|
|
68
|
-
refresh = (): void => {
|
|
69
|
-
this.refreshing.set(true);
|
|
70
|
-
setTimeout(() => {
|
|
71
|
-
this.refreshing.set(false);
|
|
72
|
-
IOSRefreshProjectionApp.refreshes += 1;
|
|
73
|
-
}, 0);
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
Component({
|
|
77
|
-
selector: 'symbiote-scroll-ios-refresh-projection-test',
|
|
78
|
-
standalone: true,
|
|
79
|
-
imports: [ScrollView, RefreshControl],
|
|
80
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
81
|
-
template: `
|
|
82
|
-
<ScrollView>
|
|
83
|
-
<RefreshControl [refreshing]="refreshing()" (refresh)="refresh()" />
|
|
84
|
-
<symbiote-view testID="content"></symbiote-view>
|
|
85
|
-
</ScrollView>
|
|
86
|
-
`,
|
|
87
|
-
})(IOSRefreshProjectionApp);
|
|
88
|
-
|
|
89
|
-
class AndroidRefreshProjectionApp {
|
|
90
|
-
static refreshes = 0;
|
|
91
|
-
|
|
92
|
-
refresh = (): void => {
|
|
93
|
-
AndroidRefreshProjectionApp.refreshes += 1;
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
Component({
|
|
97
|
-
selector: 'symbiote-scroll-android-refresh-projection-test',
|
|
98
|
-
standalone: true,
|
|
99
|
-
imports: [AndroidScrollView, RefreshControl],
|
|
100
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
101
|
-
template: `
|
|
102
|
-
<ScrollView [style]="{ marginTop: 4, backgroundColor: 'red' }">
|
|
103
|
-
<RefreshControl [refreshing]="true" (refresh)="refresh()" />
|
|
104
|
-
<symbiote-view testID="content"></symbiote-view>
|
|
105
|
-
</ScrollView>
|
|
106
|
-
`,
|
|
107
|
-
})(AndroidRefreshProjectionApp);
|
|
108
|
-
|
|
109
|
-
beforeEach(() => {
|
|
110
|
-
fabric.reset();
|
|
111
|
-
CustomStickyHeader.instantiated = false;
|
|
112
|
-
IOSRefreshProjectionApp.refreshes = 0;
|
|
113
|
-
AndroidRefreshProjectionApp.refreshes = 0;
|
|
114
|
-
});
|
|
115
|
-
afterEach(() => unmount(ROOT_TAG));
|
|
116
|
-
|
|
117
|
-
describe('Angular ScrollView projection parity', () => {
|
|
118
|
-
it('auto-wraps projected children selected by stickyHeaderIndices', async () => {
|
|
119
|
-
mount(ROOT_TAG, StickyProjectionApp);
|
|
120
|
-
await tick();
|
|
121
|
-
|
|
122
|
-
const root = fabric.appRoot();
|
|
123
|
-
expect(fabric.serialize(root.children)).toBe(
|
|
124
|
-
'RCTScrollView(RCTScrollContentView(RCTViewRCTView(RCTView)RCTView))',
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
const stickyWrapper = fabric.find(
|
|
128
|
-
node =>
|
|
129
|
-
node.props.collapsable === false &&
|
|
130
|
-
node.children.some(child => child.props.testID === 'sticky'),
|
|
131
|
-
);
|
|
132
|
-
expect(stickyWrapper?.props).toMatchObject({ collapsable: false, onLayout: true });
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('keeps auto StickyHeaderComponent projection on the built-in AOT-safe wrapper', async () => {
|
|
136
|
-
mount(ROOT_TAG, CustomStickyProjectionApp);
|
|
137
|
-
await tick();
|
|
138
|
-
|
|
139
|
-
expect(CustomStickyHeader.instantiated).toBe(false);
|
|
140
|
-
expect(fabric.find(node => node.props.testID === 'custom-sticky-wrapper')).toBeUndefined();
|
|
141
|
-
|
|
142
|
-
const stickyWrapper = fabric.find(
|
|
143
|
-
node =>
|
|
144
|
-
node.props.collapsable === false &&
|
|
145
|
-
node.children.some(child => child.props.testID === 'sticky'),
|
|
146
|
-
);
|
|
147
|
-
expect(stickyWrapper?.props).toMatchObject({ collapsable: false, onLayout: true });
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('renders iOS RefreshControl before content and syncs the controlled native spinner', async () => {
|
|
151
|
-
mount(ROOT_TAG, IOSRefreshProjectionApp);
|
|
152
|
-
await tick();
|
|
153
|
-
|
|
154
|
-
const root = fabric.appRoot();
|
|
155
|
-
expect(fabric.serialize(root.children)).toBe(
|
|
156
|
-
'RCTScrollView(PullToRefreshViewRCTScrollContentView(RCTView))',
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const refresh = root.children[0]?.children[0];
|
|
160
|
-
expect(refresh?.viewName).toBe('PullToRefreshView');
|
|
161
|
-
fabric.fireEvent(refresh?.instanceHandle, 'topRefresh');
|
|
162
|
-
await tick();
|
|
163
|
-
await tick();
|
|
164
|
-
|
|
165
|
-
expect(IOSRefreshProjectionApp.refreshes).toBe(1);
|
|
166
|
-
expect(fabric.commands.at(-1)).toMatchObject({
|
|
167
|
-
commandName: 'setNativeRefreshing',
|
|
168
|
-
args: [false],
|
|
169
|
-
});
|
|
170
|
-
expect(fabric.commands.at(-1)?.node.tag).toBe(refresh?.tag);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('wraps an Android projected RefreshControl around the scroll view', async () => {
|
|
174
|
-
mount(ROOT_TAG, AndroidRefreshProjectionApp);
|
|
175
|
-
await tick();
|
|
176
|
-
|
|
177
|
-
const root = fabric.appRoot();
|
|
178
|
-
expect(fabric.serialize(root.children)).toBe(
|
|
179
|
-
'PullToRefreshView(RCTScrollView(RCTScrollContentView(RCTView)))',
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
const refresh = root.children[0];
|
|
183
|
-
expect(refresh?.props).toMatchObject({ refreshing: true, marginTop: 4 });
|
|
184
|
-
fabric.fireEvent(refresh?.instanceHandle, 'topRefresh');
|
|
185
|
-
await tick();
|
|
186
|
-
|
|
187
|
-
expect(AndroidRefreshProjectionApp.refreshes).toBe(1);
|
|
188
|
-
expect(refresh?.children[0]?.props).toMatchObject({
|
|
189
|
-
backgroundColor: 'red',
|
|
190
|
-
nestedScrollEnabled: true,
|
|
191
|
-
});
|
|
192
|
-
expect(fabric.find(node => node.props.testID === 'content')).toBeDefined();
|
|
193
|
-
});
|
|
194
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// Android-specific twin of the class= regression covered for iOS in switch.test.ts. Switch's
|
|
2
|
-
// hostProps getter is overridden per-platform component (index.ios.ts / index.android.ts), each
|
|
3
|
-
// injecting its OWN ElementRef, so the fix needs its own coverage against the Android build too.
|
|
4
|
-
import '@angular/compiler';
|
|
5
|
-
import { Component } from '@angular/core';
|
|
6
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
8
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
9
|
-
|
|
10
|
-
import { mount, unmount } from '../../render';
|
|
11
|
-
import { Switch } from './index.android';
|
|
12
|
-
|
|
13
|
-
const ROOT_TAG = 942;
|
|
14
|
-
const fabric = installFabric();
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
fabric.reset();
|
|
18
|
-
});
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
unmount(ROOT_TAG);
|
|
21
|
-
clearGlobalStyles();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
@Component({
|
|
25
|
-
selector: 'symbiote-android-switch-class-host',
|
|
26
|
-
standalone: true,
|
|
27
|
-
imports: [Switch],
|
|
28
|
-
template: `<Switch [testID]="'switch-with-class'" class="card"></Switch>`,
|
|
29
|
-
})
|
|
30
|
-
class AndroidSwitchClassHost {}
|
|
31
|
-
|
|
32
|
-
describe('Switch (android)', () => {
|
|
33
|
-
it('resolves a class= on the Switch use site onto the real committed view, not the anchor', async () => {
|
|
34
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
35
|
-
|
|
36
|
-
mount(ROOT_TAG, AndroidSwitchClassHost);
|
|
37
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
38
|
-
|
|
39
|
-
const node = fabric.find(n => n.props.testID === 'switch-with-class');
|
|
40
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
41
|
-
});
|
|
42
|
-
});
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import '@angular/compiler';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
5
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
6
|
-
|
|
7
|
-
import { mount, unmount } from '../../render';
|
|
8
|
-
import { Switch } from './index';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 902;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
|
|
13
|
-
let capturedHost: SwitchHost | undefined;
|
|
14
|
-
|
|
15
|
-
@Component({
|
|
16
|
-
selector: 'symbiote-switch-host',
|
|
17
|
-
standalone: true,
|
|
18
|
-
imports: [Switch],
|
|
19
|
-
template: `
|
|
20
|
-
<Switch [value]="value" (valueChange)="onValueChange($event)" (change)="onChange($event)">
|
|
21
|
-
</Switch>
|
|
22
|
-
`,
|
|
23
|
-
})
|
|
24
|
-
class SwitchHost {
|
|
25
|
-
value = false;
|
|
26
|
-
onValueChange = vi.fn((next: boolean) => {
|
|
27
|
-
this.value = next;
|
|
28
|
-
});
|
|
29
|
-
onChange = vi.fn();
|
|
30
|
-
|
|
31
|
-
constructor() {
|
|
32
|
-
// Captures the live component instance so the test can drive its signals after mount.
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
34
|
-
capturedHost = this;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
beforeEach(() => {
|
|
39
|
-
capturedHost = undefined;
|
|
40
|
-
fabric.reset();
|
|
41
|
-
});
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
unmount(ROOT_TAG);
|
|
44
|
-
clearGlobalStyles();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('Switch', () => {
|
|
48
|
-
it('commits a controlled Switch with the resolved iOS color props', async () => {
|
|
49
|
-
mount(ROOT_TAG, SwitchHost);
|
|
50
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
51
|
-
|
|
52
|
-
const node = fabric.find(n => n.viewName === 'Switch');
|
|
53
|
-
expect(node, 'Switch node committed').toBeDefined();
|
|
54
|
-
expect(node?.props).toMatchObject({
|
|
55
|
-
value: false,
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('fires onValueChange and onChange when native reports a change', async () => {
|
|
60
|
-
mount(ROOT_TAG, SwitchHost);
|
|
61
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
62
|
-
|
|
63
|
-
const node = fabric.find(n => n.viewName === 'Switch');
|
|
64
|
-
expect(node).toBeDefined();
|
|
65
|
-
|
|
66
|
-
fabric.fireEvent(node?.instanceHandle, 'topChange', { value: true, eventCount: 1 });
|
|
67
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
68
|
-
|
|
69
|
-
const host = capturedHost;
|
|
70
|
-
expect(host?.onValueChange).toHaveBeenCalledWith(true);
|
|
71
|
-
expect(host?.onChange).toHaveBeenCalled();
|
|
72
|
-
expect(host?.value).toBe(true);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('resolves a class= on the Switch use site onto the real committed view, not the anchor', async () => {
|
|
76
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
77
|
-
|
|
78
|
-
mount(ROOT_TAG, SwitchClassHost);
|
|
79
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
80
|
-
|
|
81
|
-
const node = fabric.find(n => n.props.testID === 'switch-with-class');
|
|
82
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
@Component({
|
|
87
|
-
selector: 'symbiote-switch-class-host',
|
|
88
|
-
standalone: true,
|
|
89
|
-
imports: [Switch],
|
|
90
|
-
template: `<Switch [testID]="'switch-with-class'" class="card"></Switch>`,
|
|
91
|
-
})
|
|
92
|
-
class SwitchClassHost {}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// Regression test for the anchor/class bug: TextInput is its own
|
|
2
|
-
// ANCHOR_HOST_COMPONENTS entry — a class= on <TextInput> resolves onto TextInput's OWN anchor and
|
|
3
|
-
// needs its OWN anchorHostStyle merge (see text-input.ts's buildPassthrough), for BOTH the
|
|
4
|
-
// single-line and multiline host it renders through (`@if`/`@else` picks one at runtime). Mirrors
|
|
5
|
-
// pressable.test.ts's "resolves a class=" case.
|
|
6
|
-
import '@angular/compiler';
|
|
7
|
-
import { Component } from '@angular/core';
|
|
8
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
9
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
10
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
11
|
-
|
|
12
|
-
import { mount, unmount } from '../render';
|
|
13
|
-
import { TextInput } from './text-input';
|
|
14
|
-
|
|
15
|
-
const ROOT_TAG = 917;
|
|
16
|
-
const fabric = installFabric();
|
|
17
|
-
|
|
18
|
-
@Component({
|
|
19
|
-
selector: 'symbiote-text-input-class-host',
|
|
20
|
-
standalone: true,
|
|
21
|
-
imports: [TextInput],
|
|
22
|
-
template: `
|
|
23
|
-
<TextInput [testID]="'single-line'" class="card" />
|
|
24
|
-
<TextInput [testID]="'multiline'" [multiline]="true" class="card" />
|
|
25
|
-
`,
|
|
26
|
-
})
|
|
27
|
-
class TextInputClassHost {}
|
|
28
|
-
|
|
29
|
-
beforeEach(() => {
|
|
30
|
-
fabric.reset();
|
|
31
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
32
|
-
});
|
|
33
|
-
afterEach(() => {
|
|
34
|
-
unmount(ROOT_TAG);
|
|
35
|
-
clearGlobalStyles();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('TextInput anchor class= resolution', () => {
|
|
39
|
-
it('resolves a class= on the TextInput use site onto the real committed single-line host', async () => {
|
|
40
|
-
mount(ROOT_TAG, TextInputClassHost);
|
|
41
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
42
|
-
|
|
43
|
-
const node = fabric.find(n => n.props.testID === 'single-line');
|
|
44
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('resolves a class= on the TextInput use site onto the real committed multiline host', async () => {
|
|
48
|
-
mount(ROOT_TAG, TextInputClassHost);
|
|
49
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
50
|
-
|
|
51
|
-
const node = fabric.find(n => n.props.testID === 'multiline');
|
|
52
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
53
|
-
});
|
|
54
|
-
});
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
// Regression coverage for the anchor-vs-real-content class bug (see pressable.test.ts for the
|
|
2
|
-
// full writeup): a `class="..."` written on a composed component's OWN use site always resolves
|
|
3
|
-
// through Angular's addClass/removeClass onto that component's non-painting ANCHOR host, never
|
|
4
|
-
// onto the real committed Fabric view one (or more) levels down. Each Touchable forwards its own
|
|
5
|
-
// anchor's resolved style into whatever it commits, mirroring Pressable's fix.
|
|
6
|
-
import '@angular/compiler';
|
|
7
|
-
import { Component } from '@angular/core';
|
|
8
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
9
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
10
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
11
|
-
|
|
12
|
-
import { mount, unmount } from '../../render';
|
|
13
|
-
import { TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback } from './index';
|
|
14
|
-
|
|
15
|
-
const ROOT_TAG = 940;
|
|
16
|
-
const fabric = installFabric();
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
fabric.reset();
|
|
20
|
-
});
|
|
21
|
-
afterEach(() => {
|
|
22
|
-
unmount(ROOT_TAG);
|
|
23
|
-
clearGlobalStyles();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
@Component({
|
|
27
|
-
selector: 'symbiote-touchable-opacity-host',
|
|
28
|
-
standalone: true,
|
|
29
|
-
imports: [TouchableOpacity],
|
|
30
|
-
template: `
|
|
31
|
-
<TouchableOpacity [testID]="'opacity'" class="card">
|
|
32
|
-
<symbiote-text>Press</symbiote-text>
|
|
33
|
-
</TouchableOpacity>
|
|
34
|
-
`,
|
|
35
|
-
})
|
|
36
|
-
class TouchableOpacityHost {}
|
|
37
|
-
|
|
38
|
-
@Component({
|
|
39
|
-
selector: 'symbiote-touchable-highlight-host',
|
|
40
|
-
standalone: true,
|
|
41
|
-
imports: [TouchableHighlight],
|
|
42
|
-
template: `
|
|
43
|
-
<TouchableHighlight [testID]="'highlight'" class="card">
|
|
44
|
-
<symbiote-text>Press</symbiote-text>
|
|
45
|
-
</TouchableHighlight>
|
|
46
|
-
`,
|
|
47
|
-
})
|
|
48
|
-
class TouchableHighlightHost {}
|
|
49
|
-
|
|
50
|
-
@Component({
|
|
51
|
-
selector: 'symbiote-touchable-without-feedback-host',
|
|
52
|
-
standalone: true,
|
|
53
|
-
imports: [TouchableWithoutFeedback],
|
|
54
|
-
template: `
|
|
55
|
-
<TouchableWithoutFeedback [testID]="'without-feedback'" class="card">
|
|
56
|
-
<symbiote-text>Press</symbiote-text>
|
|
57
|
-
</TouchableWithoutFeedback>
|
|
58
|
-
`,
|
|
59
|
-
})
|
|
60
|
-
class TouchableWithoutFeedbackHost {}
|
|
61
|
-
|
|
62
|
-
describe('TouchableOpacity', () => {
|
|
63
|
-
it('resolves a class= on the TouchableOpacity use site onto the real committed view, not the anchor', async () => {
|
|
64
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
65
|
-
|
|
66
|
-
mount(ROOT_TAG, TouchableOpacityHost);
|
|
67
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
68
|
-
|
|
69
|
-
// TouchableOpacity folds its OWN class-derived style into the inner AnimatedView leaf, not
|
|
70
|
-
// the outer Pressable — mirroring React's TouchableOpacity (see adapters/react/src/components/
|
|
71
|
-
// touchable/index.ts's comment: "className is pulled out here, like style, and applied to the
|
|
72
|
-
// inner AnimatedView... it would land on the outer Pressable instead, which is not what a user
|
|
73
|
-
// expects"), so the testID-carrying outer view is NOT where the resolved style lands.
|
|
74
|
-
expect(fabric.find(n => n.props.testID === 'opacity')).toBeDefined();
|
|
75
|
-
const node = fabric.find(n => n.props.backgroundColor === 'red');
|
|
76
|
-
expect(node, 'a committed node received the class-derived style').toBeDefined();
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe('TouchableHighlight', () => {
|
|
81
|
-
it('resolves a class= on the TouchableHighlight use site onto the real committed view, not the anchor', async () => {
|
|
82
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
83
|
-
|
|
84
|
-
mount(ROOT_TAG, TouchableHighlightHost);
|
|
85
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
86
|
-
|
|
87
|
-
const node = fabric.find(n => n.props.testID === 'highlight');
|
|
88
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('TouchableWithoutFeedback', () => {
|
|
93
|
-
it('resolves a class= on the TouchableWithoutFeedback use site onto the real committed view, not the anchor', async () => {
|
|
94
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
95
|
-
|
|
96
|
-
mount(ROOT_TAG, TouchableWithoutFeedbackHost);
|
|
97
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
98
|
-
|
|
99
|
-
const node = fabric.find(n => n.props.testID === 'without-feedback');
|
|
100
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
101
|
-
});
|
|
102
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Regression coverage for the anchor-vs-real-content class bug (see pressable.test.ts for the
|
|
2
|
-
// full writeup): a `class="..."` written on TouchableNativeFeedback's OWN use site always resolves
|
|
3
|
-
// through Angular's addClass/removeClass onto its non-painting ANCHOR host, never onto the real
|
|
4
|
-
// committed feedback <symbiote-view> one level down. TouchableNativeFeedback has no explicit
|
|
5
|
-
// `style`/`class`-forwarding @Input() of its own, so the anchor's class-derived style is the
|
|
6
|
-
// ONLY style source hostProps.style forwards.
|
|
7
|
-
import '@angular/compiler';
|
|
8
|
-
import { Component } from '@angular/core';
|
|
9
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
10
|
-
import { clearGlobalStyles, registerStyles } from '@symbiote-native/engine';
|
|
11
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
12
|
-
|
|
13
|
-
import { mount, unmount } from '../../render';
|
|
14
|
-
import { TouchableNativeFeedback } from './index';
|
|
15
|
-
|
|
16
|
-
const ROOT_TAG = 941;
|
|
17
|
-
const fabric = installFabric();
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
fabric.reset();
|
|
21
|
-
});
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
unmount(ROOT_TAG);
|
|
24
|
-
clearGlobalStyles();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
@Component({
|
|
28
|
-
selector: 'symbiote-touchable-native-feedback-host',
|
|
29
|
-
standalone: true,
|
|
30
|
-
imports: [TouchableNativeFeedback],
|
|
31
|
-
template: `
|
|
32
|
-
<TouchableNativeFeedback [testID]="'native-feedback'" class="card">
|
|
33
|
-
<symbiote-text>Press</symbiote-text>
|
|
34
|
-
</TouchableNativeFeedback>
|
|
35
|
-
`,
|
|
36
|
-
})
|
|
37
|
-
class TouchableNativeFeedbackHost {}
|
|
38
|
-
|
|
39
|
-
describe('TouchableNativeFeedback', () => {
|
|
40
|
-
it('resolves a class= on the TouchableNativeFeedback use site onto the real committed view, not the anchor', async () => {
|
|
41
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
42
|
-
|
|
43
|
-
mount(ROOT_TAG, TouchableNativeFeedbackHost);
|
|
44
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
45
|
-
|
|
46
|
-
const node = fabric.find(n => n.props.testID === 'native-feedback');
|
|
47
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
48
|
-
});
|
|
49
|
-
});
|