@aws-amplify/ui-react-native 0.0.0-in-app-messaging-20220826014803

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 (242) hide show
  1. package/.eslintrc.js +100 -0
  2. package/.lintstagedrc.js +6 -0
  3. package/.turbo/turbo-build.log +4 -0
  4. package/CHANGELOG.md +11 -0
  5. package/LICENSE +201 -0
  6. package/README.md +25 -0
  7. package/babel.config.js +3 -0
  8. package/dist/InAppMessaging/components/BannerMessage/BannerMessage.d.ts +3 -0
  9. package/dist/InAppMessaging/components/BannerMessage/BannerMessage.js +16 -0
  10. package/dist/InAppMessaging/components/BannerMessage/index.d.ts +2 -0
  11. package/dist/InAppMessaging/components/BannerMessage/index.js +1 -0
  12. package/dist/InAppMessaging/components/BannerMessage/styles.d.ts +7 -0
  13. package/dist/InAppMessaging/components/BannerMessage/styles.js +77 -0
  14. package/dist/InAppMessaging/components/BannerMessage/types.d.ts +12 -0
  15. package/dist/InAppMessaging/components/BannerMessage/types.js +1 -0
  16. package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.d.ts +3 -0
  17. package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.js +20 -0
  18. package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.d.ts +3 -0
  19. package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.js +18 -0
  20. package/dist/InAppMessaging/components/CarouselMessage/index.d.ts +2 -0
  21. package/dist/InAppMessaging/components/CarouselMessage/index.js +1 -0
  22. package/dist/InAppMessaging/components/CarouselMessage/styles.d.ts +5 -0
  23. package/dist/InAppMessaging/components/CarouselMessage/styles.js +98 -0
  24. package/dist/InAppMessaging/components/CarouselMessage/types.d.ts +18 -0
  25. package/dist/InAppMessaging/components/CarouselMessage/types.js +1 -0
  26. package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.d.ts +3 -0
  27. package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.js +18 -0
  28. package/dist/InAppMessaging/components/FullScreenMessage/index.d.ts +2 -0
  29. package/dist/InAppMessaging/components/FullScreenMessage/index.js +1 -0
  30. package/dist/InAppMessaging/components/FullScreenMessage/styles.d.ts +3 -0
  31. package/dist/InAppMessaging/components/FullScreenMessage/styles.js +86 -0
  32. package/dist/InAppMessaging/components/FullScreenMessage/types.d.ts +6 -0
  33. package/dist/InAppMessaging/components/FullScreenMessage/types.js +1 -0
  34. package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.d.ts +10 -0
  35. package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.js +29 -0
  36. package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.d.ts +3 -0
  37. package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.js +24 -0
  38. package/dist/InAppMessaging/components/InAppMessageDisplay/index.d.ts +2 -0
  39. package/dist/InAppMessaging/components/InAppMessageDisplay/index.js +1 -0
  40. package/dist/InAppMessaging/components/InAppMessageDisplay/types.d.ts +24 -0
  41. package/dist/InAppMessaging/components/InAppMessageDisplay/types.js +1 -0
  42. package/dist/InAppMessaging/components/MessageLayout/MessageLayout.d.ts +3 -0
  43. package/dist/InAppMessaging/components/MessageLayout/MessageLayout.js +34 -0
  44. package/dist/InAppMessaging/components/MessageLayout/index.d.ts +1 -0
  45. package/dist/InAppMessaging/components/MessageLayout/index.js +1 -0
  46. package/dist/InAppMessaging/components/MessageLayout/types.d.ts +7 -0
  47. package/dist/InAppMessaging/components/MessageLayout/types.js +1 -0
  48. package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.d.ts +3 -0
  49. package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.js +20 -0
  50. package/dist/InAppMessaging/components/MessageWrapper/index.d.ts +2 -0
  51. package/dist/InAppMessaging/components/MessageWrapper/index.js +1 -0
  52. package/dist/InAppMessaging/components/MessageWrapper/styles.d.ts +2 -0
  53. package/dist/InAppMessaging/components/MessageWrapper/styles.js +5 -0
  54. package/dist/InAppMessaging/components/MessageWrapper/types.d.ts +10 -0
  55. package/dist/InAppMessaging/components/MessageWrapper/types.js +1 -0
  56. package/dist/InAppMessaging/components/ModalMessage/ModalMessage.d.ts +3 -0
  57. package/dist/InAppMessaging/components/ModalMessage/ModalMessage.js +18 -0
  58. package/dist/InAppMessaging/components/ModalMessage/index.d.ts +2 -0
  59. package/dist/InAppMessaging/components/ModalMessage/index.js +1 -0
  60. package/dist/InAppMessaging/components/ModalMessage/styles.d.ts +4 -0
  61. package/dist/InAppMessaging/components/ModalMessage/styles.js +99 -0
  62. package/dist/InAppMessaging/components/ModalMessage/types.d.ts +6 -0
  63. package/dist/InAppMessaging/components/ModalMessage/types.js +1 -0
  64. package/dist/InAppMessaging/components/index.d.ts +6 -0
  65. package/dist/InAppMessaging/components/index.js +2 -0
  66. package/dist/InAppMessaging/components/withInAppMessaging/index.d.ts +1 -0
  67. package/dist/InAppMessaging/components/withInAppMessaging/index.js +1 -0
  68. package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.d.ts +5 -0
  69. package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.js +11 -0
  70. package/dist/InAppMessaging/constants.d.ts +31 -0
  71. package/dist/InAppMessaging/constants.js +43 -0
  72. package/dist/InAppMessaging/hooks/index.d.ts +2 -0
  73. package/dist/InAppMessaging/hooks/index.js +2 -0
  74. package/dist/InAppMessaging/hooks/useMessageImage/constants.d.ts +8 -0
  75. package/dist/InAppMessaging/hooks/useMessageImage/constants.js +18 -0
  76. package/dist/InAppMessaging/hooks/useMessageImage/index.d.ts +2 -0
  77. package/dist/InAppMessaging/hooks/useMessageImage/index.js +1 -0
  78. package/dist/InAppMessaging/hooks/useMessageImage/types.d.ts +15 -0
  79. package/dist/InAppMessaging/hooks/useMessageImage/types.js +6 -0
  80. package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.d.ts +10 -0
  81. package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.js +50 -0
  82. package/dist/InAppMessaging/hooks/useMessageImage/utils.d.ts +4 -0
  83. package/dist/InAppMessaging/hooks/useMessageImage/utils.js +56 -0
  84. package/dist/InAppMessaging/hooks/useMessageProps/index.d.ts +2 -0
  85. package/dist/InAppMessaging/hooks/useMessageProps/index.js +1 -0
  86. package/dist/InAppMessaging/hooks/useMessageProps/types.d.ts +109 -0
  87. package/dist/InAppMessaging/hooks/useMessageProps/types.js +1 -0
  88. package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.d.ts +12 -0
  89. package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.js +49 -0
  90. package/dist/InAppMessaging/hooks/useMessageProps/utils.d.ts +43 -0
  91. package/dist/InAppMessaging/hooks/useMessageProps/utils.js +192 -0
  92. package/dist/InAppMessaging/index.d.ts +2 -0
  93. package/dist/InAppMessaging/index.js +2 -0
  94. package/dist/__mocks__/react-native-safe-area-context.d.ts +3 -0
  95. package/dist/__mocks__/react-native-safe-area-context.js +4 -0
  96. package/dist/assets/close.png +0 -0
  97. package/dist/assets/index.d.ts +5 -0
  98. package/dist/assets/index.js +4 -0
  99. package/dist/assets/index.ts +7 -0
  100. package/dist/hooks/index.d.ts +1 -0
  101. package/dist/hooks/index.js +1 -0
  102. package/dist/hooks/useDeviceOrientation/index.d.ts +1 -0
  103. package/dist/hooks/useDeviceOrientation/index.js +1 -0
  104. package/dist/hooks/useDeviceOrientation/useDeviceOrientation.d.ts +6 -0
  105. package/dist/hooks/useDeviceOrientation/useDeviceOrientation.js +33 -0
  106. package/dist/index.d.ts +1 -0
  107. package/dist/index.js +1 -0
  108. package/dist/primitives/Button/Button.d.ts +3 -0
  109. package/dist/primitives/Button/Button.js +8 -0
  110. package/dist/primitives/Button/index.d.ts +2 -0
  111. package/dist/primitives/Button/index.js +1 -0
  112. package/dist/primitives/Button/styles.d.ts +2 -0
  113. package/dist/primitives/Button/styles.js +4 -0
  114. package/dist/primitives/Button/types.d.ts +7 -0
  115. package/dist/primitives/Button/types.js +1 -0
  116. package/dist/primitives/Carousel/Carousel.d.ts +3 -0
  117. package/dist/primitives/Carousel/Carousel.js +58 -0
  118. package/dist/primitives/Carousel/CarouselPageIndicator.d.ts +3 -0
  119. package/dist/primitives/Carousel/CarouselPageIndicator.js +10 -0
  120. package/dist/primitives/Carousel/constants.d.ts +9 -0
  121. package/dist/primitives/Carousel/constants.js +18 -0
  122. package/dist/primitives/Carousel/index.d.ts +3 -0
  123. package/dist/primitives/Carousel/index.js +2 -0
  124. package/dist/primitives/Carousel/styles.d.ts +2 -0
  125. package/dist/primitives/Carousel/styles.js +11 -0
  126. package/dist/primitives/Carousel/types.d.ts +19 -0
  127. package/dist/primitives/Carousel/types.js +1 -0
  128. package/dist/primitives/IconButton/IconButton.d.ts +3 -0
  129. package/dist/primitives/IconButton/IconButton.js +9 -0
  130. package/dist/primitives/IconButton/index.d.ts +2 -0
  131. package/dist/primitives/IconButton/index.js +1 -0
  132. package/dist/primitives/IconButton/styles.d.ts +2 -0
  133. package/dist/primitives/IconButton/styles.js +9 -0
  134. package/dist/primitives/IconButton/types.d.ts +18 -0
  135. package/dist/primitives/IconButton/types.js +1 -0
  136. package/dist/primitives/index.d.ts +3 -0
  137. package/dist/primitives/index.js +3 -0
  138. package/dist/utils/index.d.ts +1 -0
  139. package/dist/utils/index.js +4 -0
  140. package/jest.config.js +20 -0
  141. package/package.json +55 -0
  142. package/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx +37 -0
  143. package/src/InAppMessaging/components/BannerMessage/__tests__/BannerMessage.spec.tsx +138 -0
  144. package/src/InAppMessaging/components/BannerMessage/__tests__/__snapshots__/BannerMessage.spec.tsx.snap +224 -0
  145. package/src/InAppMessaging/components/BannerMessage/index.ts +2 -0
  146. package/src/InAppMessaging/components/BannerMessage/styles.ts +105 -0
  147. package/src/InAppMessaging/components/BannerMessage/types.ts +15 -0
  148. package/src/InAppMessaging/components/CarouselMessage/CarouselMessage.tsx +42 -0
  149. package/src/InAppMessaging/components/CarouselMessage/CarouselMessageItem.tsx +37 -0
  150. package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessage.spec.tsx +55 -0
  151. package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessageItem.spec.tsx +56 -0
  152. package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessage.spec.tsx.snap +86 -0
  153. package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessageItem.spec.tsx.snap +248 -0
  154. package/src/InAppMessaging/components/CarouselMessage/index.ts +2 -0
  155. package/src/InAppMessaging/components/CarouselMessage/styles.ts +125 -0
  156. package/src/InAppMessaging/components/CarouselMessage/types.ts +28 -0
  157. package/src/InAppMessaging/components/FullScreenMessage/FullScreenMessage.tsx +38 -0
  158. package/src/InAppMessaging/components/FullScreenMessage/__tests__/FullScreenMessage.spec.tsx +53 -0
  159. package/src/InAppMessaging/components/FullScreenMessage/__tests__/__snapshots__/FullScreenMessage.spec.tsx.snap +236 -0
  160. package/src/InAppMessaging/components/FullScreenMessage/index.ts +2 -0
  161. package/src/InAppMessaging/components/FullScreenMessage/styles.ts +106 -0
  162. package/src/InAppMessaging/components/FullScreenMessage/types.ts +7 -0
  163. package/src/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.tsx +48 -0
  164. package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/InAppMessageDisplay.spec.tsx +33 -0
  165. package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/__snapshots__/InAppMessageDisplay.spec.tsx.snap +9 -0
  166. package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/handleMessageLinkAction.spec.ts +51 -0
  167. package/src/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.ts +30 -0
  168. package/src/InAppMessaging/components/InAppMessageDisplay/index.ts +2 -0
  169. package/src/InAppMessaging/components/InAppMessageDisplay/types.ts +32 -0
  170. package/src/InAppMessaging/components/MessageLayout/MessageLayout.tsx +102 -0
  171. package/src/InAppMessaging/components/MessageLayout/index.ts +1 -0
  172. package/src/InAppMessaging/components/MessageLayout/types.ts +15 -0
  173. package/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx +34 -0
  174. package/src/InAppMessaging/components/MessageWrapper/__tests__/MessageWrapper.spec.tsx +19 -0
  175. package/src/InAppMessaging/components/MessageWrapper/__tests__/__snapshots__/MessageWrapper.spec.tsx.snap +35 -0
  176. package/src/InAppMessaging/components/MessageWrapper/index.ts +2 -0
  177. package/src/InAppMessaging/components/MessageWrapper/styles.ts +7 -0
  178. package/src/InAppMessaging/components/MessageWrapper/types.ts +12 -0
  179. package/src/InAppMessaging/components/ModalMessage/ModalMessage.tsx +37 -0
  180. package/src/InAppMessaging/components/ModalMessage/__tests__/ModalMessage.spec.tsx +155 -0
  181. package/src/InAppMessaging/components/ModalMessage/__tests__/__snapshots__/ModalMessage.spec.tsx.snap +323 -0
  182. package/src/InAppMessaging/components/ModalMessage/index.ts +2 -0
  183. package/src/InAppMessaging/components/ModalMessage/styles.ts +132 -0
  184. package/src/InAppMessaging/components/ModalMessage/types.ts +8 -0
  185. package/src/InAppMessaging/components/index.ts +6 -0
  186. package/src/InAppMessaging/components/withInAppMessaging/__tests__/__snapshots__/withInAppMessaging.spec.tsx.snap +3 -0
  187. package/src/InAppMessaging/components/withInAppMessaging/__tests__/withInAppMessaging.spec.tsx +15 -0
  188. package/src/InAppMessaging/components/withInAppMessaging/index.ts +1 -0
  189. package/src/InAppMessaging/components/withInAppMessaging/withInAppMessaging.tsx +18 -0
  190. package/src/InAppMessaging/constants.ts +56 -0
  191. package/src/InAppMessaging/hooks/index.ts +9 -0
  192. package/src/InAppMessaging/hooks/useMessageImage/__tests__/useMessageImage.spec.ts +141 -0
  193. package/src/InAppMessaging/hooks/useMessageImage/__tests__/utils.spec.ts +107 -0
  194. package/src/InAppMessaging/hooks/useMessageImage/constants.ts +27 -0
  195. package/src/InAppMessaging/hooks/useMessageImage/index.ts +2 -0
  196. package/src/InAppMessaging/hooks/useMessageImage/types.ts +18 -0
  197. package/src/InAppMessaging/hooks/useMessageImage/useMessageImage.ts +74 -0
  198. package/src/InAppMessaging/hooks/useMessageImage/utils.ts +80 -0
  199. package/src/InAppMessaging/hooks/useMessageProps/__tests__/__snapshots__/utils.spec.ts.snap +223 -0
  200. package/src/InAppMessaging/hooks/useMessageProps/__tests__/useMessageProps.spec.ts +162 -0
  201. package/src/InAppMessaging/hooks/useMessageProps/__tests__/utils.spec.ts +354 -0
  202. package/src/InAppMessaging/hooks/useMessageProps/index.ts +8 -0
  203. package/src/InAppMessaging/hooks/useMessageProps/types.ts +131 -0
  204. package/src/InAppMessaging/hooks/useMessageProps/useMessageProps.ts +70 -0
  205. package/src/InAppMessaging/hooks/useMessageProps/utils.ts +274 -0
  206. package/src/InAppMessaging/index.ts +14 -0
  207. package/src/__mocks__/react-native-safe-area-context.ts +6 -0
  208. package/src/__tests__/__snapshots__/index.spec.ts.snap +15 -0
  209. package/src/__tests__/index.spec.ts +8 -0
  210. package/src/assets/close.png +0 -0
  211. package/src/assets/index.ts +7 -0
  212. package/src/hooks/index.ts +4 -0
  213. package/src/hooks/useDeviceOrientation/__tests__/useDeviceOrientation.spec.ts +87 -0
  214. package/src/hooks/useDeviceOrientation/index.ts +4 -0
  215. package/src/hooks/useDeviceOrientation/useDeviceOrientation.ts +47 -0
  216. package/src/index.ts +1 -0
  217. package/src/primitives/Button/Button.tsx +21 -0
  218. package/src/primitives/Button/__tests__/Button.spec.tsx +24 -0
  219. package/src/primitives/Button/__tests__/__snapshots__/Button.spec.tsx.snap +52 -0
  220. package/src/primitives/Button/index.ts +2 -0
  221. package/src/primitives/Button/styles.ts +6 -0
  222. package/src/primitives/Button/types.ts +9 -0
  223. package/src/primitives/Carousel/Carousel.tsx +115 -0
  224. package/src/primitives/Carousel/CarouselPageIndicator.tsx +39 -0
  225. package/src/primitives/Carousel/__tests__/Carousel.spec.tsx +185 -0
  226. package/src/primitives/Carousel/__tests__/CarouselPageIndicator.spec.tsx +71 -0
  227. package/src/primitives/Carousel/__tests__/__snapshots__/Carousel.spec.tsx.snap +216 -0
  228. package/src/primitives/Carousel/__tests__/__snapshots__/CarouselPageIndicator.spec.tsx.snap +191 -0
  229. package/src/primitives/Carousel/constants.ts +25 -0
  230. package/src/primitives/Carousel/index.ts +3 -0
  231. package/src/primitives/Carousel/styles.ts +14 -0
  232. package/src/primitives/Carousel/types.ts +22 -0
  233. package/src/primitives/IconButton/IconButton.tsx +20 -0
  234. package/src/primitives/IconButton/__tests__/IconButton.spec.tsx +13 -0
  235. package/src/primitives/IconButton/__tests__/__snapshots__/IconButton.spec.tsx.snap +34 -0
  236. package/src/primitives/IconButton/index.ts +2 -0
  237. package/src/primitives/IconButton/styles.ts +16 -0
  238. package/src/primitives/IconButton/types.ts +27 -0
  239. package/src/primitives/index.ts +3 -0
  240. package/src/utils/index.ts +6 -0
  241. package/tsconfig.dist.json +4 -0
  242. package/tsconfig.json +21 -0
@@ -0,0 +1,274 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import {
3
+ MessageComponentBaseProps,
4
+ MessageLayout,
5
+ MessagePayloadStyle,
6
+ } from '@aws-amplify/ui-react-core';
7
+
8
+ import { DEFAULT_CAROUSEL_INDICATOR_SIZE } from '../../../primitives';
9
+ import { BUTTON_PRESSED_OPACITY, SPACING_EXTRA_LARGE } from '../../constants';
10
+
11
+ import {
12
+ MessageButtonStyleParams,
13
+ MessageButtonStyleProps,
14
+ MessageComponentStyles,
15
+ MessageContainerAndWrapperStyle,
16
+ MessageStyleParams,
17
+ } from './types';
18
+
19
+ // Carousel page indicator size + margins
20
+ const DEFAULT_CAROUSEL_INDICATOR_PADDING =
21
+ (DEFAULT_CAROUSEL_INDICATOR_SIZE * 5) / 3;
22
+
23
+ /**
24
+ * Parse and assign appropriate button container and text style from style objects params
25
+ *
26
+ * @param {MessageButtonStyleParams} params - message styleParams and button type
27
+ * @returns {MessageButtonStyleProps} resolved button container and text style arrays
28
+ */
29
+ export const getComponentButtonStyle = ({
30
+ styleParams,
31
+ buttonType,
32
+ }: MessageButtonStyleParams): MessageButtonStyleProps => {
33
+ const { defaultStyle, payloadStyle, overrideStyle } = styleParams;
34
+ // default component styles defined at the UI component level
35
+ const {
36
+ buttonContainer: containerDefaultStyle = {},
37
+ buttonText: textDefaultStyle = {},
38
+ } = defaultStyle ?? {};
39
+
40
+ // message specific styles in the in-app message payload, overrides default component styles
41
+ const { backgroundColor, borderRadius, color } =
42
+ payloadStyle?.[buttonType] ?? {};
43
+
44
+ const containePayloadStyle = {
45
+ ...(backgroundColor ? { backgroundColor } : null),
46
+ ...(borderRadius ? { borderRadius } : null),
47
+ };
48
+
49
+ const textMessageStyle = { ...(color ? { color } : null) };
50
+
51
+ // custom component override styles passed as style prop, overrides all previous styles
52
+ const {
53
+ container: containerOverrideStyle = {},
54
+ text: textOverrideStyle = {},
55
+ } = overrideStyle?.[buttonType] ?? {};
56
+
57
+ return {
58
+ // the style prop of the React Native Pressable component used in the message UI accepts either a ViewStyle array
59
+ // or a function receiving a boolean reflecting whether the component is currently pressed, returning a ViewStyle
60
+ // array. Utilizing the latter, we add an opacity value to the UI message button style during press events
61
+ container: ({ pressed } = { pressed: false }) => {
62
+ // default button press interaction opacity
63
+ const pressedOpacity = pressed ? { opacity: BUTTON_PRESSED_OPACITY } : {};
64
+
65
+ // pass `pressed` to containerOverrideStyle and evaluate if the consumer passed a function for custom
66
+ // button style
67
+ const containerOverrideFinalStyle =
68
+ typeof containerOverrideStyle === 'function'
69
+ ? containerOverrideStyle({ pressed })
70
+ : containerOverrideStyle;
71
+
72
+ return [
73
+ pressedOpacity,
74
+ containerDefaultStyle,
75
+ containePayloadStyle,
76
+ containerOverrideFinalStyle,
77
+ ];
78
+ },
79
+ text: [textDefaultStyle, textMessageStyle, textOverrideStyle],
80
+ };
81
+ };
82
+
83
+ /**
84
+ * Utility for determining if the provided layout requires filling the entire device screen.
85
+ *
86
+ * @param {InAppMessageLayout} layout - message layout
87
+ * @returns {Boolean} boolean indicating whether entire screen should be filled
88
+ */
89
+
90
+ export const shouldFillDeviceScreen = (layout: MessageLayout): boolean => {
91
+ switch (layout) {
92
+ case 'CAROUSEL':
93
+ case 'FULL_SCREEN': {
94
+ return true;
95
+ }
96
+ case 'MODAL':
97
+ case 'TOP_BANNER':
98
+ case 'MIDDLE_BANNER':
99
+ case 'BOTTOM_BANNER':
100
+ default: {
101
+ return false;
102
+ }
103
+ }
104
+ };
105
+
106
+ /**
107
+ * Parse and assign appropriate message container and wrapper style from style params
108
+ *
109
+ * @param {MessageStyleParams} params - message styleParams, layout, and device orientation
110
+ * @returns {ContainerAndWrapperStyle} resolved containerStyle and wrapperStyle
111
+ */
112
+
113
+ export const getContainerAndWrapperStyle = ({
114
+ styleParams,
115
+ layout,
116
+ }: MessageStyleParams): MessageContainerAndWrapperStyle => {
117
+ const { defaultStyle, payloadStyle, overrideStyle } = styleParams;
118
+
119
+ const containerDefaultStyle = defaultStyle?.container ?? {};
120
+ const containerPayloadStyle = payloadStyle?.container ?? {};
121
+ const containerOverrideStyle = overrideStyle?.container ?? {};
122
+
123
+ const wrapperDefaultStyle = defaultStyle?.wrapper ?? {};
124
+
125
+ if (!shouldFillDeviceScreen(layout)) {
126
+ return {
127
+ wrapper: wrapperDefaultStyle,
128
+ container: [
129
+ containerDefaultStyle,
130
+ containerPayloadStyle,
131
+ containerOverrideStyle,
132
+ ],
133
+ };
134
+ }
135
+
136
+ // in non-banner and landscape modal layouts container backgroundColor values should be applied as
137
+ // wrapper style to ensure that the backgroundColor is applied to the entire screen
138
+ const {
139
+ backgroundColor: defaultBackgroundColor,
140
+ ...restContainerDefaultStyle
141
+ } = containerDefaultStyle;
142
+ const {
143
+ backgroundColor: messageBackgroundColor,
144
+ ...restContainerPayloadStyle
145
+ } = containerPayloadStyle;
146
+
147
+ // flatten overrideStyle to access override backgroundColor
148
+ const {
149
+ backgroundColor: overrideBackgroundColor,
150
+ ...restContainerOverrideStyle
151
+ } = StyleSheet.flatten(containerOverrideStyle);
152
+
153
+ // all non-backgroundColor container override style are applied to the container View
154
+ const container: MessageContainerAndWrapperStyle['container'] = [
155
+ restContainerDefaultStyle,
156
+ restContainerPayloadStyle,
157
+ restContainerOverrideStyle,
158
+ ];
159
+
160
+ // use ternaries to prevent passing backgroundColor object with undefined or null value
161
+ const wrapper: MessageContainerAndWrapperStyle['wrapper'] = [
162
+ wrapperDefaultStyle,
163
+ defaultBackgroundColor ? { backgroundColor: defaultBackgroundColor } : {},
164
+ messageBackgroundColor ? { backgroundColor: messageBackgroundColor } : {},
165
+ overrideBackgroundColor ? { backgroundColor: overrideBackgroundColor } : {},
166
+ ];
167
+
168
+ return { wrapper, container };
169
+ };
170
+
171
+ /**
172
+ * Utility for extracting message payload style
173
+ *
174
+ * @param {MessageComponentBaseProps} props - message props
175
+ * @returns {Object} message payload specific style
176
+ */
177
+
178
+ export const getPayloadStyle = ({
179
+ body,
180
+ container,
181
+ header,
182
+ primaryButton,
183
+ secondaryButton,
184
+ }: MessageComponentBaseProps): MessagePayloadStyle => ({
185
+ body: body?.style ?? {},
186
+ container: container?.style ?? {},
187
+ header: header?.style ?? {},
188
+ primaryButton: primaryButton?.style ?? {},
189
+ secondaryButton: secondaryButton?.style ?? {},
190
+ });
191
+
192
+ /**
193
+ * Receives message styling and returns style property values for use with in-app message
194
+ * UI components. Handles resolvement style precedence between default, payload, and custom style
195
+ *
196
+ * Style param resolve precedence from lowest to highest:
197
+ * 1. defaultStyle
198
+ * 2. messageStyle
199
+ * 3. overrideStyle
200
+ *
201
+ * @param {MessageStyleParams} params - message style params, layout, and device orientation
202
+ * @returns {MessageStyles} message style props
203
+ */
204
+
205
+ export function getMessageStyles({
206
+ styleParams,
207
+ layout,
208
+ }: MessageStyleParams): MessageComponentStyles {
209
+ // view style applied to the wrapper and primary container views
210
+ const { wrapper, container } = getContainerAndWrapperStyle({
211
+ styleParams,
212
+ layout,
213
+ });
214
+
215
+ // primary and secondary button container and text style
216
+ const primaryButton = getComponentButtonStyle({
217
+ styleParams,
218
+ buttonType: 'primaryButton',
219
+ });
220
+ const secondaryButton = getComponentButtonStyle({
221
+ styleParams,
222
+ buttonType: 'secondaryButton',
223
+ });
224
+
225
+ const { defaultStyle, payloadStyle, overrideStyle } = styleParams;
226
+
227
+ // image style composed of default and override style
228
+ const image = [defaultStyle?.image, overrideStyle?.image];
229
+
230
+ const iconButton = {
231
+ // view style applied to icon button
232
+ container: [defaultStyle?.iconButton, overrideStyle?.closeIconButton],
233
+ // close icon color, only specified as an overrideStyle
234
+ iconColor: overrideStyle?.closeIconColor,
235
+ };
236
+
237
+ // text style applied to message body and header respectively
238
+ const body = [defaultStyle?.body, payloadStyle?.body, overrideStyle?.body];
239
+ const header = [
240
+ defaultStyle?.header,
241
+ payloadStyle?.header,
242
+ overrideStyle?.header,
243
+ ];
244
+
245
+ const { buttonsContainer, contentContainer, imageContainer, textContainer } =
246
+ defaultStyle ?? {};
247
+
248
+ const styleProps: MessageComponentStyles = {
249
+ body,
250
+ buttonsContainer,
251
+ wrapper,
252
+ contentContainer,
253
+ container,
254
+ header,
255
+ iconButton,
256
+ image,
257
+ imageContainer,
258
+ primaryButton,
259
+ secondaryButton,
260
+ textContainer,
261
+ };
262
+
263
+ if (layout === 'CAROUSEL') {
264
+ styleProps.container = [
265
+ styleProps.container,
266
+ // Add bottom padding for carousel page indicators
267
+ {
268
+ paddingBottom: SPACING_EXTRA_LARGE + DEFAULT_CAROUSEL_INDICATOR_PADDING,
269
+ },
270
+ ];
271
+ }
272
+
273
+ return styleProps;
274
+ }
@@ -0,0 +1,14 @@
1
+ export {
2
+ InAppMessagingProvider,
3
+ useInAppMessaging,
4
+ } from '@aws-amplify/ui-react-core';
5
+
6
+ export {
7
+ BannerMessageProps,
8
+ CarouselMessageProps,
9
+ FullScreenMessageProps,
10
+ ModalMessageProps,
11
+ InAppMessageDisplay,
12
+ MessageComponents,
13
+ withInAppMessaging,
14
+ } from './components';
@@ -0,0 +1,6 @@
1
+ jest.mock('react-native-safe-area-context');
2
+
3
+ const SafeAreaProvider = 'SafeAreaProvider';
4
+ const SafeAreaView = 'SafeAreaView';
5
+
6
+ export { SafeAreaProvider, SafeAreaView };
@@ -0,0 +1,15 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`@aws-amplify/ui-react-native exports should match snapshot 1`] = `
4
+ Array [
5
+ "BannerMessageProps",
6
+ "CarouselMessageProps",
7
+ "FullScreenMessageProps",
8
+ "InAppMessageDisplay",
9
+ "InAppMessagingProvider",
10
+ "MessageComponents",
11
+ "ModalMessageProps",
12
+ "useInAppMessaging",
13
+ "withInAppMessaging",
14
+ ]
15
+ `;
@@ -0,0 +1,8 @@
1
+ import * as exported from '..';
2
+
3
+ describe('@aws-amplify/ui-react-native', () => {
4
+ it('exports should match snapshot', () => {
5
+ const exportedKeys = Object.keys(exported);
6
+ expect(exportedKeys).toMatchSnapshot();
7
+ });
8
+ });
Binary file
@@ -0,0 +1,7 @@
1
+ import { ImageSourcePropType } from 'react-native';
2
+
3
+ const icons = {
4
+ close: require('./close.png') as ImageSourcePropType,
5
+ };
6
+
7
+ export default icons;
@@ -0,0 +1,4 @@
1
+ export {
2
+ DeviceOrientation,
3
+ useDeviceOrientation,
4
+ } from './useDeviceOrientation';
@@ -0,0 +1,87 @@
1
+ import { Dimensions, EventSubscription, ScaledSize } from 'react-native';
2
+ import { renderHook } from '@testing-library/react-hooks';
3
+ import useDeviceOrientation from '../useDeviceOrientation';
4
+
5
+ const dimensions = {
6
+ landscape: { height: 100, width: 300 },
7
+ portrait: { height: 300, width: 100 },
8
+ };
9
+
10
+ describe('useDeviceOrientation', () => {
11
+ const subscription: Pick<EventSubscription, 'remove'> = { remove: jest.fn() };
12
+
13
+ let getSpy: jest.SpyInstance;
14
+ let addEventListenerSpy: jest.SpyInstance;
15
+ let removeEventListener: jest.SpyInstance;
16
+
17
+ beforeEach(() => {
18
+ jest.resetAllMocks();
19
+
20
+ getSpy = jest.spyOn(Dimensions, 'get');
21
+
22
+ addEventListenerSpy = jest.spyOn(Dimensions, 'addEventListener');
23
+
24
+ removeEventListener = jest.spyOn(Dimensions, 'removeEventListener');
25
+ });
26
+
27
+ /* eslint-disable no-console */
28
+ // turn off console errors during tests, can be safely removed once React Native v0.64 is no longer supported
29
+ const consoleWarn = console.warn;
30
+ console.warn = jest.fn();
31
+ afterAll(() => {
32
+ console.warn = consoleWarn;
33
+ /* eslint-enable no-console */
34
+ });
35
+
36
+ it('should handle unsubscribing for React Native versions < 0.65', () => {
37
+ getSpy.mockImplementation((_: string) => dimensions['portrait']);
38
+
39
+ // mock an `undefined` return to simulate React Native versions < 0.65
40
+ addEventListenerSpy.mockReturnValueOnce(undefined);
41
+
42
+ const { unmount } = renderHook(() => useDeviceOrientation());
43
+
44
+ expect(getSpy).toHaveBeenCalledTimes(1);
45
+ expect(getSpy).toHaveBeenCalledWith('screen');
46
+ expect(addEventListenerSpy).toHaveBeenCalledTimes(1);
47
+
48
+ unmount();
49
+
50
+ expect(removeEventListener).toHaveBeenCalledTimes(1);
51
+ expect(subscription.remove).not.toHaveBeenCalled();
52
+ });
53
+
54
+ it('should handle unsubscribing for React Native versions >= 0.65', () => {
55
+ getSpy.mockImplementation((_: string) => dimensions['landscape']);
56
+ addEventListenerSpy.mockReturnValue(subscription);
57
+
58
+ const { unmount } = renderHook(() => useDeviceOrientation());
59
+
60
+ expect(getSpy).toHaveBeenCalledTimes(1);
61
+ expect(getSpy).toHaveBeenCalledWith('screen');
62
+ expect(addEventListenerSpy).toHaveBeenCalledTimes(1);
63
+
64
+ unmount();
65
+
66
+ expect(subscription.remove).toHaveBeenCalledTimes(1);
67
+ expect(removeEventListener).not.toHaveBeenCalled();
68
+ });
69
+
70
+ it.each([
71
+ ['landscape', true, false],
72
+ ['portrait', false, true],
73
+ ])(
74
+ 'returns the expected values when the device is in %s mode',
75
+ (deviceOrientation, isLandscapeMode, isPortraitMode) => {
76
+ getSpy.mockImplementation(
77
+ (_: string) => dimensions[deviceOrientation] as ScaledSize
78
+ );
79
+
80
+ const { result } = renderHook(() => useDeviceOrientation());
81
+
82
+ expect(result.current.deviceOrientation).toBe(deviceOrientation);
83
+ expect(result.current.isLandscapeMode).toBe(isLandscapeMode);
84
+ expect(result.current.isPortraitMode).toBe(isPortraitMode);
85
+ }
86
+ );
87
+ });
@@ -0,0 +1,4 @@
1
+ export {
2
+ default as useDeviceOrientation,
3
+ DeviceOrientation,
4
+ } from './useDeviceOrientation';
@@ -0,0 +1,47 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Dimensions, EventSubscription } from 'react-native';
3
+
4
+ export type DeviceOrientation = 'portrait' | 'landscape';
5
+ const getDeviceOrientation = (): DeviceOrientation => {
6
+ const { height, width } = Dimensions.get('screen');
7
+ return height >= width ? 'portrait' : 'landscape';
8
+ };
9
+
10
+ export default function useDeviceOrientation(): {
11
+ deviceOrientation: DeviceOrientation;
12
+ isLandscapeMode: boolean;
13
+ isPortraitMode: boolean;
14
+ } {
15
+ const [deviceOrientation, setDeviceOrientation] =
16
+ useState<DeviceOrientation>(getDeviceOrientation);
17
+ const isLandscapeMode = deviceOrientation === 'landscape';
18
+ const isPortraitMode = deviceOrientation === 'portrait';
19
+
20
+ useEffect(() => {
21
+ const handler = () => {
22
+ setDeviceOrientation(getDeviceOrientation);
23
+ };
24
+
25
+ // The below cast and conditional unsubscribe handling is due to subscription removal variation
26
+ // between `Dimensions.addEventListener` in React Native prior to and after v0.65.
27
+ //
28
+ // Beginning with v0.65, `Dimensions.addEventListener` returns an `EventSubscription` object,
29
+ // which includes a `remove` method for removing the subscription. Prior versions return
30
+ // `undefined`, and subscription removal is handled by `Dimensions.removeEventListener`,
31
+ // which is deprecated in v0.65
32
+ const subscription = Dimensions.addEventListener(
33
+ 'change',
34
+ handler
35
+ ) as unknown as EventSubscription;
36
+
37
+ return () => {
38
+ if (typeof subscription?.remove === 'function') {
39
+ subscription.remove();
40
+ } else {
41
+ Dimensions.removeEventListener('change', handler);
42
+ }
43
+ };
44
+ }, []);
45
+
46
+ return { deviceOrientation, isLandscapeMode, isPortraitMode };
47
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './InAppMessaging';
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Pressable, Text } from 'react-native';
3
+
4
+ import { styles } from './styles';
5
+ import { ButtonProps } from './types';
6
+
7
+ export default function Button({
8
+ children,
9
+ textStyle,
10
+ ...pressableProps
11
+ }: ButtonProps): JSX.Element {
12
+ return (
13
+ <Pressable {...pressableProps}>
14
+ {typeof children === 'string' ? (
15
+ <Text style={[styles.text, textStyle]}>{children}</Text>
16
+ ) : (
17
+ children
18
+ )}
19
+ </Pressable>
20
+ );
21
+ }
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+ import TestRenderer from 'react-test-renderer';
4
+
5
+ import Button from '../Button';
6
+
7
+ const title = 'A preesable button';
8
+ const Title = () => <Text>{title}</Text>;
9
+
10
+ describe('Button', () => {
11
+ it('renders as expected with a string passed as children', () => {
12
+ const button = TestRenderer.create(<Button>{title}</Button>);
13
+ expect(button.toJSON()).toMatchSnapshot();
14
+ });
15
+
16
+ it('renders as expected with a component passed as children', () => {
17
+ const button = TestRenderer.create(
18
+ <Button>
19
+ <Title />
20
+ </Button>
21
+ );
22
+ expect(button.toJSON()).toMatchSnapshot();
23
+ });
24
+ });
@@ -0,0 +1,52 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Button renders as expected with a component passed as children 1`] = `
4
+ <View
5
+ accessible={true}
6
+ collapsable={false}
7
+ focusable={true}
8
+ onBlur={[Function]}
9
+ onClick={[Function]}
10
+ onFocus={[Function]}
11
+ onResponderGrant={[Function]}
12
+ onResponderMove={[Function]}
13
+ onResponderRelease={[Function]}
14
+ onResponderTerminate={[Function]}
15
+ onResponderTerminationRequest={[Function]}
16
+ onStartShouldSetResponder={[Function]}
17
+ >
18
+ <Text>
19
+ A preesable button
20
+ </Text>
21
+ </View>
22
+ `;
23
+
24
+ exports[`Button renders as expected with a string passed as children 1`] = `
25
+ <View
26
+ accessible={true}
27
+ collapsable={false}
28
+ focusable={true}
29
+ onBlur={[Function]}
30
+ onClick={[Function]}
31
+ onFocus={[Function]}
32
+ onResponderGrant={[Function]}
33
+ onResponderMove={[Function]}
34
+ onResponderRelease={[Function]}
35
+ onResponderTerminate={[Function]}
36
+ onResponderTerminationRequest={[Function]}
37
+ onStartShouldSetResponder={[Function]}
38
+ >
39
+ <Text
40
+ style={
41
+ Array [
42
+ Object {
43
+ "alignSelf": "center",
44
+ },
45
+ undefined,
46
+ ]
47
+ }
48
+ >
49
+ A preesable button
50
+ </Text>
51
+ </View>
52
+ `;
@@ -0,0 +1,2 @@
1
+ export { default as Button } from './Button';
2
+ export { ButtonProps, ButtonStyles } from './types';
@@ -0,0 +1,6 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { ButtonStyles } from './types';
3
+
4
+ export const styles: ButtonStyles = StyleSheet.create({
5
+ text: { alignSelf: 'center' },
6
+ });
@@ -0,0 +1,9 @@
1
+ import { PressableProps, StyleProp, TextStyle } from 'react-native';
2
+
3
+ export interface ButtonProps extends PressableProps {
4
+ textStyle?: StyleProp<TextStyle>;
5
+ }
6
+
7
+ export interface ButtonStyles {
8
+ text: TextStyle;
9
+ }