react-native-a11y-order 0.9.1 → 0.11.0-rc1

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 (305) hide show
  1. package/README.md +55 -334
  2. package/android/src/main/java/com/a11yorder/A11yOrderPackage.java +2 -6
  3. package/android/src/main/java/com/a11yorder/core/A11yManagedFocusView.java +29 -0
  4. package/android/src/main/java/com/a11yorder/{views/A11yView/A11yView.java → core/A11yScreenReaderView.java} +3 -45
  5. package/android/src/main/java/com/a11yorder/core/A11yViewOrder.java +37 -0
  6. package/android/src/main/java/com/a11yorder/modules/A11yAnnounceModule.java +20 -7
  7. package/android/src/main/java/com/a11yorder/views/A11yCardView/A11yCardViewManager.java +18 -0
  8. package/android/src/main/java/com/a11yorder/views/A11yIndexView/A11yIndexView.java +2 -65
  9. package/android/src/main/java/com/a11yorder/views/A11yIndexView/A11yIndexViewManager.java +21 -0
  10. package/android/src/newarch/A11yCardViewManagerSpec.java +9 -0
  11. package/android/src/oldarch/A11yAnnounceModuleSpec.java +8 -1
  12. package/android/src/oldarch/A11yCardViewManagerSpec.java +8 -0
  13. package/android/src/oldarch/A11yIndexViewManagerSpec.java +8 -0
  14. package/ios/helpers/RNAOFabricEventHelper/RNAOFabricEventHelper.mm +5 -5
  15. package/ios/helpers/RNAOSpeechAttributes.h +35 -0
  16. package/ios/helpers/RNAOSpeechAttributes.mm +64 -0
  17. package/ios/modules/RNAOA11yAnnounceModule.h +13 -9
  18. package/ios/modules/RNAOA11yAnnounceModule.mm +220 -14
  19. package/ios/services/RNAOA11yAnnounceService/RNAOA11yAnnounceService.h +11 -1
  20. package/ios/services/RNAOA11yAnnounceService/RNAOA11yAnnounceService.mm +55 -51
  21. package/ios/views/RNAOA11yCardView/RNAOA11yCardView.h +29 -0
  22. package/ios/views/RNAOA11yCardView/RNAOA11yCardView.mm +83 -0
  23. package/ios/views/RNAOA11yCardView/RNAOA11yCardViewManager.h +14 -0
  24. package/ios/views/RNAOA11yCardView/RNAOA11yCardViewManager.mm +17 -0
  25. package/ios/views/RNAOA11yIndexView/RNAOA11yIndexView.h +2 -41
  26. package/ios/views/RNAOA11yIndexView/RNAOA11yIndexView.mm +24 -128
  27. package/ios/views/RNAOA11yIndexView/RNAOA11yIndexViewManager.mm +15 -0
  28. package/ios/views/RNAOA11yPaneTitleView/RNAOA11yPaneTitleView.mm +12 -2
  29. package/ios/views/base/RNAOA11yGroupChildrenView.h +21 -0
  30. package/ios/views/base/RNAOA11yGroupChildrenView.mm +19 -0
  31. package/ios/views/base/RNAOA11yManagedFocusView.h +28 -0
  32. package/ios/views/{RNAOA11yView/RNAOA11yView.mm → base/RNAOA11yManagedFocusView.mm} +64 -183
  33. package/ios/views/base/RNAOA11yScreenReaderView.h +24 -0
  34. package/ios/views/base/RNAOA11yScreenReaderView.mm +32 -0
  35. package/ios/views/base/RNAOA11yViewGroup.h +35 -0
  36. package/ios/views/base/RNAOA11yViewGroup.mm +46 -0
  37. package/ios/views/base/RNAOA11yViewOrder.h +40 -0
  38. package/ios/views/base/RNAOA11yViewOrder.mm +92 -0
  39. package/lib/commonjs/components/A11yCard/A11yCard.ios.js +49 -0
  40. package/lib/commonjs/components/A11yCard/A11yCard.ios.js.map +1 -0
  41. package/lib/commonjs/components/A11yCard/A11yCard.js +41 -0
  42. package/lib/commonjs/components/A11yCard/A11yCard.js.map +1 -0
  43. package/lib/commonjs/{types/A11yGroup.types.js → components/A11yCard/A11yCard.types.js} +1 -1
  44. package/lib/commonjs/components/A11yCard/A11yCard.types.js.map +1 -0
  45. package/lib/commonjs/components/A11yIndex/A11yIndex.js +88 -28
  46. package/lib/commonjs/components/A11yIndex/A11yIndex.js.map +1 -1
  47. package/lib/commonjs/components/A11yIndex/A11yIndex.types.js +39 -0
  48. package/lib/commonjs/components/A11yIndex/A11yIndex.types.js.map +1 -0
  49. package/lib/commonjs/components/A11yIndex/A11yIndex.web.js.map +1 -1
  50. package/lib/commonjs/components/A11yLock/A11yFocusFrame/A11yFocusFrame.js.map +1 -1
  51. package/lib/commonjs/components/A11yLock/A11yFocusTrap/A11yFocusTrap.js.map +1 -1
  52. package/lib/commonjs/components/A11yLock/A11yLock.types.js.map +1 -0
  53. package/lib/commonjs/components/{A11ySequence/A11ySequence.js → A11yOrder/A11yOrder.js} +3 -3
  54. package/lib/commonjs/components/A11yOrder/A11yOrder.js.map +1 -0
  55. package/lib/commonjs/{types/A11yModule.types.js → components/A11yOrder/A11yOrder.types.js} +1 -1
  56. package/lib/commonjs/components/A11yOrder/A11yOrder.types.js.map +1 -0
  57. package/lib/commonjs/components/A11yPaneTitle/A11yPaneTitle.js +6 -7
  58. package/lib/commonjs/components/A11yPaneTitle/A11yPaneTitle.js.map +1 -1
  59. package/lib/commonjs/components/A11yPaneTitle/A11yPaneTitle.types.js +6 -0
  60. package/lib/commonjs/components/A11yPaneTitle/A11yPaneTitle.types.js.map +1 -0
  61. package/lib/commonjs/components/A11yView/A11yView.js +7 -33
  62. package/lib/commonjs/components/A11yView/A11yView.js.map +1 -1
  63. package/lib/commonjs/components/A11yView/A11yView.types.js.map +1 -0
  64. package/lib/commonjs/index.js +37 -10
  65. package/lib/commonjs/index.js.map +1 -1
  66. package/lib/commonjs/index.web.js +12 -6
  67. package/lib/commonjs/index.web.js.map +1 -1
  68. package/lib/commonjs/modules/A11yAnnounceModule.android.js +37 -3
  69. package/lib/commonjs/modules/A11yAnnounceModule.android.js.map +1 -1
  70. package/lib/commonjs/modules/A11yAnnounceModule.js +66 -8
  71. package/lib/commonjs/modules/A11yAnnounceModule.js.map +1 -1
  72. package/lib/commonjs/nativeSpecs/{A11yGroupNativeComponent.ts → A11yCardNativeComponent.ts} +3 -3
  73. package/lib/commonjs/nativeSpecs/A11yIndexNativeComponent.ts +11 -3
  74. package/lib/commonjs/nativeSpecs/NativeA11yAnnounceModule.js +2 -0
  75. package/lib/commonjs/nativeSpecs/NativeA11yAnnounceModule.js.map +1 -1
  76. package/lib/module/components/A11yCard/A11yCard.ios.js +43 -0
  77. package/lib/module/components/A11yCard/A11yCard.ios.js.map +1 -0
  78. package/lib/module/components/A11yCard/A11yCard.js +35 -0
  79. package/lib/module/components/A11yCard/A11yCard.js.map +1 -0
  80. package/lib/module/components/A11yCard/A11yCard.types.js +4 -0
  81. package/lib/module/components/A11yCard/A11yCard.types.js.map +1 -0
  82. package/lib/module/components/A11yIndex/A11yIndex.js +88 -28
  83. package/lib/module/components/A11yIndex/A11yIndex.js.map +1 -1
  84. package/lib/module/components/A11yIndex/A11yIndex.types.js +35 -0
  85. package/lib/module/components/A11yIndex/A11yIndex.types.js.map +1 -0
  86. package/lib/module/components/A11yIndex/A11yIndex.web.js.map +1 -1
  87. package/lib/module/components/A11yLock/A11yFocusFrame/A11yFocusFrame.js.map +1 -1
  88. package/lib/module/components/A11yLock/A11yFocusTrap/A11yFocusTrap.js.map +1 -1
  89. package/lib/module/components/A11yLock/A11yLock.types.js.map +1 -0
  90. package/lib/module/components/{A11ySequence/A11ySequence.js → A11yOrder/A11yOrder.js} +2 -2
  91. package/lib/module/components/A11yOrder/A11yOrder.js.map +1 -0
  92. package/lib/module/components/A11yOrder/A11yOrder.types.js +4 -0
  93. package/lib/module/components/A11yOrder/A11yOrder.types.js.map +1 -0
  94. package/lib/module/components/A11yPaneTitle/A11yPaneTitle.js +6 -7
  95. package/lib/module/components/A11yPaneTitle/A11yPaneTitle.js.map +1 -1
  96. package/lib/module/components/A11yPaneTitle/A11yPaneTitle.types.js +4 -0
  97. package/lib/module/components/A11yPaneTitle/A11yPaneTitle.types.js.map +1 -0
  98. package/lib/module/components/A11yView/A11yView.js +7 -31
  99. package/lib/module/components/A11yView/A11yView.js.map +1 -1
  100. package/lib/module/components/A11yView/A11yView.types.js.map +1 -0
  101. package/lib/module/index.js +13 -9
  102. package/lib/module/index.js.map +1 -1
  103. package/lib/module/index.web.js +5 -5
  104. package/lib/module/index.web.js.map +1 -1
  105. package/lib/module/modules/A11yAnnounceModule.android.js +32 -2
  106. package/lib/module/modules/A11yAnnounceModule.android.js.map +1 -1
  107. package/lib/module/modules/A11yAnnounceModule.js +62 -7
  108. package/lib/module/modules/A11yAnnounceModule.js.map +1 -1
  109. package/{src/nativeSpecs/A11yGroupNativeComponent.ts → lib/module/nativeSpecs/A11yCardNativeComponent.ts} +3 -3
  110. package/lib/module/nativeSpecs/A11yIndexNativeComponent.ts +11 -3
  111. package/lib/module/nativeSpecs/NativeA11yAnnounceModule.js +4 -0
  112. package/lib/module/nativeSpecs/NativeA11yAnnounceModule.js.map +1 -1
  113. package/lib/typescript/src/components/A11yCard/A11yCard.d.ts +5 -0
  114. package/lib/typescript/src/components/A11yCard/A11yCard.d.ts.map +1 -0
  115. package/lib/typescript/src/components/A11yCard/A11yCard.ios.d.ts +5 -0
  116. package/lib/typescript/src/components/A11yCard/A11yCard.ios.d.ts.map +1 -0
  117. package/lib/typescript/src/components/A11yCard/A11yCard.types.d.ts +38 -0
  118. package/lib/typescript/src/components/A11yCard/A11yCard.types.d.ts.map +1 -0
  119. package/lib/typescript/src/components/A11yIndex/A11yIndex.d.ts +10 -128
  120. package/lib/typescript/src/components/A11yIndex/A11yIndex.d.ts.map +1 -1
  121. package/lib/typescript/src/components/A11yIndex/A11yIndex.types.d.ts +101 -0
  122. package/lib/typescript/src/components/A11yIndex/A11yIndex.types.d.ts.map +1 -0
  123. package/lib/typescript/src/components/A11yIndex/A11yIndex.web.d.ts +8 -128
  124. package/lib/typescript/src/components/A11yIndex/A11yIndex.web.d.ts.map +1 -1
  125. package/lib/typescript/src/components/A11yLock/A11yBaseLock/A11yBaseLock.d.ts +1 -1
  126. package/lib/typescript/src/components/A11yLock/A11yBaseLock/A11yBaseLock.d.ts.map +1 -1
  127. package/lib/typescript/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.android.d.ts +1 -1
  128. package/lib/typescript/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.android.d.ts.map +1 -1
  129. package/lib/typescript/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.d.ts +2 -2
  130. package/lib/typescript/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.d.ts.map +1 -1
  131. package/lib/typescript/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.android.d.ts +1 -1
  132. package/lib/typescript/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.android.d.ts.map +1 -1
  133. package/lib/typescript/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.d.ts +2 -2
  134. package/lib/typescript/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.d.ts.map +1 -1
  135. package/lib/typescript/src/components/A11yLock/A11yLock.types.d.ts +35 -0
  136. package/lib/typescript/src/components/A11yLock/A11yLock.types.d.ts.map +1 -0
  137. package/lib/typescript/src/components/A11yOrder/A11yOrder.d.ts +5 -0
  138. package/lib/typescript/src/components/A11yOrder/A11yOrder.d.ts.map +1 -0
  139. package/lib/typescript/src/components/A11yOrder/A11yOrder.types.d.ts +11 -0
  140. package/lib/typescript/src/components/A11yOrder/A11yOrder.types.d.ts.map +1 -0
  141. package/lib/typescript/src/components/A11yPaneTitle/A11yPaneTitle.d.ts +3 -17
  142. package/lib/typescript/src/components/A11yPaneTitle/A11yPaneTitle.d.ts.map +1 -1
  143. package/lib/typescript/src/components/A11yPaneTitle/A11yPaneTitle.types.d.ts +52 -0
  144. package/lib/typescript/src/components/A11yPaneTitle/A11yPaneTitle.types.d.ts.map +1 -0
  145. package/lib/typescript/src/components/A11yView/A11yView.d.ts +13 -130
  146. package/lib/typescript/src/components/A11yView/A11yView.d.ts.map +1 -1
  147. package/lib/typescript/src/components/A11yView/A11yView.types.d.ts +10 -0
  148. package/lib/typescript/src/components/A11yView/A11yView.types.d.ts.map +1 -0
  149. package/lib/typescript/src/index.d.ts +29 -403
  150. package/lib/typescript/src/index.d.ts.map +1 -1
  151. package/lib/typescript/src/index.web.d.ts +20 -171
  152. package/lib/typescript/src/index.web.d.ts.map +1 -1
  153. package/lib/typescript/src/modules/A11yAnnounceModule.android.d.ts +25 -2
  154. package/lib/typescript/src/modules/A11yAnnounceModule.android.d.ts.map +1 -1
  155. package/lib/typescript/src/modules/A11yAnnounceModule.d.ts +112 -4
  156. package/lib/typescript/src/modules/A11yAnnounceModule.d.ts.map +1 -1
  157. package/lib/typescript/src/nativeSpecs/A11yCardNativeComponent.d.ts +6 -0
  158. package/lib/typescript/src/nativeSpecs/A11yCardNativeComponent.d.ts.map +1 -0
  159. package/lib/typescript/src/nativeSpecs/A11yIndexNativeComponent.d.ts +10 -6
  160. package/lib/typescript/src/nativeSpecs/A11yIndexNativeComponent.d.ts.map +1 -1
  161. package/lib/typescript/src/nativeSpecs/A11yLockNativeComponent.d.ts +1 -3
  162. package/lib/typescript/src/nativeSpecs/A11yLockNativeComponent.d.ts.map +1 -1
  163. package/lib/typescript/src/nativeSpecs/A11yOrderNativeComponent.d.ts +1 -3
  164. package/lib/typescript/src/nativeSpecs/A11yOrderNativeComponent.d.ts.map +1 -1
  165. package/lib/typescript/src/nativeSpecs/A11yPaneTitleNativeComponent.d.ts +1 -3
  166. package/lib/typescript/src/nativeSpecs/A11yPaneTitleNativeComponent.d.ts.map +1 -1
  167. package/lib/typescript/src/nativeSpecs/NativeA11yAnnounceModule.d.ts +22 -2
  168. package/lib/typescript/src/nativeSpecs/NativeA11yAnnounceModule.d.ts.map +1 -1
  169. package/package.json +12 -11
  170. package/src/components/A11yCard/A11yCard.ios.tsx +44 -0
  171. package/src/components/A11yCard/A11yCard.tsx +35 -0
  172. package/src/components/A11yCard/A11yCard.types.ts +50 -0
  173. package/src/components/A11yIndex/A11yIndex.tsx +144 -52
  174. package/src/components/A11yIndex/A11yIndex.types.ts +119 -0
  175. package/src/components/A11yIndex/A11yIndex.web.tsx +12 -17
  176. package/src/components/A11yLock/A11yBaseLock/A11yBaseLock.tsx +1 -1
  177. package/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.android.tsx +1 -1
  178. package/src/components/A11yLock/A11yFocusFrame/A11yFocusFrame.tsx +3 -2
  179. package/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.android.tsx +1 -1
  180. package/src/components/A11yLock/A11yFocusTrap/A11yFocusTrap.tsx +2 -2
  181. package/src/components/A11yLock/A11yLock.types.ts +38 -0
  182. package/src/components/{A11ySequence/A11ySequence.tsx → A11yOrder/A11yOrder.tsx} +4 -2
  183. package/src/components/A11yOrder/A11yOrder.types.ts +11 -0
  184. package/src/components/A11yPaneTitle/A11yPaneTitle.tsx +13 -19
  185. package/src/components/A11yPaneTitle/A11yPaneTitle.types.ts +58 -0
  186. package/src/components/A11yView/A11yView.tsx +8 -63
  187. package/src/components/A11yView/A11yView.types.ts +11 -0
  188. package/src/index.ts +38 -20
  189. package/src/index.web.ts +7 -14
  190. package/src/modules/A11yAnnounceModule.android.ts +18 -2
  191. package/src/modules/A11yAnnounceModule.ts +153 -9
  192. package/{lib/module/nativeSpecs/A11yGroupNativeComponent.ts → src/nativeSpecs/A11yCardNativeComponent.ts} +3 -3
  193. package/src/nativeSpecs/A11yIndexNativeComponent.ts +11 -3
  194. package/src/nativeSpecs/NativeA11yAnnounceModule.ts +31 -1
  195. package/android/src/main/java/com/a11yorder/views/A11yGroupView/A11yGroupViewManager.java +0 -25
  196. package/android/src/main/java/com/a11yorder/views/A11yUIContainerView/A11yUIContainerViewManager.java +0 -30
  197. package/android/src/main/java/com/a11yorder/views/A11yView/A11yViewManager.java +0 -67
  198. package/android/src/newarch/A11yGroupViewManagerSpec.java +0 -9
  199. package/android/src/newarch/A11yUIContainerViewManagerSpec.java +0 -8
  200. package/android/src/newarch/A11yViewSpec.java +0 -13
  201. package/android/src/oldarch/A11yGroupViewManagerSpec.java +0 -8
  202. package/android/src/oldarch/A11yUIContainerViewManagerSpec.java +0 -9
  203. package/android/src/oldarch/A11yViewSpec.java +0 -18
  204. package/ios/views/RNAOA11yGroupView/RNAOA11yGroupView.h +0 -37
  205. package/ios/views/RNAOA11yGroupView/RNAOA11yGroupView.mm +0 -67
  206. package/ios/views/RNAOA11yGroupView/RNAOA11yGroupViewManager.h +0 -18
  207. package/ios/views/RNAOA11yGroupView/RNAOA11yGroupViewManager.mm +0 -25
  208. package/ios/views/RNAOA11yUIContainerView/RNAOA11yUIContainerView.h +0 -35
  209. package/ios/views/RNAOA11yUIContainerView/RNAOA11yUIContainerView.mm +0 -79
  210. package/ios/views/RNAOA11yUIContainerView/RNAOA11yUIContainerViewManager.h +0 -18
  211. package/ios/views/RNAOA11yUIContainerView/RNAOA11yUIContainerViewManager.mm +0 -27
  212. package/ios/views/RNAOA11yView/RNAOA11yView.h +0 -45
  213. package/ios/views/RNAOA11yView/RNAOA11yViewManager.h +0 -14
  214. package/ios/views/RNAOA11yView/RNAOA11yViewManager.mm +0 -53
  215. package/lib/commonjs/components/A11yGroup/A11yGroup.android.js +0 -18
  216. package/lib/commonjs/components/A11yGroup/A11yGroup.android.js.map +0 -1
  217. package/lib/commonjs/components/A11yGroup/A11yGroup.ios.js +0 -24
  218. package/lib/commonjs/components/A11yGroup/A11yGroup.ios.js.map +0 -1
  219. package/lib/commonjs/components/A11yGroup/A11yGroup.js +0 -9
  220. package/lib/commonjs/components/A11yGroup/A11yGroup.js.map +0 -1
  221. package/lib/commonjs/components/A11ySequence/A11ySequence.js.map +0 -1
  222. package/lib/commonjs/components/A11yUIContainer/A11yUIContainer.ios.js +0 -22
  223. package/lib/commonjs/components/A11yUIContainer/A11yUIContainer.ios.js.map +0 -1
  224. package/lib/commonjs/components/A11yUIContainer/A11yUIContainer.js +0 -9
  225. package/lib/commonjs/components/A11yUIContainer/A11yUIContainer.js.map +0 -1
  226. package/lib/commonjs/nativeSpecs/A11yUIContainerNativeComponent.ts +0 -12
  227. package/lib/commonjs/nativeSpecs/A11yViewNativeComponent.ts +0 -36
  228. package/lib/commonjs/types/A11yGroup.types.js.map +0 -1
  229. package/lib/commonjs/types/A11yIndex.types.js +0 -13
  230. package/lib/commonjs/types/A11yIndex.types.js.map +0 -1
  231. package/lib/commonjs/types/A11yLock.types.js.map +0 -1
  232. package/lib/commonjs/types/A11yModule.types.js.map +0 -1
  233. package/lib/commonjs/types/A11yUIContainerView.types.js +0 -15
  234. package/lib/commonjs/types/A11yUIContainerView.types.js.map +0 -1
  235. package/lib/commonjs/types/A11yView.types.js.map +0 -1
  236. package/lib/module/components/A11yGroup/A11yGroup.android.js +0 -12
  237. package/lib/module/components/A11yGroup/A11yGroup.android.js.map +0 -1
  238. package/lib/module/components/A11yGroup/A11yGroup.ios.js +0 -18
  239. package/lib/module/components/A11yGroup/A11yGroup.ios.js.map +0 -1
  240. package/lib/module/components/A11yGroup/A11yGroup.js +0 -5
  241. package/lib/module/components/A11yGroup/A11yGroup.js.map +0 -1
  242. package/lib/module/components/A11ySequence/A11ySequence.js.map +0 -1
  243. package/lib/module/components/A11yUIContainer/A11yUIContainer.ios.js +0 -17
  244. package/lib/module/components/A11yUIContainer/A11yUIContainer.ios.js.map +0 -1
  245. package/lib/module/components/A11yUIContainer/A11yUIContainer.js +0 -5
  246. package/lib/module/components/A11yUIContainer/A11yUIContainer.js.map +0 -1
  247. package/lib/module/nativeSpecs/A11yUIContainerNativeComponent.ts +0 -12
  248. package/lib/module/nativeSpecs/A11yViewNativeComponent.ts +0 -36
  249. package/lib/module/types/A11yGroup.types.js +0 -4
  250. package/lib/module/types/A11yGroup.types.js.map +0 -1
  251. package/lib/module/types/A11yIndex.types.js +0 -9
  252. package/lib/module/types/A11yIndex.types.js.map +0 -1
  253. package/lib/module/types/A11yLock.types.js.map +0 -1
  254. package/lib/module/types/A11yModule.types.js +0 -4
  255. package/lib/module/types/A11yModule.types.js.map +0 -1
  256. package/lib/module/types/A11yUIContainerView.types.js +0 -11
  257. package/lib/module/types/A11yUIContainerView.types.js.map +0 -1
  258. package/lib/module/types/A11yView.types.js.map +0 -1
  259. package/lib/typescript/src/components/A11yGroup/A11yGroup.android.d.ts +0 -4
  260. package/lib/typescript/src/components/A11yGroup/A11yGroup.android.d.ts.map +0 -1
  261. package/lib/typescript/src/components/A11yGroup/A11yGroup.d.ts +0 -3
  262. package/lib/typescript/src/components/A11yGroup/A11yGroup.d.ts.map +0 -1
  263. package/lib/typescript/src/components/A11yGroup/A11yGroup.ios.d.ts +0 -4
  264. package/lib/typescript/src/components/A11yGroup/A11yGroup.ios.d.ts.map +0 -1
  265. package/lib/typescript/src/components/A11ySequence/A11ySequence.d.ts +0 -126
  266. package/lib/typescript/src/components/A11ySequence/A11ySequence.d.ts.map +0 -1
  267. package/lib/typescript/src/components/A11yUIContainer/A11yUIContainer.d.ts +0 -3
  268. package/lib/typescript/src/components/A11yUIContainer/A11yUIContainer.d.ts.map +0 -1
  269. package/lib/typescript/src/components/A11yUIContainer/A11yUIContainer.ios.d.ts +0 -4
  270. package/lib/typescript/src/components/A11yUIContainer/A11yUIContainer.ios.d.ts.map +0 -1
  271. package/lib/typescript/src/nativeSpecs/A11yGroupNativeComponent.d.ts +0 -8
  272. package/lib/typescript/src/nativeSpecs/A11yGroupNativeComponent.d.ts.map +0 -1
  273. package/lib/typescript/src/nativeSpecs/A11yUIContainerNativeComponent.d.ts +0 -10
  274. package/lib/typescript/src/nativeSpecs/A11yUIContainerNativeComponent.d.ts.map +0 -1
  275. package/lib/typescript/src/nativeSpecs/A11yViewNativeComponent.d.ts +0 -26
  276. package/lib/typescript/src/nativeSpecs/A11yViewNativeComponent.d.ts.map +0 -1
  277. package/lib/typescript/src/types/A11yGroup.types.d.ts +0 -7
  278. package/lib/typescript/src/types/A11yGroup.types.d.ts.map +0 -1
  279. package/lib/typescript/src/types/A11yIndex.types.d.ts +0 -19
  280. package/lib/typescript/src/types/A11yIndex.types.d.ts.map +0 -1
  281. package/lib/typescript/src/types/A11yLock.types.d.ts +0 -8
  282. package/lib/typescript/src/types/A11yLock.types.d.ts.map +0 -1
  283. package/lib/typescript/src/types/A11yModule.types.d.ts +0 -7
  284. package/lib/typescript/src/types/A11yModule.types.d.ts.map +0 -1
  285. package/lib/typescript/src/types/A11yUIContainerView.types.d.ts +0 -13
  286. package/lib/typescript/src/types/A11yUIContainerView.types.d.ts.map +0 -1
  287. package/lib/typescript/src/types/A11yView.types.d.ts +0 -12
  288. package/lib/typescript/src/types/A11yView.types.d.ts.map +0 -1
  289. package/src/components/A11yGroup/A11yGroup.android.tsx +0 -8
  290. package/src/components/A11yGroup/A11yGroup.ios.tsx +0 -11
  291. package/src/components/A11yGroup/A11yGroup.tsx +0 -5
  292. package/src/components/A11yUIContainer/A11yUIContainer.ios.tsx +0 -20
  293. package/src/components/A11yUIContainer/A11yUIContainer.tsx +0 -5
  294. package/src/nativeSpecs/A11yUIContainerNativeComponent.ts +0 -12
  295. package/src/nativeSpecs/A11yViewNativeComponent.ts +0 -36
  296. package/src/types/A11yGroup.types.ts +0 -9
  297. package/src/types/A11yIndex.types.ts +0 -21
  298. package/src/types/A11yLock.types.ts +0 -8
  299. package/src/types/A11yModule.types.ts +0 -7
  300. package/src/types/A11yUIContainerView.types.ts +0 -15
  301. package/src/types/A11yView.types.ts +0 -19
  302. /package/lib/commonjs/{types → components/A11yLock}/A11yLock.types.js +0 -0
  303. /package/lib/commonjs/{types → components/A11yView}/A11yView.types.js +0 -0
  304. /package/lib/module/{types → components/A11yLock}/A11yLock.types.js +0 -0
  305. /package/lib/module/{types → components/A11yView}/A11yView.types.js +0 -0
@@ -1,74 +1,11 @@
1
1
  package com.a11yorder.views.A11yIndexView;
2
2
 
3
3
  import android.content.Context;
4
- import android.view.View;
5
- import android.view.accessibility.AccessibilityEvent;
6
4
 
7
- import com.a11yorder.events.EventHelper;
8
- import com.a11yorder.services.order.A11yOrderService;
9
- import com.facebook.react.bridge.ReactContext;
10
- import com.facebook.react.views.view.ReactViewGroup;
11
-
12
-
13
- public class A11yIndexView extends ReactViewGroup {
14
- private final Context context;
15
- private final A11yOrderService orderService;
5
+ import com.a11yorder.core.A11yViewOrder;
16
6
 
7
+ public class A11yIndexView extends A11yViewOrder {
17
8
  public A11yIndexView(Context context) {
18
9
  super(context);
19
- this.context = context;
20
- this.orderService = new A11yOrderService(this);
21
- }
22
-
23
- public void setIndex(int index) {
24
- this.orderService.setIndex(index);
25
- }
26
-
27
- public void setOrderFocusType(int focusType) {
28
- this.orderService.setFocusType(focusType);
29
- }
30
-
31
- public void setOrderKey(String orderKey) {
32
- this.orderService.setOrderKey(orderKey);
33
- }
34
-
35
- @Override
36
- public void onViewAdded(View child) {
37
- super.onViewAdded(child);
38
- this.orderService.link(child);
39
- }
40
-
41
- @Override
42
- public void onViewRemoved(View child) {
43
- super.onViewRemoved(child);
44
- this.orderService.clear(child);
45
- }
46
-
47
- @Override
48
- protected void onAttachedToWindow() {
49
- super.onAttachedToWindow();
50
- this.orderService.attach();
51
- }
52
-
53
- @Override
54
- protected void onDetachedFromWindow() {
55
- super.onDetachedFromWindow();
56
- this.orderService.detach();
57
- }
58
-
59
- @Override
60
- public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
61
- int eventType = event.getEventType();
62
- boolean isSubChild = (child == orderService.getStoredView());
63
-
64
- if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED && isSubChild) {
65
- EventHelper.screenReaderFocusChanged((ReactContext) context, this.getId(), true);
66
- }
67
-
68
- if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED && isSubChild) {
69
- EventHelper.screenReaderFocusChanged((ReactContext) context, this.getId(), false);
70
- }
71
-
72
- return super.onRequestSendAccessibilityEvent(child, event);
73
10
  }
74
11
  }
@@ -6,7 +6,9 @@ import androidx.annotation.NonNull;
6
6
  import androidx.annotation.Nullable;
7
7
 
8
8
  import com.a11yorder.events.EventHelper;
9
+ import com.a11yorder.events.ScreenReaderDescendantFocusChangedEvent;
9
10
  import com.a11yorder.events.ScreenReaderFocusChangedEvent;
11
+ import com.a11yorder.events.ScreenReaderFocusedEvent;
10
12
  import com.a11yorder.utils.A11yHelper;
11
13
  import com.facebook.react.bridge.ReadableArray;
12
14
  import com.facebook.react.module.annotations.ReactModule;
@@ -53,6 +55,11 @@ public class A11yIndexViewManager extends com.a11yorder.A11yIndexViewManagerSpec
53
55
  viewGroup.setOrderFocusType(value);
54
56
  }
55
57
 
58
+ @Override
59
+ public void setShouldGroupAccessibilityChildren(A11yIndexView view, int value) {
60
+ //stub
61
+ }
62
+
56
63
  @Override
57
64
  public void focus(A11yIndexView view) {
58
65
  this.focus((ReactViewGroup) view);
@@ -72,11 +79,25 @@ public class A11yIndexViewManager extends com.a11yorder.A11yIndexViewManagerSpec
72
79
  }
73
80
  }
74
81
 
82
+
83
+ @Override
84
+ public void setDescendantFocusChangedEnabled(A11yIndexView view, boolean value) {
85
+ //stub
86
+ }
87
+
88
+ @Override
89
+ public void setContainerType(A11yIndexView view, int value) {
90
+ //stub
91
+ }
92
+
93
+ @javax.annotation.Nullable
75
94
  @Override
76
95
  public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
77
96
  Map<String, Object> export = new HashMap<>();
78
97
 
98
+ export.put(ScreenReaderFocusedEvent.EVENT_NAME, EventHelper.buildDirectEventMap("onScreenReaderFocused"));
79
99
  export.put(ScreenReaderFocusChangedEvent.EVENT_NAME, EventHelper.buildDirectEventMap("onScreenReaderFocusChange"));
100
+ export.put(ScreenReaderDescendantFocusChangedEvent.EVENT_NAME, EventHelper.buildDirectEventMap("onScreenReaderDescendantFocusChanged"));
80
101
 
81
102
  return export;
82
103
  }
@@ -0,0 +1,9 @@
1
+ package com.a11yorder;
2
+
3
+ import android.view.ViewGroup;
4
+
5
+ import com.facebook.react.viewmanagers.A11yCardViewManagerInterface;
6
+ import com.facebook.react.views.view.ReactViewManager;
7
+
8
+ public abstract class A11yCardViewManagerSpec<T extends ViewGroup> extends ReactViewManager implements A11yCardViewManagerInterface<T> {
9
+ }
@@ -1,12 +1,19 @@
1
1
  package com.a11yorder;
2
2
 
3
+ import androidx.annotation.Nullable;
4
+ import com.facebook.react.bridge.Promise;
3
5
  import com.facebook.react.bridge.ReactApplicationContext;
4
6
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
7
+ import com.facebook.react.bridge.ReadableMap;
5
8
 
6
9
  public abstract class A11yAnnounceModuleSpec extends ReactContextBaseJavaModule {
7
10
  protected A11yAnnounceModuleSpec(ReactApplicationContext context) {
8
11
  super(context);
9
12
  }
10
13
 
11
- public abstract void announce(String message);
14
+ public abstract void announce(String message, @Nullable ReadableMap options, Promise promise);
15
+
16
+ public abstract void cancel(String id, Promise promise);
17
+
18
+ public abstract void cancelAll(Promise promise);
12
19
  }
@@ -0,0 +1,8 @@
1
+ package com.a11yorder;
2
+
3
+ import android.view.ViewGroup;
4
+
5
+ import com.facebook.react.views.view.ReactViewManager;
6
+
7
+ public abstract class A11yCardViewManagerSpec<T extends ViewGroup> extends ReactViewManager {
8
+ }
@@ -1,6 +1,7 @@
1
1
  package com.a11yorder;
2
2
 
3
3
  import com.a11yorder.views.A11yIndexView.A11yIndexView;
4
+ import com.facebook.react.uimanager.annotations.ReactProp;
4
5
  import com.facebook.react.views.view.ReactViewManager;
5
6
 
6
7
  public abstract class A11yIndexViewManagerSpec<T extends A11yIndexView> extends ReactViewManager {
@@ -11,4 +12,11 @@ public abstract class A11yIndexViewManagerSpec<T extends A11yIndexView> extends
11
12
  public abstract void setOrderFocusType(T viewGroup, int value);
12
13
 
13
14
  public abstract void focus(T view);
15
+
16
+ public abstract void setDescendantFocusChangedEnabled(A11yIndexView view, boolean value);
17
+
18
+ public abstract void setContainerType(A11yIndexView view, int value);
19
+
20
+ public abstract void setShouldGroupAccessibilityChildren(A11yIndexView view, int value);
21
+
14
22
  }
@@ -32,8 +32,8 @@ using namespace facebook::react;
32
32
 
33
33
  + (void)onA11yViewFocusChange:(BOOL)isFocused withEmitter:(facebook::react::SharedViewEventEmitter) _eventEmitter {
34
34
  if (_eventEmitter) {
35
- auto viewEventEmitter = std::static_pointer_cast<A11yViewEventEmitter const>(_eventEmitter);
36
- facebook::react::A11yViewEventEmitter::OnScreenReaderFocusChange data = {
35
+ auto viewEventEmitter = std::static_pointer_cast<A11yIndexViewEventEmitter const>(_eventEmitter);
36
+ facebook::react::A11yIndexViewEventEmitter::OnScreenReaderFocusChange data = {
37
37
  .isFocused = isFocused,
38
38
  };
39
39
  viewEventEmitter->onScreenReaderFocusChange(data);
@@ -42,16 +42,16 @@ using namespace facebook::react;
42
42
 
43
43
  + (void)onA11yViewFocused:(facebook::react::SharedViewEventEmitter) _eventEmitter {
44
44
  if (_eventEmitter) {
45
- auto viewEventEmitter = std::static_pointer_cast<A11yViewEventEmitter const>(_eventEmitter);
45
+ auto viewEventEmitter = std::static_pointer_cast<A11yIndexViewEventEmitter const>(_eventEmitter);
46
46
  viewEventEmitter->onScreenReaderFocused({});
47
47
  };
48
48
  }
49
49
 
50
50
  + (void)onA11yViewScreenReaderDescendantFocusChanged:(NSString*)status withId:(NSString*)nativeId withEmitter:(facebook::react::SharedViewEventEmitter) _eventEmitter {
51
51
  if (_eventEmitter) {
52
- auto viewEventEmitter = std::static_pointer_cast<A11yViewEventEmitter const>(_eventEmitter);
52
+ auto viewEventEmitter = std::static_pointer_cast<A11yIndexViewEventEmitter const>(_eventEmitter);
53
53
  NSString* resultID = nativeId == nil ? @"" :nativeId;
54
- facebook::react::A11yViewEventEmitter::OnScreenReaderDescendantFocusChanged data = {
54
+ facebook::react::A11yIndexViewEventEmitter::OnScreenReaderDescendantFocusChanged data = {
55
55
  .status = [status UTF8String],
56
56
  .nativeId = [resultID UTF8String],
57
57
  };
@@ -0,0 +1,35 @@
1
+ //
2
+ // RNAOSpeechAttributes.h
3
+ // react-native-a11y-order
4
+ //
5
+
6
+ #ifndef RNAOSpeechAttributes_h
7
+ #define RNAOSpeechAttributes_h
8
+
9
+ #import <Foundation/Foundation.h>
10
+ #import <UIKit/UIKit.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ /**
15
+ * Builds an NSAttributedString suitable for UIAccessibilityPostNotification
16
+ * from a flat options dictionary. Keys consumed:
17
+ *
18
+ * priority NSString "low" | "default" | "high" | "critical"
19
+ * queue NSNumber BOOL (defaults to YES; "critical" forces NO)
20
+ * language NSString BCP-47 tag
21
+ * pitch NSNumber 0.0–2.0 (skipped at 1.0 ± 0.001)
22
+ * spellOut NSNumber BOOL
23
+ * punctuation NSNumber BOOL
24
+ * ipaNotation NSString
25
+ */
26
+ @interface RNAOSpeechAttributes : NSObject
27
+
28
+ + (NSAttributedString *)attributedStringFor:(NSString *)message
29
+ options:(NSDictionary *)options;
30
+
31
+ @end
32
+
33
+ NS_ASSUME_NONNULL_END
34
+
35
+ #endif /* RNAOSpeechAttributes_h */
@@ -0,0 +1,64 @@
1
+ //
2
+ // RNAOSpeechAttributes.mm
3
+ // react-native-a11y-order
4
+ //
5
+
6
+ #import "RNAOSpeechAttributes.h"
7
+
8
+ @implementation RNAOSpeechAttributes
9
+
10
+ + (NSAttributedString *)attributedStringFor:(NSString *)message
11
+ options:(NSDictionary *)options
12
+ {
13
+ NSMutableDictionary<NSAttributedStringKey, id> *attrs = [NSMutableDictionary new];
14
+
15
+ BOOL shouldQueue = options[@"queue"] ? [options[@"queue"] boolValue] : YES;
16
+
17
+ if (@available(iOS 11.0, *)) {
18
+ attrs[UIAccessibilitySpeechAttributeQueueAnnouncement] = @(shouldQueue);
19
+ }
20
+
21
+ if (@available(iOS 17.0, *)) {
22
+ NSString *priority = options[@"priority"] ?: @"default";
23
+ UIAccessibilityPriority nativePriority = UIAccessibilityPriorityDefault;
24
+ if ([priority isEqualToString:@"low"])
25
+ nativePriority = UIAccessibilityPriorityLow;
26
+ else if ([priority isEqualToString:@"high"])
27
+ nativePriority = UIAccessibilityPriorityHigh;
28
+ attrs[UIAccessibilitySpeechAttributeAnnouncementPriority] = nativePriority;
29
+ }
30
+
31
+ id langVal = options[@"language"];
32
+ if ([langVal isKindOfClass:[NSString class]]) {
33
+ attrs[UIAccessibilitySpeechAttributeLanguage] = langVal;
34
+ }
35
+
36
+ // Pitch only written when it deviates from default 1.0.
37
+ id pitchVal = options[@"pitch"];
38
+ if (pitchVal && ![pitchVal isEqual:[NSNull null]]) {
39
+ CGFloat raw = [pitchVal floatValue];
40
+ if (fabs(raw - 1.0f) > 0.001f) {
41
+ attrs[UIAccessibilitySpeechAttributePitch] = @(MAX(0.0f, MIN(2.0f, raw)));
42
+ }
43
+ }
44
+
45
+ if (@available(iOS 13.0, *)) {
46
+ if ([options[@"spellOut"] boolValue]) {
47
+ attrs[UIAccessibilitySpeechAttributeSpellOut] = @YES;
48
+ }
49
+ }
50
+
51
+ if (@available(iOS 11.0, *)) {
52
+ if ([options[@"punctuation"] boolValue]) {
53
+ attrs[UIAccessibilitySpeechAttributePunctuation] = @YES;
54
+ }
55
+ id ipaVal = options[@"ipaNotation"];
56
+ if ([ipaVal isKindOfClass:[NSString class]]) {
57
+ attrs[UIAccessibilitySpeechAttributeIPANotation] = ipaVal;
58
+ }
59
+ }
60
+
61
+ return [[NSAttributedString alloc] initWithString:message attributes:attrs];
62
+ }
63
+
64
+ @end
@@ -1,14 +1,11 @@
1
1
  //
2
2
  // RNAOA11yAnnounceModule.h
3
- // Pods
4
- //
5
- // Created by Artur Kalach on 06/12/2025.
3
+ // react-native-a11y-order
6
4
  //
7
5
 
8
6
  #ifndef RNAOA11yAnnounceModule_h
9
7
  #define RNAOA11yAnnounceModule_h
10
8
 
11
-
12
9
  #import <Foundation/Foundation.h>
13
10
 
14
11
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -16,19 +13,26 @@
16
13
 
17
14
  @interface RNAOA11yAnnounceModule : NSObject <NativeA11yAnnounceModuleSpec>
18
15
 
19
- @end
20
-
21
16
  #else
22
17
 
23
18
  #import <React/RCTBridgeModule.h>
24
19
 
25
-
26
20
  @interface RNAOA11yAnnounceModule : NSObject <RCTBridgeModule>
27
21
 
28
- - (void)announce:(NSString *)message;
22
+ - (void)announce:(NSString *)message
23
+ options:(NSDictionary *)options
24
+ resolve:(RCTPromiseResolveBlock)resolve
25
+ reject:(RCTPromiseRejectBlock)reject;
29
26
 
30
- @end
27
+ - (void)cancel:(NSString *)announcementId
28
+ resolve:(RCTPromiseResolveBlock)resolve
29
+ reject:(RCTPromiseRejectBlock)reject;
30
+
31
+ - (void)cancelAll:(RCTPromiseResolveBlock)resolve
32
+ reject:(RCTPromiseRejectBlock)reject;
31
33
 
32
34
  #endif
33
35
 
36
+ @end
37
+
34
38
  #endif /* RNAOA11yAnnounceModule_h */
@@ -1,40 +1,246 @@
1
1
  //
2
- // RNAOA11yAnnounceModule.m
2
+ // RNAOA11yAnnounceModule.mm
3
3
  // react-native-a11y-order
4
4
  //
5
- // Created by Artur Kalach on 06/12/2025.
6
- //
7
5
 
8
6
  #import <Foundation/Foundation.h>
7
+ #import <UIKit/UIKit.h>
9
8
  #import "RNAOA11yAnnounceModule.h"
10
9
  #import "RNAOA11yAnnounceService.h"
10
+ #import "RNAOSpeechAttributes.h"
11
11
 
12
12
  #ifdef RCT_NEW_ARCH_ENABLED
13
-
14
13
  using namespace facebook::react;
15
-
16
14
  #endif
17
15
 
16
+ // ─────────────────────────────────────────────────────────────────────────────
17
+ // MARK: - Pending entry
18
+ // ─────────────────────────────────────────────────────────────────────────────
19
+
20
+ @interface RNAOPendingAnnouncement : NSObject
21
+ @property (nonatomic, copy) RCTPromiseResolveBlock resolve;
22
+ @property (nonatomic, copy) NSString *text; // for direct-mode finish-notification matching
23
+ @property (nonatomic, assign) BOOL isDirect;
24
+ @end
25
+ @implementation RNAOPendingAnnouncement
26
+ @end
27
+
28
+
29
+ // ─────────────────────────────────────────────────────────────────────────────
30
+ // MARK: - Private interface
31
+ // ─────────────────────────────────────────────────────────────────────────────
32
+
33
+ @interface RNAOA11yAnnounceModule ()
34
+
35
+ // Single source of truth: announcementId → entry.
36
+ @property (nonatomic, strong) NSMutableDictionary<NSString *, RNAOPendingAnnouncement *> *pending;
37
+
38
+ // At most one direct announcement is in-flight; pointer into `pending`.
39
+ @property (nonatomic, copy, nullable) NSString *currentDirectId;
40
+
41
+ @end
42
+
43
+
44
+ // ─────────────────────────────────────────────────────────────────────────────
45
+ // MARK: - Implementation
46
+ // ─────────────────────────────────────────────────────────────────────────────
47
+
18
48
  @implementation RNAOA11yAnnounceModule
19
49
 
50
+ + (BOOL)requiresMainQueueSetup { return YES; }
20
51
 
21
- + (BOOL)requiresMainQueueSetup
22
- {
23
- return YES;
52
+ RCT_EXPORT_MODULE(A11yAnnounceModule);
53
+
54
+ - (instancetype)init {
55
+ if (self = [super init]) {
56
+ _pending = [NSMutableDictionary new];
57
+ [[NSNotificationCenter defaultCenter]
58
+ addObserver:self
59
+ selector:@selector(_handleAnnouncementFinished:)
60
+ name:UIAccessibilityAnnouncementDidFinishNotification
61
+ object:nil];
62
+ }
63
+ return self;
24
64
  }
25
65
 
66
+ - (void)dealloc {
67
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
68
+ }
26
69
 
27
- RCT_EXPORT_MODULE(A11yAnnounceModule);
28
70
 
29
- RCT_EXPORT_METHOD(announce: (nonnull NSString*) title) {
30
- [[RNAOA11yAnnounceService shared] announce: title];
71
+ // ─────────────────────────────────────────────────────────────────────────────
72
+ // MARK: - announce (arch-split: C++ struct vs NSDictionary)
73
+ // ─────────────────────────────────────────────────────────────────────────────
74
+
75
+ /**
76
+ * calm: true — Routes through RNAOA11yAnnounceService (300 ms debounce +
77
+ * navigation-lock + VoiceOver-state guard). Promise resolves
78
+ * when the service **actually fires** the announcement, not just
79
+ * when it is enqueued, so `await` is meaningful.
80
+ *
81
+ * calm: false — Posts via UIAccessibilityPostNotification with speech attrs.
82
+ * Promise resolves when UIAccessibilityAnnouncementDidFinishNotification
83
+ * fires ('spoken') or the announcement is interrupted ('fired').
84
+ */
85
+ - (void)_announceMessage:(NSString *)message
86
+ opts:(NSDictionary *)opts
87
+ resolve:(RCTPromiseResolveBlock)resolve
88
+ reject:(RCTPromiseRejectBlock)reject
89
+ {
90
+ if (!message || [message stringByTrimmingCharactersInSet:
91
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0) {
92
+ message = @"";
93
+ }
94
+
95
+ NSString *announcementId = [[NSUUID UUID] UUIDString];
96
+ BOOL calm = [opts[@"calm"] boolValue];
97
+
98
+ RNAOPendingAnnouncement *entry = [RNAOPendingAnnouncement new];
99
+ entry.resolve = resolve;
100
+ entry.text = message;
101
+ entry.isDirect = !calm;
102
+ self.pending[announcementId] = entry;
103
+
104
+ if (calm) {
105
+ __weak RNAOA11yAnnounceModule *weakSelf = self;
106
+ [[RNAOA11yAnnounceService shared] announce:message onFired:^{
107
+ // Guard against cancel:id that already removed the entry — avoids double-resolve.
108
+ [weakSelf _resolveId:announcementId status:@"fired"];
109
+ }];
110
+ return;
111
+ }
112
+
113
+ // Direct mode: at most one in-flight; supersede any previous.
114
+ if (self.currentDirectId && ![self.currentDirectId isEqualToString:announcementId]) {
115
+ [self _resolveId:self.currentDirectId status:@"fired"];
116
+ }
117
+ self.currentDirectId = announcementId;
118
+
119
+ NSAttributedString *attrStr = [RNAOSpeechAttributes attributedStringFor:message options:opts];
120
+ NSTimeInterval delayMs = [opts[@"delayMs"] doubleValue];
121
+
122
+ dispatch_block_t post = ^{
123
+ UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, attrStr);
124
+ };
125
+
126
+ if (delayMs > 0) {
127
+ dispatch_after(
128
+ dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayMs * NSEC_PER_MSEC)),
129
+ dispatch_get_main_queue(),
130
+ post
131
+ );
132
+ } else {
133
+ dispatch_async(dispatch_get_main_queue(), post);
134
+ }
31
135
  }
32
136
 
33
137
  #ifdef RCT_NEW_ARCH_ENABLED
34
- - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
35
- return std::make_shared<facebook::react::NativeA11yAnnounceModuleSpecJSI>(params);
138
+
139
+ - (void)announce:(NSString *)message
140
+ options:(JS::NativeA11yAnnounceModule::AnnounceOptions &)options
141
+ resolve:(RCTPromiseResolveBlock)resolve
142
+ reject:(RCTPromiseRejectBlock)reject
143
+ {
144
+ NSMutableDictionary *opts = [NSMutableDictionary new];
145
+
146
+ if (options.calm().has_value()) opts[@"calm"] = @(*options.calm());
147
+ if (options.priority()) opts[@"priority"] = options.priority();
148
+ if (options.queue().has_value()) opts[@"queue"] = @(*options.queue());
149
+ if (options.delayMs().has_value()) opts[@"delayMs"] = @(*options.delayMs());
150
+ // Speech options (flat at bridge level, grouped under `speech` in JS API)
151
+ if (options.language()) opts[@"language"] = options.language();
152
+ if (options.pitch().has_value()) opts[@"pitch"] = @(*options.pitch());
153
+ if (options.spellOut().has_value()) opts[@"spellOut"] = @(*options.spellOut());
154
+ if (options.punctuation().has_value()) opts[@"punctuation"] = @(*options.punctuation());
155
+ if (options.ipaNotation()) opts[@"ipaNotation"] = options.ipaNotation();
156
+
157
+ [self _announceMessage:message opts:opts resolve:resolve reject:reject];
36
158
  }
37
159
 
160
+ #else
161
+
162
+ RCT_EXPORT_METHOD(announce:(NSString *)message
163
+ options:(NSDictionary *)options
164
+ resolve:(RCTPromiseResolveBlock)resolve
165
+ reject:(RCTPromiseRejectBlock)reject)
166
+ {
167
+ NSDictionary *opts = ([options isKindOfClass:[NSDictionary class]]) ? options : @{};
168
+ [self _announceMessage:message opts:opts resolve:resolve reject:reject];
169
+ }
170
+
171
+ #endif // RCT_NEW_ARCH_ENABLED
172
+
173
+
174
+ // ─────────────────────────────────────────────────────────────────────────────
175
+ // MARK: - cancel / cancelAll
176
+ // ─────────────────────────────────────────────────────────────────────────────
177
+
178
+ RCT_EXPORT_METHOD(cancel:(NSString *)announcementId
179
+ resolve:(RCTPromiseResolveBlock)resolve
180
+ reject:(RCTPromiseRejectBlock)reject)
181
+ {
182
+ [self _resolveId:announcementId status:@"cancelled"];
183
+ resolve(@{ @"id": announcementId ?: @"", @"status": @"cancelled" });
184
+ }
185
+
186
+ RCT_EXPORT_METHOD(cancelAll:(RCTPromiseResolveBlock)resolve
187
+ reject:(RCTPromiseRejectBlock)reject)
188
+ {
189
+ [[RNAOA11yAnnounceService shared] cancelAll];
190
+
191
+ NSDictionary<NSString *, RNAOPendingAnnouncement *> *snapshot = [self.pending copy];
192
+ [self.pending removeAllObjects];
193
+ self.currentDirectId = nil;
194
+
195
+ for (NSString *aid in snapshot) {
196
+ snapshot[aid].resolve(@{ @"id": aid, @"status": @"cancelled" });
197
+ }
198
+ resolve(@{ @"id": @"", @"status": @"cancelled" });
199
+ }
200
+
201
+
202
+ // ─────────────────────────────────────────────────────────────────────────────
203
+ // MARK: - VoiceOver finish notification (direct mode only)
204
+ // ─────────────────────────────────────────────────────────────────────────────
205
+
206
+ - (void)_handleAnnouncementFinished:(NSNotification *)note {
207
+ NSString *directId = self.currentDirectId;
208
+ if (!directId) return;
209
+
210
+ RNAOPendingAnnouncement *entry = self.pending[directId];
211
+ if (!entry) return;
212
+
213
+ NSString *spokenText = note.userInfo[UIAccessibilityAnnouncementKeyStringValue];
214
+ if (![entry.text isEqualToString:spokenText]) return;
215
+
216
+ BOOL wasSuccessful = [note.userInfo[UIAccessibilityAnnouncementKeyWasSuccessful] boolValue];
217
+ [self _resolveId:directId status:wasSuccessful ? @"spoken" : @"fired"];
218
+ }
219
+
220
+
221
+ // ─────────────────────────────────────────────────────────────────────────────
222
+ // MARK: - Resolve helper
223
+ // ─────────────────────────────────────────────────────────────────────────────
224
+
225
+ - (void)_resolveId:(NSString *)announcementId status:(NSString *)status {
226
+ if (!announcementId) return;
227
+ RNAOPendingAnnouncement *entry = self.pending[announcementId];
228
+ if (!entry) return;
229
+
230
+ [self.pending removeObjectForKey:announcementId];
231
+ if ([self.currentDirectId isEqualToString:announcementId]) {
232
+ self.currentDirectId = nil;
233
+ }
234
+ entry.resolve(@{ @"id": announcementId, @"status": status });
235
+ }
236
+
237
+
238
+ #ifdef RCT_NEW_ARCH_ENABLED
239
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
240
+ (const facebook::react::ObjCTurboModule::InitParams &)params
241
+ {
242
+ return std::make_shared<facebook::react::NativeA11yAnnounceModuleSpecJSI>(params);
243
+ }
38
244
  #endif
39
- @end
40
245
 
246
+ @end
@@ -15,10 +15,20 @@
15
15
 
16
16
  + (instancetype)shared;
17
17
 
18
+ /**
19
+ * Enqueues `announcement` and schedules a navigation-aware debounced post.
20
+ * `onFired` is called on the main queue when the service actually speaks
21
+ * the announcement. Pass nil if no completion callback is needed.
22
+ * If cancelAll is called before the service fires, `onFired` is NOT called.
23
+ */
24
+ - (void)announce:(NSString *)announcement onFired:(nullable dispatch_block_t)onFired;
25
+
26
+ /** Convenience — equivalent to announce:onFired:nil. */
18
27
  - (void)announce:(NSString *)announcement;
28
+
29
+ - (void)cancelAll;
19
30
  - (void)temporarilyLockAnnounce;
20
31
  - (void)temporarilyLockAnnounce:(NSTimeInterval)interval;
21
- //@property (nonatomic, assign) BOOL announceLock;
22
32
 
23
33
  @end
24
34