@adobe/react-native-aepmessaging 7.2.1 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/RCTAEPMessaging.podspec +1 -1
  2. package/README.md +145 -16
  3. package/android/src/main/java/com/adobe/marketing/mobile/reactnative/messaging/RCTAEPMessagingConstants.java +3 -0
  4. package/android/src/main/java/com/adobe/marketing/mobile/reactnative/messaging/RCTAEPMessagingModule.java +103 -33
  5. package/babel.config.js +3 -0
  6. package/dist/module/Messaging.js +334 -0
  7. package/dist/module/Messaging.js.map +1 -0
  8. package/dist/module/index.js +30 -0
  9. package/dist/module/index.js.map +1 -0
  10. package/dist/module/models/ContentCard.js +24 -0
  11. package/dist/module/models/ContentCard.js.map +1 -0
  12. package/dist/{models → module/models}/HTMLProposition.js +8 -9
  13. package/dist/module/models/HTMLProposition.js.map +1 -0
  14. package/dist/module/models/InAppMessage.js +4 -0
  15. package/dist/module/models/InAppMessage.js.map +1 -0
  16. package/dist/module/models/JSONProposition.js +22 -0
  17. package/dist/module/models/JSONProposition.js.map +1 -0
  18. package/dist/module/models/Message.js +182 -0
  19. package/dist/module/models/Message.js.map +1 -0
  20. package/dist/module/models/MessagingDelegate.js +4 -0
  21. package/dist/module/models/MessagingDelegate.js.map +1 -0
  22. package/dist/module/models/MessagingEdgeEventType.js +24 -0
  23. package/dist/module/models/MessagingEdgeEventType.js.map +1 -0
  24. package/dist/module/models/MessagingProposition.js +57 -0
  25. package/dist/module/models/MessagingProposition.js.map +1 -0
  26. package/dist/module/models/MessagingPropositionItem.js +4 -0
  27. package/dist/module/models/MessagingPropositionItem.js.map +1 -0
  28. package/dist/module/models/PersonalizationSchema.js +26 -0
  29. package/dist/module/models/PersonalizationSchema.js.map +1 -0
  30. package/dist/module/models/PropositionItem.js +113 -0
  31. package/dist/module/models/PropositionItem.js.map +1 -0
  32. package/dist/module/models/ScopeDetails.js +2 -0
  33. package/dist/module/models/ScopeDetails.js.map +1 -0
  34. package/dist/{models/JSONProposition.js → module/models/index.js} +14 -12
  35. package/dist/module/models/index.js.map +1 -0
  36. package/dist/module/ui/components/Button/Button.js +57 -0
  37. package/dist/module/ui/components/Button/Button.js.map +1 -0
  38. package/dist/module/ui/components/Button/Button.spec.js +476 -0
  39. package/dist/module/ui/components/Button/Button.spec.js.map +1 -0
  40. package/dist/module/ui/components/ContentCardView/ContentCardView.js +257 -0
  41. package/dist/module/ui/components/ContentCardView/ContentCardView.js.map +1 -0
  42. package/dist/module/ui/components/ContentCardView/ContentCardView.spec.js +363 -0
  43. package/dist/module/ui/components/ContentCardView/ContentCardView.spec.js.map +1 -0
  44. package/dist/module/ui/components/DismissButton/DismissButton.js +70 -0
  45. package/dist/module/ui/components/DismissButton/DismissButton.js.map +1 -0
  46. package/dist/module/ui/components/DismissButton/DismissButton.spec.js +279 -0
  47. package/dist/module/ui/components/DismissButton/DismissButton.spec.js.map +1 -0
  48. package/dist/module/ui/components/FullScreenCenterView/FullScreenCenterView.js +34 -0
  49. package/dist/module/ui/components/FullScreenCenterView/FullScreenCenterView.js.map +1 -0
  50. package/dist/module/ui/components/Inbox/EmptyState.js +64 -0
  51. package/dist/module/ui/components/Inbox/EmptyState.js.map +1 -0
  52. package/dist/module/ui/components/Inbox/Inbox.js +235 -0
  53. package/dist/module/ui/components/Inbox/Inbox.js.map +1 -0
  54. package/dist/module/ui/components/Inbox/Inbox.spec.js +847 -0
  55. package/dist/module/ui/components/Inbox/Inbox.spec.js.map +1 -0
  56. package/dist/module/ui/components/Pagination/Pagination.js +176 -0
  57. package/dist/module/ui/components/Pagination/Pagination.js.map +1 -0
  58. package/dist/module/ui/components/Pagination/Pagination.spec.js +193 -0
  59. package/dist/module/ui/components/Pagination/Pagination.spec.js.map +1 -0
  60. package/dist/module/ui/components/UnreadIcon/UnreadIcon.js +184 -0
  61. package/dist/module/ui/components/UnreadIcon/UnreadIcon.js.map +1 -0
  62. package/dist/module/ui/components/UnreadIcon/UnreadIcon.spec.js +815 -0
  63. package/dist/module/ui/components/UnreadIcon/UnreadIcon.spec.js.map +1 -0
  64. package/dist/{models/ContentCard.js → module/ui/components/index.js} +12 -12
  65. package/dist/module/ui/components/index.js.map +1 -0
  66. package/dist/module/ui/hooks/index.js +18 -0
  67. package/dist/module/ui/hooks/index.js.map +1 -0
  68. package/dist/module/ui/hooks/useAspectRatio.js +33 -0
  69. package/dist/module/ui/hooks/useAspectRatio.js.map +1 -0
  70. package/dist/module/ui/hooks/useAspectRatio.spec.js +65 -0
  71. package/dist/module/ui/hooks/useAspectRatio.spec.js.map +1 -0
  72. package/dist/module/ui/hooks/useContentCardUI.js +51 -0
  73. package/dist/module/ui/hooks/useContentCardUI.js.map +1 -0
  74. package/dist/module/ui/hooks/useContentCardUI.spec.js +85 -0
  75. package/dist/module/ui/hooks/useContentCardUI.spec.js.map +1 -0
  76. package/dist/module/ui/hooks/useInbox.js +49 -0
  77. package/dist/module/ui/hooks/useInbox.js.map +1 -0
  78. package/dist/module/ui/hooks/useInbox.spec.js +93 -0
  79. package/dist/module/ui/hooks/useInbox.spec.js.map +1 -0
  80. package/dist/module/ui/hooks/useInboxSettings.js +26 -0
  81. package/dist/module/ui/hooks/useInboxSettings.js.map +1 -0
  82. package/dist/module/ui/hooks/useInboxSettings.spec.js +50 -0
  83. package/dist/module/ui/hooks/useInboxSettings.spec.js.map +1 -0
  84. package/dist/module/ui/index.js +10 -0
  85. package/dist/module/ui/index.js.map +1 -0
  86. package/dist/module/ui/providers/InboxProvider.js +27 -0
  87. package/dist/module/ui/providers/InboxProvider.js.map +1 -0
  88. package/dist/module/ui/theme/Theme.js +2 -0
  89. package/dist/module/ui/theme/Theme.js.map +1 -0
  90. package/dist/module/ui/theme/ThemeProvider.js +112 -0
  91. package/dist/module/ui/theme/ThemeProvider.js.map +1 -0
  92. package/dist/{models/InAppMessage.js → module/ui/theme/index.js} +6 -3
  93. package/dist/module/ui/theme/index.js.map +1 -0
  94. package/dist/module/ui/types/ContentViewEvent.js +2 -0
  95. package/dist/module/ui/types/ContentViewEvent.js.map +1 -0
  96. package/dist/module/ui/types/Templates.js +26 -0
  97. package/dist/module/ui/types/Templates.js.map +1 -0
  98. package/dist/{models/ScopeDetails.js → module/ui/types/index.js} +6 -3
  99. package/dist/module/ui/types/index.js.map +1 -0
  100. package/dist/module/ui/utils/generateCardHash.js +50 -0
  101. package/dist/module/ui/utils/generateCardHash.js.map +1 -0
  102. package/dist/module/ui/utils/generateCardHash.spec.js +103 -0
  103. package/dist/module/ui/utils/generateCardHash.spec.js.map +1 -0
  104. package/dist/module/ui/utils/inboxStorage.js +65 -0
  105. package/dist/module/ui/utils/inboxStorage.js.map +1 -0
  106. package/dist/module/ui/utils/inboxStorage.spec.js +123 -0
  107. package/dist/module/ui/utils/inboxStorage.spec.js.map +1 -0
  108. package/dist/module/ui/utils/index.js +5 -0
  109. package/dist/module/ui/utils/index.js.map +1 -0
  110. package/dist/{Messaging.d.ts → typescript/Messaging.d.ts} +23 -7
  111. package/dist/typescript/Messaging.d.ts.map +1 -0
  112. package/dist/{index.d.ts → typescript/index.d.ts} +4 -2
  113. package/dist/typescript/index.d.ts.map +1 -0
  114. package/dist/typescript/models/ContentCard.d.ts +57 -0
  115. package/dist/typescript/models/ContentCard.d.ts.map +1 -0
  116. package/dist/{models → typescript/models}/HTMLProposition.d.ts +1 -0
  117. package/dist/typescript/models/HTMLProposition.d.ts.map +1 -0
  118. package/dist/{models → typescript/models}/InAppMessage.d.ts +1 -0
  119. package/dist/typescript/models/InAppMessage.d.ts.map +1 -0
  120. package/dist/{models → typescript/models}/JSONProposition.d.ts +1 -0
  121. package/dist/typescript/models/JSONProposition.d.ts.map +1 -0
  122. package/dist/{models → typescript/models}/Message.d.ts +14 -0
  123. package/dist/typescript/models/Message.d.ts.map +1 -0
  124. package/dist/{models → typescript/models}/MessagingDelegate.d.ts +1 -0
  125. package/dist/typescript/models/MessagingDelegate.d.ts.map +1 -0
  126. package/dist/{models → typescript/models}/MessagingEdgeEventType.d.ts +1 -0
  127. package/dist/typescript/models/MessagingEdgeEventType.d.ts.map +1 -0
  128. package/dist/{models → typescript/models}/MessagingProposition.d.ts +1 -0
  129. package/dist/typescript/models/MessagingProposition.d.ts.map +1 -0
  130. package/dist/{models → typescript/models}/MessagingPropositionItem.d.ts +1 -0
  131. package/dist/typescript/models/MessagingPropositionItem.d.ts.map +1 -0
  132. package/dist/{models → typescript/models}/PersonalizationSchema.d.ts +2 -0
  133. package/dist/typescript/models/PersonalizationSchema.d.ts.map +1 -0
  134. package/dist/{models → typescript/models}/PropositionItem.d.ts +1 -0
  135. package/dist/typescript/models/PropositionItem.d.ts.map +1 -0
  136. package/dist/{models → typescript/models}/ScopeDetails.d.ts +1 -0
  137. package/dist/typescript/models/ScopeDetails.d.ts.map +1 -0
  138. package/dist/typescript/models/index.d.ts +11 -0
  139. package/dist/typescript/models/index.d.ts.map +1 -0
  140. package/dist/typescript/ui/components/Button/Button.d.ts +14 -0
  141. package/dist/typescript/ui/components/Button/Button.d.ts.map +1 -0
  142. package/dist/typescript/ui/components/Button/Button.spec.d.ts +2 -0
  143. package/dist/typescript/ui/components/Button/Button.spec.d.ts.map +1 -0
  144. package/dist/typescript/ui/components/ContentCardView/ContentCardView.d.ts +39 -0
  145. package/dist/typescript/ui/components/ContentCardView/ContentCardView.d.ts.map +1 -0
  146. package/dist/typescript/ui/components/ContentCardView/ContentCardView.spec.d.ts +2 -0
  147. package/dist/typescript/ui/components/ContentCardView/ContentCardView.spec.d.ts.map +1 -0
  148. package/dist/typescript/ui/components/DismissButton/DismissButton.d.ts +13 -0
  149. package/dist/typescript/ui/components/DismissButton/DismissButton.d.ts.map +1 -0
  150. package/dist/typescript/ui/components/DismissButton/DismissButton.spec.d.ts +2 -0
  151. package/dist/typescript/ui/components/DismissButton/DismissButton.spec.d.ts.map +1 -0
  152. package/dist/typescript/ui/components/FullScreenCenterView/FullScreenCenterView.d.ts +5 -0
  153. package/dist/typescript/ui/components/FullScreenCenterView/FullScreenCenterView.d.ts.map +1 -0
  154. package/dist/typescript/ui/components/Inbox/EmptyState.d.ts +19 -0
  155. package/dist/typescript/ui/components/Inbox/EmptyState.d.ts.map +1 -0
  156. package/dist/typescript/ui/components/Inbox/Inbox.d.ts +21 -0
  157. package/dist/typescript/ui/components/Inbox/Inbox.d.ts.map +1 -0
  158. package/dist/typescript/ui/components/Inbox/Inbox.spec.d.ts +2 -0
  159. package/dist/typescript/ui/components/Inbox/Inbox.spec.d.ts.map +1 -0
  160. package/dist/typescript/ui/components/Pagination/Pagination.d.ts +14 -0
  161. package/dist/typescript/ui/components/Pagination/Pagination.d.ts.map +1 -0
  162. package/dist/typescript/ui/components/Pagination/Pagination.spec.d.ts +2 -0
  163. package/dist/typescript/ui/components/Pagination/Pagination.spec.d.ts.map +1 -0
  164. package/dist/typescript/ui/components/UnreadIcon/UnreadIcon.d.ts +14 -0
  165. package/dist/typescript/ui/components/UnreadIcon/UnreadIcon.d.ts.map +1 -0
  166. package/dist/typescript/ui/components/UnreadIcon/UnreadIcon.spec.d.ts +2 -0
  167. package/dist/typescript/ui/components/UnreadIcon/UnreadIcon.spec.d.ts.map +1 -0
  168. package/dist/typescript/ui/components/index.d.ts +10 -0
  169. package/dist/typescript/ui/components/index.d.ts.map +1 -0
  170. package/dist/typescript/ui/hooks/index.d.ts +4 -0
  171. package/dist/typescript/ui/hooks/index.d.ts.map +1 -0
  172. package/dist/typescript/ui/hooks/useAspectRatio.d.ts +3 -0
  173. package/dist/typescript/ui/hooks/useAspectRatio.d.ts.map +1 -0
  174. package/dist/typescript/ui/hooks/useAspectRatio.spec.d.ts +2 -0
  175. package/dist/typescript/ui/hooks/useAspectRatio.spec.d.ts.map +1 -0
  176. package/dist/typescript/ui/hooks/useContentCardUI.d.ts +14 -0
  177. package/dist/typescript/ui/hooks/useContentCardUI.d.ts.map +1 -0
  178. package/dist/typescript/ui/hooks/useContentCardUI.spec.d.ts +2 -0
  179. package/dist/typescript/ui/hooks/useContentCardUI.spec.d.ts.map +1 -0
  180. package/dist/typescript/ui/hooks/useInbox.d.ts +12 -0
  181. package/dist/typescript/ui/hooks/useInbox.d.ts.map +1 -0
  182. package/dist/typescript/ui/hooks/useInbox.spec.d.ts +2 -0
  183. package/dist/typescript/ui/hooks/useInbox.spec.d.ts.map +1 -0
  184. package/dist/typescript/ui/hooks/useInboxSettings.d.ts +7 -0
  185. package/dist/typescript/ui/hooks/useInboxSettings.d.ts.map +1 -0
  186. package/dist/typescript/ui/hooks/useInboxSettings.spec.d.ts +2 -0
  187. package/dist/typescript/ui/hooks/useInboxSettings.spec.d.ts.map +1 -0
  188. package/dist/typescript/ui/index.d.ts +8 -0
  189. package/dist/typescript/ui/index.d.ts.map +1 -0
  190. package/dist/typescript/ui/providers/InboxProvider.d.ts +56 -0
  191. package/dist/typescript/ui/providers/InboxProvider.d.ts.map +1 -0
  192. package/dist/typescript/ui/theme/Theme.d.ts +44 -0
  193. package/dist/typescript/ui/theme/Theme.d.ts.map +1 -0
  194. package/dist/typescript/ui/theme/ThemeProvider.d.ts +21 -0
  195. package/dist/typescript/ui/theme/ThemeProvider.d.ts.map +1 -0
  196. package/dist/typescript/ui/theme/index.d.ts +3 -0
  197. package/dist/typescript/ui/theme/index.d.ts.map +1 -0
  198. package/dist/typescript/ui/types/ContentViewEvent.d.ts +9 -0
  199. package/dist/typescript/ui/types/ContentViewEvent.d.ts.map +1 -0
  200. package/dist/typescript/ui/types/Templates.d.ts +43 -0
  201. package/dist/typescript/ui/types/Templates.d.ts.map +1 -0
  202. package/dist/typescript/ui/types/index.d.ts +3 -0
  203. package/dist/typescript/ui/types/index.d.ts.map +1 -0
  204. package/dist/typescript/ui/utils/generateCardHash.d.ts +21 -0
  205. package/dist/typescript/ui/utils/generateCardHash.d.ts.map +1 -0
  206. package/dist/typescript/ui/utils/generateCardHash.spec.d.ts +2 -0
  207. package/dist/typescript/ui/utils/generateCardHash.spec.d.ts.map +1 -0
  208. package/dist/typescript/ui/utils/inboxStorage.d.ts +20 -0
  209. package/dist/typescript/ui/utils/inboxStorage.d.ts.map +1 -0
  210. package/dist/typescript/ui/utils/inboxStorage.spec.d.ts +2 -0
  211. package/dist/typescript/ui/utils/inboxStorage.spec.d.ts.map +1 -0
  212. package/dist/typescript/ui/utils/index.d.ts +3 -0
  213. package/dist/typescript/ui/utils/index.d.ts.map +1 -0
  214. package/ios/src/RCTAEPMessaging.mm +15 -0
  215. package/ios/src/RCTAEPMessaging.swift +61 -3
  216. package/ios/src/RCTAEPMessagingConstants.swift +4 -1
  217. package/jest.config.js +15 -0
  218. package/package.json +33 -5
  219. package/src/Messaging.ts +288 -32
  220. package/src/index.ts +3 -3
  221. package/src/models/ContentCard.ts +52 -27
  222. package/src/models/HTMLProposition.ts +1 -1
  223. package/src/models/JSONProposition.ts +1 -1
  224. package/src/models/Message.ts +50 -0
  225. package/src/models/PersonalizationSchema.ts +1 -0
  226. package/src/models/index.ts +22 -0
  227. package/src/ui/components/Button/Button.spec.tsx +496 -0
  228. package/src/ui/components/Button/Button.tsx +76 -0
  229. package/src/ui/components/ContentCardView/ContentCardView.spec.tsx +278 -0
  230. package/src/ui/components/ContentCardView/ContentCardView.tsx +400 -0
  231. package/src/ui/components/DismissButton/DismissButton.spec.tsx +314 -0
  232. package/src/ui/components/DismissButton/DismissButton.tsx +100 -0
  233. package/src/ui/components/FullScreenCenterView/FullScreenCenterView.tsx +32 -0
  234. package/src/ui/components/Inbox/EmptyState.tsx +89 -0
  235. package/src/ui/components/Inbox/Inbox.spec.tsx +478 -0
  236. package/src/ui/components/Inbox/Inbox.tsx +275 -0
  237. package/src/ui/components/Pagination/Pagination.spec.tsx +159 -0
  238. package/src/ui/components/Pagination/Pagination.tsx +222 -0
  239. package/src/ui/components/UnreadIcon/UnreadIcon.spec.tsx +878 -0
  240. package/src/ui/components/UnreadIcon/UnreadIcon.tsx +234 -0
  241. package/src/ui/components/index.ts +22 -0
  242. package/{dist/models/MessagingPropositionItem.js → src/ui/hooks/index.ts} +5 -4
  243. package/src/ui/hooks/useAspectRatio.spec.tsx +66 -0
  244. package/src/ui/hooks/useAspectRatio.tsx +39 -0
  245. package/src/ui/hooks/useContentCardUI.spec.tsx +82 -0
  246. package/src/ui/hooks/useContentCardUI.ts +48 -0
  247. package/src/ui/hooks/useInbox.spec.tsx +87 -0
  248. package/src/ui/hooks/useInbox.ts +46 -0
  249. package/src/ui/hooks/useInboxSettings.spec.tsx +41 -0
  250. package/src/ui/hooks/useInboxSettings.ts +24 -0
  251. package/src/ui/index.ts +7 -0
  252. package/src/ui/providers/InboxProvider.tsx +79 -0
  253. package/src/ui/theme/Theme.ts +57 -0
  254. package/src/ui/theme/ThemeProvider.tsx +120 -0
  255. package/src/ui/theme/index.ts +14 -0
  256. package/src/ui/types/ContentViewEvent.ts +20 -0
  257. package/src/ui/types/Templates.ts +77 -0
  258. package/src/ui/types/index.ts +14 -0
  259. package/src/ui/utils/generateCardHash.spec.tsx +86 -0
  260. package/src/ui/utils/generateCardHash.ts +59 -0
  261. package/src/ui/utils/inboxStorage.spec.tsx +136 -0
  262. package/src/ui/utils/inboxStorage.ts +64 -0
  263. package/src/ui/utils/index.ts +3 -0
  264. package/tutorials/ContentCardCustomizationGuide.md +661 -0
  265. package/tutorials/ContentCards.md +419 -0
  266. package/tutorials/In-App Messaging.md +31 -0
  267. package/tutorials/Inbox.md +515 -0
  268. package/tutorials/resources/image-only-template.png +0 -0
  269. package/tutorials/resources/large-image-template.png +0 -0
  270. package/tutorials/resources/small-image-template.png +0 -0
  271. package/dist/Messaging.js +0 -151
  272. package/dist/Messaging.js.map +0 -1
  273. package/dist/index.js +0 -34
  274. package/dist/index.js.map +0 -1
  275. package/dist/models/ContentCard.d.ts +0 -51
  276. package/dist/models/ContentCard.js.map +0 -1
  277. package/dist/models/HTMLProposition.js.map +0 -1
  278. package/dist/models/InAppMessage.js.map +0 -1
  279. package/dist/models/JSONProposition.js.map +0 -1
  280. package/dist/models/Message.js +0 -114
  281. package/dist/models/Message.js.map +0 -1
  282. package/dist/models/MessagingDelegate.js +0 -14
  283. package/dist/models/MessagingDelegate.js.map +0 -1
  284. package/dist/models/MessagingEdgeEventType.js +0 -24
  285. package/dist/models/MessagingEdgeEventType.js.map +0 -1
  286. package/dist/models/MessagingProposition.js +0 -59
  287. package/dist/models/MessagingProposition.js.map +0 -1
  288. package/dist/models/MessagingPropositionItem.js.map +0 -1
  289. package/dist/models/PersonalizationSchema.js +0 -25
  290. package/dist/models/PersonalizationSchema.js.map +0 -1
  291. package/dist/models/PropositionItem.js +0 -78
  292. package/dist/models/PropositionItem.js.map +0 -1
  293. package/dist/models/ScopeDetails.js.map +0 -1
@@ -0,0 +1,314 @@
1
+ /*
2
+ Copyright 2026 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the
4
+ "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
7
+ or agreed to in writing, software distributed under the License is
8
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF
9
+ ANY KIND, either express or implied. See the License for the specific
10
+ language governing permissions and limitations under the License.
11
+ */
12
+ import { render, screen, fireEvent } from '@testing-library/react-native';
13
+ import { useColorScheme } from 'react-native';
14
+ import DismissButton from './DismissButton';
15
+
16
+ // Mock useColorScheme
17
+ jest.mock('react-native/Libraries/Utilities/useColorScheme');
18
+ const mockUseColorScheme = useColorScheme as jest.MockedFunction<
19
+ typeof useColorScheme
20
+ >;
21
+
22
+ describe('DismissButton', () => {
23
+ const mockOnPress = jest.fn();
24
+
25
+ beforeEach(() => {
26
+ jest.clearAllMocks();
27
+ mockUseColorScheme.mockReturnValue('light');
28
+ });
29
+
30
+ describe('Basic rendering', () => {
31
+ it('should render a dismiss button with type "simple"', () => {
32
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
33
+
34
+ const button = screen.getByText('\u00D7');
35
+ expect(button).toBeTruthy();
36
+ });
37
+
38
+ it('should render a dismiss button with type "circle"', () => {
39
+ render(<DismissButton onPress={mockOnPress} type="circle" />);
40
+
41
+ const button = screen.getByText('\u00D7');
42
+ expect(button).toBeTruthy();
43
+ });
44
+
45
+ it('should display "×" as the button text', () => {
46
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
47
+
48
+ expect(screen.getByText('\u00D7')).toBeTruthy();
49
+ });
50
+ });
51
+
52
+ describe('Press handling', () => {
53
+ it('should call onPress when the button is pressed', () => {
54
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
55
+
56
+ const button = screen.getByText('\u00D7');
57
+ fireEvent.press(button);
58
+
59
+ expect(mockOnPress).toHaveBeenCalledTimes(1);
60
+ });
61
+
62
+ it('should call onPress multiple times when pressed multiple times', () => {
63
+ render(<DismissButton onPress={mockOnPress} type="circle" />);
64
+
65
+ const button = screen.getByText('\u00D7');
66
+ fireEvent.press(button);
67
+ fireEvent.press(button);
68
+ fireEvent.press(button);
69
+
70
+ expect(mockOnPress).toHaveBeenCalledTimes(3);
71
+ });
72
+ });
73
+
74
+ describe('Color scheme handling', () => {
75
+ it('should apply light color scheme styles', () => {
76
+ mockUseColorScheme.mockReturnValue('light');
77
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
78
+
79
+ const text = screen.getByText('\u00D7');
80
+ expect(JSON.stringify(text.props.style)).toContain('#000000');
81
+ });
82
+
83
+ it('should apply dark color scheme styles', () => {
84
+ mockUseColorScheme.mockReturnValue('dark');
85
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
86
+
87
+ const text = screen.getByText('\u00D7');
88
+ expect(JSON.stringify(text.props.style)).toContain('#FFFFFF');
89
+ });
90
+
91
+ it('should apply correct background color for circle type in light mode', () => {
92
+ mockUseColorScheme.mockReturnValue('light');
93
+ const { getByTestId } = render(
94
+ <DismissButton
95
+ onPress={mockOnPress}
96
+ type="circle"
97
+ testID="dismiss-button"
98
+ />
99
+ );
100
+
101
+ const button = getByTestId('dismiss-button');
102
+ const styles = JSON.stringify(button.props.style);
103
+ expect(styles).toContain('#0000001A');
104
+ });
105
+
106
+ it('should apply correct background color for circle type in dark mode', () => {
107
+ mockUseColorScheme.mockReturnValue('dark');
108
+ const { getByTestId } = render(
109
+ <DismissButton
110
+ onPress={mockOnPress}
111
+ type="circle"
112
+ testID="dismiss-button"
113
+ />
114
+ );
115
+
116
+ const button = getByTestId('dismiss-button');
117
+ const styles = JSON.stringify(button.props.style);
118
+ expect(styles).toContain('#FFFFFF1A');
119
+ });
120
+ });
121
+
122
+ describe('Type variations', () => {
123
+ it('should apply simple type styles', () => {
124
+ const { getByTestId } = render(
125
+ <DismissButton
126
+ onPress={mockOnPress}
127
+ type="simple"
128
+ testID="dismiss-button"
129
+ />
130
+ );
131
+
132
+ const button = getByTestId('dismiss-button');
133
+ expect(button.props.style).toEqual(
134
+ expect.arrayContaining([
135
+ expect.objectContaining({
136
+ backgroundColor: 'transparent'
137
+ })
138
+ ])
139
+ );
140
+ });
141
+
142
+ it('should apply circle type styles', () => {
143
+ const { getByTestId } = render(
144
+ <DismissButton
145
+ onPress={mockOnPress}
146
+ type="circle"
147
+ testID="dismiss-button"
148
+ />
149
+ );
150
+
151
+ const button = getByTestId('dismiss-button');
152
+ const styles = JSON.stringify(button.props.style);
153
+ expect(styles).toContain('"borderRadius":10');
154
+ expect(styles).toContain('"width":18');
155
+ expect(styles).toContain('"height":18');
156
+ });
157
+ });
158
+
159
+ describe('Custom props and styles', () => {
160
+ it('should accept and apply custom style props', () => {
161
+ const customStyle = { opacity: 0.5 };
162
+ const { getByTestId } = render(
163
+ <DismissButton
164
+ onPress={mockOnPress}
165
+ type="simple"
166
+ style={customStyle}
167
+ testID="dismiss-button"
168
+ />
169
+ );
170
+
171
+ const button = getByTestId('dismiss-button');
172
+ expect(button.props.style).toEqual(
173
+ expect.arrayContaining([
174
+ expect.objectContaining({
175
+ opacity: 0.5
176
+ })
177
+ ])
178
+ );
179
+ });
180
+
181
+ it('should accept function-based style props', () => {
182
+ const styleFn = jest.fn().mockReturnValue({ opacity: 0.8 });
183
+ const { getByTestId } = render(
184
+ <DismissButton
185
+ onPress={mockOnPress}
186
+ type="simple"
187
+ style={styleFn}
188
+ testID="dismiss-button"
189
+ />
190
+ );
191
+
192
+ expect(styleFn).toHaveBeenCalled();
193
+
194
+ const button = getByTestId('dismiss-button');
195
+ expect(button.props.style).toEqual(
196
+ expect.arrayContaining([
197
+ expect.objectContaining({
198
+ opacity: 0.8
199
+ })
200
+ ])
201
+ );
202
+ });
203
+
204
+ it('should accept additional Pressable props', () => {
205
+ const { getByTestId } = render(
206
+ <DismissButton
207
+ onPress={mockOnPress}
208
+ type="simple"
209
+ testID="dismiss-button"
210
+ disabled={true}
211
+ accessibilityLabel="Close button"
212
+ />
213
+ );
214
+
215
+ const button = getByTestId('dismiss-button');
216
+ expect(button.props.accessibilityState?.disabled).toBe(true);
217
+ expect(button.props.accessibilityLabel).toBe('Close button');
218
+ });
219
+ });
220
+
221
+ describe('Accessibility', () => {
222
+ it('should be accessible by default', () => {
223
+ const { getByTestId } = render(
224
+ <DismissButton
225
+ onPress={mockOnPress}
226
+ type="simple"
227
+ testID="dismiss-button"
228
+ />
229
+ );
230
+
231
+ const button = getByTestId('dismiss-button');
232
+ expect(button).toBeTruthy();
233
+ });
234
+
235
+ it('should accept custom accessibility props', () => {
236
+ const { getByTestId } = render(
237
+ <DismissButton
238
+ onPress={mockOnPress}
239
+ type="simple"
240
+ testID="dismiss-button"
241
+ accessibilityLabel="Dismiss notification"
242
+ accessibilityHint="Double tap to close this notification"
243
+ />
244
+ );
245
+
246
+ const button = getByTestId('dismiss-button');
247
+ expect(button.props.accessibilityLabel).toBe('Dismiss notification');
248
+ expect(button.props.accessibilityHint).toBe(
249
+ 'Double tap to close this notification'
250
+ );
251
+ });
252
+ });
253
+
254
+ describe('Positioning and layout', () => {
255
+ it('should have absolute positioning styles', () => {
256
+ const { getByTestId } = render(
257
+ <DismissButton
258
+ onPress={mockOnPress}
259
+ type="simple"
260
+ testID="dismiss-button"
261
+ />
262
+ );
263
+
264
+ const button = getByTestId('dismiss-button');
265
+ expect(button.props.style).toEqual(
266
+ expect.arrayContaining([
267
+ expect.objectContaining({
268
+ position: 'absolute',
269
+ top: 6,
270
+ right: 6,
271
+ })
272
+ ])
273
+ );
274
+ });
275
+
276
+ it('should have minimum dimensions', () => {
277
+ const { getByTestId } = render(
278
+ <DismissButton
279
+ onPress={mockOnPress}
280
+ type="simple"
281
+ testID="dismiss-button"
282
+ />
283
+ );
284
+
285
+ const button = getByTestId('dismiss-button');
286
+ expect(button.props.style).toEqual(
287
+ expect.arrayContaining([
288
+ expect.objectContaining({
289
+ minWidth: 18,
290
+ minHeight: 18
291
+ })
292
+ ])
293
+ );
294
+ });
295
+ });
296
+
297
+ describe('Edge cases', () => {
298
+ it('should handle undefined color scheme gracefully', () => {
299
+ mockUseColorScheme.mockReturnValue(undefined as any);
300
+
301
+ expect(() => {
302
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
303
+ }).not.toThrow();
304
+ });
305
+
306
+ it('should handle null color scheme gracefully', () => {
307
+ mockUseColorScheme.mockReturnValue(null as any);
308
+
309
+ expect(() => {
310
+ render(<DismissButton onPress={mockOnPress} type="simple" />);
311
+ }).not.toThrow();
312
+ });
313
+ });
314
+ });
@@ -0,0 +1,100 @@
1
+ /*
2
+ Copyright 2026 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the
4
+ "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
7
+ or agreed to in writing, software distributed under the License is
8
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF
9
+ ANY KIND, either express or implied. See the License for the specific
10
+ language governing permissions and limitations under the License.
11
+ */
12
+ import {
13
+ Pressable,
14
+ PressableProps,
15
+ StyleSheet,
16
+ Text,
17
+ TextStyle
18
+ } from "react-native";
19
+ import { useTheme } from "../../theme";
20
+
21
+ /** Props for the DismissButton component. Extends the PressableProps from react-native. */
22
+ export interface DismissButtonProps extends PressableProps {
23
+ /** The style of the text for the dismiss button */
24
+ textStyle?: TextStyle;
25
+ /** The function to call when the dismiss button is pressed */
26
+ onPress?: () => void;
27
+ /** The style of the dismiss button */
28
+ type: "simple" | "circle";
29
+ }
30
+
31
+ const DismissButton = ({
32
+ onPress,
33
+ type,
34
+ textStyle,
35
+ style,
36
+ ...props
37
+ }: DismissButtonProps) => {
38
+ const { colors } = useTheme();
39
+
40
+ return (
41
+ <Pressable
42
+ accessibilityLabel="Dismiss Button"
43
+ onPress={onPress}
44
+ style={(state) => [
45
+ styles.container,
46
+ type === "simple" && styles.simple,
47
+ type === "circle" && [
48
+ styles.circle,
49
+ {
50
+ backgroundColor: `${colors.textPrimary}1A`,
51
+ },
52
+ ],
53
+ state.pressed && styles.pressed,
54
+ typeof style === "function" ? style(state) : style,
55
+ ]}
56
+ {...props}
57
+ >
58
+ <Text
59
+ style={[
60
+ styles.text,
61
+ { color: colors.textPrimary },
62
+ textStyle,
63
+ ]}
64
+ >
65
+ {/* Unicode for multiplication sign */}
66
+ {'\u00D7'}
67
+ </Text>
68
+ </Pressable>
69
+ );
70
+ };
71
+
72
+ export default DismissButton;
73
+
74
+ const styles = StyleSheet.create({
75
+ container: {
76
+ position: "absolute",
77
+ top: 6,
78
+ right: 6,
79
+ justifyContent: "center",
80
+ alignItems: "center",
81
+ minWidth: 18,
82
+ minHeight: 18,
83
+ },
84
+ pressed: {
85
+ opacity: 0.7,
86
+ },
87
+ simple: {
88
+ backgroundColor: "transparent",
89
+ },
90
+ circle: {
91
+ borderRadius: 10,
92
+ width: 18,
93
+ height: 18,
94
+ },
95
+ text: {
96
+ fontSize: 14,
97
+ fontWeight: "bold",
98
+ textAlign: "center",
99
+ },
100
+ });
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright 2026 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the
4
+ "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
7
+ or agreed to in writing, software distributed under the License is
8
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF
9
+ ANY KIND, either express or implied. See the License for the specific
10
+ language governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { PropsWithChildren } from "react";
14
+ import { StyleSheet, View, ViewProps } from "react-native";
15
+
16
+ const FullScreenCenterView = ({ children, style, ...rest }: PropsWithChildren<ViewProps>) => {
17
+ return (
18
+ <View style={[styles.container, style]} {...rest}>
19
+ {children}
20
+ </View>
21
+ );
22
+ };
23
+
24
+ export default FullScreenCenterView;
25
+
26
+ const styles = StyleSheet.create({
27
+ container: {
28
+ flex: 1,
29
+ justifyContent: "center",
30
+ alignItems: "center",
31
+ },
32
+ });
@@ -0,0 +1,89 @@
1
+ /*
2
+ Copyright 2026 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the
4
+ "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
7
+ or agreed to in writing, software distributed under the License is
8
+ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF
9
+ ANY KIND, either express or implied. See the License for the specific
10
+ language governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {
14
+ Image,
15
+ ImageProps,
16
+ ImageStyle,
17
+ StyleSheet,
18
+ Text,
19
+ TextProps,
20
+ TextStyle,
21
+ ViewProps,
22
+ ViewStyle
23
+ } from "react-native";
24
+ import useAspectRatio from "../../hooks/useAspectRatio";
25
+ import { useTheme } from "../../theme";
26
+ import FullScreenCenterView from "../FullScreenCenterView/FullScreenCenterView";
27
+
28
+ interface EmptyStateProps extends ViewProps {
29
+ image: string;
30
+ text: string;
31
+ styleOverrides?: {
32
+ container?: ViewStyle;
33
+ image?: ImageStyle;
34
+ text?: TextStyle;
35
+ };
36
+ InboxProps?: Partial<ViewProps>;
37
+ ImageProps?: Partial<ImageProps>;
38
+ TextProps?: Partial<TextProps>;
39
+ }
40
+
41
+ /**
42
+ * @experimental First React Native inbox UI — subject to change while we expand testing.
43
+ */
44
+ const EmptyState: React.FC<EmptyStateProps> = ({
45
+ image,
46
+ text,
47
+ styleOverrides,
48
+ InboxProps,
49
+ ImageProps,
50
+ TextProps
51
+ }) => {
52
+ const { colors } = useTheme();
53
+ const ratio = useAspectRatio(image);
54
+
55
+ return (
56
+ <FullScreenCenterView
57
+ style={[styles.container, styleOverrides?.container]}
58
+ {...InboxProps}
59
+ >
60
+ {image && <Image
61
+ source={{ uri: image }}
62
+ style={[styles.image, { aspectRatio: ratio }, styleOverrides?.image]}
63
+ resizeMode="contain"
64
+ {...ImageProps}
65
+ />}
66
+ <Text
67
+ style={[styles.text, { color: colors.textPrimary }, styleOverrides?.text]}
68
+ {...TextProps}
69
+ >
70
+ {text}
71
+ </Text>
72
+ </FullScreenCenterView>
73
+ );
74
+ };
75
+
76
+ export default EmptyState;
77
+
78
+ const styles = StyleSheet.create({
79
+ image: {
80
+ width: '50%'
81
+ },
82
+ text: {
83
+ fontWeight: '600',
84
+ fontSize: 16
85
+ },
86
+ container: {
87
+ gap: 16
88
+ }
89
+ });