@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.
Files changed (193) hide show
  1. package/README.md +1 -1
  2. package/babel-register-composed.cjs +11 -3
  3. package/build/angular/anchor-host-registry.d.ts +2 -0
  4. package/build/angular/anchor-host-registry.js +84 -0
  5. package/build/angular/anchor-host-registry.js.map +1 -0
  6. package/build/angular/components/input-accessory-view/index.d.ts +2 -1
  7. package/build/angular/components/input-accessory-view/index.js +28 -39
  8. package/build/angular/components/input-accessory-view/index.js.map +1 -1
  9. package/build/angular/components/scroll-view/projection.js +70 -48
  10. package/build/angular/components/scroll-view/projection.js.map +1 -1
  11. package/build/angular/components/scroll-view/shared.js +28 -25
  12. package/build/angular/components/scroll-view/shared.js.map +1 -1
  13. package/build/angular/components/scroll-view/sticky-header.d.ts +6 -7
  14. package/build/angular/components/scroll-view/sticky-header.js +82 -65
  15. package/build/angular/components/scroll-view/sticky-header.js.map +1 -1
  16. package/build/angular/components/touchable/index.d.ts +2 -5
  17. package/build/angular/components/touchable/index.js +36 -56
  18. package/build/angular/components/touchable/index.js.map +1 -1
  19. package/build/angular/components/virtualized-list/index.d.ts +5 -20
  20. package/build/angular/components/virtualized-list/index.js +145 -275
  21. package/build/angular/components/virtualized-list/index.js.map +1 -1
  22. package/build/angular/components/virtualized-section-list/index.js +2 -4
  23. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  24. package/build/angular/index.d.ts +2 -1
  25. package/build/angular/index.js +6 -1
  26. package/build/angular/index.js.map +1 -1
  27. package/build/angular/renderer/index.d.ts +0 -1
  28. package/build/angular/renderer/index.js +5 -60
  29. package/build/angular/renderer/index.js.map +1 -1
  30. package/package.json +8 -4
  31. package/src/anchor-host-registry.ts +88 -0
  32. package/src/components/input-accessory-view/index.ts +30 -39
  33. package/src/components/scroll-view/projection.ts +76 -46
  34. package/src/components/scroll-view/shared.ts +27 -19
  35. package/src/components/scroll-view/sticky-header.ts +89 -64
  36. package/src/components/touchable/index.ts +52 -66
  37. package/src/components/virtualized-list/index.ts +157 -368
  38. package/src/components/virtualized-section-list/index.ts +6 -3
  39. package/src/index.ts +6 -1
  40. package/src/renderer/index.ts +5 -63
  41. package/build/bootstrap.d.ts +0 -7
  42. package/build/bootstrap.js +0 -14
  43. package/build/components/activity-indicator/index.android.d.ts +0 -9
  44. package/build/components/activity-indicator/index.android.js +0 -64
  45. package/build/components/activity-indicator/index.d.ts +0 -1
  46. package/build/components/activity-indicator/index.ios.d.ts +0 -5
  47. package/build/components/activity-indicator/index.ios.js +0 -64
  48. package/build/components/activity-indicator/index.js +0 -3
  49. package/build/components/activity-indicator/shared.d.ts +0 -64
  50. package/build/components/activity-indicator/shared.js +0 -424
  51. package/build/components/button.d.ts +0 -60
  52. package/build/components/button.js +0 -456
  53. package/build/components/flat-list/index.d.ts +0 -119
  54. package/build/components/flat-list/index.js +0 -691
  55. package/build/components/image/index.android.d.ts +0 -7
  56. package/build/components/image/index.android.js +0 -88
  57. package/build/components/image/index.d.ts +0 -1
  58. package/build/components/image/index.ios.d.ts +0 -7
  59. package/build/components/image/index.ios.js +0 -88
  60. package/build/components/image/index.js +0 -2
  61. package/build/components/image/shared.d.ts +0 -101
  62. package/build/components/image/shared.js +0 -405
  63. package/build/components/image-background.d.ts +0 -78
  64. package/build/components/image-background.js +0 -583
  65. package/build/components/input-accessory-view/index.d.ts +0 -56
  66. package/build/components/input-accessory-view/index.js +0 -403
  67. package/build/components/keyboard-avoiding-view/index.d.ts +0 -79
  68. package/build/components/keyboard-avoiding-view/index.js +0 -504
  69. package/build/components/modal/index.d.ts +0 -89
  70. package/build/components/modal/index.js +0 -529
  71. package/build/components/pressable/index.d.ts +0 -120
  72. package/build/components/pressable/index.js +0 -639
  73. package/build/components/refresh-control/index.d.ts +0 -83
  74. package/build/components/refresh-control/index.js +0 -509
  75. package/build/components/safe-area-view/index.d.ts +0 -54
  76. package/build/components/safe-area-view/index.js +0 -388
  77. package/build/components/scroll-view/index.android.d.ts +0 -16
  78. package/build/components/scroll-view/index.android.js +0 -228
  79. package/build/components/scroll-view/index.d.ts +0 -3
  80. package/build/components/scroll-view/index.ios.d.ts +0 -6
  81. package/build/components/scroll-view/index.ios.js +0 -113
  82. package/build/components/scroll-view/index.js +0 -5
  83. package/build/components/scroll-view/projection.d.ts +0 -32
  84. package/build/components/scroll-view/projection.js +0 -311
  85. package/build/components/scroll-view/shared.d.ts +0 -225
  86. package/build/components/scroll-view/shared.js +0 -757
  87. package/build/components/scroll-view/sticky-header.d.ts +0 -38
  88. package/build/components/scroll-view/sticky-header.js +0 -257
  89. package/build/components/section-list/index.d.ts +0 -113
  90. package/build/components/section-list/index.js +0 -768
  91. package/build/components/switch/index.android.d.ts +0 -17
  92. package/build/components/switch/index.android.js +0 -107
  93. package/build/components/switch/index.d.ts +0 -1
  94. package/build/components/switch/index.ios.d.ts +0 -16
  95. package/build/components/switch/index.ios.js +0 -106
  96. package/build/components/switch/index.js +0 -3
  97. package/build/components/switch/shared.d.ts +0 -37
  98. package/build/components/switch/shared.js +0 -176
  99. package/build/components/text-input.d.ts +0 -150
  100. package/build/components/text-input.js +0 -821
  101. package/build/components/touchable/index.d.ts +0 -241
  102. package/build/components/touchable/index.js +0 -1672
  103. package/build/components/touchable-native-feedback/index.d.ts +0 -80
  104. package/build/components/touchable-native-feedback/index.js +0 -545
  105. package/build/components/virtualized-list/directives.d.ts +0 -41
  106. package/build/components/virtualized-list/directives.js +0 -249
  107. package/build/components/virtualized-list/index.d.ts +0 -265
  108. package/build/components/virtualized-list/index.js +0 -1343
  109. package/build/components/virtualized-section-list/directives.d.ts +0 -28
  110. package/build/components/virtualized-section-list/directives.js +0 -148
  111. package/build/components/virtualized-section-list/index.d.ts +0 -175
  112. package/build/components/virtualized-section-list/index.js +0 -854
  113. package/build/components.d.ts +0 -39
  114. package/build/components.js +0 -37
  115. package/build/create-portal/index.d.ts +0 -17
  116. package/build/create-portal/index.js +0 -128
  117. package/build/create-tunnel/index.d.ts +0 -29
  118. package/build/create-tunnel/index.js +0 -181
  119. package/build/descriptor-to-angular/index.d.ts +0 -19
  120. package/build/descriptor-to-angular/index.js +0 -186
  121. package/build/host-instance/index.d.ts +0 -2
  122. package/build/host-instance/index.js +0 -36
  123. package/build/index.d.ts +0 -21
  124. package/build/index.js +0 -40
  125. package/build/modules/animated/animated-leaf-binder/index.d.ts +0 -14
  126. package/build/modules/animated/animated-leaf-binder/index.js +0 -90
  127. package/build/modules/animated/animated-leaf-binder.d.ts +0 -14
  128. package/build/modules/animated/animated-leaf-binder.js +0 -90
  129. package/build/modules/animated/create-animated-component.d.ts +0 -48
  130. package/build/modules/animated/create-animated-component.js +0 -425
  131. package/build/modules/animated/index.d.ts +0 -51
  132. package/build/modules/animated/index.js +0 -58
  133. package/build/modules/app-registry/index.d.ts +0 -7
  134. package/build/modules/app-registry/index.js +0 -22
  135. package/build/modules/status-bar/index.d.ts +0 -17
  136. package/build/modules/status-bar/index.js +0 -121
  137. package/build/primitives/index.d.ts +0 -32
  138. package/build/primitives/index.js +0 -386
  139. package/build/primitives/shared.d.ts +0 -83
  140. package/build/primitives/shared.js +0 -230
  141. package/build/render/index.d.ts +0 -11
  142. package/build/render/index.js +0 -170
  143. package/build/renderer/index.d.ts +0 -38
  144. package/build/renderer/index.js +0 -355
  145. package/build/services/color-scheme.service.d.ts +0 -13
  146. package/build/services/color-scheme.service.js +0 -72
  147. package/build/services/index.d.ts +0 -2
  148. package/build/services/index.js +0 -2
  149. package/build/services/window-dimensions.service.d.ts +0 -13
  150. package/build/services/window-dimensions.service.js +0 -83
  151. package/src/__tests__/responder-change-detection.test.ts +0 -102
  152. package/src/__tests__/responder-nested-cd.test.ts +0 -113
  153. package/src/angular-gaps.test.ts +0 -142
  154. package/src/angular-imports.test.ts +0 -100
  155. package/src/components/activity-indicator/activity-indicator-class-style.test.ts +0 -44
  156. package/src/components/activity-indicator/activity-indicator.test.ts +0 -131
  157. package/src/components/flat-list/column-wrapper-style-class.test.ts +0 -116
  158. package/src/components/flat-list/flat-list-array-style.test.ts +0 -131
  159. package/src/components/flat-list/flat-list-class-style.test.ts +0 -74
  160. package/src/components/flat-list/flat-list-scroll-containment.test.ts +0 -107
  161. package/src/components/flat-list/flat-list.test.ts +0 -99
  162. package/src/components/image/image-class-style.test.ts +0 -46
  163. package/src/components/image-background-class-style.test.ts +0 -48
  164. package/src/components/image-background-style-class.test.ts +0 -79
  165. package/src/components/input-accessory-view/input-accessory-view.test.ts +0 -43
  166. package/src/components/keyboard-avoiding-view/keyboard-avoiding-view.test.ts +0 -54
  167. package/src/components/modal/modal.test.ts +0 -43
  168. package/src/components/pressable/pressable.test.ts +0 -85
  169. package/src/components/refresh-control/refresh-control.test.ts +0 -41
  170. package/src/components/safe-area-view/safe-area-view.test.ts +0 -43
  171. package/src/components/scroll-view/android-scroll-view-axis-projection.test.ts +0 -123
  172. package/src/components/scroll-view/content-container-style-class.test.ts +0 -75
  173. package/src/components/scroll-view/scroll-view-class-style.test.ts +0 -134
  174. package/src/components/scroll-view/scroll-view-projection.test.ts +0 -194
  175. package/src/components/switch/android-switch-class.test.ts +0 -42
  176. package/src/components/switch/switch.test.ts +0 -92
  177. package/src/components/text-input-class-style.test.ts +0 -54
  178. package/src/components/touchable/touchable.test.ts +0 -102
  179. package/src/components/touchable-native-feedback/touchable-native-feedback.test.ts +0 -49
  180. package/src/components/virtualized-list/virtualized-list-class-style.test.ts +0 -76
  181. package/src/components/virtualized-section-list/virtualized-section-list-class-style.test.ts +0 -60
  182. package/src/create-portal/create-portal.test.ts +0 -90
  183. package/src/create-tunnel/create-tunnel.test.ts +0 -120
  184. package/src/descriptor-to-angular/descriptor-outlet.test.ts +0 -94
  185. package/src/host-instance/host-instance.test.ts +0 -49
  186. package/src/modules/animated/animated-leaf-binder/animated-leaf-binder.test.ts +0 -116
  187. package/src/modules/animated/animated-leaf-binder.test.ts +0 -116
  188. package/src/modules/animated/animated-scroll-view.test.ts +0 -102
  189. package/src/modules/app-registry/app-registry.test.ts +0 -106
  190. package/src/modules/status-bar/status-bar.test.ts +0 -50
  191. package/src/render/render.test.ts +0 -147
  192. package/src/renderer/renderer.test.ts +0 -202
  193. package/src/services/services.test.ts +0 -163
@@ -1,757 +0,0 @@
1
- // ScrollView, the Angular lifecycle half. The Fabric tree is nested: a scroll view
2
- // wraps a content view that holds the children (RN's ScrollView.js shape). The platform-invariant
3
- // math (decelerationRate, the per-axis intrinsics/base style, the content-size dedupe, the
4
- // imperative handle, the native sticky scroll-attach, the aria/role fold) lives in
5
- // @symbiote-native/components, shared verbatim with React/Vue. Here Angular supplies only the lifecycle:
6
- // the host node held by IDENTITY through a directive's ElementRef, a forwarded-prop bag set onto
7
- // that node through Renderer2 (-> routeProp), the imperative handle (scrollTo/scrollToEnd/
8
- // flashScrollIndicators), the content-size dedupe, and the native sticky scroll-attach wired
9
- // through whenCommitted. This is the Angular twin of the React useRef + Vue shallowRef host.
10
- //
11
- // What diverges per platform, how a RefreshControl integrates, stays in the
12
- // .ios/.android files (Metro filename-selected): iOS renders the RefreshControl as a SIBLING
13
- // before the content container; on Android an AndroidSwipeRefreshLayout WRAPS the scroll view.
14
- //
15
- // Angular cannot transform <ng-content> children in the template the way React children.map /
16
- // Vue slots() can, so ScrollView owns a tiny projection bridge: the content host registers a
17
- // ScrollViewProjectionController with the Angular renderer, and the renderer wraps direct projected
18
- // children whose indices match stickyHeaderIndices. Android RefreshControl projection is handled by
19
- // re-rendering the projected component's native prop surface as the wrapper around the scroll view
20
- // (RN's Android shape), while excluding the original projected node from the content slot.
21
- var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
22
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
23
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
24
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
25
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
26
- var _, done = false;
27
- for (var i = decorators.length - 1; i >= 0; i--) {
28
- var context = {};
29
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
30
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
31
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
32
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
33
- if (kind === "accessor") {
34
- if (result === void 0) continue;
35
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
36
- if (_ = accept(result.get)) descriptor.get = _;
37
- if (_ = accept(result.set)) descriptor.set = _;
38
- if (_ = accept(result.init)) initializers.unshift(_);
39
- }
40
- else if (_ = accept(result)) {
41
- if (kind === "field") initializers.unshift(_);
42
- else descriptor[key] = _;
43
- }
44
- }
45
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
46
- done = true;
47
- };
48
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
49
- var useValue = arguments.length > 2;
50
- for (var i = 0; i < initializers.length; i++) {
51
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
52
- }
53
- return useValue ? value : void 0;
54
- };
55
- import { Directive, ElementRef, EventEmitter, Output, ViewChild, ContentChild, inject, } from '@angular/core';
56
- import { attachStickyScroll, buildScrollViewHandle, didContentSizeChange, forwardScrollEvent, readLayoutDimension, resolveAccessibilityProps, resolveDecelerationRate, selectScrollIntrinsics, splitLayoutProps, } from '@symbiote-native/components';
57
- import { AnimatedValue, dlog, event as animatedEvent, isNativeAnimatedAvailable, isSymbioteNode, resolveClassName, whenCommitted, } from '@symbiote-native/engine';
58
- import { SymbioteHostPropsDirective } from '../../primitives';
59
- import { RefreshControl } from '../refresh-control';
60
- import { ScrollViewProjectionController } from './projection';
61
- // The inputs every platform ScrollView accepts, listed on each concrete @Component (the adapter
62
- // convention, mirroring Switch/Animated) so the base fields bind consistently. The aria-* /
63
- // role aliases ride here too and are folded by resolveAccessibilityProps before reaching native.
64
- export const SCROLL_VIEW_INPUTS = [
65
- 'style',
66
- 'contentContainerStyle',
67
- 'horizontal',
68
- 'scrollEnabled',
69
- 'showsVerticalScrollIndicator',
70
- 'showsHorizontalScrollIndicator',
71
- 'pagingEnabled',
72
- 'bounces',
73
- 'decelerationRate',
74
- 'scrollEventThrottle',
75
- 'contentInset',
76
- 'contentOffset',
77
- 'removeClippedSubviews',
78
- 'snapToInterval',
79
- 'snapToOffsets',
80
- 'snapToAlignment',
81
- 'snapToStart',
82
- 'snapToEnd',
83
- 'disableIntervalMomentum',
84
- 'stickyHeaderIndices',
85
- 'invertStickyHeaders',
86
- 'StickyHeaderComponent',
87
- 'keyboardDismissMode',
88
- 'keyboardShouldPersistTaps',
89
- 'maintainVisibleContentPosition',
90
- 'alwaysBounceHorizontal',
91
- 'alwaysBounceVertical',
92
- 'centerContent',
93
- 'scrollIndicatorInsets',
94
- 'indicatorStyle',
95
- 'directionalLockEnabled',
96
- 'automaticallyAdjustKeyboardInsets',
97
- 'contentInsetAdjustmentBehavior',
98
- 'minimumZoomScale',
99
- 'maximumZoomScale',
100
- 'zoomScale',
101
- 'bouncesZoom',
102
- 'pinchGestureEnabled',
103
- 'nestedScrollEnabled',
104
- 'overScrollMode',
105
- 'fadingEdgeLength',
106
- 'persistentScrollbar',
107
- 'endFillColor',
108
- 'onScroll',
109
- 'onScrollBeginDrag',
110
- 'onScrollEndDrag',
111
- 'onMomentumScrollBegin',
112
- 'onMomentumScrollEnd',
113
- 'testID',
114
- 'nativeID',
115
- 'accessible',
116
- 'accessibilityLabel',
117
- 'accessibilityHint',
118
- 'accessibilityRole',
119
- 'accessibilityState',
120
- 'accessibilityValue',
121
- 'accessibilityActions',
122
- 'accessibilityLabelledBy',
123
- 'importantForAccessibility',
124
- 'accessibilityLiveRegion',
125
- 'screenReaderFocusable',
126
- 'accessibilityViewIsModal',
127
- 'accessibilityElementsHidden',
128
- 'accessibilityIgnoresInvertColors',
129
- 'accessibilityLanguage',
130
- 'accessibilityRespondsToUserInteraction',
131
- 'accessibilityShowsLargeContentViewer',
132
- 'accessibilityLargeContentTitle',
133
- 'role',
134
- 'aria-label',
135
- 'aria-labelledby',
136
- 'aria-live',
137
- 'aria-hidden',
138
- 'aria-busy',
139
- 'aria-checked',
140
- 'aria-disabled',
141
- 'aria-expanded',
142
- 'aria-selected',
143
- 'aria-modal',
144
- 'aria-valuemax',
145
- 'aria-valuemin',
146
- 'aria-valuenow',
147
- 'aria-valuetext',
148
- ];
149
- // Strip undefined entries so a prop the user never set is not forwarded to the host (an undefined
150
- // reaching Fabric is at best a no-op, at worst clears a default). The Angular twin of React/Vue
151
- // destructuring `...rest` past the defined props.
152
- function compact(bag) {
153
- const result = {};
154
- for (const key of Object.keys(bag)) {
155
- if (bag[key] !== undefined)
156
- result[key] = bag[key];
157
- }
158
- return result;
159
- }
160
- // ScrollView's forwarded surface (scroll events + the snap/keyboard/zoom families) is exactly the
161
- // flat-bag shape SymbioteHostPropsDirective spreads onto a host element via Renderer2 (-> routeProp).
162
- // The scroll-event callbacks ride this bag (not the (event) channel) because routeProp must be free
163
- // to wire onScroll as an Animated.event when sticky headers drive the value natively, which the
164
- // listen()/setEventListener channel cannot carry. This mirrors React/Vue putting onScroll on
165
- // outerProps.
166
- let ScrollViewProjectionDirective = (() => {
167
- let _classDecorators = [Directive({
168
- selector: '[symbioteScrollViewProjection]',
169
- standalone: true,
170
- inputs: ['symbioteScrollViewProjection'],
171
- })];
172
- let _classDescriptor;
173
- let _classExtraInitializers = [];
174
- let _classThis;
175
- var ScrollViewProjectionDirective = class {
176
- static { _classThis = this; }
177
- static {
178
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
179
- __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
180
- ScrollViewProjectionDirective = _classThis = _classDescriptor.value;
181
- if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
182
- __runInitializers(_classThis, _classExtraInitializers);
183
- }
184
- elementRef = inject(ElementRef);
185
- set symbioteScrollViewProjection(controller) {
186
- const node = this.elementRef.nativeElement;
187
- if (isSymbioteNode(node))
188
- controller.bindContentNode(node);
189
- }
190
- };
191
- return ScrollViewProjectionDirective = _classThis;
192
- })();
193
- export { ScrollViewProjectionDirective };
194
- // @Directive() (no selector) is the Angular-sanctioned decorator for an abstract base that
195
- // declares lifecycle hooks and @ViewChild queries (mirrors AnimatedComponentBase) — without it
196
- // ngtsc rejects the inherited hooks/queries (NG2007). The concrete platform @Components add ONLY a
197
- // decorator + their platform template; all behavior lives here.
198
- let ScrollViewBase = (() => {
199
- let _classDecorators = [Directive()];
200
- let _classDescriptor;
201
- let _classExtraInitializers = [];
202
- let _classThis;
203
- let _layout_decorators;
204
- let _layout_initializers = [];
205
- let _layout_extraInitializers = [];
206
- let _scrollToTop_decorators;
207
- let _scrollToTop_initializers = [];
208
- let _scrollToTop_extraInitializers = [];
209
- let _contentSizeChange_decorators;
210
- let _contentSizeChange_initializers = [];
211
- let _contentSizeChange_extraInitializers = [];
212
- let _accessibilityAction_decorators;
213
- let _accessibilityAction_initializers = [];
214
- let _accessibilityAction_extraInitializers = [];
215
- let _accessibilityTap_decorators;
216
- let _accessibilityTap_initializers = [];
217
- let _accessibilityTap_extraInitializers = [];
218
- let _magicTap_decorators;
219
- let _magicTap_initializers = [];
220
- let _magicTap_extraInitializers = [];
221
- let _accessibilityEscape_decorators;
222
- let _accessibilityEscape_initializers = [];
223
- let _accessibilityEscape_extraInitializers = [];
224
- let _hostDirective_decorators;
225
- let _hostDirective_initializers = [];
226
- let _hostDirective_extraInitializers = [];
227
- let _projectedRefreshControl_decorators;
228
- let _projectedRefreshControl_initializers = [];
229
- let _projectedRefreshControl_extraInitializers = [];
230
- var ScrollViewBase = class {
231
- static { _classThis = this; }
232
- static {
233
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
234
- _layout_decorators = [Output()];
235
- _scrollToTop_decorators = [Output()];
236
- _contentSizeChange_decorators = [Output()];
237
- _accessibilityAction_decorators = [Output()];
238
- _accessibilityTap_decorators = [Output()];
239
- _magicTap_decorators = [Output()];
240
- _accessibilityEscape_decorators = [Output()];
241
- _hostDirective_decorators = [ViewChild('host', { read: SymbioteHostPropsDirective })];
242
- _projectedRefreshControl_decorators = [ContentChild(RefreshControl)];
243
- __esDecorate(null, null, _layout_decorators, { kind: "field", name: "layout", static: false, private: false, access: { has: obj => "layout" in obj, get: obj => obj.layout, set: (obj, value) => { obj.layout = value; } }, metadata: _metadata }, _layout_initializers, _layout_extraInitializers);
244
- __esDecorate(null, null, _scrollToTop_decorators, { kind: "field", name: "scrollToTop", static: false, private: false, access: { has: obj => "scrollToTop" in obj, get: obj => obj.scrollToTop, set: (obj, value) => { obj.scrollToTop = value; } }, metadata: _metadata }, _scrollToTop_initializers, _scrollToTop_extraInitializers);
245
- __esDecorate(null, null, _contentSizeChange_decorators, { kind: "field", name: "contentSizeChange", static: false, private: false, access: { has: obj => "contentSizeChange" in obj, get: obj => obj.contentSizeChange, set: (obj, value) => { obj.contentSizeChange = value; } }, metadata: _metadata }, _contentSizeChange_initializers, _contentSizeChange_extraInitializers);
246
- __esDecorate(null, null, _accessibilityAction_decorators, { kind: "field", name: "accessibilityAction", static: false, private: false, access: { has: obj => "accessibilityAction" in obj, get: obj => obj.accessibilityAction, set: (obj, value) => { obj.accessibilityAction = value; } }, metadata: _metadata }, _accessibilityAction_initializers, _accessibilityAction_extraInitializers);
247
- __esDecorate(null, null, _accessibilityTap_decorators, { kind: "field", name: "accessibilityTap", static: false, private: false, access: { has: obj => "accessibilityTap" in obj, get: obj => obj.accessibilityTap, set: (obj, value) => { obj.accessibilityTap = value; } }, metadata: _metadata }, _accessibilityTap_initializers, _accessibilityTap_extraInitializers);
248
- __esDecorate(null, null, _magicTap_decorators, { kind: "field", name: "magicTap", static: false, private: false, access: { has: obj => "magicTap" in obj, get: obj => obj.magicTap, set: (obj, value) => { obj.magicTap = value; } }, metadata: _metadata }, _magicTap_initializers, _magicTap_extraInitializers);
249
- __esDecorate(null, null, _accessibilityEscape_decorators, { kind: "field", name: "accessibilityEscape", static: false, private: false, access: { has: obj => "accessibilityEscape" in obj, get: obj => obj.accessibilityEscape, set: (obj, value) => { obj.accessibilityEscape = value; } }, metadata: _metadata }, _accessibilityEscape_initializers, _accessibilityEscape_extraInitializers);
250
- __esDecorate(null, null, _hostDirective_decorators, { kind: "field", name: "hostDirective", static: false, private: false, access: { has: obj => "hostDirective" in obj, get: obj => obj.hostDirective, set: (obj, value) => { obj.hostDirective = value; } }, metadata: _metadata }, _hostDirective_initializers, _hostDirective_extraInitializers);
251
- __esDecorate(null, null, _projectedRefreshControl_decorators, { kind: "field", name: "projectedRefreshControl", static: false, private: false, access: { has: obj => "projectedRefreshControl" in obj, get: obj => obj.projectedRefreshControl, set: (obj, value) => { obj.projectedRefreshControl = value; } }, metadata: _metadata }, _projectedRefreshControl_initializers, _projectedRefreshControl_extraInitializers);
252
- __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
253
- ScrollViewBase = _classThis = _classDescriptor.value;
254
- if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
255
- __runInitializers(_classThis, _classExtraInitializers);
256
- }
257
- style;
258
- contentContainerStyle;
259
- horizontal;
260
- scrollEnabled;
261
- showsVerticalScrollIndicator;
262
- showsHorizontalScrollIndicator;
263
- pagingEnabled;
264
- bounces;
265
- decelerationRate;
266
- scrollEventThrottle;
267
- contentInset;
268
- contentOffset;
269
- removeClippedSubviews;
270
- snapToInterval;
271
- snapToOffsets;
272
- snapToAlignment;
273
- snapToStart;
274
- snapToEnd;
275
- disableIntervalMomentum;
276
- stickyHeaderIndices;
277
- invertStickyHeaders;
278
- StickyHeaderComponent;
279
- keyboardDismissMode;
280
- keyboardShouldPersistTaps;
281
- maintainVisibleContentPosition;
282
- alwaysBounceHorizontal;
283
- alwaysBounceVertical;
284
- centerContent;
285
- scrollIndicatorInsets;
286
- indicatorStyle;
287
- directionalLockEnabled;
288
- automaticallyAdjustKeyboardInsets;
289
- contentInsetAdjustmentBehavior;
290
- minimumZoomScale;
291
- maximumZoomScale;
292
- zoomScale;
293
- bouncesZoom;
294
- pinchGestureEnabled;
295
- nestedScrollEnabled;
296
- overScrollMode;
297
- fadingEdgeLength;
298
- persistentScrollbar;
299
- endFillColor;
300
- onScroll;
301
- onScrollBeginDrag;
302
- onScrollEndDrag;
303
- onMomentumScrollBegin;
304
- onMomentumScrollEnd;
305
- // The layout/content-size/accessibility events as real Angular events: `(layout)="…"`, not
306
- // `[onLayout]="…"`. onScroll and the drag/momentum family stay plain @Input() callbacks above —
307
- // they must also accept an Animated.event(...) native-driver marker (see the file header note),
308
- // which no @Output() binding can carry.
309
- layout = __runInitializers(this, _layout_initializers, new EventEmitter());
310
- scrollToTop = (__runInitializers(this, _layout_extraInitializers), __runInitializers(this, _scrollToTop_initializers, new EventEmitter()));
311
- contentSizeChange = (__runInitializers(this, _scrollToTop_extraInitializers), __runInitializers(this, _contentSizeChange_initializers, new EventEmitter()));
312
- accessibilityAction = (__runInitializers(this, _contentSizeChange_extraInitializers), __runInitializers(this, _accessibilityAction_initializers, new EventEmitter()));
313
- accessibilityTap = (__runInitializers(this, _accessibilityAction_extraInitializers), __runInitializers(this, _accessibilityTap_initializers, new EventEmitter()));
314
- magicTap = (__runInitializers(this, _accessibilityTap_extraInitializers), __runInitializers(this, _magicTap_initializers, new EventEmitter()));
315
- accessibilityEscape = (__runInitializers(this, _magicTap_extraInitializers), __runInitializers(this, _accessibilityEscape_initializers, new EventEmitter()));
316
- testID = __runInitializers(this, _accessibilityEscape_extraInitializers);
317
- nativeID;
318
- accessible;
319
- accessibilityLabel;
320
- accessibilityHint;
321
- accessibilityRole;
322
- accessibilityState;
323
- accessibilityValue;
324
- accessibilityActions;
325
- accessibilityLabelledBy;
326
- importantForAccessibility;
327
- accessibilityLiveRegion;
328
- screenReaderFocusable;
329
- accessibilityViewIsModal;
330
- accessibilityElementsHidden;
331
- accessibilityIgnoresInvertColors;
332
- accessibilityLanguage;
333
- accessibilityRespondsToUserInteraction;
334
- accessibilityShowsLargeContentViewer;
335
- accessibilityLargeContentTitle;
336
- role;
337
- 'aria-label';
338
- 'aria-labelledby';
339
- 'aria-live';
340
- 'aria-hidden';
341
- 'aria-busy';
342
- 'aria-checked';
343
- 'aria-disabled';
344
- 'aria-expanded';
345
- 'aria-selected';
346
- 'aria-modal';
347
- 'aria-valuemax';
348
- 'aria-valuemin';
349
- 'aria-valuenow';
350
- 'aria-valuetext';
351
- // The host directive on the scroll-view intrinsic; `.node` is the committed SymbioteNode held by
352
- // IDENTITY (Renderer2.createElement returned the engine node, ElementRef hands it back unwrapped).
353
- // Inherited by the decorated subclass — Angular collects base-class @ViewChild queries.
354
- hostDirective = __runInitializers(this, _hostDirective_initializers, void 0);
355
- projectedRefreshControl = (__runInitializers(this, _hostDirective_extraInitializers), __runInitializers(this, _projectedRefreshControl_initializers, void 0));
356
- // A single AnimatedValue tracks the scroll offset and drives every sticky header's translateY
357
- // (RN's _scrollAnimatedValue). A stable field (allocated once, held by identity — Angular does
358
- // not proxy class fields, so no markRaw needed); the native attach below feeds it on the UI
359
- // thread. Allocated unconditionally; inert until a sticky header consumes it.
360
- scrollAnimatedValue = (__runInitializers(this, _projectedRefreshControl_extraInitializers), new AnimatedValue(0));
361
- // The last-seen content size, used to dedupe onContentSizeChange: RN fires the content onLayout
362
- // on every layout pass; only real size changes emit (didContentSizeChange).
363
- lastContentSize = null;
364
- // Inverted sticky headers stick to the BOTTOM, so they need the viewport height (RN _handleLayout).
365
- viewportHeight = undefined;
366
- projectionController = new ScrollViewProjectionController({
367
- stickyHeaderIndices: undefined,
368
- invertStickyHeaders: undefined,
369
- scrollViewHeight: undefined,
370
- scrollAnimatedValue: this.scrollAnimatedValue,
371
- customStickyHeaderComponent: undefined,
372
- excludeRefreshControl: false,
373
- });
374
- // Native sticky-scroll attach (RN attachNativeEvent): when the native module is available the
375
- // scroll value is driven on the UI thread so the interpolations ride scroll natively (no JS
376
- // jitter). Through whenCommitted because under Angular's zoneless batched CD the host's Fabric
377
- // tag does not exist yet at ngAfterViewInit time (the async-commit gotcha Vue documents); the
378
- // bind runs now if committed, else after the commit that assigns the tag. Detached on destroy.
379
- detachStickyScroll;
380
- cancelStickyBind;
381
- lastLoggedIsHorizontal = undefined;
382
- // Stable reference (bound once): inverted sticky headers need the viewport height captured off
383
- // the scroll-view's own onLayout before forwarding to the user (RN _handleLayout). A getter that
384
- // built this arrow function fresh on every `scrollProps` access would hand `[symbioteHostProps]`
385
- // a new function reference every change-detection pass touching this component — jsonEqual
386
- // (commit.ts) falls back to Object.is on a function leaf, so even a structurally-identical bag
387
- // reads as "props changed" and forces a real Fabric re-clone that cascades up every ancestor
388
- // (see AnimatedComponentBase.reconcile()'s identical warning).
389
- handleInvertedStickyLayout = (event) => {
390
- const height = readLayoutDimension(event, 'height');
391
- if (height !== undefined)
392
- this.viewportHeight = height;
393
- this.layout.emit(event);
394
- };
395
- // Same reasoning as handleInvertedStickyLayout: the content view's onLayout synthesizes
396
- // onContentSizeChange (deduped) and must stay a stable reference across `contentProps` re-reads.
397
- handleContentLayout = (event) => {
398
- const width = readLayoutDimension(event, 'width');
399
- const height = readLayoutDimension(event, 'height');
400
- if (width === undefined || height === undefined)
401
- return;
402
- if (!didContentSizeChange(this.lastContentSize, { width, height }))
403
- return;
404
- this.lastContentSize = { width, height };
405
- dlog(`Angular ScrollView contentSizeChange ${width}x${height}`);
406
- this.contentSizeChange.emit({ width, height });
407
- };
408
- // Memoizes the wrapper each `emitterCallback` builds, keyed by the emitter it closes over
409
- // (identity holds across ScrollViewBase's own @Output()s and a projected RefreshControl's,
410
- // since a WeakMap key is just object identity). Without this, `scrollProps`/`refreshControlProps`
411
- // handed a fresh `(event) => emitter.emit(event)` closure to the forwarded prop bag on every
412
- // evaluation — the same jsonEqual/Object.is function-leaf problem as the arrow fields above, one
413
- // level further removed. `.observed` is checked BEFORE the cache so an unbound event still
414
- // resolves to `undefined` (the "nobody cares" contract `emitterCallback`'s own comment documents),
415
- // not a stale cached wrapper from before the last subscriber unsubscribed.
416
- emitterCallbackCache = new WeakMap();
417
- // The sticky JS-path Animated.event handler depends on a REAL input (onScroll), so it can't be a
418
- // plain stable field the way handleInvertedStickyLayout/handleContentLayout are — it must track
419
- // `this.onScroll` genuinely changing, mirroring sticky-header.ts's own rebuildInterpolation cache
420
- // (rebuild only when the tracked dependency's reference actually differs, not on every getter
421
- // read). A fresh `animatedEvent(...)` call every `scrollProps` access would otherwise construct a
422
- // new listener wrapper (and a new AnimatedEvent walking `collectMappedValues`) on every unrelated
423
- // change-detection pass while sticky headers are active.
424
- cachedStickyOnScrollSource;
425
- cachedStickyOnScrollHandler;
426
- get isHorizontal() {
427
- const value = this.horizontal === true;
428
- if (value !== this.lastLoggedIsHorizontal) {
429
- this.lastLoggedIsHorizontal = value;
430
- dlog(`Angular ScrollView isHorizontal changed to ${value} (horizontal input=${this.horizontal})`);
431
- }
432
- return value;
433
- }
434
- get hasStickyHeaders() {
435
- return this.stickyHeaderIndices !== undefined && this.stickyHeaderIndices.length > 0;
436
- }
437
- // A class-name string resolves through the shared registry before it reaches
438
- // selectScrollIntrinsics, which only understands style objects/arrays.
439
- get resolvedContentContainerStyle() {
440
- return typeof this.contentContainerStyle === 'string'
441
- ? resolveClassName(this.contentContainerStyle)
442
- : this.contentContainerStyle;
443
- }
444
- get scrollViewBaseStyle() {
445
- return selectScrollIntrinsics(this.isHorizontal, this.resolvedContentContainerStyle)
446
- .scrollViewBaseStyle;
447
- }
448
- // The forwarded host-prop bag for the scroll-view node: aria/role folded, the native pass-through
449
- // families, the scroll-event callbacks, then the lifecycle-managed overrides (nestedScrollEnabled
450
- // default ON, horizontal when defined, decelerationRate resolved per-platform, the sticky onScroll
451
- // path). Base style UNDER user style so an explicit user value still wins. Mirrors Vue's outerProps
452
- // + scrollProps assembly.
453
- get scrollProps() {
454
- const bag = compact({
455
- ...resolveAccessibilityProps(this.accessibilityInputs()),
456
- scrollEnabled: this.scrollEnabled,
457
- showsVerticalScrollIndicator: this.showsVerticalScrollIndicator,
458
- showsHorizontalScrollIndicator: this.showsHorizontalScrollIndicator,
459
- pagingEnabled: this.pagingEnabled,
460
- bounces: this.bounces,
461
- contentInset: this.contentInset,
462
- contentOffset: this.contentOffset,
463
- removeClippedSubviews: this.removeClippedSubviews,
464
- snapToInterval: this.snapToInterval,
465
- snapToOffsets: this.snapToOffsets,
466
- snapToAlignment: this.snapToAlignment,
467
- snapToStart: this.snapToStart,
468
- snapToEnd: this.snapToEnd,
469
- disableIntervalMomentum: this.disableIntervalMomentum,
470
- keyboardDismissMode: this.keyboardDismissMode,
471
- keyboardShouldPersistTaps: this.keyboardShouldPersistTaps,
472
- maintainVisibleContentPosition: this.maintainVisibleContentPosition,
473
- alwaysBounceHorizontal: this.alwaysBounceHorizontal,
474
- alwaysBounceVertical: this.alwaysBounceVertical,
475
- centerContent: this.centerContent,
476
- scrollIndicatorInsets: this.scrollIndicatorInsets,
477
- indicatorStyle: this.indicatorStyle,
478
- directionalLockEnabled: this.directionalLockEnabled,
479
- automaticallyAdjustKeyboardInsets: this.automaticallyAdjustKeyboardInsets,
480
- contentInsetAdjustmentBehavior: this.contentInsetAdjustmentBehavior,
481
- minimumZoomScale: this.minimumZoomScale,
482
- maximumZoomScale: this.maximumZoomScale,
483
- zoomScale: this.zoomScale,
484
- bouncesZoom: this.bouncesZoom,
485
- pinchGestureEnabled: this.pinchGestureEnabled,
486
- overScrollMode: this.overScrollMode,
487
- fadingEdgeLength: this.fadingEdgeLength,
488
- persistentScrollbar: this.persistentScrollbar,
489
- endFillColor: this.endFillColor,
490
- onScrollBeginDrag: this.onScrollBeginDrag,
491
- onScrollEndDrag: this.onScrollEndDrag,
492
- onMomentumScrollBegin: this.onMomentumScrollBegin,
493
- onMomentumScrollEnd: this.onMomentumScrollEnd,
494
- onScrollToTop: this.emitterCallback(this.scrollToTop),
495
- onAccessibilityAction: this.emitterCallback(this.accessibilityAction),
496
- onAccessibilityTap: this.emitterCallback(this.accessibilityTap),
497
- onMagicTap: this.emitterCallback(this.magicTap),
498
- onAccessibilityEscape: this.emitterCallback(this.accessibilityEscape),
499
- });
500
- // RN defaults nested scrolling ON (ScrollView.js `nestedScrollEnabled ?? true`); Android needs
501
- // it to scroll a nested scrollable independently, iOS handles nesting natively (a no-op there).
502
- bag.nestedScrollEnabled = this.nestedScrollEnabled ?? true;
503
- // iOS needs `horizontal` to flip RCTScrollView's axis; Android's dedicated manager ignores it.
504
- if (this.horizontal !== undefined)
505
- bag.horizontal = this.horizontal;
506
- if (this.decelerationRate !== undefined) {
507
- bag.decelerationRate = resolveDecelerationRate(this.decelerationRate);
508
- }
509
- // onScroll: when sticky headers are active, the offset must reach the AnimatedValue (RN
510
- // _scrollAnimatedValueAttachment). With the native module, the value is driven on the UI thread
511
- // by the post-commit attach below, so onScroll forwards to the user with throttle 1
512
- // (ScrollView.js:1798). Without it, Animated.event drives the value each frame (the JS jitter)
513
- // and forwards the user handler as the listener passthrough.
514
- const nativeStickyAvailable = this.hasStickyHeaders && isNativeAnimatedAvailable();
515
- if (this.hasStickyHeaders) {
516
- if (nativeStickyAvailable) {
517
- if (this.onScroll !== undefined)
518
- bag.onScroll = this.onScroll;
519
- bag.scrollEventThrottle = this.scrollEventThrottle ?? 1;
520
- }
521
- else {
522
- bag.onScroll = this.stickyOnScrollHandler(this.onScroll);
523
- bag.scrollEventThrottle = this.scrollEventThrottle ?? 16;
524
- }
525
- // Inverted sticky headers need the viewport height (RN _handleLayout): capture it on the
526
- // scroll-view onLayout, then call the user's handler. Non-inverted forwards onLayout as-is.
527
- if (this.invertStickyHeaders === true) {
528
- bag.onLayout = this.handleInvertedStickyLayout;
529
- }
530
- else {
531
- const layoutCallback = this.emitterCallback(this.layout);
532
- if (layoutCallback !== undefined)
533
- bag.onLayout = layoutCallback;
534
- }
535
- }
536
- else {
537
- if (this.onScroll !== undefined)
538
- bag.onScroll = this.onScroll;
539
- if (this.scrollEventThrottle !== undefined)
540
- bag.scrollEventThrottle = this.scrollEventThrottle;
541
- const layoutCallback = this.emitterCallback(this.layout);
542
- if (layoutCallback !== undefined)
543
- bag.onLayout = layoutCallback;
544
- }
545
- dlog(`Angular ScrollView -> ${this.isHorizontal ? 'horizontal' : 'vertical'} (sticky=${this.hasStickyHeaders})`);
546
- bag.style = [this.scrollViewBaseStyle, this.style];
547
- this.updateProjectionController();
548
- return bag;
549
- }
550
- // Overridable hook, NOT `this.style` directly: `splitLayoutProps` below decides which layout
551
- // properties (flex/height/gap/…) go on the Android outer refresh-control wrapper vs. the inner
552
- // scroll view. `this.style` alone only ever carries the explicit `[style]` @Input — a composed
553
- // component's OWN anchor host (see anchorHostStyle's doc comment in primitives/shared.ts) can
554
- // hold ADDITIONAL class-derived layout style that's otherwise invisible to this split, so its
555
- // wrapper never gets its needed layout (collapses to zero size — the Android outer wrapper
556
- // shows literally nothing on screen). This mirrors the Vue adapter's identical
557
- // `layoutSplitStyle` field and the real Android device bug it fixes; the Angular Android
558
- // ScrollView (index.android.ts) overrides this to merge in `anchorHostStyle`. Default here is
559
- // `this.style` alone, preserving current behavior for anything that doesn't override it.
560
- get layoutSplitStyle() {
561
- return this.style;
562
- }
563
- get androidWrappedScrollProps() {
564
- const props = { ...this.scrollProps };
565
- const { inner, outer } = splitLayoutProps(this.layoutSplitStyle);
566
- dlog(`Angular ScrollView splitProbe layoutSplitStyle=${JSON.stringify(this.layoutSplitStyle)} ` +
567
- `outer=${JSON.stringify(outer)} inner=${JSON.stringify(inner)}`);
568
- props.style = [this.scrollViewBaseStyle, inner];
569
- props.nestedScrollEnabled = true;
570
- return props;
571
- }
572
- get iosRefreshControlProps() {
573
- return this.refreshControlProps();
574
- }
575
- get androidRefreshControlProps() {
576
- const { outer } = splitLayoutProps(this.layoutSplitStyle);
577
- dlog(`Angular ScrollView refreshControlProbe outer=${JSON.stringify(outer)} ` +
578
- `hasRefresh=${this.projectedRefreshControl !== undefined}`);
579
- return this.refreshControlProps(outer);
580
- }
581
- handleProjectedRefresh(nativeNode) {
582
- this.projectedRefreshControl?.handleRefresh(nativeNode);
583
- }
584
- refreshControlProps(style) {
585
- const refresh = this.projectedRefreshControl;
586
- if (refresh === undefined)
587
- return {};
588
- return compact({
589
- ...refresh.folded,
590
- refreshing: refresh.refreshing,
591
- tintColor: refresh.tintColor,
592
- title: refresh.title,
593
- titleColor: refresh.titleColor,
594
- progressViewOffset: refresh.progressViewOffset,
595
- colors: refresh.colors,
596
- progressBackgroundColor: refresh.progressBackgroundColor,
597
- size: refresh.size,
598
- enabled: refresh.enabled,
599
- style,
600
- testID: refresh.testID,
601
- nativeID: refresh.nativeID,
602
- accessible: refresh.accessible,
603
- onAccessibilityAction: this.emitterCallback(refresh.accessibilityAction),
604
- onAccessibilityTap: this.emitterCallback(refresh.accessibilityTap),
605
- onMagicTap: this.emitterCallback(refresh.magicTap),
606
- onAccessibilityEscape: this.emitterCallback(refresh.accessibilityEscape),
607
- });
608
- }
609
- get hasProjectedRefreshControl() {
610
- return this.projectedRefreshControl !== undefined;
611
- }
612
- // The content (inner) view's prop bag. `collapsable: false` keeps the layout-only content view a
613
- // real native view (Android Fabric view-flattens it away otherwise, hoisting cells as direct
614
- // children of a scroll view that hosts exactly one — an addViewAt crash). collapsableChildren
615
- // false preserves the cell views maintainVisibleContentPosition/snapToAlignment anchor against.
616
- // onLayout synthesizes onContentSizeChange (deduped). iOS never flattens; both are no-ops there.
617
- get contentProps() {
618
- const { contentStyle } = selectScrollIntrinsics(this.isHorizontal, this.resolvedContentContainerStyle);
619
- const bag = { style: contentStyle, collapsable: false };
620
- if (this.maintainVisibleContentPosition !== undefined || this.snapToAlignment !== undefined) {
621
- bag.collapsableChildren = false;
622
- }
623
- bag.onLayout = this.handleContentLayout;
624
- return bag;
625
- }
626
- // Wraps an @Output() as a plain callback only while it has a subscriber, so an unbound event
627
- // still leaves the forwarded prop bag key absent — the same "undefined means nobody cares"
628
- // contract the old @Input() callbacks had. Mirrors Pressable's emitterHandler. The wrapper itself
629
- // is memoized per emitter (emitterCallbackCache) rather than rebuilt on every call: see that
630
- // field's comment for why an unstable closure here breaks the forwarded prop bag.
631
- emitterCallback(emitter) {
632
- if (!emitter.observed)
633
- return undefined;
634
- let cached = this.emitterCallbackCache.get(emitter);
635
- if (cached === undefined) {
636
- cached = (event) => emitter.emit(event);
637
- this.emitterCallbackCache.set(emitter, cached);
638
- }
639
- return cached;
640
- }
641
- // Rebuilds the JS-path Animated.event handler only when the tracked `onScroll` input actually
642
- // changes reference (see cachedStickyOnScrollHandler's comment).
643
- stickyOnScrollHandler(userOnScroll) {
644
- if (this.cachedStickyOnScrollHandler === undefined ||
645
- this.cachedStickyOnScrollSource !== userOnScroll) {
646
- this.cachedStickyOnScrollSource = userOnScroll;
647
- this.cachedStickyOnScrollHandler = animatedEvent([{ nativeEvent: { contentOffset: { y: this.scrollAnimatedValue } } }], userOnScroll === undefined
648
- ? undefined
649
- : { listener: (...args) => forwardScrollEvent(userOnScroll, args) });
650
- }
651
- return this.cachedStickyOnScrollHandler;
652
- }
653
- // The committed scroll-view node held by IDENTITY (the directive's ElementRef). null until the
654
- // element commits; the imperative handle and the sticky attach both read it through this getter.
655
- get hostNode() {
656
- const native = this.hostDirective?.node;
657
- return isSymbioteNode(native) ? native : null;
658
- }
659
- // The imperative API a parent reaches via @ViewChild(ScrollView). buildScrollViewHandle is the
660
- // shared, proven handle (React/Vue use it verbatim); it reads the node through the LAZY getter on
661
- // every call, so a command before commit no-ops rather than freezing a null node.
662
- handle = buildScrollViewHandle(() => this.hostNode);
663
- scrollTo(options) {
664
- this.handle.scrollTo(options);
665
- }
666
- scrollToEnd(options) {
667
- this.handle.scrollToEnd(options);
668
- }
669
- flashScrollIndicators() {
670
- this.handle.flashScrollIndicators();
671
- }
672
- getScrollNode() {
673
- return this.handle.getScrollNode();
674
- }
675
- ngAfterViewInit() {
676
- this.updateProjectionController();
677
- this.attachSticky();
678
- }
679
- // Wire the native sticky-scroll attach after the view exists. Re-attaches if the node identity
680
- // changes; no-op when sticky is off or the native module is absent.
681
- attachSticky() {
682
- this.cancelStickyBind?.();
683
- this.cancelStickyBind = undefined;
684
- if (this.detachStickyScroll !== undefined) {
685
- this.detachStickyScroll();
686
- this.detachStickyScroll = undefined;
687
- }
688
- if (!this.hasStickyHeaders || !isNativeAnimatedAvailable())
689
- return;
690
- const node = this.hostNode;
691
- if (node === null)
692
- return;
693
- this.cancelStickyBind = whenCommitted(node, () => {
694
- this.detachStickyScroll = attachStickyScroll(node, this.scrollAnimatedValue);
695
- });
696
- }
697
- ngOnDestroy() {
698
- this.cancelStickyBind?.();
699
- this.cancelStickyBind = undefined;
700
- if (this.detachStickyScroll !== undefined)
701
- this.detachStickyScroll();
702
- }
703
- updateProjectionController() {
704
- this.projectionController.update({
705
- stickyHeaderIndices: this.stickyHeaderIndices,
706
- invertStickyHeaders: this.invertStickyHeaders,
707
- scrollViewHeight: this.viewportHeight,
708
- scrollAnimatedValue: this.scrollAnimatedValue,
709
- customStickyHeaderComponent: this.StickyHeaderComponent,
710
- excludeRefreshControl: this.hasProjectedRefreshControl,
711
- });
712
- }
713
- // Typed as the a11y intersection WITH the string index so resolveAccessibilityProps's result
714
- // stays assignable into the forwarded bag (a genuine narrowing, built at that type — no cast).
715
- accessibilityInputs() {
716
- return {
717
- testID: this.testID,
718
- nativeID: this.nativeID,
719
- accessible: this.accessible,
720
- accessibilityLabel: this.accessibilityLabel,
721
- accessibilityHint: this.accessibilityHint,
722
- accessibilityRole: this.accessibilityRole,
723
- accessibilityState: this.accessibilityState,
724
- accessibilityValue: this.accessibilityValue,
725
- accessibilityActions: this.accessibilityActions,
726
- accessibilityLabelledBy: this.accessibilityLabelledBy,
727
- importantForAccessibility: this.importantForAccessibility,
728
- accessibilityLiveRegion: this.accessibilityLiveRegion,
729
- screenReaderFocusable: this.screenReaderFocusable,
730
- accessibilityViewIsModal: this.accessibilityViewIsModal,
731
- accessibilityElementsHidden: this.accessibilityElementsHidden,
732
- accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
733
- accessibilityLanguage: this.accessibilityLanguage,
734
- accessibilityRespondsToUserInteraction: this.accessibilityRespondsToUserInteraction,
735
- accessibilityShowsLargeContentViewer: this.accessibilityShowsLargeContentViewer,
736
- accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
737
- role: this.role,
738
- 'aria-label': this['aria-label'],
739
- 'aria-labelledby': this['aria-labelledby'],
740
- 'aria-live': this['aria-live'],
741
- 'aria-hidden': this['aria-hidden'],
742
- 'aria-busy': this['aria-busy'],
743
- 'aria-checked': this['aria-checked'],
744
- 'aria-disabled': this['aria-disabled'],
745
- 'aria-expanded': this['aria-expanded'],
746
- 'aria-selected': this['aria-selected'],
747
- 'aria-modal': this['aria-modal'],
748
- 'aria-valuemax': this['aria-valuemax'],
749
- 'aria-valuemin': this['aria-valuemin'],
750
- 'aria-valuenow': this['aria-valuenow'],
751
- 'aria-valuetext': this['aria-valuetext'],
752
- };
753
- }
754
- };
755
- return ScrollViewBase = _classThis;
756
- })();
757
- export { ScrollViewBase };