@symbiote-native/angular 0.6.0 → 0.6.2
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/babel-register-composed.cjs +11 -3
- package/build/angular/anchor-host-registry.d.ts +2 -0
- package/build/angular/anchor-host-registry.js +84 -0
- package/build/angular/anchor-host-registry.js.map +1 -0
- package/build/angular/components/input-accessory-view/index.d.ts +2 -1
- package/build/angular/components/input-accessory-view/index.js +28 -39
- package/build/angular/components/input-accessory-view/index.js.map +1 -1
- package/build/angular/components/scroll-view/projection.js +70 -48
- package/build/angular/components/scroll-view/projection.js.map +1 -1
- package/build/angular/components/scroll-view/shared.js +28 -25
- package/build/angular/components/scroll-view/shared.js.map +1 -1
- package/build/angular/components/scroll-view/sticky-header.d.ts +6 -7
- package/build/angular/components/scroll-view/sticky-header.js +82 -65
- package/build/angular/components/scroll-view/sticky-header.js.map +1 -1
- package/build/angular/components/touchable/index.d.ts +2 -5
- package/build/angular/components/touchable/index.js +36 -56
- package/build/angular/components/touchable/index.js.map +1 -1
- package/build/angular/components/virtualized-list/index.d.ts +5 -20
- package/build/angular/components/virtualized-list/index.js +145 -275
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/index.js +2 -4
- package/build/angular/components/virtualized-section-list/index.js.map +1 -1
- package/build/angular/index.d.ts +2 -1
- package/build/angular/index.js +6 -1
- package/build/angular/index.js.map +1 -1
- package/build/angular/renderer/index.d.ts +0 -1
- package/build/angular/renderer/index.js +5 -60
- package/build/angular/renderer/index.js.map +1 -1
- package/package.json +8 -4
- package/src/anchor-host-registry.ts +88 -0
- package/src/components/input-accessory-view/index.ts +30 -39
- package/src/components/scroll-view/projection.ts +76 -46
- package/src/components/scroll-view/shared.ts +27 -19
- package/src/components/scroll-view/sticky-header.ts +89 -64
- package/src/components/touchable/index.ts +52 -66
- package/src/components/virtualized-list/index.ts +157 -368
- package/src/components/virtualized-section-list/index.ts +6 -3
- package/src/index.ts +6 -1
- package/src/renderer/index.ts +5 -63
- package/build/bootstrap.d.ts +0 -7
- package/build/bootstrap.js +0 -14
- package/build/components/activity-indicator/index.android.d.ts +0 -9
- package/build/components/activity-indicator/index.android.js +0 -64
- package/build/components/activity-indicator/index.d.ts +0 -1
- package/build/components/activity-indicator/index.ios.d.ts +0 -5
- package/build/components/activity-indicator/index.ios.js +0 -64
- package/build/components/activity-indicator/index.js +0 -3
- package/build/components/activity-indicator/shared.d.ts +0 -64
- package/build/components/activity-indicator/shared.js +0 -424
- package/build/components/button.d.ts +0 -60
- package/build/components/button.js +0 -456
- package/build/components/flat-list/index.d.ts +0 -119
- package/build/components/flat-list/index.js +0 -691
- package/build/components/image/index.android.d.ts +0 -7
- package/build/components/image/index.android.js +0 -88
- package/build/components/image/index.d.ts +0 -1
- package/build/components/image/index.ios.d.ts +0 -7
- package/build/components/image/index.ios.js +0 -88
- package/build/components/image/index.js +0 -2
- package/build/components/image/shared.d.ts +0 -101
- package/build/components/image/shared.js +0 -405
- package/build/components/image-background.d.ts +0 -78
- package/build/components/image-background.js +0 -583
- package/build/components/input-accessory-view/index.d.ts +0 -56
- package/build/components/input-accessory-view/index.js +0 -403
- package/build/components/keyboard-avoiding-view/index.d.ts +0 -79
- package/build/components/keyboard-avoiding-view/index.js +0 -504
- package/build/components/modal/index.d.ts +0 -89
- package/build/components/modal/index.js +0 -529
- package/build/components/pressable/index.d.ts +0 -120
- package/build/components/pressable/index.js +0 -639
- package/build/components/refresh-control/index.d.ts +0 -83
- package/build/components/refresh-control/index.js +0 -509
- package/build/components/safe-area-view/index.d.ts +0 -54
- package/build/components/safe-area-view/index.js +0 -388
- package/build/components/scroll-view/index.android.d.ts +0 -16
- package/build/components/scroll-view/index.android.js +0 -228
- package/build/components/scroll-view/index.d.ts +0 -3
- package/build/components/scroll-view/index.ios.d.ts +0 -6
- package/build/components/scroll-view/index.ios.js +0 -113
- package/build/components/scroll-view/index.js +0 -5
- package/build/components/scroll-view/projection.d.ts +0 -32
- package/build/components/scroll-view/projection.js +0 -311
- package/build/components/scroll-view/shared.d.ts +0 -225
- package/build/components/scroll-view/shared.js +0 -757
- package/build/components/scroll-view/sticky-header.d.ts +0 -38
- package/build/components/scroll-view/sticky-header.js +0 -257
- package/build/components/section-list/index.d.ts +0 -113
- package/build/components/section-list/index.js +0 -768
- package/build/components/switch/index.android.d.ts +0 -17
- package/build/components/switch/index.android.js +0 -107
- package/build/components/switch/index.d.ts +0 -1
- package/build/components/switch/index.ios.d.ts +0 -16
- package/build/components/switch/index.ios.js +0 -106
- package/build/components/switch/index.js +0 -3
- package/build/components/switch/shared.d.ts +0 -37
- package/build/components/switch/shared.js +0 -176
- package/build/components/text-input.d.ts +0 -150
- package/build/components/text-input.js +0 -821
- package/build/components/touchable/index.d.ts +0 -241
- package/build/components/touchable/index.js +0 -1672
- package/build/components/touchable-native-feedback/index.d.ts +0 -80
- package/build/components/touchable-native-feedback/index.js +0 -545
- package/build/components/virtualized-list/directives.d.ts +0 -41
- package/build/components/virtualized-list/directives.js +0 -249
- package/build/components/virtualized-list/index.d.ts +0 -265
- package/build/components/virtualized-list/index.js +0 -1343
- package/build/components/virtualized-section-list/directives.d.ts +0 -28
- package/build/components/virtualized-section-list/directives.js +0 -148
- package/build/components/virtualized-section-list/index.d.ts +0 -175
- package/build/components/virtualized-section-list/index.js +0 -854
- package/build/components.d.ts +0 -39
- package/build/components.js +0 -37
- package/build/create-portal/index.d.ts +0 -17
- package/build/create-portal/index.js +0 -128
- package/build/create-tunnel/index.d.ts +0 -29
- package/build/create-tunnel/index.js +0 -181
- package/build/descriptor-to-angular/index.d.ts +0 -19
- package/build/descriptor-to-angular/index.js +0 -186
- package/build/host-instance/index.d.ts +0 -2
- package/build/host-instance/index.js +0 -36
- package/build/index.d.ts +0 -21
- package/build/index.js +0 -40
- package/build/modules/animated/animated-leaf-binder/index.d.ts +0 -14
- package/build/modules/animated/animated-leaf-binder/index.js +0 -90
- package/build/modules/animated/animated-leaf-binder.d.ts +0 -14
- package/build/modules/animated/animated-leaf-binder.js +0 -90
- package/build/modules/animated/create-animated-component.d.ts +0 -48
- package/build/modules/animated/create-animated-component.js +0 -425
- package/build/modules/animated/index.d.ts +0 -51
- package/build/modules/animated/index.js +0 -58
- package/build/modules/app-registry/index.d.ts +0 -7
- package/build/modules/app-registry/index.js +0 -22
- package/build/modules/status-bar/index.d.ts +0 -17
- package/build/modules/status-bar/index.js +0 -121
- package/build/primitives/index.d.ts +0 -32
- package/build/primitives/index.js +0 -386
- package/build/primitives/shared.d.ts +0 -83
- package/build/primitives/shared.js +0 -230
- package/build/render/index.d.ts +0 -11
- package/build/render/index.js +0 -170
- package/build/renderer/index.d.ts +0 -38
- package/build/renderer/index.js +0 -355
- package/build/services/color-scheme.service.d.ts +0 -13
- package/build/services/color-scheme.service.js +0 -72
- package/build/services/index.d.ts +0 -2
- package/build/services/index.js +0 -2
- package/build/services/window-dimensions.service.d.ts +0 -13
- package/build/services/window-dimensions.service.js +0 -83
- 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.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 -202
- package/src/services/services.test.ts +0 -163
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import '@angular/compiler';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it } 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 { Modal } from './index';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 912;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'symbiote-modal-host',
|
|
15
|
-
standalone: true,
|
|
16
|
-
imports: [Modal],
|
|
17
|
-
template: `
|
|
18
|
-
<Modal [visible]="true" [testID]="'modal'" class="sheet">
|
|
19
|
-
<symbiote-text>Hello</symbiote-text>
|
|
20
|
-
</Modal>
|
|
21
|
-
`,
|
|
22
|
-
})
|
|
23
|
-
class ModalHostFixture {}
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
fabric.reset();
|
|
27
|
-
});
|
|
28
|
-
afterEach(() => {
|
|
29
|
-
unmount(ROOT_TAG);
|
|
30
|
-
clearGlobalStyles();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('Modal', () => {
|
|
34
|
-
it('resolves a class= on the Modal use site onto the real committed view, not the anchor', async () => {
|
|
35
|
-
registerStyles({ sheet: { backgroundColor: 'purple' } });
|
|
36
|
-
|
|
37
|
-
mount(ROOT_TAG, ModalHostFixture);
|
|
38
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
39
|
-
|
|
40
|
-
const node = fabric.find(n => n.props.testID === 'modal');
|
|
41
|
-
expect(node?.props.backgroundColor).toBe('purple');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
@@ -1,85 +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 { Pressable } from './index';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 903;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
|
|
13
|
-
let capturedHost: PressableHost | undefined;
|
|
14
|
-
|
|
15
|
-
@Component({
|
|
16
|
-
selector: 'symbiote-pressable-host',
|
|
17
|
-
standalone: true,
|
|
18
|
-
imports: [Pressable],
|
|
19
|
-
template: `
|
|
20
|
-
<Pressable
|
|
21
|
-
[testID]="'pressable'"
|
|
22
|
-
class="card"
|
|
23
|
-
(press)="onPress($event)"
|
|
24
|
-
(pressIn)="onPressIn($event)"
|
|
25
|
-
(pressOut)="onPressOut($event)"
|
|
26
|
-
>
|
|
27
|
-
<symbiote-text>Press me</symbiote-text>
|
|
28
|
-
</Pressable>
|
|
29
|
-
`,
|
|
30
|
-
})
|
|
31
|
-
class PressableHost {
|
|
32
|
-
onPress = vi.fn();
|
|
33
|
-
onPressIn = vi.fn();
|
|
34
|
-
onPressOut = vi.fn();
|
|
35
|
-
|
|
36
|
-
constructor() {
|
|
37
|
-
// Captures the live component instance so the test can drive its signals after mount.
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
39
|
-
capturedHost = this;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
capturedHost = undefined;
|
|
45
|
-
fabric.reset();
|
|
46
|
-
});
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
unmount(ROOT_TAG);
|
|
49
|
-
clearGlobalStyles();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('Pressable', () => {
|
|
53
|
-
it('synthesizes a press from a touch sequence and fires the lifecycle handlers', async () => {
|
|
54
|
-
mount(ROOT_TAG, PressableHost);
|
|
55
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
56
|
-
|
|
57
|
-
const node = fabric.find(n => n.props.testID === 'pressable');
|
|
58
|
-
expect(node, 'Pressable view committed').toBeDefined();
|
|
59
|
-
|
|
60
|
-
const now = Date.now();
|
|
61
|
-
const touch = { identifier: 1, pageX: 10, pageY: 10, timestamp: now };
|
|
62
|
-
const nativeEvent = { touches: [touch], changedTouches: [touch] };
|
|
63
|
-
|
|
64
|
-
fabric.fireEvent(node?.instanceHandle, 'topTouchStart', nativeEvent);
|
|
65
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
66
|
-
|
|
67
|
-
expect(capturedHost?.onPressIn).toHaveBeenCalledOnce();
|
|
68
|
-
|
|
69
|
-
fabric.fireEvent(node?.instanceHandle, 'topTouchEnd', nativeEvent);
|
|
70
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
71
|
-
|
|
72
|
-
expect(capturedHost?.onPress).toHaveBeenCalledOnce();
|
|
73
|
-
expect(capturedHost?.onPressOut).toHaveBeenCalledOnce();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('resolves a class= on the Pressable use site onto the real committed view, not the anchor', async () => {
|
|
77
|
-
registerStyles({ card: { backgroundColor: 'red' } });
|
|
78
|
-
|
|
79
|
-
mount(ROOT_TAG, PressableHost);
|
|
80
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
81
|
-
|
|
82
|
-
const node = fabric.find(n => n.props.testID === 'pressable');
|
|
83
|
-
expect(node?.props.backgroundColor).toBe('red');
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import '@angular/compiler';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it } 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 { RefreshControl } from './index';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 914;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'symbiote-refresh-control-host',
|
|
15
|
-
standalone: true,
|
|
16
|
-
imports: [RefreshControl],
|
|
17
|
-
template: `
|
|
18
|
-
<RefreshControl [refreshing]="false" [testID]="'refresh'" class="spinner"></RefreshControl>
|
|
19
|
-
`,
|
|
20
|
-
})
|
|
21
|
-
class RefreshControlHostFixture {}
|
|
22
|
-
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
fabric.reset();
|
|
25
|
-
});
|
|
26
|
-
afterEach(() => {
|
|
27
|
-
unmount(ROOT_TAG);
|
|
28
|
-
clearGlobalStyles();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe('RefreshControl', () => {
|
|
32
|
-
it('resolves a class= on the RefreshControl use site onto the real committed view, not the anchor', async () => {
|
|
33
|
-
registerStyles({ spinner: { backgroundColor: 'green' } });
|
|
34
|
-
|
|
35
|
-
mount(ROOT_TAG, RefreshControlHostFixture);
|
|
36
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
37
|
-
|
|
38
|
-
const node = fabric.find(n => n.props.testID === 'refresh');
|
|
39
|
-
expect(node?.props.backgroundColor).toBe('green');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import '@angular/compiler';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it } 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 { SafeAreaView } from './index';
|
|
9
|
-
|
|
10
|
-
const ROOT_TAG = 910;
|
|
11
|
-
const fabric = installFabric();
|
|
12
|
-
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'symbiote-safe-area-view-host',
|
|
15
|
-
standalone: true,
|
|
16
|
-
imports: [SafeAreaView],
|
|
17
|
-
template: `
|
|
18
|
-
<SafeAreaView [testID]="'safe-area'" class="screen">
|
|
19
|
-
<symbiote-text>Hello</symbiote-text>
|
|
20
|
-
</SafeAreaView>
|
|
21
|
-
`,
|
|
22
|
-
})
|
|
23
|
-
class SafeAreaViewHostFixture {}
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
fabric.reset();
|
|
27
|
-
});
|
|
28
|
-
afterEach(() => {
|
|
29
|
-
unmount(ROOT_TAG);
|
|
30
|
-
clearGlobalStyles();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('SafeAreaView', () => {
|
|
34
|
-
it('resolves a class= on the SafeAreaView use site onto the real committed view, not the anchor', async () => {
|
|
35
|
-
registerStyles({ screen: { backgroundColor: 'navy' } });
|
|
36
|
-
|
|
37
|
-
mount(ROOT_TAG, SafeAreaViewHostFixture);
|
|
38
|
-
await new Promise<void>(resolve => setTimeout(resolve, 0));
|
|
39
|
-
|
|
40
|
-
const node = fabric.find(n => n.props.testID === 'safe-area');
|
|
41
|
-
expect(node?.props.backgroundColor).toBe('navy');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
// Regression test for an Android content-projection bug:
|
|
2
|
-
// ScrollView on Android picks a different native content view per axis (RCTView vs
|
|
3
|
-
// AndroidHorizontalScrollContentView), which used to require a separate <ng-content> per
|
|
4
|
-
// axis x refresh-control combination — and Angular only reliably projects into a component's
|
|
5
|
-
// LAST-declared <ng-content> when 2+ distinct declarations exist. Fixed by routing all four
|
|
6
|
-
// branches through a single shared <ng-template>/<ng-content> via a local template-outlet
|
|
7
|
-
// directive (see index.android.ts). Covers all four static combinations plus a runtime axis
|
|
8
|
-
// flip, which the projection.ts records/reconcile path must survive without dropping children.
|
|
9
|
-
import '@angular/compiler';
|
|
10
|
-
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
|
|
11
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
12
|
-
import { installFabric } from '@symbiote-native/test-utils';
|
|
13
|
-
import { mount, unmount } from '../../render';
|
|
14
|
-
import { RefreshControl } from '../refresh-control';
|
|
15
|
-
import { ScrollView } from './index.android';
|
|
16
|
-
|
|
17
|
-
const ROOT_TAG = 919;
|
|
18
|
-
const fabric = installFabric();
|
|
19
|
-
const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
|
|
20
|
-
|
|
21
|
-
function expectCellsProjected(): void {
|
|
22
|
-
expect(fabric.find(node => node.props.testID === 'a')).toBeDefined();
|
|
23
|
-
expect(fabric.find(node => node.props.testID === 'b')).toBeDefined();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
class HorizontalNoRefreshApp {}
|
|
27
|
-
Component({
|
|
28
|
-
selector: 'axis-projection-horizontal-no-refresh',
|
|
29
|
-
standalone: true,
|
|
30
|
-
imports: [ScrollView],
|
|
31
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
32
|
-
template: `
|
|
33
|
-
<ScrollView [horizontal]="true">
|
|
34
|
-
<symbiote-view testID="a"></symbiote-view>
|
|
35
|
-
<symbiote-view testID="b"></symbiote-view>
|
|
36
|
-
</ScrollView>
|
|
37
|
-
`,
|
|
38
|
-
})(HorizontalNoRefreshApp);
|
|
39
|
-
|
|
40
|
-
class HorizontalRefreshApp {
|
|
41
|
-
refresh = (): void => {};
|
|
42
|
-
}
|
|
43
|
-
Component({
|
|
44
|
-
selector: 'axis-projection-horizontal-refresh',
|
|
45
|
-
standalone: true,
|
|
46
|
-
imports: [ScrollView, RefreshControl],
|
|
47
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
48
|
-
template: `
|
|
49
|
-
<ScrollView [horizontal]="true">
|
|
50
|
-
<RefreshControl [refreshing]="true" (refresh)="refresh()" />
|
|
51
|
-
<symbiote-view testID="a"></symbiote-view>
|
|
52
|
-
<symbiote-view testID="b"></symbiote-view>
|
|
53
|
-
</ScrollView>
|
|
54
|
-
`,
|
|
55
|
-
})(HorizontalRefreshApp);
|
|
56
|
-
|
|
57
|
-
class VerticalNoRefreshApp {}
|
|
58
|
-
Component({
|
|
59
|
-
selector: 'axis-projection-vertical-no-refresh',
|
|
60
|
-
standalone: true,
|
|
61
|
-
imports: [ScrollView],
|
|
62
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
63
|
-
template: `
|
|
64
|
-
<ScrollView>
|
|
65
|
-
<symbiote-view testID="a"></symbiote-view>
|
|
66
|
-
<symbiote-view testID="b"></symbiote-view>
|
|
67
|
-
</ScrollView>
|
|
68
|
-
`,
|
|
69
|
-
})(VerticalNoRefreshApp);
|
|
70
|
-
|
|
71
|
-
class AxisSwitchApp {
|
|
72
|
-
static readonly horizontal = signal(false);
|
|
73
|
-
get isHorizontal(): boolean {
|
|
74
|
-
return AxisSwitchApp.horizontal();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
Component({
|
|
78
|
-
selector: 'axis-projection-axis-switch',
|
|
79
|
-
standalone: true,
|
|
80
|
-
imports: [ScrollView],
|
|
81
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
82
|
-
template: `
|
|
83
|
-
<ScrollView [horizontal]="isHorizontal">
|
|
84
|
-
<symbiote-view testID="a"></symbiote-view>
|
|
85
|
-
<symbiote-view testID="b"></symbiote-view>
|
|
86
|
-
</ScrollView>
|
|
87
|
-
`,
|
|
88
|
-
})(AxisSwitchApp);
|
|
89
|
-
|
|
90
|
-
beforeEach(() => fabric.reset());
|
|
91
|
-
afterEach(() => unmount(ROOT_TAG));
|
|
92
|
-
|
|
93
|
-
describe('Android ScrollView projects content across every axis x refresh combination', () => {
|
|
94
|
-
it('horizontal, no refresh control', async () => {
|
|
95
|
-
mount(ROOT_TAG, HorizontalNoRefreshApp);
|
|
96
|
-
await tick();
|
|
97
|
-
expectCellsProjected();
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('horizontal, with a projected refresh control', async () => {
|
|
101
|
-
mount(ROOT_TAG, HorizontalRefreshApp);
|
|
102
|
-
await tick();
|
|
103
|
-
expectCellsProjected();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('vertical, no refresh control', async () => {
|
|
107
|
-
mount(ROOT_TAG, VerticalNoRefreshApp);
|
|
108
|
-
await tick();
|
|
109
|
-
expectCellsProjected();
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('survives a runtime vertical -> horizontal axis switch', async () => {
|
|
113
|
-
AxisSwitchApp.horizontal.set(false);
|
|
114
|
-
mount(ROOT_TAG, AxisSwitchApp);
|
|
115
|
-
await tick();
|
|
116
|
-
expectCellsProjected();
|
|
117
|
-
|
|
118
|
-
AxisSwitchApp.horizontal.set(true);
|
|
119
|
-
await tick();
|
|
120
|
-
await tick();
|
|
121
|
-
expectCellsProjected();
|
|
122
|
-
});
|
|
123
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// Regression guard: contentContainerStyle previously accepted ONLY a JS style object/array. It
|
|
2
|
-
// now also resolves a class-name string through the shared style registry, same as `class`/
|
|
3
|
-
// `style` (see shared.ts's resolvedContentContainerStyle getter). Mirrors the Vue twin
|
|
4
|
-
// (content-container-style-class.test.ts) and scroll-view-class-style.test.ts's style-for-this-
|
|
5
|
-
// exact-scenario shape.
|
|
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, type IFakeNode } from '@symbiote-native/test-utils';
|
|
11
|
-
|
|
12
|
-
import { mount, unmount } from '../../render';
|
|
13
|
-
import { ScrollView } from './index.ios';
|
|
14
|
-
|
|
15
|
-
const ROOT_TAG = 952;
|
|
16
|
-
const fabric = installFabric();
|
|
17
|
-
const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
|
|
18
|
-
|
|
19
|
-
function committedContentView(): IFakeNode {
|
|
20
|
-
const node = fabric.find(n => n.viewName === 'RCTScrollContentView');
|
|
21
|
-
expect(node, 'the scroll content view was committed').toBeDefined();
|
|
22
|
-
if (node === undefined) throw new Error('unreachable: content view missing');
|
|
23
|
-
return node;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Component({
|
|
27
|
-
selector: 'symbiote-scroll-content-style-class-host',
|
|
28
|
-
standalone: true,
|
|
29
|
-
imports: [ScrollView],
|
|
30
|
-
template: `
|
|
31
|
-
<ScrollView [contentContainerStyle]="'padded'">
|
|
32
|
-
<symbiote-text>content</symbiote-text>
|
|
33
|
-
</ScrollView>
|
|
34
|
-
`,
|
|
35
|
-
})
|
|
36
|
-
class ScrollViewContentStyleClassHost {}
|
|
37
|
-
|
|
38
|
-
@Component({
|
|
39
|
-
selector: 'symbiote-scroll-content-style-object-host',
|
|
40
|
-
standalone: true,
|
|
41
|
-
imports: [ScrollView],
|
|
42
|
-
template: `
|
|
43
|
-
<ScrollView [contentContainerStyle]="{ padding: 12 }">
|
|
44
|
-
<symbiote-text>content</symbiote-text>
|
|
45
|
-
</ScrollView>
|
|
46
|
-
`,
|
|
47
|
-
})
|
|
48
|
-
class ScrollViewContentStyleObjectHost {}
|
|
49
|
-
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
fabric.reset();
|
|
52
|
-
registerStyles({ padded: { padding: 20 } });
|
|
53
|
-
});
|
|
54
|
-
afterEach(() => {
|
|
55
|
-
unmount(ROOT_TAG);
|
|
56
|
-
clearGlobalStyles();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('ScrollView contentContainerStyle class-name support', () => {
|
|
60
|
-
it('resolves a class-name string onto the content view, not the outer scroll view', async () => {
|
|
61
|
-
mount(ROOT_TAG, ScrollViewContentStyleClassHost);
|
|
62
|
-
await tick();
|
|
63
|
-
|
|
64
|
-
expect(committedContentView().props.padding).toBe(20);
|
|
65
|
-
const scrollHost = fabric.find(n => n.viewName === 'RCTScrollView');
|
|
66
|
-
expect(scrollHost?.props.padding).toBeUndefined();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('still accepts an ordinary style object unchanged', async () => {
|
|
70
|
-
mount(ROOT_TAG, ScrollViewContentStyleObjectHost);
|
|
71
|
-
await tick();
|
|
72
|
-
|
|
73
|
-
expect(committedContentView().props.padding).toBe(12);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
@@ -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
|
-
});
|