@symbiote-native/angular 0.7.0 → 0.8.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 +3 -3
- package/build/angular/bootstrap.js +1 -1
- package/build/angular/bootstrap.js.map +1 -1
- package/build/angular/components/activity-indicator/index.android.js +7 -2
- package/build/angular/components/activity-indicator/index.android.js.map +1 -1
- package/build/angular/components/activity-indicator/index.ios.js +3 -1
- package/build/angular/components/activity-indicator/index.ios.js.map +1 -1
- package/build/angular/components/activity-indicator/shared.d.ts +1 -1
- package/build/angular/components/activity-indicator/shared.js +1 -1
- package/build/angular/components/activity-indicator/shared.js.map +1 -1
- package/build/angular/components/button.js +13 -5
- package/build/angular/components/button.js.map +1 -1
- package/build/angular/components/flat-list/index.d.ts +1 -1
- package/build/angular/components/flat-list/index.js +47 -14
- package/build/angular/components/flat-list/index.js.map +1 -1
- package/build/angular/components/image/index.android.js +4 -2
- package/build/angular/components/image/index.android.js.map +1 -1
- package/build/angular/components/image/index.ios.js +4 -2
- package/build/angular/components/image/index.ios.js.map +1 -1
- package/build/angular/components/image/shared.js +18 -6
- package/build/angular/components/image/shared.js.map +1 -1
- package/build/angular/components/image-background.js +22 -8
- package/build/angular/components/image-background.js.map +1 -1
- package/build/angular/components/input-accessory-view/index.js +7 -2
- package/build/angular/components/input-accessory-view/index.js.map +1 -1
- package/build/angular/components/keyboard-avoiding-view/index.d.ts +1 -0
- package/build/angular/components/keyboard-avoiding-view/index.js +39 -9
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
- package/build/angular/components/modal/index.js +7 -2
- package/build/angular/components/modal/index.js.map +1 -1
- package/build/angular/components/pressable/index.d.ts +1 -1
- package/build/angular/components/pressable/index.js +6 -2
- package/build/angular/components/pressable/index.js.map +1 -1
- package/build/angular/components/refresh-control/index.js +3 -1
- package/build/angular/components/refresh-control/index.js.map +1 -1
- package/build/angular/components/safe-area-view/index.js +3 -1
- package/build/angular/components/safe-area-view/index.js.map +1 -1
- package/build/angular/components/scroll-view/index.android.js +44 -14
- package/build/angular/components/scroll-view/index.android.js.map +1 -1
- package/build/angular/components/scroll-view/index.ios.js +13 -5
- package/build/angular/components/scroll-view/index.ios.js.map +1 -1
- package/build/angular/components/scroll-view/projection.d.ts +32 -0
- package/build/angular/components/scroll-view/projection.js +212 -47
- package/build/angular/components/scroll-view/projection.js.map +1 -1
- package/build/angular/components/scroll-view/shared.js +28 -7
- package/build/angular/components/scroll-view/shared.js.map +1 -1
- package/build/angular/components/scroll-view/sticky-header.js +7 -3
- package/build/angular/components/scroll-view/sticky-header.js.map +1 -1
- package/build/angular/components/section-list/index.d.ts +6 -1
- package/build/angular/components/section-list/index.js +63 -18
- package/build/angular/components/section-list/index.js.map +1 -1
- package/build/angular/components/switch/index.android.js +17 -3
- package/build/angular/components/switch/index.android.js.map +1 -1
- package/build/angular/components/switch/index.ios.js +17 -3
- package/build/angular/components/switch/index.ios.js.map +1 -1
- package/build/angular/components/switch/shared.d.ts +1 -1
- package/build/angular/components/switch/shared.js +5 -2
- package/build/angular/components/switch/shared.js.map +1 -1
- package/build/angular/components/text-input.d.ts +1 -1
- package/build/angular/components/text-input.js +25 -5
- package/build/angular/components/text-input.js.map +1 -1
- package/build/angular/components/touchable/index.d.ts +29 -7
- package/build/angular/components/touchable/index.js +246 -69
- package/build/angular/components/touchable/index.js.map +1 -1
- package/build/angular/components/touchable-native-feedback/index.js +2 -2
- package/build/angular/components/touchable-native-feedback/index.js.map +1 -1
- package/build/angular/components/virtualized-list/directives.js +4 -0
- package/build/angular/components/virtualized-list/directives.js.map +1 -1
- package/build/angular/components/virtualized-list/index.d.ts +5 -2
- package/build/angular/components/virtualized-list/index.js +197 -60
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/directives.js.map +1 -1
- package/build/angular/components/virtualized-section-list/index.d.ts +18 -1
- package/build/angular/components/virtualized-section-list/index.js +90 -21
- 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.map +1 -1
- package/build/angular/create-portal/index.js +5 -1
- package/build/angular/create-portal/index.js.map +1 -1
- package/build/angular/create-tunnel/index.js.map +1 -1
- package/build/angular/descriptor-to-angular/index.js +3 -1
- package/build/angular/descriptor-to-angular/index.js.map +1 -1
- package/build/angular/diagnostics.d.ts +33 -0
- package/build/angular/diagnostics.js +82 -0
- package/build/angular/diagnostics.js.map +1 -0
- package/build/angular/host-instance/index.js +1 -1
- package/build/angular/host-instance/index.js.map +1 -1
- package/build/angular/index.d.ts +5 -2
- package/build/angular/index.js +15 -1
- package/build/angular/index.js.map +1 -1
- package/build/angular/modules/animated/create-animated-component.js +27 -9
- 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 +1 -1
- package/build/angular/modules/status-bar/index.js.map +1 -1
- package/build/angular/primitives/index.d.ts +19 -2
- package/build/angular/primitives/index.js +39 -3
- package/build/angular/primitives/index.js.map +1 -1
- package/build/angular/primitives/shared.d.ts +9 -1
- package/build/angular/primitives/shared.js +49 -3
- package/build/angular/primitives/shared.js.map +1 -1
- package/build/angular/render/index.js +48 -5
- package/build/angular/render/index.js.map +1 -1
- package/build/angular/renderer/index.d.ts +1 -0
- package/build/angular/renderer/index.js +37 -2
- package/build/angular/renderer/index.js.map +1 -1
- package/build/angular/services/color-scheme.service.js.map +1 -1
- package/build/angular/services/window-dimensions.service.js +1 -1
- package/build/angular/services/window-dimensions.service.js.map +1 -1
- package/package.json +5 -5
- package/src/bootstrap.ts +4 -1
- package/src/components/activity-indicator/index.android.ts +7 -2
- package/src/components/activity-indicator/index.ios.ts +3 -1
- package/src/components/activity-indicator/shared.ts +32 -13
- package/src/components/button.ts +19 -6
- package/src/components/flat-list/index.ts +91 -29
- package/src/components/image/index.android.ts +9 -2
- package/src/components/image/index.ios.ts +9 -2
- package/src/components/image/shared.ts +58 -19
- package/src/components/image-background.ts +29 -10
- package/src/components/input-accessory-view/index.ts +27 -10
- package/src/components/keyboard-avoiding-view/index.ts +55 -15
- package/src/components/modal/index.ts +22 -8
- package/src/components/pressable/index.ts +51 -21
- package/src/components/refresh-control/index.ts +22 -8
- package/src/components/safe-area-view/index.ts +16 -7
- package/src/components/scroll-view/index.android.ts +31 -9
- package/src/components/scroll-view/index.ios.ts +17 -4
- package/src/components/scroll-view/projection.ts +290 -63
- package/src/components/scroll-view/shared.ts +93 -26
- package/src/components/scroll-view/sticky-header.ts +25 -8
- package/src/components/section-list/index.ts +61 -19
- package/src/components/switch/index.android.ts +14 -3
- package/src/components/switch/index.ios.ts +14 -3
- package/src/components/switch/shared.ts +15 -4
- package/src/components/text-input.ts +45 -13
- package/src/components/touchable/index.ts +296 -72
- package/src/components/touchable-native-feedback/index.ts +32 -10
- package/src/components/virtualized-list/directives.ts +19 -5
- package/src/components/virtualized-list/index.ts +274 -72
- package/src/components/virtualized-section-list/directives.ts +6 -3
- package/src/components/virtualized-section-list/index.ts +146 -34
- package/src/components.ts +4 -1
- package/src/create-portal/index.ts +8 -2
- package/src/create-tunnel/index.ts +3 -1
- package/src/descriptor-to-angular/index.ts +29 -8
- package/src/diagnostics.ts +138 -0
- package/src/host-instance/index.ts +9 -3
- package/src/index.ts +31 -2
- package/src/modules/animated/create-animated-component.ts +44 -15
- package/src/modules/app-registry/index.ts +3 -1
- package/src/modules/status-bar/index.ts +13 -4
- package/src/primitives/index.ts +46 -2
- package/src/primitives/shared.ts +70 -9
- package/src/render/index.ts +56 -6
- package/src/renderer/index.ts +76 -14
- package/src/services/color-scheme.service.ts +3 -1
- package/src/services/window-dimensions.service.ts +11 -4
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// keyboard's way as it shows/hides. The inset math + the behavior → style/structure decision
|
|
3
3
|
// live framework-agnostic in @symbiote-native/components (render-keyboard-avoiding-view), shared verbatim
|
|
4
4
|
// with React/Vue; Angular supplies only the lifecycle: a plain inset field, ngOnInit subscribes to
|
|
5
|
-
// the core Keyboard module (
|
|
5
|
+
// the core Keyboard module (the host's show / hide pair) and markForCheck pulls the OnPush view (the
|
|
6
6
|
// Angular twin of React's setState / Vue's reactive ref), ngOnDestroy tears the subscriptions down,
|
|
7
7
|
// and the wrapper's onLayout measures the frame that feeds the next event's inset. The user
|
|
8
8
|
// children nest under the wrapper (or, for 'position', an inner View) via <ng-content>. No native
|
|
@@ -26,8 +26,10 @@ import {
|
|
|
26
26
|
} from '@angular/core';
|
|
27
27
|
import {
|
|
28
28
|
computeInset,
|
|
29
|
+
keyboardAvoidingEventNamesFor,
|
|
29
30
|
readKeyboardFrame,
|
|
30
31
|
readLayoutFrame,
|
|
32
|
+
readPrefersCrossFadeTransitions,
|
|
31
33
|
resolveAccessibilityProps,
|
|
32
34
|
resolveKeyboardAvoidingLayout,
|
|
33
35
|
DEFAULT_VERTICAL_OFFSET,
|
|
@@ -40,7 +42,7 @@ import {
|
|
|
40
42
|
} from '@symbiote-native/components';
|
|
41
43
|
import {
|
|
42
44
|
Keyboard,
|
|
43
|
-
|
|
45
|
+
Platform,
|
|
44
46
|
dlog,
|
|
45
47
|
isSymbioteEvent,
|
|
46
48
|
type IEventSubscription,
|
|
@@ -60,7 +62,8 @@ export type { IKeyboardAvoidingBehavior } from '@symbiote-native/components';
|
|
|
60
62
|
// Mirrors React's IKeyboardAvoidingViewProps minus children (Angular takes children via
|
|
61
63
|
// <ng-content>), declared per-adapter over the shared accessibility base since a framework-specific
|
|
62
64
|
// children field keeps it from being fully shared across adapters.
|
|
63
|
-
export interface IAngularKeyboardAvoidingViewProps
|
|
65
|
+
export interface IAngularKeyboardAvoidingViewProps
|
|
66
|
+
extends IAccessibilityProps, IAriaProps {
|
|
64
67
|
behavior?: IKeyboardAvoidingBehavior;
|
|
65
68
|
enabled?: boolean;
|
|
66
69
|
keyboardVerticalOffset?: number;
|
|
@@ -84,7 +87,9 @@ export type IAngularKeyboardAvoidingViewInputs = Omit<
|
|
|
84
87
|
@Component({
|
|
85
88
|
selector: 'KeyboardAvoidingView',
|
|
86
89
|
standalone: true,
|
|
87
|
-
hostDirectives: [
|
|
90
|
+
hostDirectives: [
|
|
91
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
92
|
+
],
|
|
88
93
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
89
94
|
imports: [ViewHost, SymbioteHostPropsDirective],
|
|
90
95
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -110,7 +115,9 @@ export type IAngularKeyboardAvoidingViewInputs = Omit<
|
|
|
110
115
|
</symbiote-view>
|
|
111
116
|
`,
|
|
112
117
|
})
|
|
113
|
-
export class KeyboardAvoidingView
|
|
118
|
+
export class KeyboardAvoidingView
|
|
119
|
+
implements IAngularKeyboardAvoidingViewInputs, OnInit, OnDestroy
|
|
120
|
+
{
|
|
114
121
|
@Input() behavior?: IKeyboardAvoidingBehavior;
|
|
115
122
|
@Input() enabled?: boolean;
|
|
116
123
|
@Input() keyboardVerticalOffset?: number;
|
|
@@ -135,8 +142,10 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
135
142
|
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
136
143
|
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
137
144
|
@Input() accessibilityLabelledBy?: string | string[];
|
|
138
|
-
@Input()
|
|
139
|
-
|
|
145
|
+
@Input()
|
|
146
|
+
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
147
|
+
@Input()
|
|
148
|
+
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
140
149
|
@Input() screenReaderFocusable?: boolean;
|
|
141
150
|
@Input() accessibilityViewIsModal?: boolean;
|
|
142
151
|
@Input() accessibilityElementsHidden?: boolean;
|
|
@@ -168,6 +177,12 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
168
177
|
// keyboard event's inset math (React's frameRef / initialHeightRef, Vue's frame / initialHeight).
|
|
169
178
|
private frame?: IMeasuredFrame;
|
|
170
179
|
private initialHeight?: number;
|
|
180
|
+
// The iOS "Prefer Cross-Fade Transitions" setting, read once per mount. Deliberately a plain
|
|
181
|
+
// field and NOT markForCheck'd when the promise lands: it is a device setting that cannot change
|
|
182
|
+
// mid-session, and it feeds only the NEXT keyboard event's math — never the current render — so
|
|
183
|
+
// under zoneless CD there is nothing to repaint at resolve time. The keyboard event that does use
|
|
184
|
+
// it already calls markForCheck itself.
|
|
185
|
+
private prefersCrossFadeTransitions = false;
|
|
171
186
|
private subscriptions: IEventSubscription[] = [];
|
|
172
187
|
|
|
173
188
|
private readonly changeDetector = inject(ChangeDetectorRef);
|
|
@@ -177,11 +192,21 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
177
192
|
private readonly elementRef = inject(ElementRef);
|
|
178
193
|
|
|
179
194
|
ngOnInit(): void {
|
|
195
|
+
// TWO events, picked per host, never three: iOS takes the will* pair so the view rides up with
|
|
196
|
+
// the keyboard animation, Android the did* pair. The change-frame notification is deliberately
|
|
197
|
+
// absent — with an undocked/split/floating iOS keyboard it fires BEFORE the hide, so listening
|
|
198
|
+
// to it applies a frame captured mid-dismissal (RN KeyboardAvoidingView.js's own comment).
|
|
199
|
+
const events = keyboardAvoidingEventNamesFor(Platform.OS);
|
|
180
200
|
this.subscriptions = [
|
|
181
|
-
Keyboard.addListener(
|
|
182
|
-
Keyboard.addListener(
|
|
183
|
-
Keyboard.addListener(KEYBOARD_EVENT.didHide, () => this.onHide()),
|
|
201
|
+
Keyboard.addListener(events.show, payload => this.onShow(payload)),
|
|
202
|
+
Keyboard.addListener(events.hide, () => this.onHide()),
|
|
184
203
|
];
|
|
204
|
+
// The core wrapper, not AccessibilityInfo directly: the engine's iOS getter REJECTS on a
|
|
205
|
+
// native error (RN parity), and nobody awaits this read, so an unwrapped call would surface
|
|
206
|
+
// as an unhandled rejection. The wrapper answers false on a failed read.
|
|
207
|
+
void readPrefersCrossFadeTransitions().then(enabled => {
|
|
208
|
+
this.prefersCrossFadeTransitions = enabled;
|
|
209
|
+
});
|
|
185
210
|
}
|
|
186
211
|
|
|
187
212
|
ngOnDestroy(): void {
|
|
@@ -192,7 +217,17 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
192
217
|
private onShow(payload: unknown): void {
|
|
193
218
|
const keyboard = readKeyboardFrame(payload);
|
|
194
219
|
const offset = this.keyboardVerticalOffset ?? DEFAULT_VERTICAL_OFFSET;
|
|
195
|
-
const next = computeInset(this.frame, keyboard, offset
|
|
220
|
+
const next = computeInset(this.frame, keyboard, offset, {
|
|
221
|
+
// Read off the field at event time, not captured when the subscription was built: `behavior`
|
|
222
|
+
// is an @Input that can change under a long-lived subscription, and a stale one keeps
|
|
223
|
+
// applying the old mode's math (it gates the previous-inset correction below).
|
|
224
|
+
behavior: this.behavior,
|
|
225
|
+
// The inset CURRENTLY applied (RN's this.state.bottom), read off the field at event time so
|
|
226
|
+
// 'height' mode's fixpoint correction sees the live value: that mode SHRINKS the wrapper by
|
|
227
|
+
// the inset, so the next onLayout reports a frame shorter by exactly that much.
|
|
228
|
+
previousInset: this.inset,
|
|
229
|
+
prefersCrossFadeTransitions: this.prefersCrossFadeTransitions,
|
|
230
|
+
});
|
|
196
231
|
dlog(`KeyboardAvoidingView show -> inset ${next}`);
|
|
197
232
|
this.inset = next;
|
|
198
233
|
this.changeDetector.markForCheck();
|
|
@@ -211,7 +246,8 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
211
246
|
const measured = readLayoutFrame(event.nativeEvent.layout);
|
|
212
247
|
if (measured !== undefined) {
|
|
213
248
|
this.frame = measured;
|
|
214
|
-
if (this.initialHeight === undefined)
|
|
249
|
+
if (this.initialHeight === undefined)
|
|
250
|
+
this.initialHeight = measured.height;
|
|
215
251
|
}
|
|
216
252
|
this.layout.emit(event);
|
|
217
253
|
}
|
|
@@ -244,7 +280,9 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
244
280
|
}
|
|
245
281
|
|
|
246
282
|
get innerStyle(): IStyleProp<IViewStyle> | undefined {
|
|
247
|
-
return this.resolvedLayout.kind === 'nested'
|
|
283
|
+
return this.resolvedLayout.kind === 'nested'
|
|
284
|
+
? this.resolvedLayout.innerStyle
|
|
285
|
+
: undefined;
|
|
248
286
|
}
|
|
249
287
|
|
|
250
288
|
// The wrapper's full prop bag (style + identity + a11y) folded for `[symbioteHostProps]`,
|
|
@@ -286,8 +324,10 @@ export class KeyboardAvoidingView implements IAngularKeyboardAvoidingViewInputs,
|
|
|
286
324
|
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
287
325
|
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
288
326
|
accessibilityLanguage: this.accessibilityLanguage,
|
|
289
|
-
accessibilityRespondsToUserInteraction:
|
|
290
|
-
|
|
327
|
+
accessibilityRespondsToUserInteraction:
|
|
328
|
+
this.accessibilityRespondsToUserInteraction,
|
|
329
|
+
accessibilityShowsLargeContentViewer:
|
|
330
|
+
this.accessibilityShowsLargeContentViewer,
|
|
291
331
|
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
292
332
|
role: this.role,
|
|
293
333
|
'aria-label': this.ariaLabel,
|
|
@@ -101,7 +101,9 @@ export type IAngularModalInputs = Omit<
|
|
|
101
101
|
@Component({
|
|
102
102
|
selector: 'Modal',
|
|
103
103
|
standalone: true,
|
|
104
|
-
hostDirectives: [
|
|
104
|
+
hostDirectives: [
|
|
105
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
106
|
+
],
|
|
105
107
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
106
108
|
imports: [ModalHost, ViewHost, SymbioteHostPropsDirective],
|
|
107
109
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -154,8 +156,10 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
154
156
|
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
155
157
|
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
156
158
|
@Input() accessibilityLabelledBy?: string | string[];
|
|
157
|
-
@Input()
|
|
158
|
-
|
|
159
|
+
@Input()
|
|
160
|
+
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
161
|
+
@Input()
|
|
162
|
+
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
159
163
|
@Input() screenReaderFocusable?: boolean;
|
|
160
164
|
@Input() accessibilityViewIsModal?: boolean;
|
|
161
165
|
@Input() accessibilityElementsHidden?: boolean;
|
|
@@ -216,7 +220,10 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
216
220
|
// Queue on a microtask so the reducer runs AFTER this CD pass renders with the OLD state —
|
|
217
221
|
// the keep-alive frame. A synchronous dispatch here would unmount in the same pass.
|
|
218
222
|
queueMicrotask(() => {
|
|
219
|
-
this.state = modalReducer(
|
|
223
|
+
this.state = modalReducer(
|
|
224
|
+
this.state,
|
|
225
|
+
isVisible ? { type: 'show' } : { type: 'hide' },
|
|
226
|
+
);
|
|
220
227
|
this.changeDetector.markForCheck();
|
|
221
228
|
});
|
|
222
229
|
}
|
|
@@ -269,7 +276,10 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
269
276
|
readonly hostProps = computed<Record<string, unknown>>(() => {
|
|
270
277
|
this.hostPropsRevision();
|
|
271
278
|
const descriptorProps = this.descriptor.props;
|
|
272
|
-
return {
|
|
279
|
+
return {
|
|
280
|
+
...descriptorProps,
|
|
281
|
+
style: [anchorHostStyle(this.elementRef), descriptorProps.style],
|
|
282
|
+
};
|
|
273
283
|
});
|
|
274
284
|
|
|
275
285
|
get containerStyle(): unknown {
|
|
@@ -283,7 +293,9 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
283
293
|
|
|
284
294
|
// Typed as the a11y intersection WITH the string index (the bag renderModal spreads into the
|
|
285
295
|
// host props), so resolveAccessibilityProps's result stays assignable to passthrough.
|
|
286
|
-
private accessibilityInputs(): IAccessibilityProps &
|
|
296
|
+
private accessibilityInputs(): IAccessibilityProps &
|
|
297
|
+
IAriaProps &
|
|
298
|
+
Record<string, unknown> {
|
|
287
299
|
return {
|
|
288
300
|
testID: this.testID,
|
|
289
301
|
accessible: this.accessible,
|
|
@@ -301,8 +313,10 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
301
313
|
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
302
314
|
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
303
315
|
accessibilityLanguage: this.accessibilityLanguage,
|
|
304
|
-
accessibilityRespondsToUserInteraction:
|
|
305
|
-
|
|
316
|
+
accessibilityRespondsToUserInteraction:
|
|
317
|
+
this.accessibilityRespondsToUserInteraction,
|
|
318
|
+
accessibilityShowsLargeContentViewer:
|
|
319
|
+
this.accessibilityShowsLargeContentViewer,
|
|
306
320
|
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
307
321
|
role: this.role,
|
|
308
322
|
'aria-label': this.ariaLabel,
|
|
@@ -51,13 +51,17 @@ import {
|
|
|
51
51
|
ViewHost,
|
|
52
52
|
} from '../../primitives';
|
|
53
53
|
|
|
54
|
-
export type {
|
|
54
|
+
export type {
|
|
55
|
+
IPressState,
|
|
56
|
+
IPressableAndroidRippleConfig,
|
|
57
|
+
} from '@symbiote-native/components';
|
|
55
58
|
|
|
56
59
|
// The full logical Pressable surface, callback-shaped press/hover events included. Touchable* and
|
|
57
60
|
// TouchableNativeFeedback still take their OWN onPress/onPressIn/... as @Input() callbacks (that is
|
|
58
61
|
// a separate, not-yet-converted decision) and derive their public prop types from this - so it keeps
|
|
59
62
|
// the callback fields even though the Pressable component below no longer implements them directly.
|
|
60
|
-
export interface IAngularPressableProps
|
|
63
|
+
export interface IAngularPressableProps
|
|
64
|
+
extends IAccessibilityProps, IAriaProps {
|
|
61
65
|
onPress?: IPressHandler;
|
|
62
66
|
onPressIn?: IPressHandler;
|
|
63
67
|
onPressOut?: IPressHandler;
|
|
@@ -83,7 +87,8 @@ export interface IAngularPressableProps extends IAccessibilityProps, IAriaProps
|
|
|
83
87
|
nextFocusLeft?: number;
|
|
84
88
|
nextFocusRight?: number;
|
|
85
89
|
nextFocusUp?: number;
|
|
86
|
-
style?:
|
|
90
|
+
style?:
|
|
91
|
+
IStyleProp<IViewStyle> | ((state: IPressState) => IStyleProp<IViewStyle>);
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
// What the Pressable component itself takes as plain @Input()s: the full surface minus the press/
|
|
@@ -105,7 +110,9 @@ export type IAngularPressableInputs = Omit<
|
|
|
105
110
|
| 'onAccessibilityEscape'
|
|
106
111
|
>;
|
|
107
112
|
|
|
108
|
-
function isStyleFn(
|
|
113
|
+
function isStyleFn(
|
|
114
|
+
value: unknown,
|
|
115
|
+
): value is (state: IPressState) => IStyleProp<IViewStyle> {
|
|
109
116
|
return typeof value === 'function';
|
|
110
117
|
}
|
|
111
118
|
|
|
@@ -118,7 +125,9 @@ function asSymbioteEvent(event: unknown): ISymbioteEvent | undefined {
|
|
|
118
125
|
@Component({
|
|
119
126
|
selector: 'Pressable, symbiote-pressable',
|
|
120
127
|
standalone: true,
|
|
121
|
-
hostDirectives: [
|
|
128
|
+
hostDirectives: [
|
|
129
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
130
|
+
],
|
|
122
131
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
123
132
|
imports: [ViewHost, SymbioteHostPropsDirective],
|
|
124
133
|
template: `
|
|
@@ -186,10 +195,13 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
186
195
|
@Input() accessibilityRole?: IAngularPressableProps['accessibilityRole'];
|
|
187
196
|
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
188
197
|
@Input() accessibilityValue?: IAngularPressableProps['accessibilityValue'];
|
|
189
|
-
@Input()
|
|
198
|
+
@Input()
|
|
199
|
+
accessibilityActions?: IAngularPressableProps['accessibilityActions'];
|
|
190
200
|
@Input() accessibilityLabelledBy?: string | string[];
|
|
191
|
-
@Input()
|
|
192
|
-
|
|
201
|
+
@Input()
|
|
202
|
+
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
203
|
+
@Input()
|
|
204
|
+
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
193
205
|
@Input() screenReaderFocusable?: boolean;
|
|
194
206
|
@Input() accessibilityViewIsModal?: boolean;
|
|
195
207
|
@Input() accessibilityElementsHidden?: boolean;
|
|
@@ -215,7 +227,8 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
215
227
|
@Input() id?: string;
|
|
216
228
|
@Input() role?: IAngularPressableProps['role'];
|
|
217
229
|
|
|
218
|
-
@ViewChild('host', { read: ElementRef })
|
|
230
|
+
@ViewChild('host', { read: ElementRef })
|
|
231
|
+
private hostElement?: ElementRef<unknown>;
|
|
219
232
|
|
|
220
233
|
// INTERNAL mutable state, driven by the press machine rather than by an @Input, so ngOnChanges
|
|
221
234
|
// can never cover it - it carries its OWN signal, which is what lets the memoized bag below stay
|
|
@@ -293,7 +306,10 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
293
306
|
accessibilityLabel: this.accessibilityLabel,
|
|
294
307
|
accessibilityHint: this.accessibilityHint,
|
|
295
308
|
accessibilityRole: this.accessibilityRole,
|
|
296
|
-
accessibilityState: resolveDisabledAccessibilityState(
|
|
309
|
+
accessibilityState: resolveDisabledAccessibilityState(
|
|
310
|
+
this.accessibilityState,
|
|
311
|
+
this.disabled,
|
|
312
|
+
),
|
|
297
313
|
accessibilityValue: this.accessibilityValue,
|
|
298
314
|
accessibilityActions: this.accessibilityActions,
|
|
299
315
|
accessibilityLabelledBy: this.accessibilityLabelledBy,
|
|
@@ -304,8 +320,10 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
304
320
|
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
305
321
|
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
306
322
|
accessibilityLanguage: this.accessibilityLanguage,
|
|
307
|
-
accessibilityRespondsToUserInteraction:
|
|
308
|
-
|
|
323
|
+
accessibilityRespondsToUserInteraction:
|
|
324
|
+
this.accessibilityRespondsToUserInteraction,
|
|
325
|
+
accessibilityShowsLargeContentViewer:
|
|
326
|
+
this.accessibilityShowsLargeContentViewer,
|
|
309
327
|
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
310
328
|
'aria-label': this.ariaLabel,
|
|
311
329
|
'aria-busy': this.ariaBusy,
|
|
@@ -327,7 +345,9 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
327
345
|
}
|
|
328
346
|
|
|
329
347
|
get resolvedRippleProps(): Record<string, unknown> | undefined {
|
|
330
|
-
return this.android_ripple === undefined
|
|
348
|
+
return this.android_ripple === undefined
|
|
349
|
+
? undefined
|
|
350
|
+
: rippleProps(this.android_ripple);
|
|
331
351
|
}
|
|
332
352
|
|
|
333
353
|
// Flat bag for `[symbioteHostProps]` (Renderer2.setProperty per key) - see primitives/shared.ts.
|
|
@@ -352,32 +372,38 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
352
372
|
accessible: this.accessible,
|
|
353
373
|
...this.foldedAccessibility,
|
|
354
374
|
android_disableSound: this.android_disableSound,
|
|
355
|
-
nativeBackgroundAndroid:
|
|
356
|
-
|
|
375
|
+
nativeBackgroundAndroid:
|
|
376
|
+
this.resolvedRippleProps?.nativeBackgroundAndroid,
|
|
377
|
+
nativeForegroundAndroid:
|
|
378
|
+
this.resolvedRippleProps?.nativeForegroundAndroid,
|
|
357
379
|
};
|
|
358
380
|
});
|
|
359
381
|
|
|
360
382
|
handlePressIn(event: unknown): void {
|
|
361
383
|
const symbioteEvent = asSymbioteEvent(event);
|
|
362
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
384
|
+
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
385
|
+
return;
|
|
363
386
|
this.handlers.handlePressIn(symbioteEvent);
|
|
364
387
|
}
|
|
365
388
|
|
|
366
389
|
handlePressOut(event: unknown): void {
|
|
367
390
|
const symbioteEvent = asSymbioteEvent(event);
|
|
368
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
391
|
+
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
392
|
+
return;
|
|
369
393
|
this.handlers.handlePressOut(symbioteEvent);
|
|
370
394
|
}
|
|
371
395
|
|
|
372
396
|
handlePress(event: unknown): void {
|
|
373
397
|
const symbioteEvent = asSymbioteEvent(event);
|
|
374
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
398
|
+
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
399
|
+
return;
|
|
375
400
|
this.handlers.handlePress(symbioteEvent);
|
|
376
401
|
}
|
|
377
402
|
|
|
378
403
|
handleResponderMove(event: unknown): void {
|
|
379
404
|
const symbioteEvent = asSymbioteEvent(event);
|
|
380
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
405
|
+
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
406
|
+
return;
|
|
381
407
|
this.handlers.handleResponderMove(symbioteEvent);
|
|
382
408
|
}
|
|
383
409
|
|
|
@@ -398,14 +424,18 @@ export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
|
398
424
|
// is listening anyway, mirroring core's noteHoverNoop but off `.observed` instead of an @Input.
|
|
399
425
|
private noteHoverNoop(): void {
|
|
400
426
|
if (this.hoverIn.observed || this.hoverOut.observed) {
|
|
401
|
-
dlog(
|
|
427
|
+
dlog(
|
|
428
|
+
'Pressable hover is a no-op on this host (no pointer-enter/leave event)',
|
|
429
|
+
);
|
|
402
430
|
}
|
|
403
431
|
}
|
|
404
432
|
|
|
405
433
|
// Wraps an @Output() as an IPressHandler only while it has a subscriber, so an unbound
|
|
406
434
|
// (longPress) still skips arming the timer, matching createPressHandlers' "undefined means
|
|
407
435
|
// nobody cares" contract.
|
|
408
|
-
private emitterHandler(
|
|
436
|
+
private emitterHandler(
|
|
437
|
+
emitter: EventEmitter<ISymbioteEvent>,
|
|
438
|
+
): IPressHandler | undefined {
|
|
409
439
|
return emitter.observed ? event => emitter.emit(event) : undefined;
|
|
410
440
|
}
|
|
411
441
|
|
|
@@ -60,7 +60,8 @@ type IHostProps = Record<string, unknown>;
|
|
|
60
60
|
// via <ng-content>), declared per-adapter over the shared accessibility base since the framework-specific
|
|
61
61
|
// children slot keeps it from being fully shared across adapters. Read the React reference for the
|
|
62
62
|
// native prop names.
|
|
63
|
-
export interface IAngularRefreshControlProps
|
|
63
|
+
export interface IAngularRefreshControlProps
|
|
64
|
+
extends IAccessibilityProps, IAriaProps {
|
|
64
65
|
refreshing: boolean;
|
|
65
66
|
// RN's onRefresh is `() => void | Promise<void>`, the handler may be async; the promise is
|
|
66
67
|
// fire-and-forget (native already starts refreshing on the gesture).
|
|
@@ -97,7 +98,9 @@ export type IAngularRefreshControlInputs = Omit<
|
|
|
97
98
|
@Component({
|
|
98
99
|
selector: 'RefreshControl',
|
|
99
100
|
standalone: true,
|
|
100
|
-
hostDirectives: [
|
|
101
|
+
hostDirectives: [
|
|
102
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
103
|
+
],
|
|
101
104
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
102
105
|
imports: [RefreshControlHost, SymbioteHostPropsDirective],
|
|
103
106
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -116,7 +119,12 @@ export type IAngularRefreshControlInputs = Omit<
|
|
|
116
119
|
`,
|
|
117
120
|
})
|
|
118
121
|
export class RefreshControl
|
|
119
|
-
implements
|
|
122
|
+
implements
|
|
123
|
+
IAngularRefreshControlInputs,
|
|
124
|
+
OnInit,
|
|
125
|
+
OnChanges,
|
|
126
|
+
DoCheck,
|
|
127
|
+
AfterViewInit
|
|
120
128
|
{
|
|
121
129
|
// Controlled prop the parent owns; required to match the React reference surface.
|
|
122
130
|
@Input({ required: true }) refreshing!: boolean;
|
|
@@ -142,8 +150,10 @@ export class RefreshControl
|
|
|
142
150
|
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
143
151
|
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
144
152
|
@Input() accessibilityLabelledBy?: string | string[];
|
|
145
|
-
@Input()
|
|
146
|
-
|
|
153
|
+
@Input()
|
|
154
|
+
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
155
|
+
@Input()
|
|
156
|
+
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
147
157
|
@Input() screenReaderFocusable?: boolean;
|
|
148
158
|
@Input() accessibilityViewIsModal?: boolean;
|
|
149
159
|
@Input() accessibilityElementsHidden?: boolean;
|
|
@@ -218,7 +228,9 @@ export class RefreshControl
|
|
|
218
228
|
this.lastNativeRefreshing = this.refreshing;
|
|
219
229
|
return;
|
|
220
230
|
}
|
|
221
|
-
this.syncNativeRefreshing(
|
|
231
|
+
this.syncNativeRefreshing(
|
|
232
|
+
this.refreshNativeNode ?? this.host?.nativeElement,
|
|
233
|
+
);
|
|
222
234
|
}
|
|
223
235
|
|
|
224
236
|
// Native starts the spinner before JS runs. Mirror RN's RefreshControl controlled-component
|
|
@@ -303,8 +315,10 @@ export class RefreshControl
|
|
|
303
315
|
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
304
316
|
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
305
317
|
accessibilityLanguage: this.accessibilityLanguage,
|
|
306
|
-
accessibilityRespondsToUserInteraction:
|
|
307
|
-
|
|
318
|
+
accessibilityRespondsToUserInteraction:
|
|
319
|
+
this.accessibilityRespondsToUserInteraction,
|
|
320
|
+
accessibilityShowsLargeContentViewer:
|
|
321
|
+
this.accessibilityShowsLargeContentViewer,
|
|
308
322
|
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
309
323
|
role: this.role,
|
|
310
324
|
'aria-label': this.ariaLabel,
|
|
@@ -42,7 +42,8 @@ import {
|
|
|
42
42
|
// Mirrors React's ISafeAreaViewProps minus children (Angular takes children via <ng-content>),
|
|
43
43
|
// declared per-adapter over the shared accessibility base since the framework-specific children
|
|
44
44
|
// slot keeps it from being fully shared across adapters.
|
|
45
|
-
export interface IAngularSafeAreaViewProps
|
|
45
|
+
export interface IAngularSafeAreaViewProps
|
|
46
|
+
extends IAccessibilityProps, IAriaProps {
|
|
46
47
|
style?: IStyleProp<IViewStyle>;
|
|
47
48
|
onLayout?: (event: ISymbioteEvent) => void;
|
|
48
49
|
}
|
|
@@ -62,7 +63,9 @@ export type IAngularSafeAreaViewInputs = Omit<
|
|
|
62
63
|
@Component({
|
|
63
64
|
selector: 'SafeAreaView',
|
|
64
65
|
standalone: true,
|
|
65
|
-
hostDirectives: [
|
|
66
|
+
hostDirectives: [
|
|
67
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
68
|
+
],
|
|
66
69
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
67
70
|
imports: [SafeAreaViewHost, SymbioteHostPropsDirective],
|
|
68
71
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -79,7 +82,9 @@ export type IAngularSafeAreaViewInputs = Omit<
|
|
|
79
82
|
</symbiote-safe-area-view>
|
|
80
83
|
`,
|
|
81
84
|
})
|
|
82
|
-
export class SafeAreaView
|
|
85
|
+
export class SafeAreaView
|
|
86
|
+
implements IAngularSafeAreaViewInputs, OnChanges, DoCheck
|
|
87
|
+
{
|
|
83
88
|
@Input() style?: IStyleProp<IViewStyle>;
|
|
84
89
|
// Real @Output()s, not `[onX]="…"` callbacks. Safe to name `layout` the same as the native
|
|
85
90
|
// `layout` event fired inside this component's own template — the engine's bubble() treats
|
|
@@ -99,8 +104,10 @@ export class SafeAreaView implements IAngularSafeAreaViewInputs, OnChanges, DoCh
|
|
|
99
104
|
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
100
105
|
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
101
106
|
@Input() accessibilityLabelledBy?: string | string[];
|
|
102
|
-
@Input()
|
|
103
|
-
|
|
107
|
+
@Input()
|
|
108
|
+
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
109
|
+
@Input()
|
|
110
|
+
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
104
111
|
@Input() screenReaderFocusable?: boolean;
|
|
105
112
|
@Input() accessibilityViewIsModal?: boolean;
|
|
106
113
|
@Input() accessibilityElementsHidden?: boolean;
|
|
@@ -199,8 +206,10 @@ export class SafeAreaView implements IAngularSafeAreaViewInputs, OnChanges, DoCh
|
|
|
199
206
|
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
200
207
|
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
201
208
|
accessibilityLanguage: this.accessibilityLanguage,
|
|
202
|
-
accessibilityRespondsToUserInteraction:
|
|
203
|
-
|
|
209
|
+
accessibilityRespondsToUserInteraction:
|
|
210
|
+
this.accessibilityRespondsToUserInteraction,
|
|
211
|
+
accessibilityShowsLargeContentViewer:
|
|
212
|
+
this.accessibilityShowsLargeContentViewer,
|
|
204
213
|
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
205
214
|
role: this.role,
|
|
206
215
|
'aria-label': this.ariaLabel,
|
|
@@ -43,7 +43,11 @@ import {
|
|
|
43
43
|
SymbioteHostPropsDirective,
|
|
44
44
|
SymbioteStyleInputDirective,
|
|
45
45
|
} from '../../primitives';
|
|
46
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
ScrollViewBase,
|
|
48
|
+
ScrollViewProjectionDirective,
|
|
49
|
+
SCROLL_VIEW_INPUTS,
|
|
50
|
+
} from './shared';
|
|
47
51
|
export type { IAngularScrollViewProps, IScrollViewHandle } from './shared';
|
|
48
52
|
|
|
49
53
|
// Minimal local twin of `@angular/common`'s NgTemplateOutlet (this adapter deliberately has no
|
|
@@ -66,7 +70,9 @@ export class SymbioteTemplateOutletDirective implements OnChanges, OnDestroy {
|
|
|
66
70
|
this.viewRef = undefined;
|
|
67
71
|
}
|
|
68
72
|
if (this.symbioteTemplateOutlet !== null) {
|
|
69
|
-
this.viewRef = this.viewContainerRef.createEmbeddedView(
|
|
73
|
+
this.viewRef = this.viewContainerRef.createEmbeddedView(
|
|
74
|
+
this.symbioteTemplateOutlet,
|
|
75
|
+
);
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
|
|
@@ -87,7 +93,9 @@ function asStyle(value: unknown): IStyleProp<IViewStyle> | undefined {
|
|
|
87
93
|
@Component({
|
|
88
94
|
selector: 'ScrollView',
|
|
89
95
|
standalone: true,
|
|
90
|
-
hostDirectives: [
|
|
96
|
+
hostDirectives: [
|
|
97
|
+
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
98
|
+
],
|
|
91
99
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
92
100
|
imports: [
|
|
93
101
|
ScrollViewHost,
|
|
@@ -120,17 +128,24 @@ function asStyle(value: unknown): IStyleProp<IViewStyle> | undefined {
|
|
|
120
128
|
[symbioteHostProps]="contentProps()"
|
|
121
129
|
[symbioteScrollViewProjection]="projectionController"
|
|
122
130
|
>
|
|
123
|
-
<ng-container
|
|
131
|
+
<ng-container
|
|
132
|
+
[symbioteTemplateOutlet]="sharedContent"
|
|
133
|
+
></ng-container>
|
|
124
134
|
</symbiote-horizontal-scroll-content>
|
|
125
135
|
</symbiote-horizontal-scroll-view>
|
|
126
136
|
</symbiote-refresh-control>
|
|
127
137
|
} @else {
|
|
128
|
-
<symbiote-horizontal-scroll-view
|
|
138
|
+
<symbiote-horizontal-scroll-view
|
|
139
|
+
#host="symbioteHost"
|
|
140
|
+
[symbioteHostProps]="scrollProps()"
|
|
141
|
+
>
|
|
129
142
|
<symbiote-horizontal-scroll-content
|
|
130
143
|
[symbioteHostProps]="contentProps()"
|
|
131
144
|
[symbioteScrollViewProjection]="projectionController"
|
|
132
145
|
>
|
|
133
|
-
<ng-container
|
|
146
|
+
<ng-container
|
|
147
|
+
[symbioteTemplateOutlet]="sharedContent"
|
|
148
|
+
></ng-container>
|
|
134
149
|
</symbiote-horizontal-scroll-content>
|
|
135
150
|
</symbiote-horizontal-scroll-view>
|
|
136
151
|
}
|
|
@@ -149,17 +164,24 @@ function asStyle(value: unknown): IStyleProp<IViewStyle> | undefined {
|
|
|
149
164
|
[symbioteHostProps]="contentProps()"
|
|
150
165
|
[symbioteScrollViewProjection]="projectionController"
|
|
151
166
|
>
|
|
152
|
-
<ng-container
|
|
167
|
+
<ng-container
|
|
168
|
+
[symbioteTemplateOutlet]="sharedContent"
|
|
169
|
+
></ng-container>
|
|
153
170
|
</symbiote-scroll-content>
|
|
154
171
|
</symbiote-scroll-view>
|
|
155
172
|
</symbiote-refresh-control>
|
|
156
173
|
} @else {
|
|
157
|
-
<symbiote-scroll-view
|
|
174
|
+
<symbiote-scroll-view
|
|
175
|
+
#host="symbioteHost"
|
|
176
|
+
[symbioteHostProps]="scrollProps()"
|
|
177
|
+
>
|
|
158
178
|
<symbiote-scroll-content
|
|
159
179
|
[symbioteHostProps]="contentProps()"
|
|
160
180
|
[symbioteScrollViewProjection]="projectionController"
|
|
161
181
|
>
|
|
162
|
-
<ng-container
|
|
182
|
+
<ng-container
|
|
183
|
+
[symbioteTemplateOutlet]="sharedContent"
|
|
184
|
+
></ng-container>
|
|
163
185
|
</symbiote-scroll-content>
|
|
164
186
|
</symbiote-scroll-view>
|
|
165
187
|
}
|