@symbiote-native/angular 3.1.3 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/babel-register-composed.cjs +1 -0
- package/build/angular/accessibility-events.d.ts +12 -0
- package/build/angular/accessibility-events.js +28 -0
- package/build/angular/accessibility-events.js.map +1 -0
- package/build/angular/accessibility-inputs.d.ts +40 -0
- package/build/angular/accessibility-inputs.js +130 -0
- package/build/angular/accessibility-inputs.js.map +1 -0
- package/build/angular/bootstrap.d.ts +3 -1
- package/build/angular/bootstrap.js +4 -1
- package/build/angular/bootstrap.js.map +1 -1
- package/build/angular/components/checkbox-props.d.ts +2 -0
- package/build/angular/components/checkbox-props.js +2 -0
- package/build/angular/components/checkbox-props.js.map +1 -0
- package/build/angular/components/flat-list/flat-list-template.d.ts +1 -0
- package/build/angular/components/flat-list/flat-list-template.js +158 -0
- package/build/angular/components/flat-list/flat-list-template.js.map +1 -0
- package/build/angular/components/flat-list/index.d.ts +6 -61
- package/build/angular/components/flat-list/index.js +26 -463
- package/build/angular/components/flat-list/index.js.map +1 -1
- package/build/angular/components/keyboard-avoiding-view/index.d.ts +4 -40
- package/build/angular/components/keyboard-avoiding-view/index.js +7 -131
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
- package/build/angular/components/modal/index.d.ts +5 -41
- package/build/angular/components/modal/index.js +8 -133
- package/build/angular/components/modal/index.js.map +1 -1
- package/build/angular/components/section-list/index.d.ts +4 -51
- package/build/angular/components/section-list/index.js +18 -335
- package/build/angular/components/section-list/index.js.map +1 -1
- package/build/angular/components/virtualized-list/cell-registry.d.ts +35 -0
- package/build/angular/components/virtualized-list/cell-registry.js +133 -0
- package/build/angular/components/virtualized-list/cell-registry.js.map +1 -0
- package/build/angular/components/virtualized-list/index.d.ts +18 -253
- package/build/angular/components/virtualized-list/index.js +112 -1178
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-list/list-a11y-forward.d.ts +1 -0
- package/build/angular/components/virtualized-list/list-a11y-forward.js +42 -0
- package/build/angular/components/virtualized-list/list-a11y-forward.js.map +1 -0
- package/build/angular/components/virtualized-list/list-bags.d.ts +32 -0
- package/build/angular/components/virtualized-list/list-bags.js +120 -0
- package/build/angular/components/virtualized-list/list-bags.js.map +1 -0
- package/build/angular/components/virtualized-list/list-effects.d.ts +31 -0
- package/build/angular/components/virtualized-list/list-effects.js +83 -0
- package/build/angular/components/virtualized-list/list-effects.js.map +1 -0
- package/build/angular/components/virtualized-list/list-events.d.ts +17 -0
- package/build/angular/components/virtualized-list/list-events.js +34 -0
- package/build/angular/components/virtualized-list/list-events.js.map +1 -0
- package/build/angular/components/virtualized-list/list-handle.d.ts +35 -0
- package/build/angular/components/virtualized-list/list-handle.js +61 -0
- package/build/angular/components/virtualized-list/list-handle.js.map +1 -0
- package/build/angular/components/virtualized-list/list-inputs.d.ts +78 -0
- package/build/angular/components/virtualized-list/list-inputs.js +150 -0
- package/build/angular/components/virtualized-list/list-inputs.js.map +1 -0
- package/build/angular/components/virtualized-list/list-props.d.ts +58 -0
- package/build/angular/components/virtualized-list/list-props.js +3 -0
- package/build/angular/components/virtualized-list/list-props.js.map +1 -0
- package/build/angular/components/virtualized-list/list-styles.d.ts +23 -0
- package/build/angular/components/virtualized-list/list-styles.js +26 -0
- package/build/angular/components/virtualized-list/list-styles.js.map +1 -0
- package/build/angular/components/virtualized-list/list-template.d.ts +1 -0
- package/build/angular/components/virtualized-list/list-template.js +176 -0
- package/build/angular/components/virtualized-list/list-template.js.map +1 -0
- package/build/angular/components/virtualized-section-list/index.d.ts +13 -70
- package/build/angular/components/virtualized-section-list/index.js +22 -455
- package/build/angular/components/virtualized-section-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/section-list-template.d.ts +1 -0
- package/build/angular/components/virtualized-section-list/section-list-template.js +107 -0
- package/build/angular/components/virtualized-section-list/section-list-template.js.map +1 -0
- package/build/angular/components.d.ts +1 -0
- package/build/angular/components.js.map +1 -1
- package/build/angular/descriptor-to-angular/descriptor-host.d.ts +8 -0
- package/build/angular/descriptor-to-angular/descriptor-host.js +38 -0
- package/build/angular/descriptor-to-angular/descriptor-host.js.map +1 -0
- package/build/angular/descriptor-to-angular/index.d.ts +1 -0
- package/build/angular/descriptor-to-angular/index.js +4 -0
- package/build/angular/descriptor-to-angular/index.js.map +1 -1
- package/build/angular/element-base.d.ts +153 -0
- package/build/angular/element-base.js +272 -0
- package/build/angular/element-base.js.map +1 -0
- package/build/angular/elements-controls.d.ts +165 -0
- package/build/angular/elements-controls.js +382 -0
- package/build/angular/elements-controls.js.map +1 -0
- package/build/angular/elements-layout.d.ts +122 -0
- package/build/angular/elements-layout.js +242 -0
- package/build/angular/elements-layout.js.map +1 -0
- package/build/angular/elements-press.d.ts +96 -0
- package/build/angular/elements-press.js +227 -0
- package/build/angular/elements-press.js.map +1 -0
- package/build/angular/elements.d.ts +6 -516
- package/build/angular/elements.js +8 -1091
- package/build/angular/elements.js.map +1 -1
- package/build/angular/finalization-registry.d.ts +4 -0
- package/build/angular/finalization-registry.js +17 -0
- package/build/angular/finalization-registry.js.map +1 -0
- package/build/angular/host-instance/index.d.ts +2 -0
- package/build/angular/host-instance/index.js +4 -4
- package/build/angular/host-instance/index.js.map +1 -1
- package/build/angular/index.d.ts +9 -4
- package/build/angular/index.js +8 -3
- package/build/angular/index.js.map +1 -1
- package/build/angular/native-view-base.d.ts +27 -0
- package/build/angular/native-view-base.js +69 -0
- package/build/angular/native-view-base.js.map +1 -0
- package/build/angular/render/index.d.ts +2 -1
- package/build/angular/render/index.js +46 -73
- package/build/angular/render/index.js.map +1 -1
- package/build/angular/services/connect-watched-signal.d.ts +2 -0
- package/build/angular/services/connect-watched-signal.js +9 -0
- package/build/angular/services/connect-watched-signal.js.map +1 -0
- package/build/angular/services/create-event-value-hook.d.ts +3 -0
- package/build/angular/services/create-event-value-hook.js +17 -0
- package/build/angular/services/create-event-value-hook.js.map +1 -0
- package/build/angular/services/create-resource-hook.d.ts +7 -0
- package/build/angular/services/create-resource-hook.js +20 -0
- package/build/angular/services/create-resource-hook.js.map +1 -0
- package/build/angular/services/index.d.ts +5 -0
- package/build/angular/services/index.js +5 -0
- package/build/angular/services/index.js.map +1 -1
- package/build/angular/services/inject-event.d.ts +6 -0
- package/build/angular/services/inject-event.js +24 -0
- package/build/angular/services/inject-event.js.map +1 -0
- package/build/angular/services/permissions-service-base.d.ts +14 -0
- package/build/angular/services/permissions-service-base.js +38 -0
- package/build/angular/services/permissions-service-base.js.map +1 -0
- package/package.json +6 -6
- package/src/accessibility-events.ts +13 -0
- package/src/accessibility-inputs.ts +89 -0
- package/src/bootstrap.ts +6 -2
- package/src/components/checkbox-props.ts +12 -0
- package/src/components/flat-list/flat-list-template.ts +159 -0
- package/src/components/flat-list/index.ts +30 -307
- package/src/components/keyboard-avoiding-view/index.ts +4 -78
- package/src/components/modal/index.ts +7 -80
- package/src/components/section-list/index.ts +21 -172
- package/src/components/virtualized-list/cell-registry.ts +199 -0
- package/src/components/virtualized-list/index.ts +145 -1181
- package/src/components/virtualized-list/list-a11y-forward.ts +42 -0
- package/src/components/virtualized-list/list-bags.ts +142 -0
- package/src/components/virtualized-list/list-effects.ts +116 -0
- package/src/components/virtualized-list/list-events.ts +31 -0
- package/src/components/virtualized-list/list-handle.ts +92 -0
- package/src/components/virtualized-list/list-inputs.ts +149 -0
- package/src/components/virtualized-list/list-props.ts +81 -0
- package/src/components/virtualized-list/list-styles.ts +62 -0
- package/src/components/virtualized-list/list-template.ts +175 -0
- package/src/components/virtualized-section-list/index.ts +40 -351
- package/src/components/virtualized-section-list/section-list-template.ts +108 -0
- package/src/components.ts +1 -0
- package/src/descriptor-to-angular/descriptor-host.ts +27 -0
- package/src/descriptor-to-angular/index.ts +5 -0
- package/src/element-base.ts +272 -0
- package/src/elements-controls.ts +282 -0
- package/src/elements-layout.ts +141 -0
- package/src/elements-press.ts +145 -0
- package/src/elements.ts +73 -788
- package/src/finalization-registry.ts +18 -0
- package/src/host-instance/index.ts +4 -4
- package/src/index.ts +18 -2
- package/src/native-view-base.ts +86 -0
- package/src/render/index.ts +76 -77
- package/src/services/connect-watched-signal.ts +15 -0
- package/src/services/create-event-value-hook.ts +24 -0
- package/src/services/create-resource-hook.ts +32 -0
- package/src/services/index.ts +5 -0
- package/src/services/inject-event.ts +52 -0
- package/src/services/permissions-service-base.ts +46 -0
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
resolveAccessibilityProps,
|
|
33
33
|
shouldRenderModal,
|
|
34
34
|
type IAccessibilityProps,
|
|
35
|
-
type IAccessibilityStateValue,
|
|
36
35
|
type IAriaProps,
|
|
37
36
|
type IModalAnimationType,
|
|
38
37
|
type IModalOrientation,
|
|
@@ -47,6 +46,7 @@ import {
|
|
|
47
46
|
type ISymbioteEvent,
|
|
48
47
|
type IViewStyle,
|
|
49
48
|
} from '@symbiote-native/engine';
|
|
49
|
+
import { AccessibilityEventsBase } from '../../accessibility-events';
|
|
50
50
|
import {
|
|
51
51
|
anchorHostStyle,
|
|
52
52
|
ModalHost,
|
|
@@ -124,15 +124,13 @@ export type IAngularModalInputs = Omit<
|
|
|
124
124
|
}
|
|
125
125
|
`,
|
|
126
126
|
})
|
|
127
|
-
export class Modal
|
|
127
|
+
export class Modal
|
|
128
|
+
extends AccessibilityEventsBase
|
|
129
|
+
implements IAngularModalInputs, OnInit, OnChanges, DoCheck
|
|
130
|
+
{
|
|
128
131
|
@Output() readonly show = new EventEmitter<void>();
|
|
129
132
|
@Output() readonly dismiss = new EventEmitter<void>();
|
|
130
133
|
@Output() readonly requestClose = new EventEmitter<void>();
|
|
131
|
-
@Output() readonly orientationChange = new EventEmitter<ISymbioteEvent>();
|
|
132
|
-
@Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
|
|
133
|
-
@Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
|
|
134
|
-
@Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
|
|
135
|
-
@Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
|
|
136
134
|
@Input() visible?: boolean;
|
|
137
135
|
@Input() transparent?: boolean;
|
|
138
136
|
@Input() backdropColor?: string;
|
|
@@ -145,41 +143,7 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
145
143
|
@Input() allowSwipeDismissal?: boolean;
|
|
146
144
|
@Input() style?: IStyleProp<IViewStyle>;
|
|
147
145
|
@Input() testID?: string;
|
|
148
|
-
@
|
|
149
|
-
@Input() accessibilityLabel?: string;
|
|
150
|
-
@Input() accessibilityHint?: string;
|
|
151
|
-
@Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
|
|
152
|
-
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
153
|
-
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
154
|
-
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
155
|
-
@Input() accessibilityLabelledBy?: string | string[];
|
|
156
|
-
@Input()
|
|
157
|
-
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
158
|
-
@Input()
|
|
159
|
-
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
160
|
-
@Input() screenReaderFocusable?: boolean;
|
|
161
|
-
@Input() accessibilityViewIsModal?: boolean;
|
|
162
|
-
@Input() accessibilityElementsHidden?: boolean;
|
|
163
|
-
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
164
|
-
@Input() accessibilityLanguage?: string;
|
|
165
|
-
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
166
|
-
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
167
|
-
@Input() accessibilityLargeContentTitle?: string;
|
|
168
|
-
@Input() role?: IAriaProps['role'];
|
|
169
|
-
@Input('aria-label') ariaLabel?: string;
|
|
170
|
-
@Input('aria-labelledby') ariaLabelledBy?: string;
|
|
171
|
-
@Input('aria-live') ariaLive?: IAriaProps['aria-live'];
|
|
172
|
-
@Input('aria-hidden') ariaHidden?: boolean;
|
|
173
|
-
@Input('aria-busy') ariaBusy?: boolean;
|
|
174
|
-
@Input('aria-checked') ariaChecked?: boolean | 'mixed';
|
|
175
|
-
@Input('aria-disabled') ariaDisabled?: boolean;
|
|
176
|
-
@Input('aria-expanded') ariaExpanded?: boolean;
|
|
177
|
-
@Input('aria-selected') ariaSelected?: boolean;
|
|
178
|
-
@Input('aria-modal') ariaModal?: boolean;
|
|
179
|
-
@Input('aria-valuemax') ariaValueMax?: number;
|
|
180
|
-
@Input('aria-valuemin') ariaValueMin?: number;
|
|
181
|
-
@Input('aria-valuenow') ariaValueNow?: number;
|
|
182
|
-
@Input('aria-valuetext') ariaValueText?: string;
|
|
146
|
+
@Output() readonly orientationChange = new EventEmitter<ISymbioteEvent>();
|
|
183
147
|
|
|
184
148
|
// The iOS keep-alive (state/modal.ts): after visible→hidden the node stays until the native
|
|
185
149
|
// onDismiss (`handleDismiss`) drops it.
|
|
@@ -323,43 +287,6 @@ export class Modal implements IAngularModalInputs, OnInit, OnChanges, DoCheck {
|
|
|
323
287
|
private accessibilityInputs(): IAccessibilityProps &
|
|
324
288
|
IAriaProps &
|
|
325
289
|
Record<string, unknown> {
|
|
326
|
-
return {
|
|
327
|
-
testID: this.testID,
|
|
328
|
-
accessible: this.accessible,
|
|
329
|
-
accessibilityLabel: this.accessibilityLabel,
|
|
330
|
-
accessibilityHint: this.accessibilityHint,
|
|
331
|
-
accessibilityRole: this.accessibilityRole,
|
|
332
|
-
accessibilityState: this.accessibilityState,
|
|
333
|
-
accessibilityValue: this.accessibilityValue,
|
|
334
|
-
accessibilityActions: this.accessibilityActions,
|
|
335
|
-
accessibilityLabelledBy: this.accessibilityLabelledBy,
|
|
336
|
-
importantForAccessibility: this.importantForAccessibility,
|
|
337
|
-
accessibilityLiveRegion: this.accessibilityLiveRegion,
|
|
338
|
-
screenReaderFocusable: this.screenReaderFocusable,
|
|
339
|
-
accessibilityViewIsModal: this.accessibilityViewIsModal,
|
|
340
|
-
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
341
|
-
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
342
|
-
accessibilityLanguage: this.accessibilityLanguage,
|
|
343
|
-
accessibilityRespondsToUserInteraction:
|
|
344
|
-
this.accessibilityRespondsToUserInteraction,
|
|
345
|
-
accessibilityShowsLargeContentViewer:
|
|
346
|
-
this.accessibilityShowsLargeContentViewer,
|
|
347
|
-
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
348
|
-
role: this.role,
|
|
349
|
-
'aria-label': this.ariaLabel,
|
|
350
|
-
'aria-labelledby': this.ariaLabelledBy,
|
|
351
|
-
'aria-live': this.ariaLive,
|
|
352
|
-
'aria-hidden': this.ariaHidden,
|
|
353
|
-
'aria-busy': this.ariaBusy,
|
|
354
|
-
'aria-checked': this.ariaChecked,
|
|
355
|
-
'aria-disabled': this.ariaDisabled,
|
|
356
|
-
'aria-expanded': this.ariaExpanded,
|
|
357
|
-
'aria-selected': this.ariaSelected,
|
|
358
|
-
'aria-modal': this.ariaModal,
|
|
359
|
-
'aria-valuemax': this.ariaValueMax,
|
|
360
|
-
'aria-valuemin': this.ariaValueMin,
|
|
361
|
-
'aria-valuenow': this.ariaValueNow,
|
|
362
|
-
'aria-valuetext': this.ariaValueText,
|
|
363
|
-
};
|
|
290
|
+
return { testID: this.testID, ...this.accessibilityInputProps() };
|
|
364
291
|
}
|
|
365
292
|
}
|
|
@@ -1,43 +1,17 @@
|
|
|
1
|
-
// SectionList,
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// lives below; this layer re-exposes the same surface under the SectionList name and delegates
|
|
5
|
-
// the handle to the inner VirtualizedSectionList.
|
|
6
|
-
//
|
|
7
|
-
// SectionList is a PURE FORWARDER: its public prop surface IS VirtualizedSectionList's (RN layers
|
|
8
|
-
// them one-for-one), and the SectionList-flavour defaults (stickySectionHeadersEnabled per
|
|
9
|
-
// Platform.OS, the section entry keyExtractor) already live INSIDE VirtualizedSectionList — double-
|
|
10
|
-
// applying them here would fight it. Angular has no attrs-spread (unlike Vue's $attrs), so every
|
|
11
|
-
// prop is forwarded as an explicit @Input binding, except the seven list-lifecycle events
|
|
12
|
-
// (endReached/startReached/refresh/accessibilityAction/accessibilityTap/magicTap/
|
|
13
|
-
// accessibilityEscape), which are real @Output() EventEmitters re-emitted via a listener binding.
|
|
14
|
-
//
|
|
15
|
-
// TEMPLATE FORWARDING — RE-STAMP, the same pattern FlatList's single-column branch uses (see
|
|
16
|
-
// flat-list/index.ts). A bare `<ng-content></ng-content>` passthrough does NOT let
|
|
17
|
-
// VirtualizedSectionList's own @ContentChild resolve directives across a SECOND projection hop —
|
|
18
|
-
// Angular's content queries resolve only against what was projected directly onto the querying
|
|
19
|
-
// component's OWN tag. So SectionList captures the app's `<ng-template vSectionItem>` /
|
|
20
|
-
// vSectionHeader / vSectionFooter / vSectionSeparator / vListHeader / vListFooter / vListEmpty /
|
|
21
|
-
// vListSeparator with its OWN @ContentChild (a single, direct hop — always resolves) and
|
|
22
|
-
// re-authors equivalent `<ng-template>`s on `<VirtualizedSectionList>`, forwarding the captured
|
|
23
|
-
// templateRef + context through VListOutletDirective — mirroring how VirtualizedSectionList itself
|
|
24
|
-
// re-stamps its own captured directives onto its inner VirtualizedList.
|
|
1
|
+
// SectionList, a pure forwarder over VirtualizedSectionList, mirroring RN's layering
|
|
2
|
+
// A content query does not resolve across a second `<ng-content>` hop, so the app's templates are
|
|
3
|
+
// captured here and re-stamped onto the inner list
|
|
25
4
|
|
|
26
5
|
import {
|
|
27
6
|
ChangeDetectionStrategy,
|
|
28
7
|
Component,
|
|
29
8
|
ContentChild,
|
|
30
9
|
ElementRef,
|
|
31
|
-
EventEmitter,
|
|
32
10
|
Input,
|
|
33
|
-
Output,
|
|
34
11
|
ViewChild,
|
|
35
12
|
inject,
|
|
36
13
|
} from '@angular/core';
|
|
37
14
|
import type {
|
|
38
|
-
IAccessibilityProps,
|
|
39
|
-
IAccessibilityStateValue,
|
|
40
|
-
IAriaProps,
|
|
41
15
|
IScrollViewHandle,
|
|
42
16
|
ISection,
|
|
43
17
|
IVirtualizedSectionListHandle,
|
|
@@ -56,6 +30,9 @@ import {
|
|
|
56
30
|
type IVListSeparatorContext,
|
|
57
31
|
} from '../virtualized-list';
|
|
58
32
|
import { VListOutletDirective } from '../virtualized-list/directives';
|
|
33
|
+
import { LIST_ACCESSIBILITY_FORWARD } from '../virtualized-list/list-a11y-forward';
|
|
34
|
+
import { ListEventsBase } from '../virtualized-list/list-events';
|
|
35
|
+
import { provideGateDemand } from '../../gate-demand';
|
|
59
36
|
import {
|
|
60
37
|
stableAnchorStyle,
|
|
61
38
|
SymbioteStyleInputDirective,
|
|
@@ -69,25 +46,16 @@ import {
|
|
|
69
46
|
type IVirtualizedSectionListProps,
|
|
70
47
|
} from '../virtualized-section-list';
|
|
71
48
|
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
// argument to pin ItemT to, so `let-leadingItem`/`let-trailingItem` arrive typed `unknown`) — even
|
|
75
|
-
// though VirtualizedSectionList's own unwrap always supplies a real ItemT value. The narrowest
|
|
76
|
-
// possible I/O-boundary cast for that gap; not a general-purpose unknown-to-T narrowing (mirrors
|
|
77
|
-
// flat-list/index.ts's identical asItem helper).
|
|
49
|
+
// The separator context arrives typed `unknown`, the directive is matched structurally in the
|
|
50
|
+
// template with no type argument to pin the item type. The narrowest cast for that gap
|
|
78
51
|
function asItem<ItemT>(value: unknown): ItemT | undefined {
|
|
79
52
|
return value as ItemT | undefined;
|
|
80
53
|
}
|
|
81
54
|
|
|
82
|
-
// Re-export the shared section type + the imperative handle so app code (and any later layer) imports
|
|
83
|
-
// them from SectionList, mirroring how the Vue twin re-exposes ISection + ISectionListHandle.
|
|
84
55
|
export type { ISection } from '@symbiote-native/components';
|
|
85
56
|
export type ISectionListHandle = IVirtualizedSectionListHandle;
|
|
86
57
|
|
|
87
|
-
// Re-
|
|
88
|
-
// from '@symbiote-native/angular' gets the full `<ng-template vSection*>` / `vList*` authoring surface
|
|
89
|
-
// alongside SectionList (mirrors how virtualized-section-list/index re-exports the section ones and
|
|
90
|
-
// FlatList re-exports the list-level ones).
|
|
58
|
+
// Re-exported so app code gets the whole `vSection*` and `vList*` authoring surface from here
|
|
91
59
|
export {
|
|
92
60
|
VSectionFooterDirective,
|
|
93
61
|
VSectionHeaderDirective,
|
|
@@ -100,21 +68,11 @@ export {
|
|
|
100
68
|
VListHeaderDirective,
|
|
101
69
|
VListSeparatorDirective,
|
|
102
70
|
} from '../virtualized-list';
|
|
103
|
-
import {
|
|
104
|
-
gateWanted,
|
|
105
|
-
injectGateDemandAbove,
|
|
106
|
-
provideGateDemand,
|
|
107
|
-
type IGatedAccessibilityEvent,
|
|
108
|
-
} from '../../gate-demand';
|
|
109
71
|
|
|
110
|
-
//
|
|
111
|
-
// the prop type is shared verbatim — no SectionList-only field exists.
|
|
72
|
+
// RN layers the two one-for-one, so the prop type is shared verbatim
|
|
112
73
|
export type ISectionListProps<ItemT> = IVirtualizedSectionListProps<ItemT>;
|
|
113
74
|
|
|
114
|
-
//
|
|
115
|
-
// list-lifecycle events, which it exposes as real @Output() EventEmitters instead (see the class
|
|
116
|
-
// below) — mirrors IAngularPressableInputs in pressable/index.ts and VirtualizedSectionList's own
|
|
117
|
-
// IVirtualizedSectionListInputs.
|
|
75
|
+
// The plain inputs: the full surface minus the events exposed as real outputs
|
|
118
76
|
export type ISectionListInputs<ItemT> = Omit<
|
|
119
77
|
ISectionListProps<ItemT>,
|
|
120
78
|
| 'onEndReached'
|
|
@@ -182,47 +140,7 @@ export type ISectionListInputs<ItemT> = Omit<
|
|
|
182
140
|
[contentContainerStyle]="contentContainerStyle"
|
|
183
141
|
[testID]="testID"
|
|
184
142
|
[nativeID]="nativeID"
|
|
185
|
-
|
|
186
|
-
[accessibilityLabel]="accessibilityLabel"
|
|
187
|
-
[accessibilityHint]="accessibilityHint"
|
|
188
|
-
[accessibilityRole]="accessibilityRole"
|
|
189
|
-
[accessibilityState]="accessibilityState"
|
|
190
|
-
[accessibilityValue]="accessibilityValue"
|
|
191
|
-
[accessibilityActions]="accessibilityActions"
|
|
192
|
-
[accessibilityLabelledBy]="accessibilityLabelledBy"
|
|
193
|
-
[importantForAccessibility]="importantForAccessibility"
|
|
194
|
-
[accessibilityLiveRegion]="accessibilityLiveRegion"
|
|
195
|
-
[screenReaderFocusable]="screenReaderFocusable"
|
|
196
|
-
[accessibilityViewIsModal]="accessibilityViewIsModal"
|
|
197
|
-
[accessibilityElementsHidden]="accessibilityElementsHidden"
|
|
198
|
-
[accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
|
|
199
|
-
[accessibilityLanguage]="accessibilityLanguage"
|
|
200
|
-
[accessibilityRespondsToUserInteraction]="
|
|
201
|
-
accessibilityRespondsToUserInteraction
|
|
202
|
-
"
|
|
203
|
-
[accessibilityShowsLargeContentViewer]="
|
|
204
|
-
accessibilityShowsLargeContentViewer
|
|
205
|
-
"
|
|
206
|
-
[accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
|
|
207
|
-
(accessibilityAction)="accessibilityAction.emit($event)"
|
|
208
|
-
(accessibilityTap)="accessibilityTap.emit($event)"
|
|
209
|
-
(magicTap)="magicTap.emit($event)"
|
|
210
|
-
(accessibilityEscape)="accessibilityEscape.emit($event)"
|
|
211
|
-
[role]="role"
|
|
212
|
-
[ariaLabel]="ariaLabel"
|
|
213
|
-
[ariaLabelledBy]="ariaLabelledBy"
|
|
214
|
-
[ariaLive]="ariaLive"
|
|
215
|
-
[ariaHidden]="ariaHidden"
|
|
216
|
-
[ariaBusy]="ariaBusy"
|
|
217
|
-
[ariaChecked]="ariaChecked"
|
|
218
|
-
[ariaDisabled]="ariaDisabled"
|
|
219
|
-
[ariaExpanded]="ariaExpanded"
|
|
220
|
-
[ariaSelected]="ariaSelected"
|
|
221
|
-
[ariaModal]="ariaModal"
|
|
222
|
-
[ariaValueMax]="ariaValueMax"
|
|
223
|
-
[ariaValueMin]="ariaValueMin"
|
|
224
|
-
[ariaValueNow]="ariaValueNow"
|
|
225
|
-
[ariaValueText]="ariaValueText"
|
|
143
|
+
${LIST_ACCESSIBILITY_FORWARD}
|
|
226
144
|
>
|
|
227
145
|
<ng-template
|
|
228
146
|
vSectionItem
|
|
@@ -303,27 +221,20 @@ export type ISectionListInputs<ItemT> = Omit<
|
|
|
303
221
|
`,
|
|
304
222
|
})
|
|
305
223
|
export class SectionList<ItemT = unknown>
|
|
224
|
+
extends ListEventsBase
|
|
306
225
|
implements ISectionListInputs<ItemT>, IVirtualizedSectionListHandle
|
|
307
226
|
{
|
|
308
227
|
@Input({ required: true }) sections!: ReadonlyArray<ISection<ItemT>>;
|
|
309
228
|
@Input() keyExtractor?: (item: ItemT, index: number) => string;
|
|
310
|
-
// Passed through
|
|
311
|
-
// sections-vs-entries wrapper - see its entryItemLayout getter.
|
|
229
|
+
// Passed through flat, `VirtualizedSectionList` owns the sections-versus-entries wrapper
|
|
312
230
|
@Input() getItemLayout?: (
|
|
313
231
|
data: ReadonlyArray<ISection<ItemT>> | null,
|
|
314
232
|
index: number,
|
|
315
233
|
) => { length: number; offset: number; index: number };
|
|
316
234
|
@Input() stickySectionHeadersEnabled?: boolean;
|
|
317
235
|
@Input() extraData?: unknown;
|
|
318
|
-
@Output() readonly endReached = new EventEmitter<{
|
|
319
|
-
distanceFromEnd: number;
|
|
320
|
-
}>();
|
|
321
236
|
@Input() onEndReachedThreshold?: number;
|
|
322
|
-
@Output() readonly startReached = new EventEmitter<{
|
|
323
|
-
distanceFromStart: number;
|
|
324
|
-
}>();
|
|
325
237
|
@Input() onStartReachedThreshold?: number;
|
|
326
|
-
@Output() readonly refresh = new EventEmitter<void>();
|
|
327
238
|
@Input() refreshing?: boolean | null;
|
|
328
239
|
@Input() progressViewOffset?: number;
|
|
329
240
|
@Input() initialNumToRender?: number;
|
|
@@ -351,14 +262,8 @@ export class SectionList<ItemT = unknown>
|
|
|
351
262
|
@Input() testID?: string;
|
|
352
263
|
@Input() nativeID?: string;
|
|
353
264
|
|
|
354
|
-
//
|
|
355
|
-
//
|
|
356
|
-
// Angular's styling engine), so this flattens `style` first, merging in this component's OWN
|
|
357
|
-
// anchor's class-derived style via anchorHostStyle (`elementRef` here is SectionList's own
|
|
358
|
-
// host, not `list`'s inner VirtualizedSectionList). A plain `flattenStyle([...])` would
|
|
359
|
-
// allocate a fresh object on every CD check, defeating VirtualizedList's `ngDoCheck` dedup gate
|
|
360
|
-
// and free-running change detection forever — the bug `stableAnchorStyle` exists to prevent
|
|
361
|
-
// (see its doc comment). `cachedResolvedStyle` is the getter's own persisted "previous" value.
|
|
265
|
+
// A flat object bound to `[style]`, merged with this host's own class-derived style. A fresh
|
|
266
|
+
// object per read would defeat the inner list's dedup gate, `stableAnchorStyle` keeps it steady
|
|
362
267
|
private cachedResolvedStyle: Record<string, unknown> | undefined;
|
|
363
268
|
get resolvedStyle(): IViewStyle {
|
|
364
269
|
this.cachedResolvedStyle = stableAnchorStyle(
|
|
@@ -368,58 +273,8 @@ export class SectionList<ItemT = unknown>
|
|
|
368
273
|
);
|
|
369
274
|
return this.cachedResolvedStyle;
|
|
370
275
|
}
|
|
371
|
-
@Input() accessible?: boolean;
|
|
372
|
-
@Input() accessibilityLabel?: string;
|
|
373
|
-
@Input() accessibilityHint?: string;
|
|
374
|
-
@Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
|
|
375
|
-
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
376
|
-
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
377
|
-
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
378
|
-
@Input() accessibilityLabelledBy?: string | string[];
|
|
379
|
-
@Input()
|
|
380
|
-
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
381
|
-
@Input()
|
|
382
|
-
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
383
|
-
@Input() screenReaderFocusable?: boolean;
|
|
384
|
-
@Input() accessibilityViewIsModal?: boolean;
|
|
385
|
-
@Input() accessibilityElementsHidden?: boolean;
|
|
386
|
-
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
387
|
-
@Input() accessibilityLanguage?: string;
|
|
388
|
-
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
389
|
-
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
390
|
-
@Input() accessibilityLargeContentTitle?: string;
|
|
391
|
-
@Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
|
|
392
|
-
@Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
|
|
393
|
-
@Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
|
|
394
|
-
@Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
|
|
395
|
-
|
|
396
|
-
// This wrapper binds the four gated accessibility events on the component it renders, which
|
|
397
|
-
// Angular forces to be unconditional and which would light that component's gates on every
|
|
398
|
-
// instance. It answers for them instead — see `gate-demand.ts`.
|
|
399
|
-
private readonly gateDemandAbove = injectGateDemandAbove();
|
|
400
|
-
|
|
401
|
-
wantsGate(name: IGatedAccessibilityEvent): boolean {
|
|
402
|
-
return gateWanted(this.gateDemandAbove, name, this[name]);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
@Input() role?: IAriaProps['role'];
|
|
406
|
-
@Input() ariaLabel?: string;
|
|
407
|
-
@Input() ariaLabelledBy?: string;
|
|
408
|
-
@Input() ariaLive?: IAriaProps['aria-live'];
|
|
409
|
-
@Input() ariaHidden?: boolean;
|
|
410
|
-
@Input() ariaBusy?: boolean;
|
|
411
|
-
@Input() ariaChecked?: boolean | 'mixed';
|
|
412
|
-
@Input() ariaDisabled?: boolean;
|
|
413
|
-
@Input() ariaExpanded?: boolean;
|
|
414
|
-
@Input() ariaSelected?: boolean;
|
|
415
|
-
@Input() ariaModal?: boolean;
|
|
416
|
-
@Input() ariaValueMax?: number;
|
|
417
|
-
@Input() ariaValueMin?: number;
|
|
418
|
-
@Input() ariaValueNow?: number;
|
|
419
|
-
@Input() ariaValueText?: string;
|
|
420
276
|
|
|
421
|
-
// The app's
|
|
422
|
-
// (single hop — always resolves) and re-stamped onto the inner VirtualizedSectionList above.
|
|
277
|
+
// The app's templates, captured from directly projected content and re-stamped above
|
|
423
278
|
@ContentChild(VSectionItemDirective)
|
|
424
279
|
sectionItemDir?: VSectionItemDirective<ItemT>;
|
|
425
280
|
@ContentChild(VSectionHeaderDirective)
|
|
@@ -434,19 +289,15 @@ export class SectionList<ItemT = unknown>
|
|
|
434
289
|
@ContentChild(VListSeparatorDirective)
|
|
435
290
|
itemSeparatorDir?: VListSeparatorDirective<ItemT>;
|
|
436
291
|
|
|
437
|
-
// The
|
|
438
|
-
// SectionList's handle delegates straight to it. Available from ngAfterViewInit; reads lazily.
|
|
292
|
+
// The inner list, whose instance is the scroll handle, reads lazily
|
|
439
293
|
@ViewChild(VirtualizedSectionList)
|
|
440
294
|
private list?: VirtualizedSectionList<ItemT>;
|
|
441
295
|
|
|
442
|
-
// This component's
|
|
443
|
-
// onto (see anchorHostStyle's doc comment) — NOT `list` above, which targets the real inner
|
|
444
|
-
// `<VirtualizedSectionList>` one level down (itself its own separate anchor host).
|
|
296
|
+
// This component's own host, the anchor `class="..."` resolves onto, not the inner list's
|
|
445
297
|
private readonly elementRef = inject(ElementRef);
|
|
446
298
|
|
|
447
|
-
// The
|
|
448
|
-
//
|
|
449
|
-
// narrow through, unlike a section header/footer entry).
|
|
299
|
+
// The leading and trailing items arrive `unknown` from the template's `let` bindings, already
|
|
300
|
+
// unwrapped to real items
|
|
450
301
|
itemSeparatorContext(
|
|
451
302
|
highlighted: unknown,
|
|
452
303
|
leadingItem: unknown,
|
|
@@ -461,8 +312,6 @@ export class SectionList<ItemT = unknown>
|
|
|
461
312
|
};
|
|
462
313
|
}
|
|
463
314
|
|
|
464
|
-
// ---- imperative handle (the shared IVirtualizedSectionListHandle surface) — delegates down ----
|
|
465
|
-
|
|
466
315
|
scrollToLocation(params: {
|
|
467
316
|
sectionIndex: number;
|
|
468
317
|
itemIndex: number;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// Everything a windowed list keeps per cell between passes: the context objects (reused by
|
|
2
|
+
// identity), the measure closures, and the separator overrides a row drives through `separators`
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
isSeparatorGapInRange,
|
|
6
|
+
readLayoutLength,
|
|
7
|
+
readLayoutOffset,
|
|
8
|
+
type ISeparatorProps,
|
|
9
|
+
type ISeparators,
|
|
10
|
+
} from '@symbiote-native/components';
|
|
11
|
+
import { dlog, type ISymbioteEvent } from '@symbiote-native/engine';
|
|
12
|
+
import type { IVListItemContext, IVListSeparatorContext } from './directives';
|
|
13
|
+
|
|
14
|
+
// One in-window cell, assembled per pass and stamped by the template's `@for`
|
|
15
|
+
export interface IWindowCell<ItemT> {
|
|
16
|
+
key: string;
|
|
17
|
+
index: number;
|
|
18
|
+
context: IVListItemContext<ItemT>;
|
|
19
|
+
measure: (event: ISymbioteEvent) => void;
|
|
20
|
+
separatorContext?: IVListSeparatorContext<ItemT>;
|
|
21
|
+
// Picks the cell's TAG in the template: `sticky-header` pins, `view` does not. Stable per cell
|
|
22
|
+
// key, so the `@if` never swaps an element type under a live cell as the window slides
|
|
23
|
+
isSticky: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type ICellHost<ItemT> = {
|
|
27
|
+
itemAt: (index: number) => ItemT;
|
|
28
|
+
itemCount: () => number;
|
|
29
|
+
isHorizontal: () => boolean;
|
|
30
|
+
markForCheck: () => void;
|
|
31
|
+
measured: (index: number, length: number, offset: number | undefined) => void;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// The gap a cell's `updateProps` side addresses, relative to the cell's own index
|
|
35
|
+
const SEPARATOR_GAP_OFFSET = { leading: -1, trailing: 0 } as const;
|
|
36
|
+
|
|
37
|
+
export class CellRegistry<ItemT> {
|
|
38
|
+
// A cell's context is the only thing its stamped view reads, and the outlet refreshes that view
|
|
39
|
+
// whenever the object's identity changes. Handing back the same object for a cell whose item and
|
|
40
|
+
// index did not move keeps a window slide from refreshing every cell in it
|
|
41
|
+
private contexts = new Map<string, IVListItemContext<ItemT>>();
|
|
42
|
+
private nextContexts = new Map<string, IVListItemContext<ItemT>>();
|
|
43
|
+
// What a cell's content can depend on besides its own item: an `extraData` flip has to drop
|
|
44
|
+
// every reused context or nothing would repaint
|
|
45
|
+
private epoch: unknown[] | undefined = undefined;
|
|
46
|
+
private readonly separatorOverrides = new Map<
|
|
47
|
+
number,
|
|
48
|
+
Partial<ISeparatorProps<unknown>>
|
|
49
|
+
>();
|
|
50
|
+
private readonly measures = new Map<
|
|
51
|
+
number,
|
|
52
|
+
(event: ISymbioteEvent) => void
|
|
53
|
+
>();
|
|
54
|
+
|
|
55
|
+
constructor(private readonly host: ICellHost<ItemT>) {}
|
|
56
|
+
|
|
57
|
+
beginPass(epoch: unknown[]): void {
|
|
58
|
+
const previous = this.epoch;
|
|
59
|
+
this.epoch = epoch;
|
|
60
|
+
if (
|
|
61
|
+
previous === undefined ||
|
|
62
|
+
previous.length !== epoch.length ||
|
|
63
|
+
!previous.every((value, index) => value === epoch[index])
|
|
64
|
+
) {
|
|
65
|
+
this.contexts.clear();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
clear(): void {
|
|
70
|
+
this.contexts.clear();
|
|
71
|
+
this.nextContexts.clear();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A cell that left the window is absent from the pass that just ran, so the old map is the
|
|
75
|
+
// garbage and the new one is exactly the live set
|
|
76
|
+
endPass(): void {
|
|
77
|
+
this.contexts = this.nextContexts;
|
|
78
|
+
this.nextContexts = new Map<string, IVListItemContext<ItemT>>();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
windowCell(
|
|
82
|
+
index: number,
|
|
83
|
+
key: string,
|
|
84
|
+
includeSeparator: boolean,
|
|
85
|
+
isSticky: boolean,
|
|
86
|
+
): IWindowCell<ItemT> {
|
|
87
|
+
const item = this.host.itemAt(index);
|
|
88
|
+
return {
|
|
89
|
+
key,
|
|
90
|
+
index,
|
|
91
|
+
context: this.contextFor(key, index, item),
|
|
92
|
+
measure: this.measureFor(index),
|
|
93
|
+
separatorContext: includeSeparator
|
|
94
|
+
? this.separatorContextFor(index, item)
|
|
95
|
+
: undefined,
|
|
96
|
+
isSticky,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private contextFor(
|
|
101
|
+
key: string,
|
|
102
|
+
index: number,
|
|
103
|
+
item: ItemT,
|
|
104
|
+
): IVListItemContext<ItemT> {
|
|
105
|
+
const cached = this.contexts.get(key);
|
|
106
|
+
if (
|
|
107
|
+
cached !== undefined &&
|
|
108
|
+
cached.$implicit === item &&
|
|
109
|
+
cached.index === index
|
|
110
|
+
) {
|
|
111
|
+
this.nextContexts.set(key, cached);
|
|
112
|
+
return cached;
|
|
113
|
+
}
|
|
114
|
+
const context: IVListItemContext<ItemT> = {
|
|
115
|
+
$implicit: item,
|
|
116
|
+
index,
|
|
117
|
+
separators: this.makeSeparators(index),
|
|
118
|
+
};
|
|
119
|
+
this.nextContexts.set(key, context);
|
|
120
|
+
return context;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private separatorContextFor(
|
|
124
|
+
index: number,
|
|
125
|
+
item: ItemT,
|
|
126
|
+
): IVListSeparatorContext<ItemT> {
|
|
127
|
+
const overrides = this.separatorOverrides.get(index);
|
|
128
|
+
const highlighted = overrides?.highlighted ?? false;
|
|
129
|
+
const context: IVListSeparatorContext<ItemT> = {
|
|
130
|
+
$implicit: highlighted,
|
|
131
|
+
highlighted,
|
|
132
|
+
leadingItem: item,
|
|
133
|
+
trailingItem: this.host.itemAt(index + 1),
|
|
134
|
+
};
|
|
135
|
+
// Custom `updateProps` keys ride the index signature, typed fields stay authoritative
|
|
136
|
+
if (overrides !== undefined) {
|
|
137
|
+
for (const key of Object.keys(overrides)) {
|
|
138
|
+
if (
|
|
139
|
+
key === 'highlighted' ||
|
|
140
|
+
key === 'leadingItem' ||
|
|
141
|
+
key === 'trailingItem'
|
|
142
|
+
)
|
|
143
|
+
continue;
|
|
144
|
+
context[key] = overrides[key];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return context;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private measureFor(index: number): (event: ISymbioteEvent) => void {
|
|
151
|
+
const existing = this.measures.get(index);
|
|
152
|
+
if (existing !== undefined) return existing;
|
|
153
|
+
const measure = (event: ISymbioteEvent): void => {
|
|
154
|
+
const horizontal = this.host.isHorizontal();
|
|
155
|
+
const length = readLayoutLength(event, horizontal);
|
|
156
|
+
if (length === undefined) return;
|
|
157
|
+
const offset = readLayoutOffset(event, horizontal);
|
|
158
|
+
dlog(
|
|
159
|
+
`Angular VirtualizedList cell ${index} measured length=${length} offset=${offset ?? 'none'}`,
|
|
160
|
+
);
|
|
161
|
+
this.host.measured(index, length, offset);
|
|
162
|
+
};
|
|
163
|
+
this.measures.set(index, measure);
|
|
164
|
+
return measure;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private mergeSeparator(
|
|
168
|
+
gapIndex: number,
|
|
169
|
+
patch: Partial<ISeparatorProps<unknown>>,
|
|
170
|
+
): void {
|
|
171
|
+
if (!isSeparatorGapInRange(gapIndex, this.host.itemCount())) return;
|
|
172
|
+
this.separatorOverrides.set(gapIndex, {
|
|
173
|
+
...this.separatorOverrides.get(gapIndex),
|
|
174
|
+
...patch,
|
|
175
|
+
});
|
|
176
|
+
this.host.markForCheck();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private makeSeparators(index: number): ISeparators {
|
|
180
|
+
return {
|
|
181
|
+
highlight: (): void => {
|
|
182
|
+
dlog(`Angular VirtualizedList separator highlight cell=${index}`);
|
|
183
|
+
this.mergeSeparator(index - 1, { highlighted: true });
|
|
184
|
+
this.mergeSeparator(index, { highlighted: true });
|
|
185
|
+
},
|
|
186
|
+
unhighlight: (): void => {
|
|
187
|
+
dlog(`Angular VirtualizedList separator unhighlight cell=${index}`);
|
|
188
|
+
this.mergeSeparator(index - 1, { highlighted: false });
|
|
189
|
+
this.mergeSeparator(index, { highlighted: false });
|
|
190
|
+
},
|
|
191
|
+
updateProps: (
|
|
192
|
+
select: keyof typeof SEPARATOR_GAP_OFFSET,
|
|
193
|
+
newProps: Record<string, unknown>,
|
|
194
|
+
): void => {
|
|
195
|
+
this.mergeSeparator(index + SEPARATOR_GAP_OFFSET[select], newProps);
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|