@symbiote-native/angular 0.7.0 → 1.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 (188) hide show
  1. package/README.md +3 -3
  2. package/babel-lower-host-primitives.cjs +636 -0
  3. package/babel-register-composed.cjs +21 -3
  4. package/build/angular/anchor-host-registry.js +3 -1
  5. package/build/angular/anchor-host-registry.js.map +1 -1
  6. package/build/angular/bootstrap.js +1 -1
  7. package/build/angular/bootstrap.js.map +1 -1
  8. package/build/angular/components/activity-indicator/index.android.js +7 -2
  9. package/build/angular/components/activity-indicator/index.android.js.map +1 -1
  10. package/build/angular/components/activity-indicator/index.ios.js +3 -1
  11. package/build/angular/components/activity-indicator/index.ios.js.map +1 -1
  12. package/build/angular/components/activity-indicator/shared.d.ts +1 -1
  13. package/build/angular/components/activity-indicator/shared.js +1 -1
  14. package/build/angular/components/activity-indicator/shared.js.map +1 -1
  15. package/build/angular/components/button.d.ts +3 -0
  16. package/build/angular/components/button.js +22 -5
  17. package/build/angular/components/button.js.map +1 -1
  18. package/build/angular/components/flat-list/index.d.ts +1 -1
  19. package/build/angular/components/flat-list/index.js +47 -14
  20. package/build/angular/components/flat-list/index.js.map +1 -1
  21. package/build/angular/components/image/index.android.js +4 -10
  22. package/build/angular/components/image/index.android.js.map +1 -1
  23. package/build/angular/components/image/index.ios.js +4 -10
  24. package/build/angular/components/image/index.ios.js.map +1 -1
  25. package/build/angular/components/image/shared.d.ts +4 -4
  26. package/build/angular/components/image/shared.js +51 -33
  27. package/build/angular/components/image/shared.js.map +1 -1
  28. package/build/angular/components/image-background.d.ts +3 -0
  29. package/build/angular/components/image-background.js +32 -9
  30. package/build/angular/components/image-background.js.map +1 -1
  31. package/build/angular/components/input-accessory-view/index.d.ts +2 -1
  32. package/build/angular/components/input-accessory-view/index.js +18 -16
  33. package/build/angular/components/input-accessory-view/index.js.map +1 -1
  34. package/build/angular/components/keyboard-avoiding-view/index.d.ts +3 -1
  35. package/build/angular/components/keyboard-avoiding-view/index.js +56 -19
  36. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  37. package/build/angular/components/modal/index.d.ts +1 -0
  38. package/build/angular/components/modal/index.js +21 -10
  39. package/build/angular/components/modal/index.js.map +1 -1
  40. package/build/angular/components/pressable/index.d.ts +10 -5
  41. package/build/angular/components/pressable/index.js +61 -16
  42. package/build/angular/components/pressable/index.js.map +1 -1
  43. package/build/angular/components/refresh-control/index.d.ts +2 -1
  44. package/build/angular/components/refresh-control/index.js +13 -9
  45. package/build/angular/components/refresh-control/index.js.map +1 -1
  46. package/build/angular/components/safe-area-view/index.d.ts +3 -1
  47. package/build/angular/components/safe-area-view/index.js +22 -20
  48. package/build/angular/components/safe-area-view/index.js.map +1 -1
  49. package/build/angular/components/scroll-view/index.android.js +44 -14
  50. package/build/angular/components/scroll-view/index.android.js.map +1 -1
  51. package/build/angular/components/scroll-view/index.ios.js +13 -5
  52. package/build/angular/components/scroll-view/index.ios.js.map +1 -1
  53. package/build/angular/components/scroll-view/projection.d.ts +32 -0
  54. package/build/angular/components/scroll-view/projection.js +212 -47
  55. package/build/angular/components/scroll-view/projection.js.map +1 -1
  56. package/build/angular/components/scroll-view/shared.d.ts +2 -0
  57. package/build/angular/components/scroll-view/shared.js +48 -11
  58. package/build/angular/components/scroll-view/shared.js.map +1 -1
  59. package/build/angular/components/scroll-view/sticky-header.js +7 -3
  60. package/build/angular/components/scroll-view/sticky-header.js.map +1 -1
  61. package/build/angular/components/section-list/index.d.ts +9 -1
  62. package/build/angular/components/section-list/index.js +72 -18
  63. package/build/angular/components/section-list/index.js.map +1 -1
  64. package/build/angular/components/switch/index.android.js +23 -9
  65. package/build/angular/components/switch/index.android.js.map +1 -1
  66. package/build/angular/components/switch/index.ios.js +23 -9
  67. package/build/angular/components/switch/index.ios.js.map +1 -1
  68. package/build/angular/components/switch/shared.d.ts +1 -1
  69. package/build/angular/components/switch/shared.js +5 -2
  70. package/build/angular/components/switch/shared.js.map +1 -1
  71. package/build/angular/components/text-input.d.ts +8 -2
  72. package/build/angular/components/text-input.js +79 -34
  73. package/build/angular/components/text-input.js.map +1 -1
  74. package/build/angular/components/touchable/index.d.ts +36 -7
  75. package/build/angular/components/touchable/index.js +280 -72
  76. package/build/angular/components/touchable/index.js.map +1 -1
  77. package/build/angular/components/touchable-native-feedback/index.d.ts +2 -1
  78. package/build/angular/components/touchable-native-feedback/index.js +19 -17
  79. package/build/angular/components/touchable-native-feedback/index.js.map +1 -1
  80. package/build/angular/components/virtualized-list/directives.js +4 -0
  81. package/build/angular/components/virtualized-list/directives.js.map +1 -1
  82. package/build/angular/components/virtualized-list/index.d.ts +8 -2
  83. package/build/angular/components/virtualized-list/index.js +207 -61
  84. package/build/angular/components/virtualized-list/index.js.map +1 -1
  85. package/build/angular/components/virtualized-section-list/directives.js.map +1 -1
  86. package/build/angular/components/virtualized-section-list/index.d.ts +21 -1
  87. package/build/angular/components/virtualized-section-list/index.js +100 -22
  88. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  89. package/build/angular/components.d.ts +2 -2
  90. package/build/angular/components.js +1 -1
  91. package/build/angular/components.js.map +1 -1
  92. package/build/angular/create-portal/index.d.ts +11 -2
  93. package/build/angular/create-portal/index.js +42 -12
  94. package/build/angular/create-portal/index.js.map +1 -1
  95. package/build/angular/create-tunnel/index.js.map +1 -1
  96. package/build/angular/descriptor-to-angular/index.js +3 -1
  97. package/build/angular/descriptor-to-angular/index.js.map +1 -1
  98. package/build/angular/diagnostics.d.ts +33 -0
  99. package/build/angular/diagnostics.js +82 -0
  100. package/build/angular/diagnostics.js.map +1 -0
  101. package/build/angular/gate-demand.d.ts +37 -0
  102. package/build/angular/gate-demand.js +84 -0
  103. package/build/angular/gate-demand.js.map +1 -0
  104. package/build/angular/host-instance/index.js +1 -1
  105. package/build/angular/host-instance/index.js.map +1 -1
  106. package/build/angular/index.d.ts +6 -2
  107. package/build/angular/index.js +16 -1
  108. package/build/angular/index.js.map +1 -1
  109. package/build/angular/modules/animated/create-animated-component.d.ts +1 -0
  110. package/build/angular/modules/animated/create-animated-component.js +41 -18
  111. package/build/angular/modules/animated/create-animated-component.js.map +1 -1
  112. package/build/angular/modules/app-registry/index.js.map +1 -1
  113. package/build/angular/modules/status-bar/index.js +1 -1
  114. package/build/angular/modules/status-bar/index.js.map +1 -1
  115. package/build/angular/primitives/index.d.ts +31 -2
  116. package/build/angular/primitives/index.js +81 -3
  117. package/build/angular/primitives/index.js.map +1 -1
  118. package/build/angular/primitives/shared.d.ts +9 -1
  119. package/build/angular/primitives/shared.js +49 -3
  120. package/build/angular/primitives/shared.js.map +1 -1
  121. package/build/angular/register.d.ts +1 -0
  122. package/build/angular/register.js +35 -0
  123. package/build/angular/register.js.map +1 -0
  124. package/build/angular/render/index.js +51 -6
  125. package/build/angular/render/index.js.map +1 -1
  126. package/build/angular/renderer/index.d.ts +1 -0
  127. package/build/angular/renderer/index.js +157 -21
  128. package/build/angular/renderer/index.js.map +1 -1
  129. package/build/angular/services/color-scheme.service.js.map +1 -1
  130. package/build/angular/services/window-dimensions.service.js +1 -1
  131. package/build/angular/services/window-dimensions.service.js.map +1 -1
  132. package/build/angular/state-style.d.ts +9 -0
  133. package/build/angular/state-style.js +39 -0
  134. package/build/angular/state-style.js.map +1 -0
  135. package/metro-transformer.cjs +69 -0
  136. package/package.json +27 -8
  137. package/src/anchor-host-registry.ts +3 -1
  138. package/src/bootstrap.ts +4 -1
  139. package/src/components/activity-indicator/index.android.ts +7 -2
  140. package/src/components/activity-indicator/index.ios.ts +3 -1
  141. package/src/components/activity-indicator/shared.ts +32 -13
  142. package/src/components/button.ts +36 -6
  143. package/src/components/flat-list/index.ts +91 -29
  144. package/src/components/image/index.android.ts +9 -6
  145. package/src/components/image/index.ios.ts +9 -6
  146. package/src/components/image/shared.ts +110 -45
  147. package/src/components/image-background.ts +47 -10
  148. package/src/components/input-accessory-view/index.ts +41 -18
  149. package/src/components/keyboard-avoiding-view/index.ts +76 -22
  150. package/src/components/modal/index.ts +39 -12
  151. package/src/components/pressable/index.ts +121 -31
  152. package/src/components/refresh-control/index.ts +36 -13
  153. package/src/components/safe-area-view/index.ts +44 -19
  154. package/src/components/scroll-view/index.android.ts +31 -9
  155. package/src/components/scroll-view/index.ios.ts +17 -4
  156. package/src/components/scroll-view/projection.ts +290 -63
  157. package/src/components/scroll-view/shared.ts +124 -30
  158. package/src/components/scroll-view/sticky-header.ts +25 -8
  159. package/src/components/section-list/index.ts +79 -19
  160. package/src/components/switch/index.android.ts +18 -7
  161. package/src/components/switch/index.ios.ts +18 -7
  162. package/src/components/switch/shared.ts +15 -4
  163. package/src/components/text-input.ts +119 -31
  164. package/src/components/touchable/index.ts +339 -72
  165. package/src/components/touchable-native-feedback/index.ts +50 -18
  166. package/src/components/virtualized-list/directives.ts +19 -5
  167. package/src/components/virtualized-list/index.ts +292 -72
  168. package/src/components/virtualized-section-list/directives.ts +6 -3
  169. package/src/components/virtualized-section-list/index.ts +164 -34
  170. package/src/components.ts +6 -1
  171. package/src/create-portal/index.ts +47 -11
  172. package/src/create-tunnel/index.ts +3 -1
  173. package/src/descriptor-to-angular/index.ts +29 -8
  174. package/src/diagnostics.ts +138 -0
  175. package/src/gate-demand.ts +109 -0
  176. package/src/host-instance/index.ts +9 -3
  177. package/src/index.ts +33 -2
  178. package/src/modules/animated/create-animated-component.ts +67 -19
  179. package/src/modules/app-registry/index.ts +3 -1
  180. package/src/modules/status-bar/index.ts +13 -4
  181. package/src/primitives/index.ts +73 -2
  182. package/src/primitives/shared.ts +70 -9
  183. package/src/register.ts +43 -0
  184. package/src/render/index.ts +59 -7
  185. package/src/renderer/index.ts +209 -37
  186. package/src/services/color-scheme.service.ts +3 -1
  187. package/src/services/window-dimensions.service.ts +11 -4
  188. package/src/state-style.ts +39 -0
@@ -44,8 +44,16 @@ import {
44
44
  type IPressableAndroidRippleConfig,
45
45
  type IRectOffset,
46
46
  } from '@symbiote-native/components';
47
- import { dlog, isSymbioteEvent, type ISymbioteEvent } from '@symbiote-native/engine';
48
- import { anchorHostStyle, SymbioteHostPropsDirective, ViewHost } from '../../primitives';
47
+ import {
48
+ dlog,
49
+ isSymbioteEvent,
50
+ type ISymbioteEvent,
51
+ } from '@symbiote-native/engine';
52
+ import {
53
+ anchorHostStyle,
54
+ SymbioteHostPropsDirective,
55
+ ViewHost,
56
+ } from '../../primitives';
49
57
  import { Pressable, type IAngularPressableInputs } from '../pressable';
50
58
 
51
59
  export type {
@@ -58,7 +66,10 @@ export type {
58
66
  // feedback config) minus children (Angular takes children via <ng-content>) and minus the press/
59
67
  // hover events (declared as this component's OWN @Output()s below). Declared per-adapter over the
60
68
  // shared Pressable INPUT surface.
61
- export type IAngularTouchableNativeFeedbackProps = Omit<IAngularPressableInputs, 'style'> & {
69
+ export type IAngularTouchableNativeFeedbackProps = Omit<
70
+ IAngularPressableInputs,
71
+ 'style'
72
+ > & {
62
73
  background?: INativeFeedbackBackground;
63
74
  useForeground?: boolean;
64
75
  };
@@ -71,6 +82,7 @@ export type IAngularTouchableNativeFeedbackProps = Omit<IAngularPressableInputs,
71
82
  changeDetection: ChangeDetectionStrategy.OnPush,
72
83
  template: `
73
84
  <Pressable
85
+ [__minPressDuration]="0"
74
86
  (press)="press.emit($event)"
75
87
  (pressIn)="pressIn.emit($event)"
76
88
  (pressOut)="pressOut.emit($event)"
@@ -89,13 +101,7 @@ export type IAngularTouchableNativeFeedbackProps = Omit<IAngularPressableInputs,
89
101
  [android_ripple]="android_ripple"
90
102
  [android_disableSound]="android_disableSound"
91
103
  >
92
- <symbiote-view
93
- [symbioteHostProps]="hostProps()"
94
- (accessibilityAction)="emit(accessibilityAction, $event)"
95
- (accessibilityTap)="emit(accessibilityTap, $event)"
96
- (magicTap)="emit(magicTap, $event)"
97
- (accessibilityEscape)="emit(accessibilityEscape, $event)"
98
- >
104
+ <symbiote-view [symbioteHostProps]="hostProps()">
99
105
  <ng-content></ng-content>
100
106
  </symbiote-view>
101
107
  </Pressable>
@@ -107,7 +113,8 @@ export class TouchableNativeFeedback
107
113
  // The static helpers are pure config-dict producers; they live as members on the component class
108
114
  // so callers reach them as `TouchableNativeFeedback.Ripple(...)`, exactly like RN.
109
115
  static readonly SelectableBackground = selectableBackground;
110
- static readonly SelectableBackgroundBorderless = selectableBackgroundBorderless;
116
+ static readonly SelectableBackgroundBorderless =
117
+ selectableBackgroundBorderless;
111
118
  static readonly Ripple = rippleBackground;
112
119
  static readonly canUseNativeForeground = canUseNativeForeground;
113
120
 
@@ -144,8 +151,10 @@ export class TouchableNativeFeedback
144
151
  @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
145
152
  @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
146
153
  @Input() accessibilityLabelledBy?: string | string[];
147
- @Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
148
- @Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
154
+ @Input()
155
+ importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
156
+ @Input()
157
+ accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
149
158
  @Input() screenReaderFocusable?: boolean;
150
159
  @Input() accessibilityViewIsModal?: boolean;
151
160
  @Input() accessibilityElementsHidden?: boolean;
@@ -222,7 +231,10 @@ export class TouchableNativeFeedback
222
231
  // backgroundProps picks the foreground slot only where the platform supports it, else the
223
232
  // background slot (canUseNativeForeground) — shared with React/Vue. One side is always undefined.
224
233
  get feedback(): Record<string, INativeFeedbackBackground> {
225
- return backgroundProps(this.resolvedBackground, this.useForeground === true);
234
+ return backgroundProps(
235
+ this.resolvedBackground,
236
+ this.useForeground === true,
237
+ );
226
238
  }
227
239
 
228
240
  // Assembles the SAME resolved values the template used to bind one-by-one into a single
@@ -245,14 +257,29 @@ export class TouchableNativeFeedback
245
257
  nativeID: this.nativeID,
246
258
  accessible: this.accessible,
247
259
  ...this.folded,
260
+ onAccessibilityAction: this.eventEmitterHandler(this.accessibilityAction),
261
+ onAccessibilityTap: this.eventEmitterHandler(this.accessibilityTap),
262
+ onMagicTap: this.eventEmitterHandler(this.magicTap),
263
+ onAccessibilityEscape: this.eventEmitterHandler(this.accessibilityEscape),
248
264
  };
249
265
  });
250
266
 
251
267
  // Forward an engine event to the matching @Output(), narrowing the template's untyped $event.
252
- emit(emitter: EventEmitter<ISymbioteEvent>, event: unknown): void {
268
+ private emit(emitter: EventEmitter<ISymbioteEvent>, event: unknown): void {
253
269
  if (isSymbioteEvent(event)) emitter.emit(event);
254
270
  }
255
271
 
272
+ // The four accessibility events are boolean-GATED Fabric events
273
+ // (`.claude/rules/fabric-boolean-event-gates.md`): native fires them only when the committed
274
+ // payload carries a FUNCTION at that key, so a template binding here lit the gate on every
275
+ // instance whether or not an app ever subscribed. `.observed`-gated, mirroring Pressable's
276
+ // `accessibilityEmitterHandler`.
277
+ private eventEmitterHandler(
278
+ emitter: EventEmitter<ISymbioteEvent>,
279
+ ): ((event: unknown) => void) | undefined {
280
+ return emitter.observed ? event => this.emit(emitter, event) : undefined;
281
+ }
282
+
256
283
  // Fold the web aria-*/role aliases into the canonical accessibility* props once per render, so the
257
284
  // host never sees an aria-* key (native ignores them), and merge `disabled` into the a11y state
258
285
  // (resolveDisabledAccessibilityState) the same way Pressable does for its own host.
@@ -261,7 +288,10 @@ export class TouchableNativeFeedback
261
288
  accessibilityLabel: this.accessibilityLabel,
262
289
  accessibilityHint: this.accessibilityHint,
263
290
  accessibilityRole: this.accessibilityRole,
264
- accessibilityState: resolveDisabledAccessibilityState(this.accessibilityState, this.disabled),
291
+ accessibilityState: resolveDisabledAccessibilityState(
292
+ this.accessibilityState,
293
+ this.disabled,
294
+ ),
265
295
  accessibilityValue: this.accessibilityValue,
266
296
  accessibilityActions: this.accessibilityActions,
267
297
  accessibilityLabelledBy: this.accessibilityLabelledBy,
@@ -272,8 +302,10 @@ export class TouchableNativeFeedback
272
302
  accessibilityElementsHidden: this.accessibilityElementsHidden,
273
303
  accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
274
304
  accessibilityLanguage: this.accessibilityLanguage,
275
- accessibilityRespondsToUserInteraction: this.accessibilityRespondsToUserInteraction,
276
- accessibilityShowsLargeContentViewer: this.accessibilityShowsLargeContentViewer,
305
+ accessibilityRespondsToUserInteraction:
306
+ this.accessibilityRespondsToUserInteraction,
307
+ accessibilityShowsLargeContentViewer:
308
+ this.accessibilityShowsLargeContentViewer,
277
309
  accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
278
310
  role: this.role,
279
311
  'aria-label': this.ariaLabel,
@@ -36,6 +36,7 @@ import {
36
36
  type SimpleChanges,
37
37
  } from '@angular/core';
38
38
  import { dlog } from '@symbiote-native/engine';
39
+ import { countAngular } from '../../diagnostics';
39
40
  import type { ISeparators } from '@symbiote-native/components';
40
41
 
41
42
  let vListOutletInstanceCounter = 0;
@@ -68,7 +69,8 @@ function isRecord(value: unknown): value is Record<string, unknown> {
68
69
  // typed at the call site (let-item: ItemT, let-index: number, let-separators: ISeparators).
69
70
  @Directive({ selector: '[vListItem]', standalone: true })
70
71
  export class VListItemDirective<ItemT = unknown> {
71
- readonly templateRef = inject<TemplateRef<IVListItemContext<ItemT>>>(TemplateRef);
72
+ readonly templateRef =
73
+ inject<TemplateRef<IVListItemContext<ItemT>>>(TemplateRef);
72
74
 
73
75
  static ngTemplateContextGuard<T>(
74
76
  _dir: VListItemDirective<T>,
@@ -101,7 +103,8 @@ export class VListEmptyDirective {
101
103
  // types the `let-` bindings against the separator props.
102
104
  @Directive({ selector: '[vListSeparator]', standalone: true })
103
105
  export class VListSeparatorDirective<ItemT = unknown> {
104
- readonly templateRef = inject<TemplateRef<IVListSeparatorContext<ItemT>>>(TemplateRef);
106
+ readonly templateRef =
107
+ inject<TemplateRef<IVListSeparatorContext<ItemT>>>(TemplateRef);
105
108
 
106
109
  static ngTemplateContextGuard<T>(
107
110
  _dir: VListSeparatorDirective<T>,
@@ -130,20 +133,28 @@ export class VListOutletDirective<C = unknown> implements OnChanges, OnDestroy {
130
133
  `Angular VListOutlet#${this.instanceId} templateRef CHANGED (was=${changes['templateRef'].previousValue !== undefined} now=${this.templateRef !== undefined}) -> clear + recreate`,
131
134
  );
132
135
  this.viewContainer.clear();
136
+ countAngular('outletCreates');
133
137
  this.viewRef =
134
138
  this.templateRef === undefined
135
139
  ? null
136
- : this.viewContainer.createEmbeddedView(this.templateRef, this.context);
140
+ : this.viewContainer.createEmbeddedView(
141
+ this.templateRef,
142
+ this.context,
143
+ );
137
144
  return;
138
145
  }
139
146
  if (this.viewRef !== null && this.context !== undefined) {
140
- dlog(`Angular VListOutlet#${this.instanceId} context updated, markForCheck`);
147
+ countAngular('outletUpdates');
148
+ dlog(
149
+ `Angular VListOutlet#${this.instanceId} context updated, markForCheck`,
150
+ );
141
151
  this.updateContext(this.viewRef.context, this.context);
142
152
  this.viewRef.markForCheck();
143
153
  }
144
154
  }
145
155
 
146
156
  ngOnDestroy(): void {
157
+ countAngular('outletDestroys');
147
158
  dlog(`Angular VListOutlet#${this.instanceId} destroyed`);
148
159
  this.viewContainer.clear();
149
160
  }
@@ -158,7 +169,10 @@ export class VListOutletDirective<C = unknown> implements OnChanges, OnDestroy {
158
169
  }
159
170
  }
160
171
 
161
- function copyContextFields(target: Record<string, unknown>, source: Record<string, unknown>): void {
172
+ function copyContextFields(
173
+ target: Record<string, unknown>,
174
+ source: Record<string, unknown>,
175
+ ): void {
162
176
  for (const key of Object.keys(target)) {
163
177
  if (!(key in source)) delete target[key];
164
178
  }