one 1.2.69 → 1.2.71

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 (292) hide show
  1. package/dist/cjs/__mocks__/@react-navigation/native-stack.cjs +29 -0
  2. package/dist/cjs/__mocks__/@react-navigation/native-stack.js +24 -0
  3. package/dist/cjs/__mocks__/@react-navigation/native-stack.js.map +6 -0
  4. package/dist/cjs/__mocks__/@react-navigation/native-stack.native.js +38 -0
  5. package/dist/cjs/__mocks__/@react-navigation/native-stack.native.js.map +1 -0
  6. package/dist/cjs/__mocks__/@react-navigation/native.js +45 -0
  7. package/dist/cjs/__mocks__/@react-navigation/native.js.map +1 -0
  8. package/dist/cjs/__mocks__/expo-linking.cjs +36 -0
  9. package/dist/cjs/__mocks__/expo-linking.js +25 -0
  10. package/dist/cjs/__mocks__/expo-linking.js.map +6 -0
  11. package/dist/cjs/__mocks__/expo-linking.native.js +47 -0
  12. package/dist/cjs/__mocks__/expo-linking.native.js.map +1 -0
  13. package/dist/cjs/__mocks__/expo-modules-core.cjs +36 -0
  14. package/dist/cjs/__mocks__/expo-modules-core.js +31 -0
  15. package/dist/cjs/__mocks__/expo-modules-core.js.map +6 -0
  16. package/dist/cjs/__mocks__/expo-modules-core.native.js +67 -0
  17. package/dist/cjs/__mocks__/expo-modules-core.native.js.map +1 -0
  18. package/dist/cjs/__mocks__/react-native-screens.cjs +28 -0
  19. package/dist/cjs/__mocks__/react-native-screens.js +22 -0
  20. package/dist/cjs/__mocks__/react-native-screens.js.map +6 -0
  21. package/dist/cjs/__mocks__/react-native-screens.native.js +31 -0
  22. package/dist/cjs/__mocks__/react-native-screens.native.js.map +1 -0
  23. package/dist/cjs/__mocks__/react-native.js +49 -0
  24. package/dist/cjs/__mocks__/react-native.js.map +1 -0
  25. package/dist/cjs/cli/build.cjs +9 -1
  26. package/dist/cjs/cli/build.js +8 -1
  27. package/dist/cjs/cli/build.js.map +1 -1
  28. package/dist/cjs/cli/build.native.js +13 -1
  29. package/dist/cjs/cli/build.native.js.map +1 -1
  30. package/dist/cjs/fork/NavigationContainer.js.map +1 -1
  31. package/dist/cjs/fork/NavigationContainer.native.js.map +1 -1
  32. package/dist/cjs/index.js.map +1 -1
  33. package/dist/cjs/layouts/Stack.cjs +75 -6
  34. package/dist/cjs/layouts/Stack.js +44 -4
  35. package/dist/cjs/layouts/Stack.js.map +2 -2
  36. package/dist/cjs/layouts/Stack.native.js +81 -6
  37. package/dist/cjs/layouts/Stack.native.js.map +1 -1
  38. package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.cjs +40 -0
  39. package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.js +35 -0
  40. package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.js.map +6 -0
  41. package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.native.js +43 -0
  42. package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.native.js.map +1 -0
  43. package/dist/cjs/layouts/stack-utils/StackHeaderComponent.cjs +90 -0
  44. package/dist/cjs/layouts/stack-utils/StackHeaderComponent.js +68 -0
  45. package/dist/cjs/layouts/stack-utils/StackHeaderComponent.js.map +6 -0
  46. package/dist/cjs/layouts/stack-utils/StackHeaderComponent.native.js +99 -0
  47. package/dist/cjs/layouts/stack-utils/StackHeaderComponent.native.js.map +1 -0
  48. package/dist/cjs/layouts/stack-utils/StackHeaderLeft.cjs +35 -0
  49. package/dist/cjs/layouts/stack-utils/StackHeaderLeft.js +30 -0
  50. package/dist/cjs/layouts/stack-utils/StackHeaderLeft.js.map +6 -0
  51. package/dist/cjs/layouts/stack-utils/StackHeaderLeft.native.js +40 -0
  52. package/dist/cjs/layouts/stack-utils/StackHeaderLeft.native.js.map +1 -0
  53. package/dist/cjs/layouts/stack-utils/StackHeaderRight.cjs +35 -0
  54. package/dist/cjs/layouts/stack-utils/StackHeaderRight.js +30 -0
  55. package/dist/cjs/layouts/stack-utils/StackHeaderRight.js.map +6 -0
  56. package/dist/cjs/layouts/stack-utils/StackHeaderRight.native.js +40 -0
  57. package/dist/cjs/layouts/stack-utils/StackHeaderRight.native.js.map +1 -0
  58. package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.cjs +35 -0
  59. package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.js +30 -0
  60. package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.js.map +6 -0
  61. package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.native.js +38 -0
  62. package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.native.js.map +1 -0
  63. package/dist/cjs/layouts/stack-utils/StackHeaderTitle.cjs +65 -0
  64. package/dist/cjs/layouts/stack-utils/StackHeaderTitle.js +52 -0
  65. package/dist/cjs/layouts/stack-utils/StackHeaderTitle.js.map +6 -0
  66. package/dist/cjs/layouts/stack-utils/StackHeaderTitle.native.js +68 -0
  67. package/dist/cjs/layouts/stack-utils/StackHeaderTitle.native.js.map +1 -0
  68. package/dist/cjs/layouts/stack-utils/StackScreen.cjs +57 -0
  69. package/dist/cjs/layouts/stack-utils/StackScreen.js +43 -0
  70. package/dist/cjs/layouts/stack-utils/StackScreen.js.map +6 -0
  71. package/dist/cjs/layouts/stack-utils/StackScreen.native.js +64 -0
  72. package/dist/cjs/layouts/stack-utils/StackScreen.native.js.map +1 -0
  73. package/dist/cjs/layouts/stack-utils/__tests__/composition.test.cjs +455 -0
  74. package/dist/cjs/layouts/stack-utils/__tests__/composition.test.js +406 -0
  75. package/dist/cjs/layouts/stack-utils/__tests__/composition.test.js.map +6 -0
  76. package/dist/cjs/layouts/stack-utils/__tests__/composition.test.native.js +480 -0
  77. package/dist/cjs/layouts/stack-utils/__tests__/composition.test.native.js.map +1 -0
  78. package/dist/cjs/layouts/stack-utils/index.cjs +47 -0
  79. package/dist/cjs/layouts/stack-utils/index.js +36 -0
  80. package/dist/cjs/layouts/stack-utils/index.js.map +6 -0
  81. package/dist/cjs/layouts/stack-utils/index.native.js +50 -0
  82. package/dist/cjs/layouts/stack-utils/index.native.js.map +1 -0
  83. package/dist/cjs/layouts/withLayoutContext.cjs +2 -1
  84. package/dist/cjs/layouts/withLayoutContext.js +2 -2
  85. package/dist/cjs/layouts/withLayoutContext.js.map +1 -1
  86. package/dist/cjs/layouts/withLayoutContext.native.js +3 -2
  87. package/dist/cjs/layouts/withLayoutContext.native.js.map +1 -1
  88. package/dist/cjs/useLoader.cjs +4 -2
  89. package/dist/cjs/useLoader.js +4 -2
  90. package/dist/cjs/useLoader.js.map +1 -1
  91. package/dist/cjs/useLoader.native.js +4 -2
  92. package/dist/cjs/useLoader.native.js.map +1 -1
  93. package/dist/cjs/utils/children.cjs +46 -0
  94. package/dist/cjs/utils/children.js +47 -0
  95. package/dist/cjs/utils/children.js.map +6 -0
  96. package/dist/cjs/utils/children.native.js +76 -0
  97. package/dist/cjs/utils/children.native.js.map +1 -0
  98. package/dist/cjs/utils/style.cjs +28 -0
  99. package/dist/cjs/utils/style.js +24 -0
  100. package/dist/cjs/utils/style.js.map +6 -0
  101. package/dist/cjs/utils/style.native.js +31 -0
  102. package/dist/cjs/utils/style.native.js.map +1 -0
  103. package/dist/esm/__mocks__/@react-navigation/native-stack.js +8 -0
  104. package/dist/esm/__mocks__/@react-navigation/native-stack.js.map +6 -0
  105. package/dist/esm/__mocks__/@react-navigation/native-stack.mjs +6 -0
  106. package/dist/esm/__mocks__/@react-navigation/native-stack.mjs.map +1 -0
  107. package/dist/esm/__mocks__/@react-navigation/native-stack.native.js +12 -0
  108. package/dist/esm/__mocks__/@react-navigation/native-stack.native.js.map +1 -0
  109. package/dist/esm/__mocks__/@react-navigation/native.js +18 -0
  110. package/dist/esm/__mocks__/@react-navigation/native.js.map +1 -0
  111. package/dist/esm/__mocks__/expo-linking.js +9 -0
  112. package/dist/esm/__mocks__/expo-linking.js.map +6 -0
  113. package/dist/esm/__mocks__/expo-linking.mjs +10 -0
  114. package/dist/esm/__mocks__/expo-linking.mjs.map +1 -0
  115. package/dist/esm/__mocks__/expo-linking.native.js +18 -0
  116. package/dist/esm/__mocks__/expo-linking.native.js.map +1 -0
  117. package/dist/esm/__mocks__/expo-modules-core.js +15 -0
  118. package/dist/esm/__mocks__/expo-modules-core.js.map +6 -0
  119. package/dist/esm/__mocks__/expo-modules-core.mjs +10 -0
  120. package/dist/esm/__mocks__/expo-modules-core.mjs.map +1 -0
  121. package/dist/esm/__mocks__/expo-modules-core.native.js +38 -0
  122. package/dist/esm/__mocks__/expo-modules-core.native.js.map +1 -0
  123. package/dist/esm/__mocks__/react-native-screens.js +6 -0
  124. package/dist/esm/__mocks__/react-native-screens.js.map +6 -0
  125. package/dist/esm/__mocks__/react-native-screens.mjs +4 -0
  126. package/dist/esm/__mocks__/react-native-screens.mjs.map +1 -0
  127. package/dist/esm/__mocks__/react-native-screens.native.js +4 -0
  128. package/dist/esm/__mocks__/react-native-screens.native.js.map +1 -0
  129. package/dist/esm/__mocks__/react-native.js +19 -0
  130. package/dist/esm/__mocks__/react-native.js.map +1 -0
  131. package/dist/esm/cli/build.js +8 -1
  132. package/dist/esm/cli/build.js.map +1 -1
  133. package/dist/esm/cli/build.mjs +9 -1
  134. package/dist/esm/cli/build.mjs.map +1 -1
  135. package/dist/esm/cli/build.native.js +13 -1
  136. package/dist/esm/cli/build.native.js.map +1 -1
  137. package/dist/esm/fork/NavigationContainer.js.map +1 -1
  138. package/dist/esm/fork/NavigationContainer.mjs.map +1 -1
  139. package/dist/esm/fork/NavigationContainer.native.js.map +1 -1
  140. package/dist/esm/index.js.map +1 -1
  141. package/dist/esm/index.mjs.map +1 -1
  142. package/dist/esm/index.native.js.map +1 -1
  143. package/dist/esm/layouts/Stack.js +45 -1
  144. package/dist/esm/layouts/Stack.js.map +1 -1
  145. package/dist/esm/layouts/Stack.mjs +59 -1
  146. package/dist/esm/layouts/Stack.mjs.map +1 -1
  147. package/dist/esm/layouts/Stack.native.js +65 -1
  148. package/dist/esm/layouts/Stack.native.js.map +1 -1
  149. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.js +19 -0
  150. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.js.map +6 -0
  151. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.mjs +16 -0
  152. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.mjs.map +1 -0
  153. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.native.js +16 -0
  154. package/dist/esm/layouts/stack-utils/StackHeaderBackButton.native.js.map +1 -0
  155. package/dist/esm/layouts/stack-utils/StackHeaderComponent.js +71 -0
  156. package/dist/esm/layouts/stack-utils/StackHeaderComponent.js.map +6 -0
  157. package/dist/esm/layouts/stack-utils/StackHeaderComponent.mjs +66 -0
  158. package/dist/esm/layouts/stack-utils/StackHeaderComponent.mjs.map +1 -0
  159. package/dist/esm/layouts/stack-utils/StackHeaderComponent.native.js +72 -0
  160. package/dist/esm/layouts/stack-utils/StackHeaderComponent.native.js.map +1 -0
  161. package/dist/esm/layouts/stack-utils/StackHeaderLeft.js +14 -0
  162. package/dist/esm/layouts/stack-utils/StackHeaderLeft.js.map +6 -0
  163. package/dist/esm/layouts/stack-utils/StackHeaderLeft.mjs +11 -0
  164. package/dist/esm/layouts/stack-utils/StackHeaderLeft.mjs.map +1 -0
  165. package/dist/esm/layouts/stack-utils/StackHeaderLeft.native.js +13 -0
  166. package/dist/esm/layouts/stack-utils/StackHeaderLeft.native.js.map +1 -0
  167. package/dist/esm/layouts/stack-utils/StackHeaderRight.js +14 -0
  168. package/dist/esm/layouts/stack-utils/StackHeaderRight.js.map +6 -0
  169. package/dist/esm/layouts/stack-utils/StackHeaderRight.mjs +11 -0
  170. package/dist/esm/layouts/stack-utils/StackHeaderRight.mjs.map +1 -0
  171. package/dist/esm/layouts/stack-utils/StackHeaderRight.native.js +13 -0
  172. package/dist/esm/layouts/stack-utils/StackHeaderRight.native.js.map +1 -0
  173. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.js +14 -0
  174. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.js.map +6 -0
  175. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.mjs +11 -0
  176. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.mjs.map +1 -0
  177. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.native.js +11 -0
  178. package/dist/esm/layouts/stack-utils/StackHeaderSearchBar.native.js.map +1 -0
  179. package/dist/esm/layouts/stack-utils/StackHeaderTitle.js +37 -0
  180. package/dist/esm/layouts/stack-utils/StackHeaderTitle.js.map +6 -0
  181. package/dist/esm/layouts/stack-utils/StackHeaderTitle.mjs +41 -0
  182. package/dist/esm/layouts/stack-utils/StackHeaderTitle.mjs.map +1 -0
  183. package/dist/esm/layouts/stack-utils/StackHeaderTitle.native.js +41 -0
  184. package/dist/esm/layouts/stack-utils/StackHeaderTitle.native.js.map +1 -0
  185. package/dist/esm/layouts/stack-utils/StackScreen.js +33 -0
  186. package/dist/esm/layouts/stack-utils/StackScreen.js.map +6 -0
  187. package/dist/esm/layouts/stack-utils/StackScreen.mjs +33 -0
  188. package/dist/esm/layouts/stack-utils/StackScreen.mjs.map +1 -0
  189. package/dist/esm/layouts/stack-utils/StackScreen.native.js +38 -0
  190. package/dist/esm/layouts/stack-utils/StackScreen.native.js.map +1 -0
  191. package/dist/esm/layouts/stack-utils/__tests__/composition.test.js +431 -0
  192. package/dist/esm/layouts/stack-utils/__tests__/composition.test.js.map +6 -0
  193. package/dist/esm/layouts/stack-utils/__tests__/composition.test.mjs +456 -0
  194. package/dist/esm/layouts/stack-utils/__tests__/composition.test.mjs.map +1 -0
  195. package/dist/esm/layouts/stack-utils/__tests__/composition.test.native.js +478 -0
  196. package/dist/esm/layouts/stack-utils/__tests__/composition.test.native.js.map +1 -0
  197. package/dist/esm/layouts/stack-utils/index.js +33 -0
  198. package/dist/esm/layouts/stack-utils/index.js.map +6 -0
  199. package/dist/esm/layouts/stack-utils/index.mjs +16 -0
  200. package/dist/esm/layouts/stack-utils/index.mjs.map +1 -0
  201. package/dist/esm/layouts/stack-utils/index.native.js +16 -0
  202. package/dist/esm/layouts/stack-utils/index.native.js.map +1 -0
  203. package/dist/esm/layouts/withLayoutContext.js +2 -1
  204. package/dist/esm/layouts/withLayoutContext.js.map +1 -1
  205. package/dist/esm/layouts/withLayoutContext.mjs +2 -1
  206. package/dist/esm/layouts/withLayoutContext.mjs.map +1 -1
  207. package/dist/esm/layouts/withLayoutContext.native.js +2 -1
  208. package/dist/esm/layouts/withLayoutContext.native.js.map +1 -1
  209. package/dist/esm/useLoader.js +4 -2
  210. package/dist/esm/useLoader.js.map +1 -1
  211. package/dist/esm/useLoader.mjs +4 -2
  212. package/dist/esm/useLoader.mjs.map +1 -1
  213. package/dist/esm/useLoader.native.js +4 -2
  214. package/dist/esm/useLoader.native.js.map +1 -1
  215. package/dist/esm/utils/children.js +33 -0
  216. package/dist/esm/utils/children.js.map +6 -0
  217. package/dist/esm/utils/children.mjs +19 -0
  218. package/dist/esm/utils/children.mjs.map +1 -0
  219. package/dist/esm/utils/children.native.js +46 -0
  220. package/dist/esm/utils/children.native.js.map +1 -0
  221. package/dist/esm/utils/style.js +8 -0
  222. package/dist/esm/utils/style.js.map +6 -0
  223. package/dist/esm/utils/style.mjs +5 -0
  224. package/dist/esm/utils/style.mjs.map +1 -0
  225. package/dist/esm/utils/style.native.js +5 -0
  226. package/dist/esm/utils/style.native.js.map +1 -0
  227. package/package.json +9 -9
  228. package/src/__mocks__/@react-navigation/native-stack.ts +32 -0
  229. package/src/__mocks__/@react-navigation/native.ts +21 -0
  230. package/src/__mocks__/expo-linking.ts +6 -0
  231. package/src/__mocks__/expo-modules-core.ts +11 -0
  232. package/src/__mocks__/react-native-screens.ts +17 -0
  233. package/src/__mocks__/react-native.ts +20 -0
  234. package/src/cli/build.ts +27 -2
  235. package/src/fork/NavigationContainer.tsx +2 -0
  236. package/src/index.ts +10 -0
  237. package/src/layouts/Stack.tsx +96 -1
  238. package/src/layouts/stack-utils/README.md +211 -0
  239. package/src/layouts/stack-utils/StackHeaderBackButton.tsx +34 -0
  240. package/src/layouts/stack-utils/StackHeaderComponent.tsx +136 -0
  241. package/src/layouts/stack-utils/StackHeaderLeft.tsx +29 -0
  242. package/src/layouts/stack-utils/StackHeaderRight.tsx +29 -0
  243. package/src/layouts/stack-utils/StackHeaderSearchBar.tsx +21 -0
  244. package/src/layouts/stack-utils/StackHeaderTitle.tsx +79 -0
  245. package/src/layouts/stack-utils/StackScreen.tsx +69 -0
  246. package/src/layouts/stack-utils/__tests__/composition.test.tsx +643 -0
  247. package/src/layouts/stack-utils/index.tsx +45 -0
  248. package/src/layouts/withLayoutContext.tsx +6 -2
  249. package/src/router/router.ts +1 -1
  250. package/src/useLoader.ts +14 -6
  251. package/src/utils/children.ts +74 -0
  252. package/src/utils/style.ts +17 -0
  253. package/types/__mocks__/@react-navigation/native-stack.d.ts +30 -0
  254. package/types/__mocks__/@react-navigation/native-stack.d.ts.map +1 -0
  255. package/types/__mocks__/@react-navigation/native.d.ts +17 -0
  256. package/types/__mocks__/@react-navigation/native.d.ts.map +1 -0
  257. package/types/__mocks__/expo-linking.d.ts +9 -0
  258. package/types/__mocks__/expo-linking.d.ts.map +1 -0
  259. package/types/__mocks__/expo-modules-core.d.ts +11 -0
  260. package/types/__mocks__/expo-modules-core.d.ts.map +1 -0
  261. package/types/__mocks__/react-native-screens.d.ts +14 -0
  262. package/types/__mocks__/react-native-screens.d.ts.map +1 -0
  263. package/types/__mocks__/react-native.d.ts +12 -0
  264. package/types/__mocks__/react-native.d.ts.map +1 -0
  265. package/types/cli/build.d.ts.map +1 -1
  266. package/types/fork/NavigationContainer.d.ts.map +1 -1
  267. package/types/index.d.ts +1 -0
  268. package/types/index.d.ts.map +1 -1
  269. package/types/layouts/Stack.d.ts +14 -3
  270. package/types/layouts/Stack.d.ts.map +1 -1
  271. package/types/layouts/stack-utils/StackHeaderBackButton.d.ts +17 -0
  272. package/types/layouts/stack-utils/StackHeaderBackButton.d.ts.map +1 -0
  273. package/types/layouts/stack-utils/StackHeaderComponent.d.ts +36 -0
  274. package/types/layouts/stack-utils/StackHeaderComponent.d.ts.map +1 -0
  275. package/types/layouts/stack-utils/StackHeaderLeft.d.ts +13 -0
  276. package/types/layouts/stack-utils/StackHeaderLeft.d.ts.map +1 -0
  277. package/types/layouts/stack-utils/StackHeaderRight.d.ts +13 -0
  278. package/types/layouts/stack-utils/StackHeaderRight.d.ts.map +1 -0
  279. package/types/layouts/stack-utils/StackHeaderSearchBar.d.ts +10 -0
  280. package/types/layouts/stack-utils/StackHeaderSearchBar.d.ts.map +1 -0
  281. package/types/layouts/stack-utils/StackHeaderTitle.d.ts +26 -0
  282. package/types/layouts/stack-utils/StackHeaderTitle.d.ts.map +1 -0
  283. package/types/layouts/stack-utils/StackScreen.d.ts +22 -0
  284. package/types/layouts/stack-utils/StackScreen.d.ts.map +1 -0
  285. package/types/layouts/stack-utils/index.d.ts +20 -0
  286. package/types/layouts/stack-utils/index.d.ts.map +1 -0
  287. package/types/layouts/withLayoutContext.d.ts.map +1 -1
  288. package/types/useLoader.d.ts.map +1 -1
  289. package/types/utils/children.d.ts +23 -0
  290. package/types/utils/children.d.ts.map +1 -0
  291. package/types/utils/style.d.ts +7 -0
  292. package/types/utils/style.d.ts.map +1 -0
@@ -0,0 +1,69 @@
1
+ 'use client'
2
+
3
+ import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
4
+ import { Children, isValidElement, useMemo, type PropsWithChildren } from 'react'
5
+
6
+ import {
7
+ StackHeaderComponent,
8
+ appendStackHeaderPropsToOptions,
9
+ type StackHeaderProps,
10
+ } from './StackHeaderComponent'
11
+ import { Screen } from '../../views/Screen'
12
+
13
+ export interface StackScreenProps extends PropsWithChildren {
14
+ name?: string
15
+ options?: NativeStackNavigationOptions
16
+ }
17
+
18
+ /**
19
+ * Stack screen component with support for compositional header configuration.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <Stack.Screen name="home" options={{ title: 'Home' }}>
24
+ * <Stack.Header>
25
+ * <Stack.Header.Title large>Welcome</Stack.Header.Title>
26
+ * <Stack.Header.SearchBar placeholder="Search..." />
27
+ * </Stack.Header>
28
+ * </Stack.Screen>
29
+ * ```
30
+ */
31
+ export function StackScreen({ children, options, ...rest }: StackScreenProps) {
32
+ const updatedOptions = useMemo(
33
+ () =>
34
+ appendScreenStackPropsToOptions(options ?? {}, {
35
+ children,
36
+ }),
37
+ [options, children]
38
+ )
39
+ return <Screen {...rest} options={updatedOptions} />
40
+ }
41
+
42
+ export function appendScreenStackPropsToOptions(
43
+ options: NativeStackNavigationOptions,
44
+ props: StackScreenProps
45
+ ): NativeStackNavigationOptions {
46
+ let updatedOptions = { ...options, ...props.options }
47
+
48
+ function appendChildOptions(
49
+ child: React.ReactElement,
50
+ options: NativeStackNavigationOptions
51
+ ) {
52
+ if (child.type === StackHeaderComponent) {
53
+ return appendStackHeaderPropsToOptions(options, child.props as StackHeaderProps)
54
+ } else {
55
+ console.warn(
56
+ `Warning: Unknown child element passed to Stack.Screen: ${(child.type as { name: string }).name ?? child.type}`
57
+ )
58
+ }
59
+ return options
60
+ }
61
+
62
+ Children.forEach(props.children, (child) => {
63
+ if (isValidElement(child)) {
64
+ updatedOptions = appendChildOptions(child, updatedOptions)
65
+ }
66
+ })
67
+
68
+ return updatedOptions
69
+ }
@@ -0,0 +1,643 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import React from 'react'
3
+ import { Platform } from 'react-native'
4
+
5
+ import {
6
+ StackHeaderTitle,
7
+ appendStackHeaderTitlePropsToOptions,
8
+ } from '../StackHeaderTitle'
9
+ import { StackHeaderLeft, appendStackHeaderLeftPropsToOptions } from '../StackHeaderLeft'
10
+ import {
11
+ StackHeaderRight,
12
+ appendStackHeaderRightPropsToOptions,
13
+ } from '../StackHeaderRight'
14
+ import {
15
+ StackHeaderBackButton,
16
+ appendStackHeaderBackButtonPropsToOptions,
17
+ } from '../StackHeaderBackButton'
18
+ import {
19
+ StackHeaderSearchBar,
20
+ appendStackHeaderSearchBarPropsToOptions,
21
+ } from '../StackHeaderSearchBar'
22
+ import {
23
+ StackHeaderComponent,
24
+ appendStackHeaderPropsToOptions,
25
+ } from '../StackHeaderComponent'
26
+ import { appendScreenStackPropsToOptions } from '../StackScreen'
27
+ import { StackHeader } from '../index'
28
+
29
+ describe('Stack Header Composition', () => {
30
+ describe('StackHeaderTitle', () => {
31
+ it('sets title from children', () => {
32
+ const result = appendStackHeaderTitlePropsToOptions({}, { children: 'My Title' })
33
+ expect(result.title).toBe('My Title')
34
+ })
35
+
36
+ it('sets headerLargeTitle when large is true', () => {
37
+ const result = appendStackHeaderTitlePropsToOptions({}, { large: true })
38
+ expect(result.headerLargeTitle).toBe(true)
39
+ })
40
+
41
+ it('sets headerTitleAlign from style.textAlign', () => {
42
+ const result = appendStackHeaderTitlePropsToOptions(
43
+ {},
44
+ {
45
+ style: { textAlign: 'center' },
46
+ }
47
+ )
48
+ expect(result.headerTitleAlign).toBe('center')
49
+ })
50
+
51
+ it('converts numeric fontWeight to string', () => {
52
+ const result = appendStackHeaderTitlePropsToOptions(
53
+ {},
54
+ {
55
+ style: { fontWeight: '700' },
56
+ }
57
+ )
58
+ expect(result.headerTitleStyle).toMatchObject({ fontWeight: '700' })
59
+ })
60
+
61
+ it('preserves existing options', () => {
62
+ const result = appendStackHeaderTitlePropsToOptions(
63
+ { animation: 'slide_from_right' },
64
+ { children: 'Title' }
65
+ )
66
+ expect(result.animation).toBe('slide_from_right')
67
+ expect(result.title).toBe('Title')
68
+ })
69
+
70
+ it('sets headerTransparent only on iOS when large is true', () => {
71
+ // Store original Platform.OS
72
+ const originalOS = Platform.OS
73
+
74
+ // Test on iOS - should set headerTransparent
75
+ ;(Platform as any).OS = 'ios'
76
+ const iosResult = appendStackHeaderTitlePropsToOptions({}, { large: true })
77
+ expect(iosResult.headerTransparent).toBe(true)
78
+
79
+ // Test on Android - should NOT set headerTransparent
80
+ ;(Platform as any).OS = 'android'
81
+ const androidResult = appendStackHeaderTitlePropsToOptions({}, { large: true })
82
+ expect(androidResult.headerTransparent).toBeUndefined()
83
+
84
+ // Test on web - should NOT set headerTransparent
85
+ ;(Platform as any).OS = 'web'
86
+ const webResult = appendStackHeaderTitlePropsToOptions({}, { large: true })
87
+ expect(webResult.headerTransparent).toBeUndefined()
88
+
89
+ // Restore original
90
+ ;(Platform as any).OS = originalOS
91
+ })
92
+ })
93
+
94
+ describe('StackHeaderLeft', () => {
95
+ it('does not set headerLeft without asChild', () => {
96
+ const result = appendStackHeaderLeftPropsToOptions(
97
+ {},
98
+ {
99
+ children: <button>Back</button>,
100
+ }
101
+ )
102
+ expect(result.headerLeft).toBeUndefined()
103
+ })
104
+
105
+ it('sets headerLeft with asChild', () => {
106
+ const CustomButton = () => <button>Back</button>
107
+ const result = appendStackHeaderLeftPropsToOptions(
108
+ {},
109
+ {
110
+ asChild: true,
111
+ children: <CustomButton />,
112
+ }
113
+ )
114
+ expect(result.headerLeft).toBeDefined()
115
+ expect(typeof result.headerLeft).toBe('function')
116
+ })
117
+
118
+ it('sets headerLeft with asChild even without children', () => {
119
+ const result = appendStackHeaderLeftPropsToOptions({}, { asChild: true })
120
+ // headerLeft is set as a function that returns undefined children
121
+ expect(result.headerLeft).toBeDefined()
122
+ expect(typeof result.headerLeft).toBe('function')
123
+ })
124
+
125
+ it('preserves existing options when setting headerLeft', () => {
126
+ const result = appendStackHeaderLeftPropsToOptions(
127
+ { title: 'Existing Title', animation: 'slide_from_right' },
128
+ {
129
+ asChild: true,
130
+ children: <button>Back</button>,
131
+ }
132
+ )
133
+ expect(result.title).toBe('Existing Title')
134
+ expect(result.animation).toBe('slide_from_right')
135
+ expect(result.headerLeft).toBeDefined()
136
+ })
137
+
138
+ it('headerLeft function returns children when called', () => {
139
+ const BackButton = () => <button>Back</button>
140
+ const result = appendStackHeaderLeftPropsToOptions(
141
+ {},
142
+ {
143
+ asChild: true,
144
+ children: <BackButton />,
145
+ }
146
+ )
147
+ const headerLeftResult = result.headerLeft?.({} as any)
148
+ expect(headerLeftResult).toBeDefined()
149
+ })
150
+ })
151
+
152
+ describe('StackHeaderRight', () => {
153
+ it('does not set headerRight without asChild', () => {
154
+ const result = appendStackHeaderRightPropsToOptions(
155
+ {},
156
+ {
157
+ children: <button>Action</button>,
158
+ }
159
+ )
160
+ expect(result.headerRight).toBeUndefined()
161
+ })
162
+
163
+ it('sets headerRight with asChild', () => {
164
+ const CustomButton = () => <button>Action</button>
165
+ const result = appendStackHeaderRightPropsToOptions(
166
+ {},
167
+ {
168
+ asChild: true,
169
+ children: <CustomButton />,
170
+ }
171
+ )
172
+ expect(result.headerRight).toBeDefined()
173
+ expect(typeof result.headerRight).toBe('function')
174
+ })
175
+
176
+ it('sets headerRight with asChild even without children', () => {
177
+ const result = appendStackHeaderRightPropsToOptions({}, { asChild: true })
178
+ // headerRight is set as a function that returns undefined children
179
+ expect(result.headerRight).toBeDefined()
180
+ expect(typeof result.headerRight).toBe('function')
181
+ })
182
+
183
+ it('preserves existing options when setting headerRight', () => {
184
+ const result = appendStackHeaderRightPropsToOptions(
185
+ { title: 'Existing Title', headerLargeTitle: true },
186
+ {
187
+ asChild: true,
188
+ children: <button>Action</button>,
189
+ }
190
+ )
191
+ expect(result.title).toBe('Existing Title')
192
+ expect(result.headerLargeTitle).toBe(true)
193
+ expect(result.headerRight).toBeDefined()
194
+ })
195
+
196
+ it('headerRight function returns children when called', () => {
197
+ const ActionButton = () => <button>Action</button>
198
+ const result = appendStackHeaderRightPropsToOptions(
199
+ {},
200
+ {
201
+ asChild: true,
202
+ children: <ActionButton />,
203
+ }
204
+ )
205
+ const headerRightResult = result.headerRight?.({} as any)
206
+ expect(headerRightResult).toBeDefined()
207
+ })
208
+ })
209
+
210
+ describe('StackHeaderBackButton', () => {
211
+ it('sets headerBackTitle from children', () => {
212
+ const result = appendStackHeaderBackButtonPropsToOptions(
213
+ {},
214
+ {
215
+ children: 'Go Back',
216
+ }
217
+ )
218
+ expect(result.headerBackTitle).toBe('Go Back')
219
+ })
220
+
221
+ it('sets headerBackVisible to false when hidden', () => {
222
+ const result = appendStackHeaderBackButtonPropsToOptions(
223
+ {},
224
+ {
225
+ hidden: true,
226
+ }
227
+ )
228
+ expect(result.headerBackVisible).toBe(false)
229
+ })
230
+
231
+ it('sets headerBackButtonMenuEnabled', () => {
232
+ const result = appendStackHeaderBackButtonPropsToOptions(
233
+ {},
234
+ {
235
+ withMenu: true,
236
+ }
237
+ )
238
+ expect(result.headerBackButtonMenuEnabled).toBe(true)
239
+ })
240
+
241
+ it('sets headerBackButtonDisplayMode', () => {
242
+ const result = appendStackHeaderBackButtonPropsToOptions(
243
+ {},
244
+ {
245
+ displayMode: 'minimal',
246
+ }
247
+ )
248
+ expect(result.headerBackButtonDisplayMode).toBe('minimal')
249
+ })
250
+ })
251
+
252
+ describe('StackHeaderSearchBar', () => {
253
+ it('sets headerSearchBarOptions with placeholder', () => {
254
+ const result = appendStackHeaderSearchBarPropsToOptions(
255
+ {},
256
+ {
257
+ placeholder: 'Search...',
258
+ }
259
+ )
260
+ expect(result.headerSearchBarOptions).toMatchObject({
261
+ placeholder: 'Search...',
262
+ })
263
+ })
264
+
265
+ it('sets headerSearchBarOptions with autoCapitalize', () => {
266
+ const result = appendStackHeaderSearchBarPropsToOptions(
267
+ {},
268
+ {
269
+ autoCapitalize: 'none',
270
+ }
271
+ )
272
+ expect(result.headerSearchBarOptions).toMatchObject({
273
+ autoCapitalize: 'none',
274
+ })
275
+ })
276
+
277
+ it('sets headerSearchBarOptions with multiple props', () => {
278
+ const result = appendStackHeaderSearchBarPropsToOptions(
279
+ {},
280
+ {
281
+ placeholder: 'Search articles...',
282
+ autoCapitalize: 'words',
283
+ hideWhenScrolling: true,
284
+ obscureBackground: false,
285
+ }
286
+ )
287
+ expect(result.headerSearchBarOptions).toMatchObject({
288
+ placeholder: 'Search articles...',
289
+ autoCapitalize: 'words',
290
+ hideWhenScrolling: true,
291
+ obscureBackground: false,
292
+ })
293
+ })
294
+
295
+ it('preserves existing options when setting search bar', () => {
296
+ const result = appendStackHeaderSearchBarPropsToOptions(
297
+ { title: 'Articles', headerLargeTitle: true },
298
+ {
299
+ placeholder: 'Search...',
300
+ }
301
+ )
302
+ expect(result.title).toBe('Articles')
303
+ expect(result.headerLargeTitle).toBe(true)
304
+ expect(result.headerSearchBarOptions).toMatchObject({
305
+ placeholder: 'Search...',
306
+ })
307
+ })
308
+
309
+ it('sets headerSearchBarOptions with placement prop', () => {
310
+ const result = appendStackHeaderSearchBarPropsToOptions(
311
+ {},
312
+ {
313
+ placeholder: 'Search...',
314
+ placement: 'stacked',
315
+ }
316
+ )
317
+ expect(result.headerSearchBarOptions).toMatchObject({
318
+ placeholder: 'Search...',
319
+ placement: 'stacked',
320
+ })
321
+ })
322
+
323
+ it('sets empty headerSearchBarOptions when no props', () => {
324
+ const result = appendStackHeaderSearchBarPropsToOptions({}, {})
325
+ expect(result.headerSearchBarOptions).toBeDefined()
326
+ expect(result.headerSearchBarOptions).toEqual({})
327
+ })
328
+ })
329
+
330
+ describe('StackHeaderComponent', () => {
331
+ it('sets headerShown false when hidden', () => {
332
+ const result = appendStackHeaderPropsToOptions({}, { hidden: true })
333
+ expect(result.headerShown).toBe(false)
334
+ })
335
+
336
+ it('sets headerBlurEffect', () => {
337
+ const result = appendStackHeaderPropsToOptions({}, { blurEffect: 'regular' })
338
+ expect(result.headerBlurEffect).toBe('regular')
339
+ })
340
+
341
+ it('sets headerShadowVisible false when shadowColor is transparent', () => {
342
+ const result = appendStackHeaderPropsToOptions(
343
+ {},
344
+ {
345
+ style: { shadowColor: 'transparent' },
346
+ }
347
+ )
348
+ expect(result.headerShadowVisible).toBe(false)
349
+ })
350
+
351
+ it('sets headerTransparent when backgroundColor is transparent', () => {
352
+ const result = appendStackHeaderPropsToOptions(
353
+ {},
354
+ {
355
+ style: { backgroundColor: 'transparent' },
356
+ }
357
+ )
358
+
359
+ expect(result.headerTransparent).toBe(true)
360
+ expect(result.headerStyle).toMatchObject({ backgroundColor: 'transparent' })
361
+ })
362
+
363
+ it('sets headerTransparent with SearchBar (user controls via options if needed)', () => {
364
+ const result = appendStackHeaderPropsToOptions(
365
+ {},
366
+ {
367
+ style: { backgroundColor: 'transparent' },
368
+ children: <StackHeaderSearchBar placeholder="Search..." />,
369
+ }
370
+ )
371
+
372
+ // headerTransparent is set when backgroundColor is transparent
373
+ // Users can override with options={{ headerTransparent: false }} if no ScrollView
374
+ expect(result.headerTransparent).toBe(true)
375
+ expect(result.headerSearchBarOptions).toMatchObject({ placeholder: 'Search...' })
376
+ })
377
+
378
+ it('processes child Title component', () => {
379
+ const result = appendStackHeaderPropsToOptions(
380
+ {},
381
+ {
382
+ children: <StackHeaderTitle large>Test Title</StackHeaderTitle>,
383
+ }
384
+ )
385
+ expect(result.title).toBe('Test Title')
386
+ expect(result.headerLargeTitle).toBe(true)
387
+ })
388
+
389
+ it('processes child BackButton component', () => {
390
+ const result = appendStackHeaderPropsToOptions(
391
+ {},
392
+ {
393
+ children: <StackHeaderBackButton hidden>Back</StackHeaderBackButton>,
394
+ }
395
+ )
396
+ expect(result.headerBackTitle).toBe('Back')
397
+ expect(result.headerBackVisible).toBe(false)
398
+ })
399
+
400
+ it('processes multiple children', () => {
401
+ const result = appendStackHeaderPropsToOptions(
402
+ {},
403
+ {
404
+ children: [
405
+ <StackHeaderTitle key="title" large>
406
+ My Screen
407
+ </StackHeaderTitle>,
408
+ <StackHeaderBackButton key="back" hidden />,
409
+ ],
410
+ }
411
+ )
412
+ expect(result.title).toBe('My Screen')
413
+ expect(result.headerLargeTitle).toBe(true)
414
+ expect(result.headerBackVisible).toBe(false)
415
+ })
416
+
417
+ it('processes child Left component', () => {
418
+ const result = appendStackHeaderPropsToOptions(
419
+ {},
420
+ {
421
+ children: (
422
+ <StackHeaderLeft asChild>
423
+ <button>Back</button>
424
+ </StackHeaderLeft>
425
+ ),
426
+ }
427
+ )
428
+ expect(result.headerLeft).toBeDefined()
429
+ expect(typeof result.headerLeft).toBe('function')
430
+ })
431
+
432
+ it('processes child Right component', () => {
433
+ const result = appendStackHeaderPropsToOptions(
434
+ {},
435
+ {
436
+ children: (
437
+ <StackHeaderRight asChild>
438
+ <button>Action</button>
439
+ </StackHeaderRight>
440
+ ),
441
+ }
442
+ )
443
+ expect(result.headerRight).toBeDefined()
444
+ expect(typeof result.headerRight).toBe('function')
445
+ })
446
+
447
+ it('processes child SearchBar component', () => {
448
+ const result = appendStackHeaderPropsToOptions(
449
+ {},
450
+ {
451
+ children: <StackHeaderSearchBar placeholder="Search..." />,
452
+ }
453
+ )
454
+ expect(result.headerSearchBarOptions).toMatchObject({
455
+ placeholder: 'Search...',
456
+ })
457
+ })
458
+
459
+ it('processes all child components together', () => {
460
+ const result = appendStackHeaderPropsToOptions(
461
+ {},
462
+ {
463
+ children: [
464
+ <StackHeaderTitle key="title" large>
465
+ Articles
466
+ </StackHeaderTitle>,
467
+ <StackHeaderLeft key="left" asChild>
468
+ <button>Back</button>
469
+ </StackHeaderLeft>,
470
+ <StackHeaderRight key="right" asChild>
471
+ <button>More</button>
472
+ </StackHeaderRight>,
473
+ <StackHeaderSearchBar key="search" placeholder="Search articles..." />,
474
+ <StackHeaderBackButton key="back" displayMode="minimal" />,
475
+ ],
476
+ }
477
+ )
478
+ expect(result.title).toBe('Articles')
479
+ expect(result.headerLargeTitle).toBe(true)
480
+ expect(result.headerLeft).toBeDefined()
481
+ expect(result.headerRight).toBeDefined()
482
+ expect(result.headerSearchBarOptions).toMatchObject({
483
+ placeholder: 'Search articles...',
484
+ })
485
+ expect(result.headerBackButtonDisplayMode).toBe('minimal')
486
+ })
487
+ })
488
+
489
+ describe('StackScreen composition', () => {
490
+ it('StackHeader is same reference as StackHeaderComponent', () => {
491
+ // This is critical - if they are different, the child type check will fail
492
+ expect(StackHeader).toBe(StackHeaderComponent)
493
+ })
494
+
495
+ it('merges options with Header composition', () => {
496
+ const result = appendScreenStackPropsToOptions(
497
+ { animation: 'slide_from_right' },
498
+ {
499
+ options: { gestureEnabled: true },
500
+ children: (
501
+ <StackHeaderComponent blurEffect="regular">
502
+ <StackHeaderTitle large>Composed Title</StackHeaderTitle>
503
+ </StackHeaderComponent>
504
+ ),
505
+ }
506
+ )
507
+
508
+ expect(result.animation).toBe('slide_from_right')
509
+ expect(result.gestureEnabled).toBe(true)
510
+ expect(result.headerBlurEffect).toBe('regular')
511
+ expect(result.title).toBe('Composed Title')
512
+ expect(result.headerLargeTitle).toBe(true)
513
+ })
514
+
515
+ it('works with StackHeader compound component (as used via Stack.Header)', () => {
516
+ const result = appendScreenStackPropsToOptions(
517
+ {},
518
+ {
519
+ children: (
520
+ <StackHeader>
521
+ <StackHeader.Title large>Large Title Test</StackHeader.Title>
522
+ </StackHeader>
523
+ ),
524
+ }
525
+ )
526
+
527
+ expect(result.title).toBe('Large Title Test')
528
+ expect(result.headerLargeTitle).toBe(true)
529
+ })
530
+
531
+ it('works with StackHeader compound component with Left child', () => {
532
+ const result = appendScreenStackPropsToOptions(
533
+ {},
534
+ {
535
+ children: (
536
+ <StackHeader>
537
+ <StackHeader.Title large>Articles</StackHeader.Title>
538
+ <StackHeader.Left asChild>
539
+ <button>Back</button>
540
+ </StackHeader.Left>
541
+ </StackHeader>
542
+ ),
543
+ }
544
+ )
545
+
546
+ expect(result.title).toBe('Articles')
547
+ expect(result.headerLargeTitle).toBe(true)
548
+ expect(result.headerLeft).toBeDefined()
549
+ })
550
+
551
+ it('composition overrides options prop', () => {
552
+ const result = appendScreenStackPropsToOptions(
553
+ {},
554
+ {
555
+ options: { title: 'Options Title' },
556
+ children: (
557
+ <StackHeaderComponent>
558
+ <StackHeaderTitle>Composed Title</StackHeaderTitle>
559
+ </StackHeaderComponent>
560
+ ),
561
+ }
562
+ )
563
+
564
+ // Composition should override the options prop title
565
+ expect(result.title).toBe('Composed Title')
566
+ })
567
+
568
+ it('works with StackHeader compound component with Right child', () => {
569
+ const result = appendScreenStackPropsToOptions(
570
+ {},
571
+ {
572
+ children: (
573
+ <StackHeader>
574
+ <StackHeader.Title>Settings</StackHeader.Title>
575
+ <StackHeader.Right asChild>
576
+ <button>Save</button>
577
+ </StackHeader.Right>
578
+ </StackHeader>
579
+ ),
580
+ }
581
+ )
582
+
583
+ expect(result.title).toBe('Settings')
584
+ expect(result.headerRight).toBeDefined()
585
+ })
586
+
587
+ it('works with StackHeader compound component with SearchBar child', () => {
588
+ const result = appendScreenStackPropsToOptions(
589
+ {},
590
+ {
591
+ children: (
592
+ <StackHeader>
593
+ <StackHeader.Title large>Articles</StackHeader.Title>
594
+ <StackHeader.SearchBar placeholder="Search articles..." />
595
+ </StackHeader>
596
+ ),
597
+ }
598
+ )
599
+
600
+ expect(result.title).toBe('Articles')
601
+ expect(result.headerLargeTitle).toBe(true)
602
+ expect(result.headerSearchBarOptions).toMatchObject({
603
+ placeholder: 'Search articles...',
604
+ })
605
+ })
606
+
607
+ it('works with full compositional setup', () => {
608
+ const result = appendScreenStackPropsToOptions(
609
+ {},
610
+ {
611
+ options: { animation: 'slide_from_right' },
612
+ children: (
613
+ <StackHeader blurEffect="regular">
614
+ <StackHeader.Title large>My App</StackHeader.Title>
615
+ <StackHeader.Left asChild>
616
+ <button>Menu</button>
617
+ </StackHeader.Left>
618
+ <StackHeader.Right asChild>
619
+ <button>Settings</button>
620
+ </StackHeader.Right>
621
+ <StackHeader.BackButton displayMode="minimal" />
622
+ <StackHeader.SearchBar placeholder="Search..." placement="stacked" />
623
+ </StackHeader>
624
+ ),
625
+ }
626
+ )
627
+
628
+ expect(result.animation).toBe('slide_from_right')
629
+ expect(result.headerBlurEffect).toBe('regular')
630
+ expect(result.title).toBe('My App')
631
+ expect(result.headerLargeTitle).toBe(true)
632
+ // headerTransparent is only auto-set on iOS, not on web/android (test runs in web mock)
633
+ expect(result.headerTransparent).toBeUndefined()
634
+ expect(result.headerLeft).toBeDefined()
635
+ expect(result.headerRight).toBeDefined()
636
+ expect(result.headerBackButtonDisplayMode).toBe('minimal')
637
+ expect(result.headerSearchBarOptions).toMatchObject({
638
+ placeholder: 'Search...',
639
+ placement: 'stacked',
640
+ })
641
+ })
642
+ })
643
+ })