@symbiote-native/angular 3.1.2 → 3.2.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.
Files changed (121) hide show
  1. package/build/angular/accessibility-events.d.ts +12 -0
  2. package/build/angular/accessibility-events.js +28 -0
  3. package/build/angular/accessibility-events.js.map +1 -0
  4. package/build/angular/accessibility-inputs.d.ts +40 -0
  5. package/build/angular/accessibility-inputs.js +130 -0
  6. package/build/angular/accessibility-inputs.js.map +1 -0
  7. package/build/angular/bootstrap.d.ts +3 -1
  8. package/build/angular/bootstrap.js +4 -1
  9. package/build/angular/bootstrap.js.map +1 -1
  10. package/build/angular/components/flat-list/flat-list-template.d.ts +1 -0
  11. package/build/angular/components/flat-list/flat-list-template.js +158 -0
  12. package/build/angular/components/flat-list/flat-list-template.js.map +1 -0
  13. package/build/angular/components/flat-list/index.d.ts +6 -61
  14. package/build/angular/components/flat-list/index.js +26 -463
  15. package/build/angular/components/flat-list/index.js.map +1 -1
  16. package/build/angular/components/keyboard-avoiding-view/index.d.ts +4 -40
  17. package/build/angular/components/keyboard-avoiding-view/index.js +7 -131
  18. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  19. package/build/angular/components/modal/index.d.ts +5 -41
  20. package/build/angular/components/modal/index.js +8 -133
  21. package/build/angular/components/modal/index.js.map +1 -1
  22. package/build/angular/components/section-list/index.d.ts +4 -51
  23. package/build/angular/components/section-list/index.js +18 -335
  24. package/build/angular/components/section-list/index.js.map +1 -1
  25. package/build/angular/components/virtualized-list/cell-registry.d.ts +35 -0
  26. package/build/angular/components/virtualized-list/cell-registry.js +133 -0
  27. package/build/angular/components/virtualized-list/cell-registry.js.map +1 -0
  28. package/build/angular/components/virtualized-list/index.d.ts +18 -253
  29. package/build/angular/components/virtualized-list/index.js +112 -1178
  30. package/build/angular/components/virtualized-list/index.js.map +1 -1
  31. package/build/angular/components/virtualized-list/list-a11y-forward.d.ts +1 -0
  32. package/build/angular/components/virtualized-list/list-a11y-forward.js +42 -0
  33. package/build/angular/components/virtualized-list/list-a11y-forward.js.map +1 -0
  34. package/build/angular/components/virtualized-list/list-bags.d.ts +32 -0
  35. package/build/angular/components/virtualized-list/list-bags.js +120 -0
  36. package/build/angular/components/virtualized-list/list-bags.js.map +1 -0
  37. package/build/angular/components/virtualized-list/list-effects.d.ts +31 -0
  38. package/build/angular/components/virtualized-list/list-effects.js +83 -0
  39. package/build/angular/components/virtualized-list/list-effects.js.map +1 -0
  40. package/build/angular/components/virtualized-list/list-events.d.ts +17 -0
  41. package/build/angular/components/virtualized-list/list-events.js +34 -0
  42. package/build/angular/components/virtualized-list/list-events.js.map +1 -0
  43. package/build/angular/components/virtualized-list/list-handle.d.ts +35 -0
  44. package/build/angular/components/virtualized-list/list-handle.js +61 -0
  45. package/build/angular/components/virtualized-list/list-handle.js.map +1 -0
  46. package/build/angular/components/virtualized-list/list-inputs.d.ts +78 -0
  47. package/build/angular/components/virtualized-list/list-inputs.js +150 -0
  48. package/build/angular/components/virtualized-list/list-inputs.js.map +1 -0
  49. package/build/angular/components/virtualized-list/list-props.d.ts +58 -0
  50. package/build/angular/components/virtualized-list/list-props.js +3 -0
  51. package/build/angular/components/virtualized-list/list-props.js.map +1 -0
  52. package/build/angular/components/virtualized-list/list-styles.d.ts +23 -0
  53. package/build/angular/components/virtualized-list/list-styles.js +26 -0
  54. package/build/angular/components/virtualized-list/list-styles.js.map +1 -0
  55. package/build/angular/components/virtualized-list/list-template.d.ts +1 -0
  56. package/build/angular/components/virtualized-list/list-template.js +176 -0
  57. package/build/angular/components/virtualized-list/list-template.js.map +1 -0
  58. package/build/angular/components/virtualized-section-list/index.d.ts +13 -70
  59. package/build/angular/components/virtualized-section-list/index.js +22 -455
  60. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  61. package/build/angular/components/virtualized-section-list/section-list-template.d.ts +1 -0
  62. package/build/angular/components/virtualized-section-list/section-list-template.js +107 -0
  63. package/build/angular/components/virtualized-section-list/section-list-template.js.map +1 -0
  64. package/build/angular/finalization-registry.d.ts +4 -0
  65. package/build/angular/finalization-registry.js +17 -0
  66. package/build/angular/finalization-registry.js.map +1 -0
  67. package/build/angular/index.d.ts +5 -1
  68. package/build/angular/index.js +5 -1
  69. package/build/angular/index.js.map +1 -1
  70. package/build/angular/native-view-base.d.ts +19 -0
  71. package/build/angular/native-view-base.js +48 -0
  72. package/build/angular/native-view-base.js.map +1 -0
  73. package/build/angular/render/index.d.ts +2 -1
  74. package/build/angular/render/index.js +46 -73
  75. package/build/angular/render/index.js.map +1 -1
  76. package/build/angular/services/connect-watched-signal.d.ts +2 -0
  77. package/build/angular/services/connect-watched-signal.js +9 -0
  78. package/build/angular/services/connect-watched-signal.js.map +1 -0
  79. package/build/angular/services/create-event-value-hook.d.ts +3 -0
  80. package/build/angular/services/create-event-value-hook.js +17 -0
  81. package/build/angular/services/create-event-value-hook.js.map +1 -0
  82. package/build/angular/services/create-resource-hook.d.ts +7 -0
  83. package/build/angular/services/create-resource-hook.js +20 -0
  84. package/build/angular/services/create-resource-hook.js.map +1 -0
  85. package/build/angular/services/index.d.ts +4 -0
  86. package/build/angular/services/index.js +4 -0
  87. package/build/angular/services/index.js.map +1 -1
  88. package/build/angular/services/permissions-service-base.d.ts +14 -0
  89. package/build/angular/services/permissions-service-base.js +38 -0
  90. package/build/angular/services/permissions-service-base.js.map +1 -0
  91. package/package.json +6 -6
  92. package/src/accessibility-events.ts +13 -0
  93. package/src/accessibility-inputs.ts +89 -0
  94. package/src/bootstrap.ts +6 -2
  95. package/src/components/flat-list/flat-list-template.ts +159 -0
  96. package/src/components/flat-list/index.ts +30 -307
  97. package/src/components/keyboard-avoiding-view/index.ts +4 -78
  98. package/src/components/modal/index.ts +7 -80
  99. package/src/components/section-list/index.ts +21 -172
  100. package/src/components/virtualized-list/cell-registry.ts +199 -0
  101. package/src/components/virtualized-list/index.ts +145 -1181
  102. package/src/components/virtualized-list/list-a11y-forward.ts +42 -0
  103. package/src/components/virtualized-list/list-bags.ts +142 -0
  104. package/src/components/virtualized-list/list-effects.ts +116 -0
  105. package/src/components/virtualized-list/list-events.ts +31 -0
  106. package/src/components/virtualized-list/list-handle.ts +92 -0
  107. package/src/components/virtualized-list/list-inputs.ts +149 -0
  108. package/src/components/virtualized-list/list-props.ts +81 -0
  109. package/src/components/virtualized-list/list-styles.ts +62 -0
  110. package/src/components/virtualized-list/list-template.ts +175 -0
  111. package/src/components/virtualized-section-list/index.ts +40 -351
  112. package/src/components/virtualized-section-list/section-list-template.ts +108 -0
  113. package/src/finalization-registry.ts +18 -0
  114. package/src/index.ts +12 -1
  115. package/src/native-view-base.ts +51 -0
  116. package/src/render/index.ts +76 -77
  117. package/src/services/connect-watched-signal.ts +15 -0
  118. package/src/services/create-event-value-hook.ts +24 -0
  119. package/src/services/create-resource-hook.ts +32 -0
  120. package/src/services/index.ts +4 -0
  121. package/src/services/permissions-service-base.ts +46 -0
@@ -1,2 +1,6 @@
1
1
  export { ColorSchemeService } from './color-scheme.service';
2
2
  export { WindowDimensionsService } from './window-dimensions.service';
3
+ export { createResourceHook } from './create-resource-hook';
4
+ export { createEventValueHook } from './create-event-value-hook';
5
+ export { connectWatchedSignal } from './connect-watched-signal';
6
+ export { PermissionsServiceBase } from './permissions-service-base';
@@ -1,3 +1,7 @@
1
1
  export { ColorSchemeService } from './color-scheme.service';
2
2
  export { WindowDimensionsService } from './window-dimensions.service';
3
+ export { createResourceHook } from './create-resource-hook';
4
+ export { createEventValueHook } from './create-event-value-hook';
5
+ export { connectWatchedSignal } from './connect-watched-signal';
6
+ export { PermissionsServiceBase } from './permissions-service-base';
3
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type Signal } from '@angular/core';
2
+ export declare abstract class PermissionsServiceBase<TPermission, TOptions = void> {
3
+ private readonly getMethod;
4
+ private readonly requestMethod;
5
+ private readonly status;
6
+ private readonly fetchError;
7
+ private isAutoFetchStarted;
8
+ readonly error: Signal<Error | null>;
9
+ protected constructor(getMethod: (options?: TOptions) => Promise<TPermission>, requestMethod: (options?: TOptions) => Promise<TPermission>);
10
+ connect(): Signal<TPermission | null>;
11
+ get(options?: TOptions): Promise<TPermission>;
12
+ request(options?: TOptions): Promise<TPermission>;
13
+ private store;
14
+ }
@@ -0,0 +1,38 @@
1
+ import { signal } from '@angular/core';
2
+ // Общая часть сервисов разрешений всех Expo-пакетов, наследник передаёт пару методов
3
+ // Сбой автозапроса попадает в `error`, а не в unhandled rejection: null-статус с непустым `error`
4
+ // значит "запрос упал", а не "ещё не было"
5
+ export class PermissionsServiceBase {
6
+ constructor(getMethod, requestMethod) {
7
+ this.getMethod = getMethod;
8
+ this.requestMethod = requestMethod;
9
+ this.status = signal(null, /* @ts-ignore */
10
+ ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
11
+ this.fetchError = signal(null, /* @ts-ignore */
12
+ ...(ngDevMode ? [{ debugName: "fetchError" }] : /* istanbul ignore next */ []));
13
+ this.isAutoFetchStarted = false;
14
+ this.error = this.fetchError.asReadonly();
15
+ }
16
+ // Защёлка, а не проверка `status() === null`: упавший запрос оставляет null навсегда
17
+ connect() {
18
+ if (!this.isAutoFetchStarted) {
19
+ this.isAutoFetchStarted = true;
20
+ this.get().catch((cause) => {
21
+ this.fetchError.set(cause instanceof Error ? cause : new Error(String(cause)));
22
+ });
23
+ }
24
+ return this.status.asReadonly();
25
+ }
26
+ async get(options) {
27
+ return this.store(await this.getMethod(options));
28
+ }
29
+ async request(options) {
30
+ return this.store(await this.requestMethod(options));
31
+ }
32
+ store(response) {
33
+ this.status.set(response);
34
+ this.fetchError.set(null);
35
+ return response;
36
+ }
37
+ }
38
+ //# sourceMappingURL=permissions-service-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-service-base.js","sourceRoot":"","sources":["../../../src/services/permissions-service-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AAEpD,qFAAqF;AACrF,kGAAkG;AAClG,2CAA2C;AAC3C,MAAM,OAAgB,sBAAsB;IAO1C,YACmB,SAAuD,EACvD,aAEQ;QAHR,cAAS,GAAT,SAAS,CAA8C;QACvD,kBAAa,GAAb,aAAa,CAEL;QAVV,WAAM,GAAG,MAAM,CAAqB,IAAI;mFAAC,CAAC;QAC1C,eAAU,GAAG,MAAM,CAAe,IAAI;uFAAC,CAAC;QACjD,uBAAkB,GAAG,KAAK,CAAC;QAE1B,UAAK,GAAyB,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;IAOjE,CAAC;IAEJ,qFAAqF;IACrF,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBAClC,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAkB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAkB;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,QAAqB;QACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/angular",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "SymbioteNative's Angular adapter — a Renderer2/RendererFactory2 with DOM-less bootstrap driving real native iOS/Android views through the same engine as the other adapters.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -66,14 +66,14 @@
66
66
  "dependencies": {
67
67
  "@angular/compiler-cli": "~22.0.8",
68
68
  "@react-native/typescript-config": "0.86.0",
69
- "@symbiote-native/components": "3.1.2",
70
- "@symbiote-native/css-parser": "0.5.2"
69
+ "@symbiote-native/components": "3.1.4",
70
+ "@symbiote-native/css-parser": "0.5.3"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "@angular/core": ">=20",
74
74
  "@angular/forms": ">=20",
75
75
  "react-native": ">=0.86",
76
- "@symbiote-native/engine": "^1.3.1"
76
+ "@symbiote-native/engine": "^1.5.0"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@angular/compiler": "~22.0.8",
@@ -83,8 +83,8 @@
83
83
  "@types/babel__core": "^7.20.5",
84
84
  "@types/node": "^26.0.0",
85
85
  "typescript": "~6.0.0",
86
- "@symbiote-native/engine": "1.3.1",
87
- "@symbiote-native/test-utils": "0.4.4"
86
+ "@symbiote-native/engine": "1.5.0",
87
+ "@symbiote-native/test-utils": "0.4.6"
88
88
  },
89
89
  "scripts": {
90
90
  "clean": "rm -rf build",
@@ -0,0 +1,13 @@
1
+ import { Directive, EventEmitter, Output } from '@angular/core';
2
+ import type { ISymbioteEvent } from '@symbiote-native/engine';
3
+ import { AccessibilityInputsBase } from './accessibility-inputs';
4
+
5
+ // The four accessibility callbacks as real Angular events, for components that expose them as
6
+ // outputs rather than inputs
7
+ @Directive()
8
+ export abstract class AccessibilityEventsBase extends AccessibilityInputsBase {
9
+ @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
10
+ @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
11
+ @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
12
+ @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
13
+ }
@@ -0,0 +1,89 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import type {
3
+ IAccessibilityProps,
4
+ IAccessibilityStateValue,
5
+ IAriaProps,
6
+ } from '@symbiote-native/components';
7
+
8
+ // Inputs are declared statically, so view-shaped components extend this instead of repeating them
9
+ // The `on*` accessibility callbacks stay per component: some take inputs, others outputs
10
+ @Directive()
11
+ export abstract class AccessibilityInputsBase {
12
+ @Input() accessible?: boolean;
13
+ @Input() accessibilityLabel?: string;
14
+ @Input() accessibilityHint?: string;
15
+ @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
16
+ @Input() accessibilityState?: IAccessibilityStateValue;
17
+ @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
18
+ @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
19
+ @Input() accessibilityLabelledBy?: string | string[];
20
+ @Input()
21
+ importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
22
+ @Input()
23
+ accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
24
+ @Input() screenReaderFocusable?: boolean;
25
+ @Input() accessibilityViewIsModal?: boolean;
26
+ @Input() accessibilityElementsHidden?: boolean;
27
+ @Input() accessibilityIgnoresInvertColors?: boolean;
28
+ @Input() accessibilityLanguage?: string;
29
+ @Input() accessibilityRespondsToUserInteraction?: boolean;
30
+ @Input() accessibilityShowsLargeContentViewer?: boolean;
31
+ @Input() accessibilityLargeContentTitle?: string;
32
+
33
+ @Input() role?: IAriaProps['role'];
34
+ @Input('aria-label') ariaLabel?: string;
35
+ @Input('aria-labelledby') ariaLabelledBy?: string;
36
+ @Input('aria-live') ariaLive?: IAriaProps['aria-live'];
37
+ @Input('aria-hidden') ariaHidden?: boolean;
38
+ @Input('aria-busy') ariaBusy?: boolean;
39
+ @Input('aria-checked') ariaChecked?: boolean | 'mixed';
40
+ @Input('aria-disabled') ariaDisabled?: boolean;
41
+ @Input('aria-expanded') ariaExpanded?: boolean;
42
+ @Input('aria-selected') ariaSelected?: boolean;
43
+ @Input('aria-modal') ariaModal?: boolean;
44
+ @Input('aria-valuemax') ariaValueMax?: number;
45
+ @Input('aria-valuemin') ariaValueMin?: number;
46
+ @Input('aria-valuenow') ariaValueNow?: number;
47
+ @Input('aria-valuetext') ariaValueText?: string;
48
+
49
+ // The bag the shared fold takes, the aria inputs under their web names
50
+ protected accessibilityInputProps(): IAccessibilityProps & IAriaProps {
51
+ return {
52
+ accessible: this.accessible,
53
+ accessibilityLabel: this.accessibilityLabel,
54
+ accessibilityHint: this.accessibilityHint,
55
+ accessibilityRole: this.accessibilityRole,
56
+ accessibilityState: this.accessibilityState,
57
+ accessibilityValue: this.accessibilityValue,
58
+ accessibilityActions: this.accessibilityActions,
59
+ accessibilityLabelledBy: this.accessibilityLabelledBy,
60
+ importantForAccessibility: this.importantForAccessibility,
61
+ accessibilityLiveRegion: this.accessibilityLiveRegion,
62
+ screenReaderFocusable: this.screenReaderFocusable,
63
+ accessibilityViewIsModal: this.accessibilityViewIsModal,
64
+ accessibilityElementsHidden: this.accessibilityElementsHidden,
65
+ accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
66
+ accessibilityLanguage: this.accessibilityLanguage,
67
+ accessibilityRespondsToUserInteraction:
68
+ this.accessibilityRespondsToUserInteraction,
69
+ accessibilityShowsLargeContentViewer:
70
+ this.accessibilityShowsLargeContentViewer,
71
+ accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
72
+ role: this.role,
73
+ 'aria-label': this.ariaLabel,
74
+ 'aria-labelledby': this.ariaLabelledBy,
75
+ 'aria-live': this.ariaLive,
76
+ 'aria-hidden': this.ariaHidden,
77
+ 'aria-busy': this.ariaBusy,
78
+ 'aria-checked': this.ariaChecked,
79
+ 'aria-disabled': this.ariaDisabled,
80
+ 'aria-expanded': this.ariaExpanded,
81
+ 'aria-selected': this.ariaSelected,
82
+ 'aria-modal': this.ariaModal,
83
+ 'aria-valuemax': this.ariaValueMax,
84
+ 'aria-valuemin': this.ariaValueMin,
85
+ 'aria-valuenow': this.ariaValueNow,
86
+ 'aria-valuetext': this.ariaValueText,
87
+ };
88
+ }
89
+ }
package/src/bootstrap.ts CHANGED
@@ -3,18 +3,21 @@
3
3
  // stay there. No @Component/@Directive decorators here, so unlike the package's main "." entry
4
4
  // this needs no ngc/AOT build step and can stay a plain source reference.
5
5
 
6
+ import './finalization-registry';
6
7
  import { AppRegistry as RNAppRegistry } from 'react-native';
7
- import type { Type } from '@angular/core';
8
+ import type { EnvironmentProviders, Provider, Type } from '@angular/core';
8
9
  import {
9
10
  bootstrapHost,
10
11
  type IBootstrapHostOptions,
11
12
  } from '@symbiote-native/components/bootstrap';
12
13
  import { AppRegistry, setHostRegistrar } from './modules/app-registry';
14
+ import { setRootProviders } from './render';
13
15
 
14
16
  export type { IBootstrapHostOptions } from '@symbiote-native/components/bootstrap';
15
17
 
16
18
  export type IBootstrapApplicationOptions = IBootstrapHostOptions & {
17
19
  appName: string;
20
+ providers?: (Provider | EnvironmentProviders)[];
18
21
  };
19
22
 
20
23
  // Mirrors real Angular's bootstrapApplication(RootComponent, config) idiom.
@@ -22,7 +25,8 @@ export function bootstrapApplication(
22
25
  AppComponent: Type<unknown>,
23
26
  options: IBootstrapApplicationOptions,
24
27
  ): void {
25
- const { appName, ...bootstrapOptions } = options;
28
+ const { appName, providers = [], ...bootstrapOptions } = options;
29
+ setRootProviders(providers);
26
30
  bootstrapHost(bootstrapOptions);
27
31
  setHostRegistrar(RNAppRegistry);
28
32
  AppRegistry.registerComponent(appName, () => AppComponent);
@@ -0,0 +1,159 @@
1
+ // A content query does not resolve across a second `<ng-content>` hop, so both branches re-stamp
2
+ // the app's templates instead of projecting them (see `flat-list.test.ts`)
3
+
4
+ import { LIST_ACCESSIBILITY_FORWARD } from '../virtualized-list/list-a11y-forward';
5
+
6
+ export const FLAT_LIST_TEMPLATE = `
7
+ @if (isMultiColumn) {
8
+ <VirtualizedList
9
+ [data]="rows"
10
+ [getItem]="getRow"
11
+ [getItemCount]="getRowCount"
12
+ [keyExtractor]="rowKey"
13
+ [getItemLayout]="getItemLayout"
14
+ [horizontal]="horizontal"
15
+ [inverted]="inverted"
16
+ [extraData]="extraData"
17
+ (endReached)="endReached.emit($event)"
18
+ [onEndReachedThreshold]="onEndReachedThreshold"
19
+ (startReached)="startReached.emit($event)"
20
+ [onStartReachedThreshold]="onStartReachedThreshold"
21
+ (refresh)="refresh.emit()"
22
+ [refreshRequested]="refresh.observed"
23
+ [refreshing]="refreshing"
24
+ [progressViewOffset]="progressViewOffset"
25
+ (viewableItemsChanged)="rowViewableItemsChanged($event)"
26
+ [viewabilityConfig]="viewabilityConfig"
27
+ [viewabilityConfigCallbackPairs]="rowViewabilityPairs"
28
+ (scrollToIndexFailed)="scrollToIndexFailed.emit($event)"
29
+ [initialNumToRender]="initialNumToRender"
30
+ [initialScrollIndex]="initialScrollIndex"
31
+ [maxToRenderPerBatch]="maxToRenderPerBatch"
32
+ [updateCellsBatchingPeriod]="updateCellsBatchingPeriod"
33
+ [windowSize]="windowSize"
34
+ [stickyHeaderIndices]="stickyHeaderIndices"
35
+ [maintainVisibleContentPosition]="maintainVisibleContentPosition"
36
+ [onScroll]="onScroll"
37
+ [onScrollBeginDrag]="onScrollBeginDrag"
38
+ [onScrollEndDrag]="onScrollEndDrag"
39
+ [onMomentumScrollBegin]="onMomentumScrollBegin"
40
+ [onMomentumScrollEnd]="onMomentumScrollEnd"
41
+ [scrollEventThrottle]="scrollEventThrottle"
42
+ [keyboardShouldPersistTaps]="keyboardShouldPersistTaps"
43
+ [keyboardDismissMode]="keyboardDismissMode"
44
+ [removeClippedSubviews]="resolvedRemoveClippedSubviews"
45
+ [nestedScrollEnabled]="nestedScrollEnabled"
46
+ [testID]="testID"
47
+ [nativeID]="nativeID"
48
+ [style]="resolvedStyle"
49
+ [contentContainerStyle]="contentContainerStyle"
50
+ ${LIST_ACCESSIBILITY_FORWARD}
51
+ >
52
+ <ng-template vListItem let-row let-separators="separators">
53
+ <view [style]="rowStyle">
54
+ @for (cell of rowCells(row, separators); track cell.key) {
55
+ <view [style]="columnCellStyle">
56
+ <ng-container
57
+ [vListOutlet]="itemDir?.templateRef"
58
+ [vListOutletContext]="cell.context"
59
+ ></ng-container>
60
+ </view>
61
+ }
62
+ </view>
63
+ </ng-template>
64
+ @if (headerDir !== undefined) {
65
+ <ng-template vListHeader>
66
+ <ng-container [vListOutlet]="headerDir.templateRef"></ng-container>
67
+ </ng-template>
68
+ }
69
+ @if (footerDir !== undefined) {
70
+ <ng-template vListFooter>
71
+ <ng-container [vListOutlet]="footerDir.templateRef"></ng-container>
72
+ </ng-template>
73
+ }
74
+ @if (emptyDir !== undefined) {
75
+ <ng-template vListEmpty>
76
+ <ng-container [vListOutlet]="emptyDir.templateRef"></ng-container>
77
+ </ng-template>
78
+ }
79
+ @if (separatorDir !== undefined) {
80
+ <ng-template
81
+ vListSeparator
82
+ let-highlighted="highlighted"
83
+ let-leadingItem="leadingItem"
84
+ let-trailingItem="trailingItem"
85
+ >
86
+ <ng-container
87
+ [vListOutlet]="separatorDir.templateRef"
88
+ [vListOutletContext]="
89
+ rowSeparatorContext(highlighted, leadingItem, trailingItem)
90
+ "
91
+ ></ng-container>
92
+ </ng-template>
93
+ }
94
+ </VirtualizedList>
95
+ } @else {
96
+ <VirtualizedList
97
+ [data]="data"
98
+ [getItem]="getFlatItem"
99
+ [getItemCount]="getFlatCount"
100
+ [keyExtractor]="keyExtractor"
101
+ [getItemLayout]="getItemLayout"
102
+ [horizontal]="horizontal"
103
+ [inverted]="inverted"
104
+ [extraData]="extraData"
105
+ (endReached)="endReached.emit($event)"
106
+ [onEndReachedThreshold]="onEndReachedThreshold"
107
+ (startReached)="startReached.emit($event)"
108
+ [onStartReachedThreshold]="onStartReachedThreshold"
109
+ (refresh)="refresh.emit()"
110
+ [refreshRequested]="refresh.observed"
111
+ [refreshing]="refreshing"
112
+ [progressViewOffset]="progressViewOffset"
113
+ (viewableItemsChanged)="viewableItemsChanged.emit($event)"
114
+ [viewabilityConfig]="viewabilityConfig"
115
+ [viewabilityConfigCallbackPairs]="viewabilityConfigCallbackPairs"
116
+ (scrollToIndexFailed)="scrollToIndexFailed.emit($event)"
117
+ [initialNumToRender]="initialNumToRender"
118
+ [initialScrollIndex]="initialScrollIndex"
119
+ [maxToRenderPerBatch]="maxToRenderPerBatch"
120
+ [updateCellsBatchingPeriod]="updateCellsBatchingPeriod"
121
+ [windowSize]="windowSize"
122
+ [stickyHeaderIndices]="stickyHeaderIndices"
123
+ [maintainVisibleContentPosition]="maintainVisibleContentPosition"
124
+ [onScroll]="onScroll"
125
+ [onScrollBeginDrag]="onScrollBeginDrag"
126
+ [onScrollEndDrag]="onScrollEndDrag"
127
+ [onMomentumScrollBegin]="onMomentumScrollBegin"
128
+ [onMomentumScrollEnd]="onMomentumScrollEnd"
129
+ [scrollEventThrottle]="scrollEventThrottle"
130
+ [keyboardShouldPersistTaps]="keyboardShouldPersistTaps"
131
+ [keyboardDismissMode]="keyboardDismissMode"
132
+ [removeClippedSubviews]="resolvedRemoveClippedSubviews"
133
+ [nestedScrollEnabled]="nestedScrollEnabled"
134
+ [testID]="testID"
135
+ [nativeID]="nativeID"
136
+ [style]="resolvedStyle"
137
+ [contentContainerStyle]="contentContainerStyle"
138
+ [itemTemplate]="itemDir?.templateRef"
139
+ [itemSeparatorTemplate]="separatorDir?.templateRef"
140
+ ${LIST_ACCESSIBILITY_FORWARD}
141
+ >
142
+ @if (headerDir !== undefined) {
143
+ <ng-template vListHeader>
144
+ <ng-container [vListOutlet]="headerDir.templateRef"></ng-container>
145
+ </ng-template>
146
+ }
147
+ @if (footerDir !== undefined) {
148
+ <ng-template vListFooter>
149
+ <ng-container [vListOutlet]="footerDir.templateRef"></ng-container>
150
+ </ng-template>
151
+ }
152
+ @if (emptyDir !== undefined) {
153
+ <ng-template vListEmpty>
154
+ <ng-container [vListOutlet]="emptyDir.templateRef"></ng-container>
155
+ </ng-template>
156
+ }
157
+ </VirtualizedList>
158
+ }
159
+ `;