@symbiote-native/angular 0.0.0-canary-20260724081123

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 (276) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/babel-linker.cjs +7 -0
  4. package/babel-register-composed.cjs +127 -0
  5. package/bin/symbiote-angular-dev.cjs +93 -0
  6. package/build/angular/anchor-host-registry.d.ts +2 -0
  7. package/build/angular/anchor-host-registry.js +84 -0
  8. package/build/angular/anchor-host-registry.js.map +1 -0
  9. package/build/angular/bootstrap.d.ts +7 -0
  10. package/build/angular/bootstrap.js +15 -0
  11. package/build/angular/bootstrap.js.map +1 -0
  12. package/build/angular/components/activity-indicator/index.android.d.ts +12 -0
  13. package/build/angular/components/activity-indicator/index.android.js +21 -0
  14. package/build/angular/components/activity-indicator/index.android.js.map +1 -0
  15. package/build/angular/components/activity-indicator/index.d.ts +1 -0
  16. package/build/angular/components/activity-indicator/index.ios.d.ts +8 -0
  17. package/build/angular/components/activity-indicator/index.ios.js +21 -0
  18. package/build/angular/components/activity-indicator/index.ios.js.map +1 -0
  19. package/build/angular/components/activity-indicator/index.js +4 -0
  20. package/build/angular/components/activity-indicator/index.js.map +1 -0
  21. package/build/angular/components/activity-indicator/shared.d.ts +67 -0
  22. package/build/angular/components/activity-indicator/shared.js +260 -0
  23. package/build/angular/components/activity-indicator/shared.js.map +1 -0
  24. package/build/angular/components/button.d.ts +63 -0
  25. package/build/angular/components/button.js +332 -0
  26. package/build/angular/components/button.js.map +1 -0
  27. package/build/angular/components/flat-list/index.d.ts +122 -0
  28. package/build/angular/components/flat-list/index.js +688 -0
  29. package/build/angular/components/flat-list/index.js.map +1 -0
  30. package/build/angular/components/image/index.android.d.ts +10 -0
  31. package/build/angular/components/image/index.android.js +59 -0
  32. package/build/angular/components/image/index.android.js.map +1 -0
  33. package/build/angular/components/image/index.d.ts +1 -0
  34. package/build/angular/components/image/index.ios.d.ts +10 -0
  35. package/build/angular/components/image/index.ios.js +59 -0
  36. package/build/angular/components/image/index.ios.js.map +1 -0
  37. package/build/angular/components/image/index.js +3 -0
  38. package/build/angular/components/image/index.js.map +1 -0
  39. package/build/angular/components/image/shared.d.ts +101 -0
  40. package/build/angular/components/image/shared.js +406 -0
  41. package/build/angular/components/image/shared.js.map +1 -0
  42. package/build/angular/components/image-background.d.ts +81 -0
  43. package/build/angular/components/image-background.js +418 -0
  44. package/build/angular/components/image-background.js.map +1 -0
  45. package/build/angular/components/input-accessory-view/index.d.ts +60 -0
  46. package/build/angular/components/input-accessory-view/index.js +251 -0
  47. package/build/angular/components/input-accessory-view/index.js.map +1 -0
  48. package/build/angular/components/keyboard-avoiding-view/index.d.ts +82 -0
  49. package/build/angular/components/keyboard-avoiding-view/index.js +358 -0
  50. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -0
  51. package/build/angular/components/modal/index.d.ts +92 -0
  52. package/build/angular/components/modal/index.js +360 -0
  53. package/build/angular/components/modal/index.js.map +1 -0
  54. package/build/angular/components/pressable/index.d.ts +123 -0
  55. package/build/angular/components/pressable/index.js +420 -0
  56. package/build/angular/components/pressable/index.js.map +1 -0
  57. package/build/angular/components/refresh-control/index.d.ts +86 -0
  58. package/build/angular/components/refresh-control/index.js +342 -0
  59. package/build/angular/components/refresh-control/index.js.map +1 -0
  60. package/build/angular/components/safe-area-view/index.d.ts +57 -0
  61. package/build/angular/components/safe-area-view/index.js +248 -0
  62. package/build/angular/components/safe-area-view/index.js.map +1 -0
  63. package/build/angular/components/scroll-view/index.android.d.ts +21 -0
  64. package/build/angular/components/scroll-view/index.android.js +235 -0
  65. package/build/angular/components/scroll-view/index.android.js.map +1 -0
  66. package/build/angular/components/scroll-view/index.d.ts +3 -0
  67. package/build/angular/components/scroll-view/index.ios.d.ts +9 -0
  68. package/build/angular/components/scroll-view/index.ios.js +86 -0
  69. package/build/angular/components/scroll-view/index.ios.js.map +1 -0
  70. package/build/angular/components/scroll-view/index.js +6 -0
  71. package/build/angular/components/scroll-view/index.js.map +1 -0
  72. package/build/angular/components/scroll-view/projection.d.ts +32 -0
  73. package/build/angular/components/scroll-view/projection.js +334 -0
  74. package/build/angular/components/scroll-view/projection.js.map +1 -0
  75. package/build/angular/components/scroll-view/shared.d.ts +230 -0
  76. package/build/angular/components/scroll-view/shared.js +682 -0
  77. package/build/angular/components/scroll-view/shared.js.map +1 -0
  78. package/build/angular/components/scroll-view/sticky-header.d.ts +40 -0
  79. package/build/angular/components/scroll-view/sticky-header.js +225 -0
  80. package/build/angular/components/scroll-view/sticky-header.js.map +1 -0
  81. package/build/angular/components/section-list/index.d.ts +116 -0
  82. package/build/angular/components/section-list/index.js +641 -0
  83. package/build/angular/components/section-list/index.js.map +1 -0
  84. package/build/angular/components/switch/index.android.d.ts +20 -0
  85. package/build/angular/components/switch/index.android.js +70 -0
  86. package/build/angular/components/switch/index.android.js.map +1 -0
  87. package/build/angular/components/switch/index.d.ts +1 -0
  88. package/build/angular/components/switch/index.ios.d.ts +19 -0
  89. package/build/angular/components/switch/index.ios.js +69 -0
  90. package/build/angular/components/switch/index.ios.js.map +1 -0
  91. package/build/angular/components/switch/index.js +4 -0
  92. package/build/angular/components/switch/index.js.map +1 -0
  93. package/build/angular/components/switch/shared.d.ts +40 -0
  94. package/build/angular/components/switch/shared.js +127 -0
  95. package/build/angular/components/switch/shared.js.map +1 -0
  96. package/build/angular/components/text-input.d.ts +153 -0
  97. package/build/angular/components/text-input.js +599 -0
  98. package/build/angular/components/text-input.js.map +1 -0
  99. package/build/angular/components/touchable/index.d.ts +245 -0
  100. package/build/angular/components/touchable/index.js +1186 -0
  101. package/build/angular/components/touchable/index.js.map +1 -0
  102. package/build/angular/components/touchable-native-feedback/index.d.ts +83 -0
  103. package/build/angular/components/touchable-native-feedback/index.js +371 -0
  104. package/build/angular/components/touchable-native-feedback/index.js.map +1 -0
  105. package/build/angular/components/virtualized-list/directives.d.ts +54 -0
  106. package/build/angular/components/virtualized-list/directives.js +153 -0
  107. package/build/angular/components/virtualized-list/directives.js.map +1 -0
  108. package/build/angular/components/virtualized-list/index.d.ts +253 -0
  109. package/build/angular/components/virtualized-list/index.js +1031 -0
  110. package/build/angular/components/virtualized-list/index.js.map +1 -0
  111. package/build/angular/components/virtualized-section-list/directives.d.ts +37 -0
  112. package/build/angular/components/virtualized-section-list/directives.js +76 -0
  113. package/build/angular/components/virtualized-section-list/directives.js.map +1 -0
  114. package/build/angular/components/virtualized-section-list/index.d.ts +178 -0
  115. package/build/angular/components/virtualized-section-list/index.js +720 -0
  116. package/build/angular/components/virtualized-section-list/index.js.map +1 -0
  117. package/build/angular/components.d.ts +39 -0
  118. package/build/angular/components.js +38 -0
  119. package/build/angular/components.js.map +1 -0
  120. package/build/angular/create-portal/index.d.ts +22 -0
  121. package/build/angular/create-portal/index.js +74 -0
  122. package/build/angular/create-portal/index.js.map +1 -0
  123. package/build/angular/create-tunnel/index.d.ts +34 -0
  124. package/build/angular/create-tunnel/index.js +126 -0
  125. package/build/angular/create-tunnel/index.js.map +1 -0
  126. package/build/angular/descriptor-to-angular/index.d.ts +22 -0
  127. package/build/angular/descriptor-to-angular/index.js +142 -0
  128. package/build/angular/descriptor-to-angular/index.js.map +1 -0
  129. package/build/angular/host-instance/index.d.ts +2 -0
  130. package/build/angular/host-instance/index.js +37 -0
  131. package/build/angular/host-instance/index.js.map +1 -0
  132. package/build/angular/index.d.ts +22 -0
  133. package/build/angular/index.js +46 -0
  134. package/build/angular/index.js.map +1 -0
  135. package/build/angular/modules/animated/animated-leaf-binder/index.d.ts +14 -0
  136. package/build/angular/modules/animated/animated-leaf-binder/index.js +91 -0
  137. package/build/angular/modules/animated/animated-leaf-binder/index.js.map +1 -0
  138. package/build/angular/modules/animated/animated-leaf-binder.d.ts +14 -0
  139. package/build/angular/modules/animated/animated-leaf-binder.js +91 -0
  140. package/build/angular/modules/animated/animated-leaf-binder.js.map +1 -0
  141. package/build/angular/modules/animated/create-animated-component.d.ts +59 -0
  142. package/build/angular/modules/animated/create-animated-component.js +364 -0
  143. package/build/angular/modules/animated/create-animated-component.js.map +1 -0
  144. package/build/angular/modules/animated/index.d.ts +51 -0
  145. package/build/angular/modules/animated/index.js +59 -0
  146. package/build/angular/modules/animated/index.js.map +1 -0
  147. package/build/angular/modules/app-registry/index.d.ts +7 -0
  148. package/build/angular/modules/app-registry/index.js +23 -0
  149. package/build/angular/modules/app-registry/index.js.map +1 -0
  150. package/build/angular/modules/status-bar/index.d.ts +20 -0
  151. package/build/angular/modules/status-bar/index.js +59 -0
  152. package/build/angular/modules/status-bar/index.js.map +1 -0
  153. package/build/angular/primitives/index.d.ts +63 -0
  154. package/build/angular/primitives/index.js +189 -0
  155. package/build/angular/primitives/index.js.map +1 -0
  156. package/build/angular/primitives/shared.d.ts +88 -0
  157. package/build/angular/primitives/shared.js +171 -0
  158. package/build/angular/primitives/shared.js.map +1 -0
  159. package/build/angular/render/index.d.ts +11 -0
  160. package/build/angular/render/index.js +171 -0
  161. package/build/angular/render/index.js.map +1 -0
  162. package/build/angular/renderer/index.d.ts +37 -0
  163. package/build/angular/renderer/index.js +301 -0
  164. package/build/angular/renderer/index.js.map +1 -0
  165. package/build/angular/services/color-scheme.service.d.ts +16 -0
  166. package/build/angular/services/color-scheme.service.js +31 -0
  167. package/build/angular/services/color-scheme.service.js.map +1 -0
  168. package/build/angular/services/index.d.ts +2 -0
  169. package/build/angular/services/index.js +3 -0
  170. package/build/angular/services/index.js.map +1 -0
  171. package/build/angular/services/window-dimensions.service.d.ts +16 -0
  172. package/build/angular/services/window-dimensions.service.js +42 -0
  173. package/build/angular/services/window-dimensions.service.js.map +1 -0
  174. package/metro-config.cjs +48 -0
  175. package/metro-css-parser.cjs +13 -0
  176. package/package.json +80 -0
  177. package/src/__tests__/responder-change-detection.test.ts +102 -0
  178. package/src/__tests__/responder-nested-cd.test.ts +113 -0
  179. package/src/anchor-host-registry.ts +88 -0
  180. package/src/angular-gaps.test.ts +142 -0
  181. package/src/angular-imports.test.ts +100 -0
  182. package/src/bootstrap.ts +26 -0
  183. package/src/components/activity-indicator/activity-indicator-class-style.test.ts +44 -0
  184. package/src/components/activity-indicator/activity-indicator.test.ts +131 -0
  185. package/src/components/activity-indicator/index.android.ts +16 -0
  186. package/src/components/activity-indicator/index.ios.ts +17 -0
  187. package/src/components/activity-indicator/index.ts +4 -0
  188. package/src/components/activity-indicator/shared.ts +206 -0
  189. package/src/components/button.ts +193 -0
  190. package/src/components/flat-list/column-wrapper-style-class.test.ts +116 -0
  191. package/src/components/flat-list/flat-list-array-style.test.ts +131 -0
  192. package/src/components/flat-list/flat-list-class-style.test.ts +74 -0
  193. package/src/components/flat-list/flat-list-scroll-containment.test.ts +107 -0
  194. package/src/components/flat-list/flat-list.test.ts +99 -0
  195. package/src/components/flat-list/index.ts +574 -0
  196. package/src/components/image/image-class-style.test.ts +46 -0
  197. package/src/components/image/index.android.ts +48 -0
  198. package/src/components/image/index.ios.ts +48 -0
  199. package/src/components/image/index.ts +3 -0
  200. package/src/components/image/shared.ts +479 -0
  201. package/src/components/image-background-class-style.test.ts +48 -0
  202. package/src/components/image-background-style-class.test.ts +79 -0
  203. package/src/components/image-background.ts +270 -0
  204. package/src/components/input-accessory-view/index.ts +185 -0
  205. package/src/components/input-accessory-view/input-accessory-view.test.ts +43 -0
  206. package/src/components/keyboard-avoiding-view/index.ts +303 -0
  207. package/src/components/keyboard-avoiding-view/keyboard-avoiding-view.test.ts +54 -0
  208. package/src/components/modal/index.ts +299 -0
  209. package/src/components/modal/modal.test.ts +43 -0
  210. package/src/components/pressable/index.ts +373 -0
  211. package/src/components/pressable/pressable.test.ts +85 -0
  212. package/src/components/refresh-control/index.ts +284 -0
  213. package/src/components/refresh-control/refresh-control.test.ts +41 -0
  214. package/src/components/safe-area-view/index.ts +177 -0
  215. package/src/components/safe-area-view/safe-area-view.test.ts +43 -0
  216. package/src/components/scroll-view/android-scroll-view-axis-projection.test.ts +123 -0
  217. package/src/components/scroll-view/content-container-style-class.test.ts +75 -0
  218. package/src/components/scroll-view/index.android.ts +190 -0
  219. package/src/components/scroll-view/index.ios.ts +79 -0
  220. package/src/components/scroll-view/index.ts +7 -0
  221. package/src/components/scroll-view/projection.ts +414 -0
  222. package/src/components/scroll-view/scroll-view-class-style.test.ts +134 -0
  223. package/src/components/scroll-view/scroll-view-projection.test.ts +194 -0
  224. package/src/components/scroll-view/shared.ts +844 -0
  225. package/src/components/scroll-view/sticky-header.ts +255 -0
  226. package/src/components/section-list/index.ts +445 -0
  227. package/src/components/switch/android-switch-class.test.ts +42 -0
  228. package/src/components/switch/index.android.ts +61 -0
  229. package/src/components/switch/index.ios.ts +60 -0
  230. package/src/components/switch/index.ts +4 -0
  231. package/src/components/switch/shared.ts +197 -0
  232. package/src/components/switch/switch.test.ts +92 -0
  233. package/src/components/text-input-class-style.test.ts +54 -0
  234. package/src/components/text-input.ts +531 -0
  235. package/src/components/touchable/index.ts +629 -0
  236. package/src/components/touchable/touchable.test.ts +102 -0
  237. package/src/components/touchable-native-feedback/index.ts +254 -0
  238. package/src/components/touchable-native-feedback/touchable-native-feedback.test.ts +49 -0
  239. package/src/components/virtualized-list/directives.ts +168 -0
  240. package/src/components/virtualized-list/index.ts +992 -0
  241. package/src/components/virtualized-list/virtualized-list-class-style.test.ts +76 -0
  242. package/src/components/virtualized-section-list/directives.ts +90 -0
  243. package/src/components/virtualized-section-list/index.ts +601 -0
  244. package/src/components/virtualized-section-list/virtualized-section-list-class-style.test.ts +60 -0
  245. package/src/components.ts +149 -0
  246. package/src/create-portal/create-portal.test.ts +90 -0
  247. package/src/create-portal/index.ts +74 -0
  248. package/src/create-tunnel/create-tunnel.test.ts +120 -0
  249. package/src/create-tunnel/index.ts +136 -0
  250. package/src/descriptor-to-angular/descriptor-outlet.test.ts +94 -0
  251. package/src/descriptor-to-angular/index.ts +190 -0
  252. package/src/host-instance/host-instance.test.ts +49 -0
  253. package/src/host-instance/index.ts +36 -0
  254. package/src/index.ts +261 -0
  255. package/src/modules/animated/animated-leaf-binder/animated-leaf-binder.test.ts +116 -0
  256. package/src/modules/animated/animated-leaf-binder/index.ts +101 -0
  257. package/src/modules/animated/animated-leaf-binder.test.ts +116 -0
  258. package/src/modules/animated/animated-leaf-binder.ts +101 -0
  259. package/src/modules/animated/animated-scroll-view.test.ts +102 -0
  260. package/src/modules/animated/create-animated-component.ts +365 -0
  261. package/src/modules/animated/index.ts +105 -0
  262. package/src/modules/app-registry/app-registry.test.ts +106 -0
  263. package/src/modules/app-registry/index.ts +60 -0
  264. package/src/modules/status-bar/index.ts +57 -0
  265. package/src/modules/status-bar/status-bar.test.ts +50 -0
  266. package/src/primitives/index.ts +119 -0
  267. package/src/primitives/shared.ts +190 -0
  268. package/src/render/index.ts +235 -0
  269. package/src/render/render.test.ts +147 -0
  270. package/src/renderer/index.ts +347 -0
  271. package/src/renderer/renderer.test.ts +203 -0
  272. package/src/services/color-scheme.service.ts +27 -0
  273. package/src/services/index.ts +2 -0
  274. package/src/services/services.test.ts +163 -0
  275. package/src/services/window-dimensions.service.ts +41 -0
  276. package/tsconfig.angular.base.json +30 -0
@@ -0,0 +1,629 @@
1
+ // The Touchable* family for Angular, all built on Pressable (the Angular twin of the React/Vue
2
+ // adapter). The press-timing constants and the deactivation-floor math are shared with every
3
+ // adapter (@symbiote-native/components/state/touchable); here Angular owns only the Animated wiring + the
4
+ // press scheduling state:
5
+ // TouchableOpacity: animate an Animated.Value opacity toward activeOpacity on press-in and back
6
+ // to 1 on press-out, driven from Pressable's onPressIn/onPressOut. The opacity Value is held by
7
+ // IDENTITY as a plain field (an engine object, never an @Input / reactive wrap) and the
8
+ // <symbiote-animated-view> leaf commits it every frame.
9
+ // TouchableHighlight: paint underlayColor + lower child opacity while pressed, via Pressable's
10
+ // style-as-function (Pressable drives the pressed flag through its own responder lifecycle).
11
+ // TouchableWithoutFeedback: no visual change, just the press wiring forwarded through Pressable.
12
+ //
13
+ // Every Touchable's own press/hover/accessibility events are now real @Output() EventEmitters too,
14
+ // matching Pressable (which they wrap) — `(press)="handler($event)"`, never `[onPress]="handler"`.
15
+ // Non-event config (delayLongPress, hitSlop, ...) still rides down as plain @Input() bindings.
16
+ // Accessibility EVENTS forward straight through to Pressable's own outputs
17
+ // (`(accessibilityAction)="accessibilityAction.emit($event)"`); accessibility STATE folds the web
18
+ // aria-*/role aliases and merges `disabled` into the a11y state on Pressable's own host — no re-fold
19
+ // here (the a11y host is Pressable's view, mirroring React's `...rest` -> Pressable). No JS-side
20
+ // platform branch, so this stays a flat single file, mirroring React/Vue. Each Touchable
21
+ // forwards the Angular Pressable surface verbatim; parity is against that surface, exactly as
22
+ // React's Touchable parity is against
23
+ // the React Pressable surface.
24
+
25
+ import {
26
+ CUSTOM_ELEMENTS_SCHEMA,
27
+ ChangeDetectionStrategy,
28
+ Component,
29
+ ElementRef,
30
+ EventEmitter,
31
+ inject,
32
+ Input,
33
+ Output,
34
+ } from '@angular/core';
35
+ import {
36
+ createTouchableFeedbackHandlers,
37
+ createTouchableFeedbackRuntime,
38
+ highlightPressedStyle,
39
+ DEFAULT_ACTIVE_OPACITY,
40
+ DEFAULT_HIGHLIGHT_CHILD_OPACITY,
41
+ DEFAULT_MIN_PRESS_DURATION_MS,
42
+ DEFAULT_UNDERLAY_COLOR,
43
+ OPACITY_ACTIVE_DURATION_MS,
44
+ OPACITY_INACTIVE_DURATION_MS,
45
+ RESTING_OPACITY,
46
+ type IAccessibilityProps,
47
+ type IAccessibilityStateValue,
48
+ type IAriaProps,
49
+ type IPressableAndroidRippleConfig,
50
+ type IPressState,
51
+ type IPressTimingProps,
52
+ type IRectOffset,
53
+ type ITouchableFeedbackHandlers,
54
+ } from '@symbiote-native/components';
55
+ import { type ISymbioteEvent, type IStyleProp, type IViewStyle } from '@symbiote-native/engine';
56
+ import { anchorHostStyle, anchorStyleProp } from '../../primitives';
57
+ import { Pressable, type IAngularPressableInputs } from '../pressable';
58
+ import { Animated, AnimatedView } from '../../modules/animated';
59
+
60
+ // The shared field base for all three: the Pressable INPUT surface (minus style, which each
61
+ // Touchable routes differently, and minus the press/hover events, which each Touchable declares as
62
+ // its OWN @Output()s below) + RN's press-timing config + the public style. Mirrors React/Vue's
63
+ // ITouchableBaseProps. Declared per-adapter over the Angular Pressable surface, since children
64
+ // ride <ng-content> here rather than a field, unlike React/Vue's element-returning props.
65
+ type IAngularTouchableBaseProps = Omit<IAngularPressableInputs, 'style'> &
66
+ IPressTimingProps & {
67
+ style?: IStyleProp<IViewStyle>;
68
+ };
69
+
70
+ export type IAngularTouchableOpacityProps = IAngularTouchableBaseProps & {
71
+ activeOpacity?: number;
72
+ };
73
+
74
+ export type IAngularTouchableHighlightProps = IAngularTouchableBaseProps & {
75
+ activeOpacity?: number;
76
+ underlayColor?: string;
77
+ };
78
+
79
+ export type IAngularTouchableWithoutFeedbackProps = IAngularTouchableBaseProps;
80
+
81
+ // The real setTimeout the shared feedback machine schedules its deferred activation/deactivation on
82
+ // (core/components has no timer globals). Returns a canceller so an early release flushes the timer.
83
+ function scheduleTimeout(callback: () => void, ms: number): () => void {
84
+ const id = setTimeout(callback, ms);
85
+ return () => clearTimeout(id);
86
+ }
87
+
88
+ @Component({
89
+ selector: 'TouchableOpacity',
90
+ standalone: true,
91
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
92
+ imports: [Pressable, AnimatedView],
93
+ changeDetection: ChangeDetectionStrategy.OnPush,
94
+ template: `
95
+ <Pressable
96
+ (press)="press.emit($event)"
97
+ (pressIn)="handlePressIn($event)"
98
+ (pressOut)="handlePressOut($event)"
99
+ (pressMove)="pressMove.emit($event)"
100
+ (longPress)="longPress.emit($event)"
101
+ (hoverIn)="hoverIn.emit($event)"
102
+ (hoverOut)="hoverOut.emit($event)"
103
+ [delayLongPress]="delayLongPress"
104
+ [delayHoverIn]="delayHoverIn"
105
+ [delayHoverOut]="delayHoverOut"
106
+ [disabled]="disabled"
107
+ [cancelable]="cancelable"
108
+ [hitSlop]="hitSlop"
109
+ [pressRetentionOffset]="pressRetentionOffset"
110
+ [unstable_pressDelay]="unstable_pressDelay"
111
+ [android_ripple]="android_ripple"
112
+ [android_disableSound]="android_disableSound"
113
+ [testID]="testID"
114
+ [nativeID]="nativeID"
115
+ [hasTVPreferredFocus]="hasTVPreferredFocus"
116
+ [nextFocusDown]="nextFocusDown"
117
+ [nextFocusForward]="nextFocusForward"
118
+ [nextFocusLeft]="nextFocusLeft"
119
+ [nextFocusRight]="nextFocusRight"
120
+ [nextFocusUp]="nextFocusUp"
121
+ [accessible]="accessible"
122
+ [accessibilityLabel]="accessibilityLabel"
123
+ [accessibilityHint]="accessibilityHint"
124
+ [accessibilityRole]="accessibilityRole"
125
+ [accessibilityState]="accessibilityState"
126
+ [accessibilityValue]="accessibilityValue"
127
+ [accessibilityActions]="accessibilityActions"
128
+ [accessibilityLabelledBy]="accessibilityLabelledBy"
129
+ [importantForAccessibility]="importantForAccessibility"
130
+ [accessibilityLiveRegion]="accessibilityLiveRegion"
131
+ [screenReaderFocusable]="screenReaderFocusable"
132
+ [accessibilityViewIsModal]="accessibilityViewIsModal"
133
+ [accessibilityElementsHidden]="accessibilityElementsHidden"
134
+ [accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
135
+ [accessibilityLanguage]="accessibilityLanguage"
136
+ [accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
137
+ [accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
138
+ [accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
139
+ (accessibilityAction)="accessibilityAction.emit($event)"
140
+ (accessibilityTap)="accessibilityTap.emit($event)"
141
+ (magicTap)="magicTap.emit($event)"
142
+ (accessibilityEscape)="accessibilityEscape.emit($event)"
143
+ [ariaLabel]="ariaLabel"
144
+ [ariaBusy]="ariaBusy"
145
+ [ariaChecked]="ariaChecked"
146
+ [ariaDisabled]="ariaDisabled"
147
+ [ariaExpanded]="ariaExpanded"
148
+ [ariaHidden]="ariaHidden"
149
+ [ariaLabelledBy]="ariaLabelledBy"
150
+ [ariaLive]="ariaLive"
151
+ [ariaSelected]="ariaSelected"
152
+ [ariaModal]="ariaModal"
153
+ [ariaValueMax]="ariaValueMax"
154
+ [ariaValueMin]="ariaValueMin"
155
+ [ariaValueNow]="ariaValueNow"
156
+ [ariaValueText]="ariaValueText"
157
+ [id]="id"
158
+ [role]="role"
159
+ >
160
+ <symbiote-animated-view [style]="animatedStyle">
161
+ <ng-content></ng-content>
162
+ </symbiote-animated-view>
163
+ </Pressable>
164
+ `,
165
+ })
166
+ export class TouchableOpacity implements IAngularTouchableOpacityProps {
167
+ @Output() readonly press = new EventEmitter<ISymbioteEvent>();
168
+ @Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
169
+ @Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
170
+ @Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
171
+ @Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
172
+ @Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
173
+ @Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
174
+ @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
175
+ @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
176
+ @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
177
+ @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
178
+ @Input() activeOpacity?: number;
179
+ @Input() delayPressIn?: number;
180
+ @Input() delayPressOut?: number;
181
+ @Input() minPressDuration?: number;
182
+ @Input() style?: IStyleProp<IViewStyle>;
183
+ @Input() delayLongPress?: number;
184
+ @Input() delayHoverIn?: number;
185
+ @Input() delayHoverOut?: number;
186
+ @Input() disabled?: boolean;
187
+ @Input() cancelable?: boolean;
188
+ @Input() hitSlop?: IRectOffset;
189
+ @Input() pressRetentionOffset?: IRectOffset;
190
+ @Input() unstable_pressDelay?: number;
191
+ @Input() android_ripple?: IPressableAndroidRippleConfig;
192
+ @Input() android_disableSound?: boolean;
193
+ @Input() testID?: string;
194
+ @Input() nativeID?: string;
195
+ @Input() hasTVPreferredFocus?: boolean;
196
+ @Input() nextFocusDown?: number;
197
+ @Input() nextFocusForward?: number;
198
+ @Input() nextFocusLeft?: number;
199
+ @Input() nextFocusRight?: number;
200
+ @Input() nextFocusUp?: number;
201
+ @Input() accessible?: boolean;
202
+ @Input() accessibilityLabel?: string;
203
+ @Input() accessibilityHint?: string;
204
+ @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
205
+ @Input() accessibilityState?: IAccessibilityStateValue;
206
+ @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
207
+ @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
208
+ @Input() accessibilityLabelledBy?: string | string[];
209
+ @Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
210
+ @Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
211
+ @Input() screenReaderFocusable?: boolean;
212
+ @Input() accessibilityViewIsModal?: boolean;
213
+ @Input() accessibilityElementsHidden?: boolean;
214
+ @Input() accessibilityIgnoresInvertColors?: boolean;
215
+ @Input() accessibilityLanguage?: string;
216
+ @Input() accessibilityRespondsToUserInteraction?: boolean;
217
+ @Input() accessibilityShowsLargeContentViewer?: boolean;
218
+ @Input() accessibilityLargeContentTitle?: string;
219
+ @Input() ariaLabel?: string;
220
+ @Input() ariaBusy?: boolean;
221
+ @Input() ariaChecked?: boolean | 'mixed';
222
+ @Input() ariaDisabled?: boolean;
223
+ @Input() ariaExpanded?: boolean;
224
+ @Input() ariaHidden?: boolean;
225
+ @Input() ariaLabelledBy?: string;
226
+ @Input() ariaLive?: IAriaProps['aria-live'];
227
+ @Input() ariaSelected?: boolean;
228
+ @Input() ariaModal?: boolean;
229
+ @Input() ariaValueMax?: number;
230
+ @Input() ariaValueMin?: number;
231
+ @Input() ariaValueNow?: number;
232
+ @Input() ariaValueText?: string;
233
+ @Input() id?: string;
234
+ @Input() role?: IAriaProps['role'];
235
+
236
+ // One Animated.Value per mount, resting at full opacity. Held by IDENTITY as a plain field (an
237
+ // engine object, never an @Input / reactive wrap); the <symbiote-animated-view> leaf rasterizes
238
+ // it for the first paint and drives it through setNativeProps every frame.
239
+ private readonly opacity = new Animated.Value(RESTING_OPACITY);
240
+ // The shared press-scheduling cell (delayPressIn timer + activation clock), persisted on the
241
+ // instance; the machine's handlers are rebuilt per event over live @Input()s.
242
+ private readonly runtime = createTouchableFeedbackRuntime();
243
+ // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
244
+ // onto (see anchorHostStyle's doc comment) — NOT the <symbiote-animated-view> leaf one level down.
245
+ private readonly elementRef = inject(ElementRef);
246
+
247
+ // The (possibly animated) style the leaf reduces: the anchor's class-derived style first, then
248
+ // the user's explicit style, then the live opacity layered on top (last wins via the style array
249
+ // the commit layer flattens). `unknown` because the array mixes a plain style with an
250
+ // AnimatedNode, exactly the bag AnimatedView's `style` input accepts.
251
+ get animatedStyle(): unknown {
252
+ return [anchorHostStyle(this.elementRef), this.style, { opacity: this.opacity }];
253
+ }
254
+
255
+ private setOpacityTo(toValue: number, duration: number): void {
256
+ Animated.timing(this.opacity, {
257
+ toValue,
258
+ duration,
259
+ easing: Animated.Easing.inOut(Animated.Easing.quad),
260
+ useNativeDriver: false,
261
+ }).start();
262
+ }
263
+
264
+ // Built per event so the machine reads live @Input()s (delay/opacity); the runtime persists across
265
+ // calls. The shared machine owns the scheduling — the adapter supplies only the native seam: the
266
+ // Animated opacity fade + the @Output() emit, as activate/deactivate.
267
+ private feedbackHandlers(): ITouchableFeedbackHandlers {
268
+ return createTouchableFeedbackHandlers(
269
+ {
270
+ delayPressIn: this.delayPressIn ?? 0,
271
+ delayPressOut: this.delayPressOut ?? 0,
272
+ minPressDuration: this.minPressDuration ?? DEFAULT_MIN_PRESS_DURATION_MS,
273
+ schedule: scheduleTimeout,
274
+ now: Date.now,
275
+ },
276
+ this.runtime,
277
+ {
278
+ activate: (event: ISymbioteEvent): void => {
279
+ this.setOpacityTo(
280
+ this.activeOpacity ?? DEFAULT_ACTIVE_OPACITY,
281
+ OPACITY_ACTIVE_DURATION_MS,
282
+ );
283
+ this.pressIn.emit(event);
284
+ },
285
+ deactivate: (event: ISymbioteEvent): void => {
286
+ this.setOpacityTo(RESTING_OPACITY, OPACITY_INACTIVE_DURATION_MS);
287
+ this.pressOut.emit(event);
288
+ },
289
+ },
290
+ );
291
+ }
292
+
293
+ // Arrow fields (stable identity for OnPush, `this` intact when Pressable's `(pressIn)` invokes
294
+ // them). The delayPressIn defer + minPressDuration/delayPressOut hold live in the shared machine.
295
+ handlePressIn = (event: ISymbioteEvent): void => {
296
+ this.feedbackHandlers().handlePressIn(event);
297
+ };
298
+
299
+ handlePressOut = (event: ISymbioteEvent): void => {
300
+ this.feedbackHandlers().handlePressOut(event);
301
+ };
302
+ }
303
+
304
+ @Component({
305
+ selector: 'TouchableHighlight',
306
+ standalone: true,
307
+ imports: [Pressable],
308
+ changeDetection: ChangeDetectionStrategy.OnPush,
309
+ template: `
310
+ <Pressable
311
+ [style]="pressedStyle"
312
+ (press)="press.emit($event)"
313
+ (pressIn)="pressIn.emit($event)"
314
+ (pressOut)="pressOut.emit($event)"
315
+ (pressMove)="pressMove.emit($event)"
316
+ (longPress)="longPress.emit($event)"
317
+ (hoverIn)="hoverIn.emit($event)"
318
+ (hoverOut)="hoverOut.emit($event)"
319
+ [delayLongPress]="delayLongPress"
320
+ [delayHoverIn]="delayHoverIn"
321
+ [delayHoverOut]="delayHoverOut"
322
+ [disabled]="disabled"
323
+ [cancelable]="cancelable"
324
+ [hitSlop]="hitSlop"
325
+ [pressRetentionOffset]="pressRetentionOffset"
326
+ [unstable_pressDelay]="unstable_pressDelay"
327
+ [android_ripple]="android_ripple"
328
+ [android_disableSound]="android_disableSound"
329
+ [testID]="testID"
330
+ [nativeID]="nativeID"
331
+ [hasTVPreferredFocus]="hasTVPreferredFocus"
332
+ [nextFocusDown]="nextFocusDown"
333
+ [nextFocusForward]="nextFocusForward"
334
+ [nextFocusLeft]="nextFocusLeft"
335
+ [nextFocusRight]="nextFocusRight"
336
+ [nextFocusUp]="nextFocusUp"
337
+ [accessible]="accessible"
338
+ [accessibilityLabel]="accessibilityLabel"
339
+ [accessibilityHint]="accessibilityHint"
340
+ [accessibilityRole]="accessibilityRole"
341
+ [accessibilityState]="accessibilityState"
342
+ [accessibilityValue]="accessibilityValue"
343
+ [accessibilityActions]="accessibilityActions"
344
+ [accessibilityLabelledBy]="accessibilityLabelledBy"
345
+ [importantForAccessibility]="importantForAccessibility"
346
+ [accessibilityLiveRegion]="accessibilityLiveRegion"
347
+ [screenReaderFocusable]="screenReaderFocusable"
348
+ [accessibilityViewIsModal]="accessibilityViewIsModal"
349
+ [accessibilityElementsHidden]="accessibilityElementsHidden"
350
+ [accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
351
+ [accessibilityLanguage]="accessibilityLanguage"
352
+ [accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
353
+ [accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
354
+ [accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
355
+ (accessibilityAction)="accessibilityAction.emit($event)"
356
+ (accessibilityTap)="accessibilityTap.emit($event)"
357
+ (magicTap)="magicTap.emit($event)"
358
+ (accessibilityEscape)="accessibilityEscape.emit($event)"
359
+ [ariaLabel]="ariaLabel"
360
+ [ariaBusy]="ariaBusy"
361
+ [ariaChecked]="ariaChecked"
362
+ [ariaDisabled]="ariaDisabled"
363
+ [ariaExpanded]="ariaExpanded"
364
+ [ariaHidden]="ariaHidden"
365
+ [ariaLabelledBy]="ariaLabelledBy"
366
+ [ariaLive]="ariaLive"
367
+ [ariaSelected]="ariaSelected"
368
+ [ariaModal]="ariaModal"
369
+ [ariaValueMax]="ariaValueMax"
370
+ [ariaValueMin]="ariaValueMin"
371
+ [ariaValueNow]="ariaValueNow"
372
+ [ariaValueText]="ariaValueText"
373
+ [id]="id"
374
+ [role]="role"
375
+ >
376
+ <ng-content></ng-content>
377
+ </Pressable>
378
+ `,
379
+ })
380
+ export class TouchableHighlight implements IAngularTouchableHighlightProps {
381
+ @Output() readonly press = new EventEmitter<ISymbioteEvent>();
382
+ @Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
383
+ @Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
384
+ @Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
385
+ @Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
386
+ @Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
387
+ @Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
388
+ @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
389
+ @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
390
+ @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
391
+ @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
392
+ @Input() activeOpacity?: number;
393
+ @Input() underlayColor?: string;
394
+ @Input() delayPressIn?: number;
395
+ @Input() delayPressOut?: number;
396
+ @Input() minPressDuration?: number;
397
+ @Input() style?: IStyleProp<IViewStyle>;
398
+ @Input() delayLongPress?: number;
399
+ @Input() delayHoverIn?: number;
400
+ @Input() delayHoverOut?: number;
401
+ @Input() disabled?: boolean;
402
+ @Input() cancelable?: boolean;
403
+ @Input() hitSlop?: IRectOffset;
404
+ @Input() pressRetentionOffset?: IRectOffset;
405
+ @Input() unstable_pressDelay?: number;
406
+ @Input() android_ripple?: IPressableAndroidRippleConfig;
407
+ @Input() android_disableSound?: boolean;
408
+ @Input() testID?: string;
409
+ @Input() nativeID?: string;
410
+ @Input() hasTVPreferredFocus?: boolean;
411
+ @Input() nextFocusDown?: number;
412
+ @Input() nextFocusForward?: number;
413
+ @Input() nextFocusLeft?: number;
414
+ @Input() nextFocusRight?: number;
415
+ @Input() nextFocusUp?: number;
416
+ @Input() accessible?: boolean;
417
+ @Input() accessibilityLabel?: string;
418
+ @Input() accessibilityHint?: string;
419
+ @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
420
+ @Input() accessibilityState?: IAccessibilityStateValue;
421
+ @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
422
+ @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
423
+ @Input() accessibilityLabelledBy?: string | string[];
424
+ @Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
425
+ @Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
426
+ @Input() screenReaderFocusable?: boolean;
427
+ @Input() accessibilityViewIsModal?: boolean;
428
+ @Input() accessibilityElementsHidden?: boolean;
429
+ @Input() accessibilityIgnoresInvertColors?: boolean;
430
+ @Input() accessibilityLanguage?: string;
431
+ @Input() accessibilityRespondsToUserInteraction?: boolean;
432
+ @Input() accessibilityShowsLargeContentViewer?: boolean;
433
+ @Input() accessibilityLargeContentTitle?: string;
434
+ @Input() ariaLabel?: string;
435
+ @Input() ariaBusy?: boolean;
436
+ @Input() ariaChecked?: boolean | 'mixed';
437
+ @Input() ariaDisabled?: boolean;
438
+ @Input() ariaExpanded?: boolean;
439
+ @Input() ariaHidden?: boolean;
440
+ @Input() ariaLabelledBy?: string;
441
+ @Input() ariaLive?: IAriaProps['aria-live'];
442
+ @Input() ariaSelected?: boolean;
443
+ @Input() ariaModal?: boolean;
444
+ @Input() ariaValueMax?: number;
445
+ @Input() ariaValueMin?: number;
446
+ @Input() ariaValueNow?: number;
447
+ @Input() ariaValueText?: string;
448
+ @Input() id?: string;
449
+ @Input() role?: IAriaProps['role'];
450
+
451
+ // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
452
+ // onto (see anchorHostStyle's doc comment) — NOT the Pressable one level down.
453
+ private readonly elementRef = inject(ElementRef);
454
+
455
+ // Pressable accepts a style-as-function and calls it with the live pressed state. Arrow field so
456
+ // `this` stays bound when Pressable invokes it; it reads the inputs LIVE at call time. The
457
+ // anchor's class-derived style goes first, then the user's explicit style, so an explicit
458
+ // [style] still beats the ambient class. When pressed, paint the underlay color + lower the
459
+ // child opacity (RN drives this with setState, not Animated, so we mirror that faithfully
460
+ // through Pressable's pressed flag, no tween) — the overlay always goes last so it wins.
461
+ pressedStyle = (state: IPressState): IStyleProp<IViewStyle> => {
462
+ const base: IStyleProp<IViewStyle> = [anchorStyleProp<IViewStyle>(this.elementRef), this.style];
463
+ return highlightPressedStyle(
464
+ state.pressed,
465
+ base,
466
+ this.underlayColor ?? DEFAULT_UNDERLAY_COLOR,
467
+ this.activeOpacity ?? DEFAULT_HIGHLIGHT_CHILD_OPACITY,
468
+ );
469
+ };
470
+ }
471
+
472
+ @Component({
473
+ selector: 'TouchableWithoutFeedback',
474
+ standalone: true,
475
+ imports: [Pressable],
476
+ changeDetection: ChangeDetectionStrategy.OnPush,
477
+ template: `
478
+ <Pressable
479
+ [style]="mergedStyle"
480
+ (press)="press.emit($event)"
481
+ (pressIn)="pressIn.emit($event)"
482
+ (pressOut)="pressOut.emit($event)"
483
+ (pressMove)="pressMove.emit($event)"
484
+ (longPress)="longPress.emit($event)"
485
+ (hoverIn)="hoverIn.emit($event)"
486
+ (hoverOut)="hoverOut.emit($event)"
487
+ [delayLongPress]="delayLongPress"
488
+ [delayHoverIn]="delayHoverIn"
489
+ [delayHoverOut]="delayHoverOut"
490
+ [disabled]="disabled"
491
+ [cancelable]="cancelable"
492
+ [hitSlop]="hitSlop"
493
+ [pressRetentionOffset]="pressRetentionOffset"
494
+ [unstable_pressDelay]="unstable_pressDelay"
495
+ [android_ripple]="android_ripple"
496
+ [android_disableSound]="android_disableSound"
497
+ [testID]="testID"
498
+ [nativeID]="nativeID"
499
+ [hasTVPreferredFocus]="hasTVPreferredFocus"
500
+ [nextFocusDown]="nextFocusDown"
501
+ [nextFocusForward]="nextFocusForward"
502
+ [nextFocusLeft]="nextFocusLeft"
503
+ [nextFocusRight]="nextFocusRight"
504
+ [nextFocusUp]="nextFocusUp"
505
+ [accessible]="accessible"
506
+ [accessibilityLabel]="accessibilityLabel"
507
+ [accessibilityHint]="accessibilityHint"
508
+ [accessibilityRole]="accessibilityRole"
509
+ [accessibilityState]="accessibilityState"
510
+ [accessibilityValue]="accessibilityValue"
511
+ [accessibilityActions]="accessibilityActions"
512
+ [accessibilityLabelledBy]="accessibilityLabelledBy"
513
+ [importantForAccessibility]="importantForAccessibility"
514
+ [accessibilityLiveRegion]="accessibilityLiveRegion"
515
+ [screenReaderFocusable]="screenReaderFocusable"
516
+ [accessibilityViewIsModal]="accessibilityViewIsModal"
517
+ [accessibilityElementsHidden]="accessibilityElementsHidden"
518
+ [accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
519
+ [accessibilityLanguage]="accessibilityLanguage"
520
+ [accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
521
+ [accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
522
+ [accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
523
+ (accessibilityAction)="accessibilityAction.emit($event)"
524
+ (accessibilityTap)="accessibilityTap.emit($event)"
525
+ (magicTap)="magicTap.emit($event)"
526
+ (accessibilityEscape)="accessibilityEscape.emit($event)"
527
+ [ariaLabel]="ariaLabel"
528
+ [ariaBusy]="ariaBusy"
529
+ [ariaChecked]="ariaChecked"
530
+ [ariaDisabled]="ariaDisabled"
531
+ [ariaExpanded]="ariaExpanded"
532
+ [ariaHidden]="ariaHidden"
533
+ [ariaLabelledBy]="ariaLabelledBy"
534
+ [ariaLive]="ariaLive"
535
+ [ariaSelected]="ariaSelected"
536
+ [ariaModal]="ariaModal"
537
+ [ariaValueMax]="ariaValueMax"
538
+ [ariaValueMin]="ariaValueMin"
539
+ [ariaValueNow]="ariaValueNow"
540
+ [ariaValueText]="ariaValueText"
541
+ [id]="id"
542
+ [role]="role"
543
+ >
544
+ <ng-content></ng-content>
545
+ </Pressable>
546
+ `,
547
+ })
548
+ export class TouchableWithoutFeedback implements IAngularTouchableWithoutFeedbackProps {
549
+ // delayPressIn/delayPressOut/minPressDuration ride the prop type for surface parity with the
550
+ // other two, but TouchableWithoutFeedback has no visual feedback, so nothing schedules off them
551
+ // (RN's TouchableWithoutFeedback is the same pure passthrough).
552
+ @Output() readonly press = new EventEmitter<ISymbioteEvent>();
553
+ @Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
554
+ @Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
555
+ @Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
556
+ @Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
557
+ @Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
558
+ @Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
559
+ @Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
560
+ @Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
561
+ @Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
562
+ @Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
563
+ @Input() delayPressIn?: number;
564
+ @Input() delayPressOut?: number;
565
+ @Input() minPressDuration?: number;
566
+ @Input() style?: IStyleProp<IViewStyle>;
567
+ @Input() delayLongPress?: number;
568
+ @Input() delayHoverIn?: number;
569
+ @Input() delayHoverOut?: number;
570
+ @Input() disabled?: boolean;
571
+ @Input() cancelable?: boolean;
572
+ @Input() hitSlop?: IRectOffset;
573
+ @Input() pressRetentionOffset?: IRectOffset;
574
+ @Input() unstable_pressDelay?: number;
575
+ @Input() android_ripple?: IPressableAndroidRippleConfig;
576
+ @Input() android_disableSound?: boolean;
577
+ @Input() testID?: string;
578
+ @Input() nativeID?: string;
579
+ @Input() hasTVPreferredFocus?: boolean;
580
+ @Input() nextFocusDown?: number;
581
+ @Input() nextFocusForward?: number;
582
+ @Input() nextFocusLeft?: number;
583
+ @Input() nextFocusRight?: number;
584
+ @Input() nextFocusUp?: number;
585
+ @Input() accessible?: boolean;
586
+ @Input() accessibilityLabel?: string;
587
+ @Input() accessibilityHint?: string;
588
+ @Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
589
+ @Input() accessibilityState?: IAccessibilityStateValue;
590
+ @Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
591
+ @Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
592
+ @Input() accessibilityLabelledBy?: string | string[];
593
+ @Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
594
+ @Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
595
+ @Input() screenReaderFocusable?: boolean;
596
+ @Input() accessibilityViewIsModal?: boolean;
597
+ @Input() accessibilityElementsHidden?: boolean;
598
+ @Input() accessibilityIgnoresInvertColors?: boolean;
599
+ @Input() accessibilityLanguage?: string;
600
+ @Input() accessibilityRespondsToUserInteraction?: boolean;
601
+ @Input() accessibilityShowsLargeContentViewer?: boolean;
602
+ @Input() accessibilityLargeContentTitle?: string;
603
+ @Input() ariaLabel?: string;
604
+ @Input() ariaBusy?: boolean;
605
+ @Input() ariaChecked?: boolean | 'mixed';
606
+ @Input() ariaDisabled?: boolean;
607
+ @Input() ariaExpanded?: boolean;
608
+ @Input() ariaHidden?: boolean;
609
+ @Input() ariaLabelledBy?: string;
610
+ @Input() ariaLive?: IAriaProps['aria-live'];
611
+ @Input() ariaSelected?: boolean;
612
+ @Input() ariaModal?: boolean;
613
+ @Input() ariaValueMax?: number;
614
+ @Input() ariaValueMin?: number;
615
+ @Input() ariaValueNow?: number;
616
+ @Input() ariaValueText?: string;
617
+ @Input() id?: string;
618
+ @Input() role?: IAriaProps['role'];
619
+
620
+ // This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
621
+ // onto (see anchorHostStyle's doc comment) — NOT the Pressable one level down.
622
+ private readonly elementRef = inject(ElementRef);
623
+
624
+ // The anchor's class-derived style goes first, then the explicit style, so an explicit [style]
625
+ // still beats the ambient class.
626
+ get mergedStyle(): IStyleProp<IViewStyle> {
627
+ return [anchorStyleProp<IViewStyle>(this.elementRef), this.style];
628
+ }
629
+ }