@symbiote-native/angular 0.8.0 → 2.0.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 (256) hide show
  1. package/README.md +13 -10
  2. package/babel-register-composed.cjs +58 -18
  3. package/bin/symbiote-angular-dev.cjs +16 -4
  4. package/build/angular/anchor-host-registry.js +1 -15
  5. package/build/angular/anchor-host-registry.js.map +1 -1
  6. package/build/angular/change-detection-flush.d.ts +31 -0
  7. package/build/angular/change-detection-flush.js +110 -0
  8. package/build/angular/change-detection-flush.js.map +1 -0
  9. package/build/angular/components/activity-indicator-props.d.ts +2 -0
  10. package/build/angular/components/activity-indicator-props.js +2 -0
  11. package/build/angular/components/activity-indicator-props.js.map +1 -0
  12. package/build/angular/components/button-props.d.ts +2 -0
  13. package/build/angular/components/button-props.js +2 -0
  14. package/build/angular/components/button-props.js.map +1 -0
  15. package/build/angular/components/flat-list/index.d.ts +2 -1
  16. package/build/angular/components/flat-list/index.js +22 -10
  17. package/build/angular/components/flat-list/index.js.map +1 -1
  18. package/build/angular/components/image-background-props.d.ts +6 -0
  19. package/build/angular/components/image-background-props.js +2 -0
  20. package/build/angular/components/image-background-props.js.map +1 -0
  21. package/build/angular/components/{image/shared.d.ts → image-shared.d.ts} +4 -4
  22. package/build/angular/components/{image/shared.js → image-shared.js} +39 -28
  23. package/build/angular/components/image-shared.js.map +1 -0
  24. package/build/angular/components/input-accessory-view-props.d.ts +7 -0
  25. package/build/angular/components/input-accessory-view-props.js +9 -0
  26. package/build/angular/components/input-accessory-view-props.js.map +1 -0
  27. package/build/angular/components/keyboard-avoiding-view/index.d.ts +2 -1
  28. package/build/angular/components/keyboard-avoiding-view/index.js +28 -27
  29. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  30. package/build/angular/components/modal/index.d.ts +2 -0
  31. package/build/angular/components/modal/index.js +33 -20
  32. package/build/angular/components/modal/index.js.map +1 -1
  33. package/build/angular/components/pressable-props.d.ts +32 -0
  34. package/build/angular/components/pressable-props.js +11 -0
  35. package/build/angular/components/pressable-props.js.map +1 -0
  36. package/build/angular/components/refresh-control-props.d.ts +16 -0
  37. package/build/angular/components/refresh-control-props.js +14 -0
  38. package/build/angular/components/refresh-control-props.js.map +1 -0
  39. package/build/angular/components/safe-area-view-props.d.ts +7 -0
  40. package/build/angular/components/safe-area-view-props.js +11 -0
  41. package/build/angular/components/safe-area-view-props.js.map +1 -0
  42. package/build/angular/components/scroll-view-props.d.ts +76 -0
  43. package/build/angular/components/scroll-view-props.js +18 -0
  44. package/build/angular/components/scroll-view-props.js.map +1 -0
  45. package/build/angular/components/section-list/index.d.ts +3 -0
  46. package/build/angular/components/section-list/index.js +10 -1
  47. package/build/angular/components/section-list/index.js.map +1 -1
  48. package/build/angular/components/text-input-props.d.ts +45 -0
  49. package/build/angular/components/text-input-props.js +18 -0
  50. package/build/angular/components/text-input-props.js.map +1 -0
  51. package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +6 -0
  52. package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js +2 -0
  53. package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js.map +1 -0
  54. package/build/angular/components/touchable-props.d.ts +14 -0
  55. package/build/angular/components/touchable-props.js +13 -0
  56. package/build/angular/components/touchable-props.js.map +1 -0
  57. package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +3 -0
  58. package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js +2 -0
  59. package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js.map +1 -0
  60. package/build/angular/components/virtualized-list/index.d.ts +8 -1
  61. package/build/angular/components/virtualized-list/index.js +373 -278
  62. package/build/angular/components/virtualized-list/index.js.map +1 -1
  63. package/build/angular/components/virtualized-section-list/index.d.ts +3 -0
  64. package/build/angular/components/virtualized-section-list/index.js +10 -1
  65. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  66. package/build/angular/components.d.ts +21 -27
  67. package/build/angular/components.js +13 -15
  68. package/build/angular/components.js.map +1 -1
  69. package/build/angular/create-portal/index.d.ts +11 -2
  70. package/build/angular/create-portal/index.js +37 -11
  71. package/build/angular/create-portal/index.js.map +1 -1
  72. package/build/angular/create-tunnel/index.js +1 -1
  73. package/build/angular/element-props.d.ts +53 -0
  74. package/build/angular/element-props.js +2 -0
  75. package/build/angular/element-props.js.map +1 -0
  76. package/build/angular/elements.d.ts +528 -0
  77. package/build/angular/elements.js +1444 -0
  78. package/build/angular/elements.js.map +1 -0
  79. package/build/angular/gate-demand.d.ts +37 -0
  80. package/build/angular/gate-demand.js +84 -0
  81. package/build/angular/gate-demand.js.map +1 -0
  82. package/build/angular/host-instance/index.js +1 -1
  83. package/build/angular/index.d.ts +5 -2
  84. package/build/angular/index.js +16 -1
  85. package/build/angular/index.js.map +1 -1
  86. package/build/angular/modules/animated/create-animated-component.d.ts +6 -6
  87. package/build/angular/modules/animated/create-animated-component.js +73 -81
  88. package/build/angular/modules/animated/create-animated-component.js.map +1 -1
  89. package/build/angular/modules/animated/index.js +1 -1
  90. package/build/angular/modules/animated/index.js.map +1 -1
  91. package/build/angular/modules/image/index.d.ts +3 -0
  92. package/build/angular/modules/image/index.js +16 -0
  93. package/build/angular/modules/image/index.js.map +1 -0
  94. package/build/angular/primitives/index.d.ts +28 -16
  95. package/build/angular/primitives/index.js +77 -31
  96. package/build/angular/primitives/index.js.map +1 -1
  97. package/build/angular/primitives/shared.d.ts +2 -3
  98. package/build/angular/primitives/shared.js +8 -53
  99. package/build/angular/primitives/shared.js.map +1 -1
  100. package/build/angular/register.d.ts +1 -0
  101. package/build/angular/register.js +16 -0
  102. package/build/angular/register.js.map +1 -0
  103. package/build/angular/render/index.js +4 -2
  104. package/build/angular/render/index.js.map +1 -1
  105. package/build/angular/renderer/index.js +207 -60
  106. package/build/angular/renderer/index.js.map +1 -1
  107. package/build/angular/renderer/value-change.d.ts +2 -0
  108. package/build/angular/renderer/value-change.js +9 -0
  109. package/build/angular/renderer/value-change.js.map +1 -0
  110. package/metro-config.cjs +23 -5
  111. package/metro-css-parser.cjs +2 -1
  112. package/package.json +17 -7
  113. package/src/anchor-host-registry.ts +1 -15
  114. package/src/change-detection-flush.ts +120 -0
  115. package/src/components/activity-indicator-props.ts +21 -0
  116. package/src/components/button-props.ts +26 -0
  117. package/src/components/flat-list/index.ts +12 -4
  118. package/src/components/image-background-props.ts +24 -0
  119. package/src/components/{image/shared.ts → image-shared.ts} +57 -26
  120. package/src/components/input-accessory-view-props.ts +21 -0
  121. package/src/components/keyboard-avoiding-view/index.ts +27 -16
  122. package/src/components/modal/index.ts +32 -11
  123. package/src/components/pressable-props.ts +73 -0
  124. package/src/components/refresh-control-props.ts +43 -0
  125. package/src/components/safe-area-view-props.ts +28 -0
  126. package/src/components/scroll-view-props.ts +109 -0
  127. package/src/components/section-list/index.ts +18 -0
  128. package/src/components/text-input-props.ts +72 -0
  129. package/src/components/touchable-native-feedback/touchable-native-feedback-props.ts +23 -0
  130. package/src/components/touchable-props.ts +30 -0
  131. package/src/components/touchable-without-feedback/touchable-without-feedback-props.ts +21 -0
  132. package/src/components/virtualized-list/index.ts +254 -153
  133. package/src/components/virtualized-section-list/index.ts +18 -0
  134. package/src/components.ts +86 -35
  135. package/src/create-portal/index.ts +39 -9
  136. package/src/create-tunnel/index.ts +1 -1
  137. package/src/diagnostics.ts +1 -1
  138. package/src/element-props.ts +90 -0
  139. package/src/elements.ts +919 -0
  140. package/src/gate-demand.ts +109 -0
  141. package/src/host-instance/index.ts +1 -1
  142. package/src/index.ts +54 -15
  143. package/src/modules/animated/create-animated-component.ts +73 -59
  144. package/src/modules/animated/index.ts +1 -1
  145. package/src/modules/image/index.ts +18 -0
  146. package/src/primitives/index.ts +47 -16
  147. package/src/primitives/shared.ts +11 -44
  148. package/src/register.ts +15 -0
  149. package/src/render/index.ts +4 -2
  150. package/src/renderer/index.ts +239 -80
  151. package/src/renderer/value-change.ts +8 -0
  152. package/build/angular/components/activity-indicator/index.android.d.ts +0 -13
  153. package/build/angular/components/activity-indicator/index.android.js +0 -29
  154. package/build/angular/components/activity-indicator/index.android.js.map +0 -1
  155. package/build/angular/components/activity-indicator/index.d.ts +0 -1
  156. package/build/angular/components/activity-indicator/index.ios.d.ts +0 -9
  157. package/build/angular/components/activity-indicator/index.ios.js +0 -26
  158. package/build/angular/components/activity-indicator/index.ios.js.map +0 -1
  159. package/build/angular/components/activity-indicator/index.js +0 -4
  160. package/build/angular/components/activity-indicator/index.js.map +0 -1
  161. package/build/angular/components/activity-indicator/shared.d.ts +0 -67
  162. package/build/angular/components/activity-indicator/shared.js +0 -260
  163. package/build/angular/components/activity-indicator/shared.js.map +0 -1
  164. package/build/angular/components/button.d.ts +0 -65
  165. package/build/angular/components/button.js +0 -351
  166. package/build/angular/components/button.js.map +0 -1
  167. package/build/angular/components/image/index.android.d.ts +0 -15
  168. package/build/angular/components/image/index.android.js +0 -91
  169. package/build/angular/components/image/index.android.js.map +0 -1
  170. package/build/angular/components/image/index.d.ts +0 -1
  171. package/build/angular/components/image/index.ios.d.ts +0 -15
  172. package/build/angular/components/image/index.ios.js +0 -91
  173. package/build/angular/components/image/index.ios.js.map +0 -1
  174. package/build/angular/components/image/index.js +0 -3
  175. package/build/angular/components/image/index.js.map +0 -1
  176. package/build/angular/components/image/shared.js.map +0 -1
  177. package/build/angular/components/image-background.d.ts +0 -82
  178. package/build/angular/components/image-background.js +0 -434
  179. package/build/angular/components/image-background.js.map +0 -1
  180. package/build/angular/components/input-accessory-view/index.d.ts +0 -65
  181. package/build/angular/components/input-accessory-view/index.js +0 -290
  182. package/build/angular/components/input-accessory-view/index.js.map +0 -1
  183. package/build/angular/components/pressable/index.d.ts +0 -129
  184. package/build/angular/components/pressable/index.js +0 -473
  185. package/build/angular/components/pressable/index.js.map +0 -1
  186. package/build/angular/components/refresh-control/index.d.ts +0 -90
  187. package/build/angular/components/refresh-control/index.js +0 -380
  188. package/build/angular/components/refresh-control/index.js.map +0 -1
  189. package/build/angular/components/safe-area-view/index.d.ts +0 -62
  190. package/build/angular/components/safe-area-view/index.js +0 -287
  191. package/build/angular/components/safe-area-view/index.js.map +0 -1
  192. package/build/angular/components/scroll-view/index.android.d.ts +0 -20
  193. package/build/angular/components/scroll-view/index.android.js +0 -262
  194. package/build/angular/components/scroll-view/index.android.js.map +0 -1
  195. package/build/angular/components/scroll-view/index.d.ts +0 -3
  196. package/build/angular/components/scroll-view/index.ios.d.ts +0 -8
  197. package/build/angular/components/scroll-view/index.ios.js +0 -92
  198. package/build/angular/components/scroll-view/index.ios.js.map +0 -1
  199. package/build/angular/components/scroll-view/index.js +0 -6
  200. package/build/angular/components/scroll-view/index.js.map +0 -1
  201. package/build/angular/components/scroll-view/projection.d.ts +0 -67
  202. package/build/angular/components/scroll-view/projection.js +0 -560
  203. package/build/angular/components/scroll-view/projection.js.map +0 -1
  204. package/build/angular/components/scroll-view/shared.d.ts +0 -239
  205. package/build/angular/components/scroll-view/shared.js +0 -832
  206. package/build/angular/components/scroll-view/shared.js.map +0 -1
  207. package/build/angular/components/scroll-view/sticky-header.d.ts +0 -40
  208. package/build/angular/components/scroll-view/sticky-header.js +0 -224
  209. package/build/angular/components/scroll-view/sticky-header.js.map +0 -1
  210. package/build/angular/components/switch/index.android.d.ts +0 -24
  211. package/build/angular/components/switch/index.android.js +0 -112
  212. package/build/angular/components/switch/index.android.js.map +0 -1
  213. package/build/angular/components/switch/index.d.ts +0 -1
  214. package/build/angular/components/switch/index.ios.d.ts +0 -23
  215. package/build/angular/components/switch/index.ios.js +0 -111
  216. package/build/angular/components/switch/index.ios.js.map +0 -1
  217. package/build/angular/components/switch/index.js +0 -4
  218. package/build/angular/components/switch/index.js.map +0 -1
  219. package/build/angular/components/switch/shared.d.ts +0 -49
  220. package/build/angular/components/switch/shared.js +0 -191
  221. package/build/angular/components/switch/shared.js.map +0 -1
  222. package/build/angular/components/text-input.d.ts +0 -161
  223. package/build/angular/components/text-input.js +0 -659
  224. package/build/angular/components/text-input.js.map +0 -1
  225. package/build/angular/components/touchable/index.d.ts +0 -276
  226. package/build/angular/components/touchable/index.js +0 -1422
  227. package/build/angular/components/touchable/index.js.map +0 -1
  228. package/build/angular/components/touchable-native-feedback/index.d.ts +0 -86
  229. package/build/angular/components/touchable-native-feedback/index.js +0 -407
  230. package/build/angular/components/touchable-native-feedback/index.js.map +0 -1
  231. package/src/components/activity-indicator/index.android.ts +0 -23
  232. package/src/components/activity-indicator/index.ios.ts +0 -21
  233. package/src/components/activity-indicator/index.ts +0 -4
  234. package/src/components/activity-indicator/shared.ts +0 -225
  235. package/src/components/button.ts +0 -220
  236. package/src/components/image/index.android.ts +0 -99
  237. package/src/components/image/index.ios.ts +0 -99
  238. package/src/components/image/index.ts +0 -3
  239. package/src/components/image-background.ts +0 -290
  240. package/src/components/input-accessory-view/index.ts +0 -240
  241. package/src/components/pressable/index.ts +0 -462
  242. package/src/components/refresh-control/index.ts +0 -340
  243. package/src/components/safe-area-view/index.ts +0 -231
  244. package/src/components/scroll-view/index.android.ts +0 -205
  245. package/src/components/scroll-view/index.ios.ts +0 -81
  246. package/src/components/scroll-view/index.ts +0 -7
  247. package/src/components/scroll-view/projection.ts +0 -713
  248. package/src/components/scroll-view/shared.ts +0 -1066
  249. package/src/components/scroll-view/sticky-header.ts +0 -267
  250. package/src/components/switch/index.android.ts +0 -113
  251. package/src/components/switch/index.ios.ts +0 -112
  252. package/src/components/switch/index.ts +0 -4
  253. package/src/components/switch/shared.ts +0 -284
  254. package/src/components/text-input.ts +0 -613
  255. package/src/components/touchable/index.ts +0 -913
  256. package/src/components/touchable-native-feedback/index.ts +0 -317
@@ -1,225 +0,0 @@
1
- import {
2
- Directive,
3
- ElementRef,
4
- EventEmitter,
5
- inject,
6
- Input,
7
- Output,
8
- } from '@angular/core';
9
- import {
10
- renderActivityIndicator,
11
- resolveAccessibilityProps,
12
- type IAccessibilityProps,
13
- type IAccessibilityStateValue,
14
- type IActivityIndicatorPlatform,
15
- type IActivityIndicatorProps,
16
- type IActivityIndicatorSize,
17
- type IAriaProps,
18
- } from '@symbiote-native/components';
19
- import type { ISymbioteEvent } from '@symbiote-native/engine';
20
- import type { IDescriptor } from '@symbiote-native/components';
21
- import { anchorHostStyle } from '../../primitives';
22
-
23
- export type {
24
- IActivityIndicatorProps,
25
- IActivityIndicatorSize,
26
- } from '@symbiote-native/components';
27
-
28
- // Narrows anchorHostStyle's `unknown` (it reads an opaque engine prop bag) to the shape
29
- // IActivityIndicatorProps['style'] actually declares, the same runtime guard image/shared.ts's
30
- // asStyle() uses for the identical reason — a style value is structurally opaque at the type
31
- // level, so this only rules out non-objects, never validates individual style keys.
32
- function asStyle(value: unknown): IActivityIndicatorProps['style'] {
33
- return typeof value === 'object' && value !== null ? value : undefined;
34
- }
35
-
36
- // What the component itself takes as plain @Input()s: the full shared, cross-adapter
37
- // IActivityIndicatorProps surface minus onLayout and the accessibility callbacks, which it
38
- // exposes as real @Output() EventEmitters instead (see the class below), mirroring Pressable's
39
- // IAngularPressableInputs split.
40
- export type IActivityIndicatorInputs = Omit<
41
- IActivityIndicatorProps,
42
- | 'onLayout'
43
- | 'onAccessibilityAction'
44
- | 'onAccessibilityTap'
45
- | 'onMagicTap'
46
- | 'onAccessibilityEscape'
47
- >;
48
-
49
- @Directive()
50
- export abstract class ActivityIndicatorBase implements IActivityIndicatorInputs {
51
- @Input() animating?: boolean;
52
- @Input() color?: string;
53
- @Input() hidesWhenStopped?: boolean;
54
- @Input() nativeID?: string;
55
- @Input() size?: IActivityIndicatorSize;
56
- @Input() style?: IActivityIndicatorProps['style'];
57
- @Input() testID?: string;
58
- // Real @Output()s. This component renders through DescriptorOutlet (`symbiote-descriptor-
59
- // outlet`), not a hand-written template: emitterHandler() below wraps each EventEmitter into a
60
- // plain callback under the SAME onX key the shared, cross-adapter IActivityIndicatorProps
61
- // expects, so the Descriptor's props bag still carries a function the engine's routeProp
62
- // recognizes and routes to setEventListener — the outlet's renderer.setProperty call never
63
- // sees an EventEmitter, only the wrapper.
64
- @Output() readonly layout = new EventEmitter<ISymbioteEvent>();
65
-
66
- @Input() accessible?: boolean;
67
- @Input() accessibilityLabel?: string;
68
- @Input() accessibilityHint?: string;
69
- @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
70
- @Input() accessibilityState?: IAccessibilityStateValue;
71
- @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
72
- @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
73
- @Input() accessibilityLabelledBy?: string | string[];
74
- @Input()
75
- importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
76
- @Input()
77
- accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
78
- @Input() screenReaderFocusable?: boolean;
79
- @Input() accessibilityViewIsModal?: boolean;
80
- @Input() accessibilityElementsHidden?: boolean;
81
- @Input() accessibilityIgnoresInvertColors?: boolean;
82
- @Input() accessibilityLanguage?: string;
83
- @Input() accessibilityRespondsToUserInteraction?: boolean;
84
- @Input() accessibilityShowsLargeContentViewer?: boolean;
85
- @Input() accessibilityLargeContentTitle?: string;
86
- @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
87
- @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
88
- @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
89
- @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
90
-
91
- @Input() role?: IAriaProps['role'];
92
- @Input('aria-label') ariaLabel?: string;
93
- @Input('aria-labelledby') ariaLabelledBy?: string;
94
- @Input('aria-live') ariaLive?: IAriaProps['aria-live'];
95
- @Input('aria-hidden') ariaHidden?: boolean;
96
- @Input('aria-busy') ariaBusy?: boolean;
97
- @Input('aria-checked') ariaChecked?: boolean | 'mixed';
98
- @Input('aria-disabled') ariaDisabled?: boolean;
99
- @Input('aria-expanded') ariaExpanded?: boolean;
100
- @Input('aria-selected') ariaSelected?: boolean;
101
- @Input('aria-modal') ariaModal?: boolean;
102
- @Input('aria-valuemax') ariaValueMax?: number;
103
- @Input('aria-valuemin') ariaValueMin?: number;
104
- @Input('aria-valuenow') ariaValueNow?: number;
105
- @Input('aria-valuetext') ariaValueText?: string;
106
-
107
- protected abstract readonly defaultColor: string | null;
108
- protected readonly nativeExtras: Readonly<Record<string, unknown>> = {};
109
-
110
- // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
111
- // onto (see anchorHostStyle's doc comment) — NOT the descriptor-outlet-rendered wrapper the
112
- // `descriptor` getter below builds. Merged FIRST so an explicit `style` @Input still wins
113
- // (flattenStyle's later-wins collapse), mirroring every other composed component's anchor merge.
114
- private readonly elementRef = inject(ElementRef);
115
-
116
- // Stable bound wrappers (created ONCE, not per `descriptor` access) fed to emitterHandler below.
117
- // jsonEqual (core/engine/src/commit.ts) falls through to Object.is for a function leaf, so a
118
- // fresh closure built inside the `descriptor` getter would never equal the previous frame's
119
- // closure even when nothing changed — every CD pass would read as "props changed" and force a
120
- // real Fabric re-clone cascading up every ancestor to the root (the same hazard
121
- // AnimatedComponentBase.reconcile() and ScrollViewStickyHeader's onHostLayout guard against).
122
- private readonly onLayoutHandler = (event: ISymbioteEvent): void =>
123
- this.layout.emit(event);
124
- private readonly onAccessibilityActionHandler = (
125
- event: ISymbioteEvent,
126
- ): void => this.accessibilityAction.emit(event);
127
- private readonly onAccessibilityTapHandler = (event: ISymbioteEvent): void =>
128
- this.accessibilityTap.emit(event);
129
- private readonly onMagicTapHandler = (event: ISymbioteEvent): void =>
130
- this.magicTap.emit(event);
131
- private readonly onAccessibilityEscapeHandler = (
132
- event: ISymbioteEvent,
133
- ): void => this.accessibilityEscape.emit(event);
134
-
135
- get descriptor(): IDescriptor {
136
- const props = resolveAccessibilityProps<IActivityIndicatorProps>({
137
- animating: this.animating,
138
- color: this.color,
139
- hidesWhenStopped: this.hidesWhenStopped,
140
- nativeID: this.nativeID,
141
- size: this.size,
142
- style: [asStyle(anchorHostStyle(this.elementRef)), this.style],
143
- testID: this.testID,
144
- onLayout: this.emitterHandler(this.layout, this.onLayoutHandler),
145
- accessible: this.accessible,
146
- accessibilityLabel: this.accessibilityLabel,
147
- accessibilityHint: this.accessibilityHint,
148
- accessibilityRole: this.accessibilityRole,
149
- accessibilityState: this.accessibilityState,
150
- accessibilityValue: this.accessibilityValue,
151
- accessibilityActions: this.accessibilityActions,
152
- accessibilityLabelledBy: this.accessibilityLabelledBy,
153
- importantForAccessibility: this.importantForAccessibility,
154
- accessibilityLiveRegion: this.accessibilityLiveRegion,
155
- screenReaderFocusable: this.screenReaderFocusable,
156
- accessibilityViewIsModal: this.accessibilityViewIsModal,
157
- accessibilityElementsHidden: this.accessibilityElementsHidden,
158
- accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
159
- accessibilityLanguage: this.accessibilityLanguage,
160
- accessibilityRespondsToUserInteraction:
161
- this.accessibilityRespondsToUserInteraction,
162
- accessibilityShowsLargeContentViewer:
163
- this.accessibilityShowsLargeContentViewer,
164
- accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
165
- onAccessibilityAction: this.emitterHandler(
166
- this.accessibilityAction,
167
- this.onAccessibilityActionHandler,
168
- ),
169
- onAccessibilityTap: this.emitterHandler(
170
- this.accessibilityTap,
171
- this.onAccessibilityTapHandler,
172
- ),
173
- onMagicTap: this.emitterHandler(this.magicTap, this.onMagicTapHandler),
174
- onAccessibilityEscape: this.emitterHandler(
175
- this.accessibilityEscape,
176
- this.onAccessibilityEscapeHandler,
177
- ),
178
- role: this.role,
179
- 'aria-label': this.ariaLabel,
180
- 'aria-labelledby': this.ariaLabelledBy,
181
- 'aria-live': this.ariaLive,
182
- 'aria-hidden': this.ariaHidden,
183
- 'aria-busy': this.ariaBusy,
184
- 'aria-checked': this.ariaChecked,
185
- 'aria-disabled': this.ariaDisabled,
186
- 'aria-expanded': this.ariaExpanded,
187
- 'aria-selected': this.ariaSelected,
188
- 'aria-modal': this.ariaModal,
189
- 'aria-valuemax': this.ariaValueMax,
190
- 'aria-valuemin': this.ariaValueMin,
191
- 'aria-valuenow': this.ariaValueNow,
192
- 'aria-valuetext': this.ariaValueText,
193
- });
194
-
195
- const { animating, color, hidesWhenStopped, size, style, ...passthrough } =
196
- props;
197
- return renderActivityIndicator(
198
- {
199
- animating: animating !== false,
200
- color,
201
- hidesWhenStopped: hidesWhenStopped !== false,
202
- size: size ?? 'small',
203
- style,
204
- passthrough,
205
- },
206
- this.platform,
207
- );
208
- }
209
-
210
- private get platform(): IActivityIndicatorPlatform {
211
- return { defaultColor: this.defaultColor, nativeExtras: this.nativeExtras };
212
- }
213
-
214
- // Gates a STABLE bound handler behind `observed`, so an unbound event still resolves to
215
- // `undefined` in the descriptor's props bag — the same "undefined means nobody cares" contract
216
- // the old @Input() callback had, letting resolveAccessibilityProps drop the key entirely instead
217
- // of handing the engine a no-op function. `handler` must be one of the readonly bound fields
218
- // above, never a closure built here — see their doc comment for why.
219
- private emitterHandler(
220
- emitter: EventEmitter<ISymbioteEvent>,
221
- handler: (event: ISymbioteEvent) => void,
222
- ): ((event: ISymbioteEvent) => void) | undefined {
223
- return emitter.observed ? handler : undefined;
224
- }
225
- }
@@ -1,220 +0,0 @@
1
- // Button for Angular. The minimal cross-platform button in RN's iOS shape (Button.js): a
2
- // TouchableOpacity wrapping a Text. The base text style, the role constant, and the color fold are
3
- // shared in @symbiote-native/components/view; Angular only composes its TouchableOpacity + a
4
- // symbiote-text child and re-maps the few Button-owned props. No JS-side platform branch, so this
5
- // stays a flat single file.
6
- //
7
- // RN's Button fixes accessibilityRole="button", marks the root accessible, and propagates
8
- // `disabled` into the accessibility state; those three win over any caller value. `title` becomes
9
- // the Text child; disabled forwards straight; touchSoundDisabled maps to the pressable's
10
- // android_disableSound. Every other field of the shared IButtonProps stays RE-EXPORTED from
11
- // @symbiote-native/components verbatim. onPress and the four accessibility callbacks are the
12
- // exceptions: each is a real @Output() here (`press`, `accessibilityAction`, `accessibilityTap`,
13
- // `magicTap`, `accessibilityEscape`), mirroring the Vue adapter's Button, which forks the same
14
- // onPress field the same way — not a new precedent, the existing one extended to accessibility.
15
-
16
- import {
17
- CUSTOM_ELEMENTS_SCHEMA,
18
- ChangeDetectionStrategy,
19
- Component,
20
- ElementRef,
21
- EventEmitter,
22
- inject,
23
- Input,
24
- Output,
25
- signal,
26
- type DoCheck,
27
- } from '@angular/core';
28
- import {
29
- BUTTON_ACCESSIBILITY_ROLE,
30
- resolveButtonTextStyle,
31
- type IAccessibilityProps,
32
- type IAccessibilityStateValue,
33
- type IAriaProps,
34
- type IButtonProps as ICoreButtonProps,
35
- } from '@symbiote-native/components';
36
- import type {
37
- ISymbioteEvent,
38
- ITextStyle,
39
- IStyleProp,
40
- IViewStyle,
41
- } from '@symbiote-native/engine';
42
- import { anchorStyleProp, TextHost } from '../primitives';
43
- import { TouchableOpacity } from './touchable';
44
-
45
- export type IButtonProps = Omit<
46
- ICoreButtonProps,
47
- | 'onPress'
48
- | 'onAccessibilityAction'
49
- | 'onAccessibilityTap'
50
- | 'onMagicTap'
51
- | 'onAccessibilityEscape'
52
- >;
53
-
54
- @Component({
55
- selector: 'Button',
56
- standalone: true,
57
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
58
- imports: [TouchableOpacity, TextHost],
59
- changeDetection: ChangeDetectionStrategy.OnPush,
60
- template: `
61
- <TouchableOpacity
62
- [style]="anchorStyle"
63
- (press)="press.emit($event)"
64
- [disabled]="disabled"
65
- [android_disableSound]="touchSoundDisabled"
66
- [accessibilityRole]="buttonRole"
67
- [accessible]="true"
68
- [accessibilityState]="{ disabled }"
69
- [testID]="testID"
70
- [nativeID]="nativeID"
71
- [hasTVPreferredFocus]="hasTVPreferredFocus"
72
- [nextFocusDown]="nextFocusDown"
73
- [nextFocusForward]="nextFocusForward"
74
- [nextFocusLeft]="nextFocusLeft"
75
- [nextFocusRight]="nextFocusRight"
76
- [nextFocusUp]="nextFocusUp"
77
- [accessibilityLabel]="accessibilityLabel"
78
- [accessibilityHint]="accessibilityHint"
79
- [accessibilityValue]="accessibilityValue"
80
- [accessibilityActions]="accessibilityActions"
81
- [accessibilityLabelledBy]="accessibilityLabelledBy"
82
- [importantForAccessibility]="importantForAccessibility"
83
- [accessibilityLiveRegion]="accessibilityLiveRegion"
84
- [screenReaderFocusable]="screenReaderFocusable"
85
- [accessibilityViewIsModal]="accessibilityViewIsModal"
86
- [accessibilityElementsHidden]="accessibilityElementsHidden"
87
- [accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
88
- [accessibilityLanguage]="accessibilityLanguage"
89
- [accessibilityRespondsToUserInteraction]="
90
- accessibilityRespondsToUserInteraction
91
- "
92
- [accessibilityShowsLargeContentViewer]="
93
- accessibilityShowsLargeContentViewer
94
- "
95
- [accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
96
- (accessibilityAction)="accessibilityAction.emit($event)"
97
- (accessibilityTap)="accessibilityTap.emit($event)"
98
- (magicTap)="magicTap.emit($event)"
99
- (accessibilityEscape)="accessibilityEscape.emit($event)"
100
- [ariaLabel]="ariaLabel"
101
- [ariaBusy]="ariaBusy"
102
- [ariaChecked]="ariaChecked"
103
- [ariaDisabled]="ariaDisabled"
104
- [ariaExpanded]="ariaExpanded"
105
- [ariaHidden]="ariaHidden"
106
- [ariaLabelledBy]="ariaLabelledBy"
107
- [ariaLive]="ariaLive"
108
- [ariaSelected]="ariaSelected"
109
- [ariaModal]="ariaModal"
110
- [ariaValueMax]="ariaValueMax"
111
- [ariaValueMin]="ariaValueMin"
112
- [ariaValueNow]="ariaValueNow"
113
- [ariaValueText]="ariaValueText"
114
- [role]="role"
115
- >
116
- <symbiote-text [style]="textStyle">{{ title }}</symbiote-text>
117
- </TouchableOpacity>
118
- `,
119
- })
120
- export class Button implements IButtonProps, DoCheck {
121
- // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
122
- // onto (see anchorHostStyle's doc comment in primitives/shared.ts) — NOT the inner
123
- // TouchableOpacity/Pressable one level down. RN's real Button takes no `style` prop, so this
124
- // is the only style source forwarded.
125
- private readonly elementRef = inject(ElementRef);
126
-
127
- @Output() readonly press = new EventEmitter<ISymbioteEvent>();
128
- @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
129
- @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
130
- @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
131
- @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
132
-
133
- // Button-owned props: title is the Text child, color/disabled fold into the label style, and
134
- // touchSoundDisabled re-maps onto TouchableOpacity.
135
- @Input() title = '';
136
- @Input() color?: string;
137
- @Input() disabled?: boolean;
138
- @Input() touchSoundDisabled?: boolean;
139
- @Input() testID?: string;
140
-
141
- // TV-focus props (Button.js): inert on a phone host, forwarded through TouchableOpacity.
142
- @Input() hasTVPreferredFocus?: boolean;
143
- @Input() nextFocusDown?: number;
144
- @Input() nextFocusForward?: number;
145
- @Input() nextFocusLeft?: number;
146
- @Input() nextFocusRight?: number;
147
- @Input() nextFocusUp?: number;
148
-
149
- // Accessibility surface (IAccessibilityProps). accessibilityRole, accessible, and
150
- // accessibilityState are declared for surface completeness but Button forces its own
151
- // (button / true / { disabled }); the caller value is ignored, mirroring RN's Button.js.
152
- @Input() nativeID?: string;
153
- @Input() accessible?: boolean;
154
- @Input() accessibilityLabel?: string;
155
- @Input() accessibilityHint?: string;
156
- @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
157
- @Input() accessibilityState?: IAccessibilityStateValue;
158
- @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
159
- @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
160
- @Input() accessibilityLabelledBy?: string | string[];
161
- @Input()
162
- importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
163
- @Input()
164
- accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
165
- @Input() screenReaderFocusable?: boolean;
166
- @Input() accessibilityViewIsModal?: boolean;
167
- @Input() accessibilityElementsHidden?: boolean;
168
- @Input() accessibilityIgnoresInvertColors?: boolean;
169
- @Input() accessibilityLanguage?: string;
170
- @Input() accessibilityRespondsToUserInteraction?: boolean;
171
- @Input() accessibilityShowsLargeContentViewer?: boolean;
172
- @Input() accessibilityLargeContentTitle?: string;
173
-
174
- // Web-alias a11y surface (IAriaProps). External dashed aliases are exposed as Angular inputs and
175
- // forwarded to TouchableOpacity's camelCase aria inputs.
176
- @Input() role?: IAriaProps['role'];
177
- @Input('aria-label') ariaLabel?: string;
178
- @Input('aria-labelledby') ariaLabelledBy?: string;
179
- @Input('aria-live') ariaLive?: IAriaProps['aria-live'];
180
- @Input('aria-hidden') ariaHidden?: boolean;
181
- @Input('aria-busy') ariaBusy?: boolean;
182
- @Input('aria-checked') ariaChecked?: boolean | 'mixed';
183
- @Input('aria-disabled') ariaDisabled?: boolean;
184
- @Input('aria-expanded') ariaExpanded?: boolean;
185
- @Input('aria-selected') ariaSelected?: boolean;
186
- @Input('aria-modal') ariaModal?: boolean;
187
- @Input('aria-valuemax') ariaValueMax?: number;
188
- @Input('aria-valuemin') ariaValueMin?: number;
189
- @Input('aria-valuenow') ariaValueNow?: number;
190
- @Input('aria-valuetext') ariaValueText?: string;
191
-
192
- // RN's Button is always accessibilityRole="button"; the shared role constant, not a literal.
193
- readonly buttonRole = BUTTON_ACCESSIBILITY_ROLE;
194
-
195
- // The label style with the caller color tinted in and `disabled` greying it out (disabled wins),
196
- // computed by the shared fold so every adapter paints the identical button.
197
- get textStyle(): ITextStyle {
198
- return resolveButtonTextStyle(this.color, this.disabled);
199
- }
200
-
201
- // Polled, not read live: a class toggled after mount reaches the anchor through
202
- // addClass/removeClass, which dirties nothing, so a plain getter froze at its creation value.
203
- // Button cannot use SymbioteStyleInputDirective instead - RN's Button has no `style` prop, so
204
- // there is no `style` @Input for it to hang off.
205
- //
206
- // ngDoCheck runs during the PARENT's refresh even when this view is skipped; the signal write is
207
- // what marks this view. The anchor returns the same props.style reference until a commit changes
208
- // it, so Object.is makes an unchanged poll free.
209
- private readonly anchorStyleValue = signal<
210
- IStyleProp<IViewStyle> | undefined
211
- >(undefined);
212
-
213
- ngDoCheck(): void {
214
- this.anchorStyleValue.set(anchorStyleProp<IViewStyle>(this.elementRef));
215
- }
216
-
217
- get anchorStyle(): IStyleProp<IViewStyle> | undefined {
218
- return this.anchorStyleValue();
219
- }
220
- }
@@ -1,99 +0,0 @@
1
- import {
2
- CUSTOM_ELEMENTS_SCHEMA,
3
- Component,
4
- ElementRef,
5
- inject,
6
- signal,
7
- type DoCheck,
8
- type OnChanges,
9
- } from '@angular/core';
10
- import {
11
- anchorHostStyle,
12
- ImageHost,
13
- SymbioteHostPropsDirective,
14
- SymbioteStyleInputDirective,
15
- } from '../../primitives';
16
- import {
17
- IMAGE_INPUTS,
18
- IMAGE_OUTPUTS,
19
- ImageBase,
20
- resolveImageProps,
21
- } from './shared';
22
- export { setImageSourceResolver } from './shared';
23
- export type {
24
- IImageProps,
25
- IImageSource,
26
- IImageSourceProp,
27
- IResizeMode,
28
- IImageSize,
29
- IImageCacheStatus,
30
- } from './shared';
31
-
32
- @Component({
33
- selector: 'Image',
34
- standalone: true,
35
- hostDirectives: [
36
- { directive: SymbioteStyleInputDirective, inputs: ['style'] },
37
- ],
38
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
39
- imports: [ImageHost, SymbioteHostPropsDirective],
40
- inputs: IMAGE_INPUTS,
41
- outputs: IMAGE_OUTPUTS,
42
- template: `
43
- <symbiote-image
44
- [symbioteHostProps]="imageProps()"
45
- (accessibilityAction)="handleAccessibilityAction($event)"
46
- (accessibilityTap)="handleAccessibilityTap($event)"
47
- (magicTap)="handleMagicTap($event)"
48
- (accessibilityEscape)="handleAccessibilityEscape($event)"
49
- (loadStart)="handleLoadStart($event)"
50
- (load)="handleLoad($event)"
51
- (loadEnd)="handleLoadEnd($event)"
52
- (error)="handleError($event)"
53
- (progress)="handleProgress($event)"
54
- (partialLoad)="handlePartialLoad($event)"
55
- />
56
- `,
57
- })
58
- export class Image extends ImageBase implements OnChanges, DoCheck {
59
- // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
60
- // onto (see anchorHostStyle's doc comment) — NOT the inner `symbiote-image` one level down.
61
- private readonly elementRef = inject(ElementRef);
62
-
63
- // The anchor's class-derived style is written by the renderer's addClass/removeClass and never
64
- // reaches Angular's input pipeline (a bare `class="x"` never appears in SimpleChanges — see
65
- // anchorHostStyle's doc comment), so ImageBase's inputsRevision cannot see it. Hence its own
66
- // signal: a plain field read inside a computed() would be untracked and the bag would go stale
67
- // the moment a `[class.x]`/`[ngClass]` toggled.
68
- //
69
- // ngDoCheck is the right cadence: render3's callHooks flushes a node's pre-order hooks at the
70
- // next `ɵɵadvance` past it (or in refreshView's post-template flush), i.e. AFTER the declaring
71
- // template's ɵɵclassProp wrote the class onto this element and BEFORE this component's own view
72
- // refreshes — the exact window a class poll needs. callHooks also runs under
73
- // setActiveConsumer(null), so the write registers no dependency on the caller's view (no NG0600).
74
- // commitClassStyle allocates a fresh style array only when a token actually moved, so signal.set's
75
- // own Object.is check makes an unchanged poll a no-op that dirties nothing.
76
- //
77
- // Known gap, shared with every other component polling this way (Pressable, SafeAreaView,
78
- // TouchableNativeFeedback): `[ngClass]` applies its tokens from NgClass's OWN ngDoCheck, and a
79
- // node's hooks flush in registration order with the component's first, so an [ngClass] flip lands
80
- // one pass after this poll reads it. `class=` and `[class.x]` are written by the declaring
81
- // template's styling instructions and so are always current here.
82
- private readonly anchorStyle = signal<unknown>(undefined);
83
-
84
- // ImageBase is undecorated, so the input bump is declared here rather than inherited.
85
- ngOnChanges(): void {
86
- this.bumpInputsRevision();
87
- }
88
-
89
- ngDoCheck(): void {
90
- this.anchorStyle.set(anchorHostStyle(this.elementRef));
91
- }
92
-
93
- protected override buildImageProps(): Record<string, unknown> {
94
- return resolveImageProps({
95
- ...this.imageInputProps,
96
- style: [this.anchorStyle(), this.style],
97
- });
98
- }
99
- }
@@ -1,99 +0,0 @@
1
- import {
2
- CUSTOM_ELEMENTS_SCHEMA,
3
- Component,
4
- ElementRef,
5
- inject,
6
- signal,
7
- type DoCheck,
8
- type OnChanges,
9
- } from '@angular/core';
10
- import {
11
- anchorHostStyle,
12
- ImageHost,
13
- SymbioteHostPropsDirective,
14
- SymbioteStyleInputDirective,
15
- } from '../../primitives';
16
- import {
17
- IMAGE_INPUTS,
18
- IMAGE_OUTPUTS,
19
- ImageBase,
20
- resolveImageProps,
21
- } from './shared';
22
- export { setImageSourceResolver } from './shared';
23
- export type {
24
- IImageProps,
25
- IImageSource,
26
- IImageSourceProp,
27
- IResizeMode,
28
- IImageSize,
29
- IImageCacheStatus,
30
- } from './shared';
31
-
32
- @Component({
33
- selector: 'Image',
34
- standalone: true,
35
- hostDirectives: [
36
- { directive: SymbioteStyleInputDirective, inputs: ['style'] },
37
- ],
38
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
39
- imports: [ImageHost, SymbioteHostPropsDirective],
40
- inputs: IMAGE_INPUTS,
41
- outputs: IMAGE_OUTPUTS,
42
- template: `
43
- <symbiote-image
44
- [symbioteHostProps]="imageProps()"
45
- (accessibilityAction)="handleAccessibilityAction($event)"
46
- (accessibilityTap)="handleAccessibilityTap($event)"
47
- (magicTap)="handleMagicTap($event)"
48
- (accessibilityEscape)="handleAccessibilityEscape($event)"
49
- (loadStart)="handleLoadStart($event)"
50
- (load)="handleLoad($event)"
51
- (loadEnd)="handleLoadEnd($event)"
52
- (error)="handleError($event)"
53
- (progress)="handleProgress($event)"
54
- (partialLoad)="handlePartialLoad($event)"
55
- />
56
- `,
57
- })
58
- export class Image extends ImageBase implements OnChanges, DoCheck {
59
- // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
60
- // onto (see anchorHostStyle's doc comment) — NOT the inner `symbiote-image` one level down.
61
- private readonly elementRef = inject(ElementRef);
62
-
63
- // The anchor's class-derived style is written by the renderer's addClass/removeClass and never
64
- // reaches Angular's input pipeline (a bare `class="x"` never appears in SimpleChanges — see
65
- // anchorHostStyle's doc comment), so ImageBase's inputsRevision cannot see it. Hence its own
66
- // signal: a plain field read inside a computed() would be untracked and the bag would go stale
67
- // the moment a `[class.x]`/`[ngClass]` toggled.
68
- //
69
- // ngDoCheck is the right cadence: render3's callHooks flushes a node's pre-order hooks at the
70
- // next `ɵɵadvance` past it (or in refreshView's post-template flush), i.e. AFTER the declaring
71
- // template's ɵɵclassProp wrote the class onto this element and BEFORE this component's own view
72
- // refreshes — the exact window a class poll needs. callHooks also runs under
73
- // setActiveConsumer(null), so the write registers no dependency on the caller's view (no NG0600).
74
- // commitClassStyle allocates a fresh style array only when a token actually moved, so signal.set's
75
- // own Object.is check makes an unchanged poll a no-op that dirties nothing.
76
- //
77
- // Known gap, shared with every other component polling this way (Pressable, SafeAreaView,
78
- // TouchableNativeFeedback): `[ngClass]` applies its tokens from NgClass's OWN ngDoCheck, and a
79
- // node's hooks flush in registration order with the component's first, so an [ngClass] flip lands
80
- // one pass after this poll reads it. `class=` and `[class.x]` are written by the declaring
81
- // template's styling instructions and so are always current here.
82
- private readonly anchorStyle = signal<unknown>(undefined);
83
-
84
- // ImageBase is undecorated, so the input bump is declared here rather than inherited.
85
- ngOnChanges(): void {
86
- this.bumpInputsRevision();
87
- }
88
-
89
- ngDoCheck(): void {
90
- this.anchorStyle.set(anchorHostStyle(this.elementRef));
91
- }
92
-
93
- protected override buildImageProps(): Record<string, unknown> {
94
- return resolveImageProps({
95
- ...this.imageInputProps,
96
- style: [this.anchorStyle(), this.style],
97
- });
98
- }
99
- }
@@ -1,3 +0,0 @@
1
- // Base/default Image. Re-exports the iOS build; Metro picks index.ios.ts / index.android.ts in platform bundles.
2
-
3
- export * from './index.ios';