@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,132 @@
1
+ import { ImageStyle, StyleSheet } from 'react-native';
2
+ import {
3
+ BORDER_RADIUS_BASE,
4
+ COLOR_BLACK,
5
+ COLOR_LIGHT_GREY,
6
+ COLOR_WHITE,
7
+ FONT_SIZE_BASE,
8
+ FONT_SIZE_LARGE,
9
+ FONT_WEIGHT_BASE,
10
+ LINE_HEIGHT_BASE,
11
+ LINE_HEIGHT_LARGE,
12
+ MESSAGE_ELEVATION,
13
+ MESSAGE_SHADOW_HEIGHT,
14
+ MESSAGE_SHADOW_OPACITY,
15
+ MESSAGE_SHADOW_RADIUS,
16
+ MESSAGE_SHADOW_WIDTH,
17
+ SPACING_EXTRA_LARGE,
18
+ SPACING_LARGE,
19
+ SPACING_MEDIUM,
20
+ SPACING_SMALL,
21
+ } from '../../constants';
22
+
23
+ import { ModalMessageStyle } from './types';
24
+
25
+ const commonStyles: Omit<
26
+ ModalMessageStyle,
27
+ 'contentContainer' | 'image' | 'textContainer'
28
+ > = {
29
+ body: {
30
+ fontSize: FONT_SIZE_BASE,
31
+ fontWeight: FONT_WEIGHT_BASE,
32
+ lineHeight: LINE_HEIGHT_BASE,
33
+ },
34
+ buttonContainer: {
35
+ backgroundColor: COLOR_LIGHT_GREY,
36
+ borderRadius: BORDER_RADIUS_BASE,
37
+ flex: 1,
38
+ margin: SPACING_MEDIUM,
39
+ padding: SPACING_LARGE,
40
+ },
41
+ buttonsContainer: {
42
+ flexDirection: 'row',
43
+ justifyContent: 'center',
44
+ },
45
+ container: {
46
+ backgroundColor: COLOR_WHITE,
47
+ elevation: MESSAGE_ELEVATION,
48
+ margin: SPACING_EXTRA_LARGE,
49
+ shadowColor: COLOR_BLACK,
50
+ shadowOffset: {
51
+ width: MESSAGE_SHADOW_WIDTH,
52
+ height: MESSAGE_SHADOW_HEIGHT,
53
+ },
54
+ shadowOpacity: MESSAGE_SHADOW_OPACITY,
55
+ shadowRadius: MESSAGE_SHADOW_RADIUS,
56
+ },
57
+ buttonText: {
58
+ fontSize: FONT_SIZE_BASE,
59
+ fontWeight: FONT_WEIGHT_BASE,
60
+ lineHeight: LINE_HEIGHT_BASE,
61
+ textAlign: 'center',
62
+ },
63
+ header: {
64
+ fontSize: FONT_SIZE_LARGE,
65
+ fontWeight: FONT_WEIGHT_BASE,
66
+ lineHeight: LINE_HEIGHT_LARGE,
67
+ },
68
+ iconButton: {
69
+ alignSelf: 'flex-start',
70
+ marginLeft: 'auto',
71
+ },
72
+ imageContainer: {
73
+ alignItems: 'center',
74
+ margin: SPACING_LARGE,
75
+ },
76
+ wrapper: {
77
+ flex: 1,
78
+ justifyContent: 'center',
79
+ },
80
+ };
81
+
82
+ export const getPortraitStyles = (
83
+ imageDimensions: ImageStyle
84
+ ): ModalMessageStyle =>
85
+ StyleSheet.create({
86
+ ...commonStyles,
87
+ buttonsContainer: {
88
+ ...commonStyles.buttonsContainer,
89
+ marginTop: 'auto',
90
+ paddingHorizontal: SPACING_SMALL,
91
+ paddingBottom: SPACING_SMALL,
92
+ },
93
+ container: {
94
+ ...commonStyles.container,
95
+ minHeight: '40%',
96
+ },
97
+ contentContainer: { padding: SPACING_LARGE },
98
+ image: { ...imageDimensions },
99
+ textContainer: {
100
+ marginTop: SPACING_LARGE,
101
+ },
102
+ });
103
+
104
+ export const getLandscapeStyles = (
105
+ imageDimensions: ImageStyle
106
+ ): ModalMessageStyle =>
107
+ StyleSheet.create({
108
+ ...commonStyles,
109
+ container: {
110
+ ...commonStyles.container,
111
+ flex: 1,
112
+ padding: SPACING_EXTRA_LARGE,
113
+ },
114
+ contentContainer: {
115
+ flex: 1,
116
+ flexDirection: 'row',
117
+ },
118
+ iconButton: {
119
+ ...commonStyles.iconButton,
120
+ marginRight: SPACING_MEDIUM,
121
+ },
122
+ image: { ...imageDimensions },
123
+ imageContainer: {
124
+ ...commonStyles.imageContainer,
125
+ justifyContent: 'center',
126
+ },
127
+ textContainer: {
128
+ flex: 1,
129
+ justifyContent: 'center',
130
+ paddingHorizontal: SPACING_MEDIUM,
131
+ },
132
+ });
@@ -0,0 +1,8 @@
1
+ import { ModalMessageCommonProps } from '@aws-amplify/ui-react-core';
2
+
3
+ import { MessageDefaultStyle, MessageOverrideStyle } from '../../hooks';
4
+
5
+ export interface ModalMessageProps
6
+ extends ModalMessageCommonProps<MessageOverrideStyle | undefined> {}
7
+
8
+ export interface ModalMessageStyle extends MessageDefaultStyle {}
@@ -0,0 +1,6 @@
1
+ export { BannerMessageProps } from './BannerMessage';
2
+ export { CarouselMessageProps } from './CarouselMessage';
3
+ export { FullScreenMessageProps } from './FullScreenMessage';
4
+ export { InAppMessageDisplay, MessageComponents } from './InAppMessageDisplay';
5
+ export { ModalMessageProps } from './ModalMessage';
6
+ export { withInAppMessaging } from './withInAppMessaging';
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`withInAppMessaging renders as expected 1`] = `"example"`;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import TestRenderer from 'react-test-renderer';
3
+
4
+ import withInAppMessaging from '../withInAppMessaging';
5
+
6
+ const TestComponent = ({ title }: { title: string }) => <>{title}</>;
7
+
8
+ describe('withInAppMessaging', () => {
9
+ it('renders as expected', () => {
10
+ const WrappedComponent = withInAppMessaging(TestComponent);
11
+ const output = TestRenderer.create(<WrappedComponent title="example" />);
12
+
13
+ expect(output.toJSON()).toMatchSnapshot();
14
+ });
15
+ });
@@ -0,0 +1 @@
1
+ export { default as withInAppMessaging } from './withInAppMessaging';
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { InAppMessagingProvider } from '@aws-amplify/ui-react-core';
3
+
4
+ import { InAppMessageDisplay, MessageComponents } from '../InAppMessageDisplay';
5
+
6
+ export default function withInAppMessaging<Props>(
7
+ Component: (props: Props) => JSX.Element,
8
+ options?: { components?: MessageComponents }
9
+ ): (props: Props) => JSX.Element {
10
+ return function WrappedWithInAppMessaging(props: Props) {
11
+ return (
12
+ <InAppMessagingProvider>
13
+ <InAppMessageDisplay {...options} />
14
+ <Component {...props} />
15
+ </InAppMessagingProvider>
16
+ );
17
+ };
18
+ }
@@ -0,0 +1,56 @@
1
+ import { getLineHeight } from '../utils';
2
+
3
+ // color
4
+ export const COLOR_BLACK = '#000';
5
+ export const COLOR_GREY = '#a1a1a1';
6
+ export const COLOR_LIGHT_GREY = '#e8e8e8';
7
+ export const COLOR_LIGHT_GREY_2 = '#d8d8d8';
8
+ export const COLOR_WHITE = '#fff';
9
+
10
+ // spacing
11
+ export const SPACING_SMALL = 4;
12
+ export const SPACING_MEDIUM = 8;
13
+ export const SPACING_LARGE = 12;
14
+ export const SPACING_EXTRA_LARGE = 16;
15
+
16
+ // border radius
17
+ export const BORDER_RADIUS_BASE = 4;
18
+
19
+ // font
20
+ export const FONT_SIZE_BASE = 16;
21
+ export const FONT_SIZE_LARGE = 18;
22
+
23
+ export const LINE_HEIGHT_BASE = getLineHeight(FONT_SIZE_BASE);
24
+ export const LINE_HEIGHT_LARGE = getLineHeight(FONT_SIZE_LARGE);
25
+
26
+ export const FONT_WEIGHT_BASE = '400';
27
+
28
+ // icon
29
+ export const ICON_BUTTON_SIZE = 20;
30
+ export const ICON_BUTTON_HIT_SLOP = 10;
31
+
32
+ // shadow properties
33
+
34
+ // iOS shadow values
35
+ export const MESSAGE_SHADOW_HEIGHT = 2;
36
+ export const MESSAGE_SHADOW_WIDTH = 2;
37
+ export const MESSAGE_SHADOW_OPACITY = 0.1;
38
+ export const MESSAGE_SHADOW_RADIUS = 2;
39
+
40
+ // android shadow values
41
+ export const MESSAGE_ELEVATION = 3;
42
+
43
+ // Message UI Buttons
44
+
45
+ // default value applied in React Native TouchableOpacity
46
+ export const BUTTON_PRESSED_OPACITY = 0.8;
47
+
48
+ // Message Component Test IDs
49
+ export const IN_APP_MESSAGING_TEST_ID = {
50
+ BODY: 'in-app-messaging--body',
51
+ CLOSE_BUTTON: 'in-app-messaging--close-button',
52
+ HEADER: 'in-app-messaging--header',
53
+ IMAGE: 'in-app-messaging--image',
54
+ PRIMARY_BUTTON: 'in-app-messaging--primary-button',
55
+ SECONDARY_BUTTON: 'in-app-messaging--secondary-button',
56
+ };
@@ -0,0 +1,9 @@
1
+ export { ImageDimensions, useMessageImage } from './useMessageImage';
2
+ export {
3
+ GetDefaultStyle,
4
+ MessageComponentStyles,
5
+ MessageDefaultStyle,
6
+ MessageOverrideStyle,
7
+ useMessageProps,
8
+ UseMessageProps,
9
+ } from './useMessageProps';
@@ -0,0 +1,141 @@
1
+ import { Image } from 'react-native';
2
+ import { renderHook } from '@testing-library/react-hooks';
3
+ import { ConsoleLogger as Logger } from '@aws-amplify/core';
4
+ import { MessageImage } from '@aws-amplify/ui-react-core';
5
+
6
+ import { getLayoutImageDimensions, prefetchNetworkImage } from '../utils';
7
+ import useMessageImage from '../useMessageImage';
8
+
9
+ jest.mock('react-native', () => ({
10
+ Dimensions: { get: jest.fn(() => ({ height: 844, width: 400 })) },
11
+ Image: { getSize: jest.fn() },
12
+ }));
13
+ jest.mock('../utils');
14
+
15
+ // use empty mockImplementation to turn off console output
16
+ const errorSpy = jest.spyOn(Logger.prototype, 'error').mockImplementation();
17
+
18
+ const src = 'https://test.jpeg';
19
+ const image = { src };
20
+
21
+ describe('useMessageImage', () => {
22
+ beforeEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('behaves as expected in the happy path', async () => {
27
+ const imageDimensions = { height: 100, width: 100 };
28
+ (prefetchNetworkImage as jest.Mock).mockResolvedValue('loaded');
29
+ (getLayoutImageDimensions as jest.Mock).mockReturnValueOnce(
30
+ imageDimensions
31
+ );
32
+ (Image.getSize as jest.Mock).mockImplementationOnce(
33
+ (_, onSuccess: () => void) => {
34
+ onSuccess();
35
+ }
36
+ );
37
+
38
+ const { result, waitForNextUpdate } = renderHook(() =>
39
+ useMessageImage(image, 'TOP_BANNER')
40
+ );
41
+
42
+ // first render
43
+ expect(result.current).toStrictEqual({
44
+ hasRenderableImage: false,
45
+ imageDimensions: { height: undefined, width: undefined },
46
+ isImageFetching: true,
47
+ });
48
+
49
+ await waitForNextUpdate();
50
+
51
+ expect(result.current).toStrictEqual({
52
+ hasRenderableImage: true,
53
+ imageDimensions,
54
+ isImageFetching: false,
55
+ });
56
+ });
57
+
58
+ it('handles size retrieval errors as expected', async () => {
59
+ const error = 'ERROR';
60
+
61
+ (prefetchNetworkImage as jest.Mock).mockResolvedValue('loaded');
62
+ (Image.getSize as jest.Mock).mockImplementationOnce(
63
+ (_, __, onError: (error) => void) => {
64
+ onError(error);
65
+ }
66
+ );
67
+
68
+ const { result, waitForNextUpdate } = renderHook(() =>
69
+ useMessageImage(image, 'TOP_BANNER')
70
+ );
71
+
72
+ // first render
73
+ expect(result.current).toStrictEqual({
74
+ hasRenderableImage: false,
75
+ imageDimensions: { height: undefined, width: undefined },
76
+ isImageFetching: true,
77
+ });
78
+
79
+ await waitForNextUpdate();
80
+
81
+ expect(errorSpy).toHaveBeenCalledWith(
82
+ `Unable to retrieve size for image: ${error}`
83
+ );
84
+ expect(errorSpy).toHaveBeenCalledTimes(1);
85
+
86
+ expect(result.current).toStrictEqual({
87
+ hasRenderableImage: false,
88
+ imageDimensions: { height: undefined, width: undefined },
89
+ isImageFetching: false,
90
+ });
91
+ });
92
+
93
+ it('handles prefetching errors as expected', async () => {
94
+ (prefetchNetworkImage as jest.Mock).mockResolvedValue('failed');
95
+
96
+ const { result, waitForNextUpdate } = renderHook(() =>
97
+ useMessageImage(image, 'TOP_BANNER')
98
+ );
99
+
100
+ // first render
101
+ expect(result.current).toStrictEqual({
102
+ hasRenderableImage: false,
103
+ imageDimensions: { height: undefined, width: undefined },
104
+ isImageFetching: true,
105
+ });
106
+
107
+ await waitForNextUpdate();
108
+
109
+ expect(errorSpy).not.toHaveBeenCalled();
110
+
111
+ expect(result.current).toStrictEqual({
112
+ hasRenderableImage: false,
113
+ imageDimensions: { height: undefined, width: undefined },
114
+ isImageFetching: false,
115
+ });
116
+ });
117
+
118
+ it('returns the expected values when the image argument is an empty object', () => {
119
+ const { result } = renderHook(() =>
120
+ useMessageImage({} as MessageImage, 'TOP_BANNER')
121
+ );
122
+
123
+ expect(result.current).toStrictEqual({
124
+ hasRenderableImage: false,
125
+ imageDimensions: { height: undefined, width: undefined },
126
+ isImageFetching: false,
127
+ });
128
+ });
129
+
130
+ it('returns the expected values when the image argument is undefined', () => {
131
+ const { result } = renderHook(() =>
132
+ useMessageImage(undefined, 'TOP_BANNER')
133
+ );
134
+
135
+ expect(result.current).toStrictEqual({
136
+ hasRenderableImage: false,
137
+ imageDimensions: { height: undefined, width: undefined },
138
+ isImageFetching: false,
139
+ });
140
+ });
141
+ });
@@ -0,0 +1,107 @@
1
+ import { Image } from 'react-native';
2
+ import { ConsoleLogger as Logger } from '@aws-amplify/core';
3
+
4
+ import {
5
+ BANNER_IMAGE_SCREEN_MULTIPLIER,
6
+ BANNER_IMAGE_SCREEN_SIZE,
7
+ } from '../constants';
8
+ import { getLayoutImageDimensions, prefetchNetworkImage } from '../utils';
9
+
10
+ jest.mock('react-native', () => ({
11
+ Dimensions: { get: jest.fn(() => ({ height: 844, width: 400 })) },
12
+ Image: { prefetch: jest.fn() },
13
+ }));
14
+
15
+ // use empty mockImplementation to turn off console output
16
+ const errorSpy = jest.spyOn(Logger.prototype, 'error').mockImplementation();
17
+
18
+ const url = 'https://test.jpeg';
19
+
20
+ describe('prefetchNetworkImage', () => {
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ it('behaves as expected in the happy path', async () => {
26
+ (Image.prefetch as jest.Mock).mockResolvedValueOnce(true);
27
+
28
+ const output = await prefetchNetworkImage(url);
29
+
30
+ expect(output).toBe('loaded');
31
+ });
32
+
33
+ it('handles a false response from Image.prefetch as expected', async () => {
34
+ (Image.prefetch as jest.Mock).mockResolvedValueOnce(false);
35
+
36
+ const output = await prefetchNetworkImage(url);
37
+
38
+ expect(errorSpy).toHaveBeenLastCalledWith(`Image failed to load: ${url}`);
39
+ expect(errorSpy).toHaveBeenCalledTimes(1);
40
+
41
+ expect(output).toBe('failed');
42
+ });
43
+
44
+ it('handles an error from Imaage.prefetch as expected', async () => {
45
+ const error = 'ERROR';
46
+ (Image.prefetch as jest.Mock).mockRejectedValueOnce(new Error(error));
47
+
48
+ const output = await prefetchNetworkImage(url);
49
+
50
+ expect(errorSpy).toHaveBeenLastCalledWith(
51
+ `Image.prefetch failed: Error: ${error}`
52
+ );
53
+ expect(errorSpy).toHaveBeenCalledTimes(1);
54
+
55
+ expect(output).toBe('failed');
56
+ });
57
+ });
58
+
59
+ describe('getLayoutImageDimensions', () => {
60
+ it('returns the expected values for a square image', () => {
61
+ const imageHeight = 100;
62
+ const imageWidth = 100;
63
+
64
+ const output = getLayoutImageDimensions(
65
+ imageHeight,
66
+ imageWidth,
67
+ 'TOP_BANNER'
68
+ );
69
+
70
+ expect(output).toStrictEqual({
71
+ height: BANNER_IMAGE_SCREEN_SIZE,
72
+ width: BANNER_IMAGE_SCREEN_SIZE,
73
+ });
74
+ });
75
+
76
+ it('returns the expected values for a portrait image', () => {
77
+ const imageHeight = 200;
78
+ const imageWidth = 100;
79
+
80
+ const output = getLayoutImageDimensions(
81
+ imageHeight,
82
+ imageWidth,
83
+ 'TOP_BANNER'
84
+ );
85
+
86
+ expect(output).toStrictEqual({
87
+ height: BANNER_IMAGE_SCREEN_SIZE,
88
+ width: imageHeight * BANNER_IMAGE_SCREEN_MULTIPLIER,
89
+ });
90
+ });
91
+
92
+ it('returns the expected values for a landscape image', () => {
93
+ const imageHeight = 100;
94
+ const imageWidth = 200;
95
+
96
+ const output = getLayoutImageDimensions(
97
+ imageHeight,
98
+ imageWidth,
99
+ 'TOP_BANNER'
100
+ );
101
+
102
+ expect(output).toStrictEqual({
103
+ height: imageWidth * BANNER_IMAGE_SCREEN_MULTIPLIER,
104
+ width: BANNER_IMAGE_SCREEN_SIZE,
105
+ });
106
+ });
107
+ });
@@ -0,0 +1,27 @@
1
+ import { Dimensions } from 'react-native';
2
+
3
+ // as images are not expected to be responsive to orientation changes get screen dimensions at app start
4
+ const SCREEN_DIMENSIONS = Dimensions.get('screen');
5
+
6
+ // compare screen width and height and assign the lesser of the two as the base screen dimension
7
+ const BASE_SCREEN_DIMENSION =
8
+ SCREEN_DIMENSIONS.width < SCREEN_DIMENSIONS.height
9
+ ? SCREEN_DIMENSIONS.width
10
+ : SCREEN_DIMENSIONS.height;
11
+
12
+ // base size that message images should fill
13
+ // - all banner message images should fill 20 percent of the base screen dimension
14
+ // - all other components should fill 60 percent of the base screen dimension
15
+ export const BANNER_IMAGE_SCREEN_MULTIPLIER = 0.2;
16
+ export const CAROUSEL_IMAGE_SCREEN_MULTIPLIER = 0.6;
17
+ export const FULL_SCREEN_IMAGE_SCREEN_MULTIPLIER = 0.6;
18
+ export const MODAL_IMAGE_SCREEN_MULTIPLIER = 0.6;
19
+
20
+ export const BANNER_IMAGE_SCREEN_SIZE =
21
+ BANNER_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
22
+ export const CAROUSEL_IMAGE_SCREEN_SIZE =
23
+ CAROUSEL_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
24
+ export const FULL_SCREEN_IMAGE_SCREEN_SIZE =
25
+ FULL_SCREEN_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
26
+ export const MODAL_IMAGE_SCREEN_SIZE =
27
+ MODAL_IMAGE_SCREEN_MULTIPLIER * BASE_SCREEN_DIMENSION;
@@ -0,0 +1,2 @@
1
+ export { default as useMessageImage } from './useMessageImage';
2
+ export { ImageDimensions } from './types';
@@ -0,0 +1,18 @@
1
+ export type ImageDimensions = {
2
+ height: number | undefined;
3
+ width: number | undefined;
4
+ };
5
+
6
+ export type ImageLoadingState = 'loaded' | 'failed';
7
+
8
+ export enum ImagePrefetchStatus {
9
+ Failure = 'FAILURE',
10
+ Fetching = 'FETCHING',
11
+ Success = 'SUCCESS',
12
+ }
13
+
14
+ export type UseMessageImage = {
15
+ hasRenderableImage: boolean;
16
+ imageDimensions: ImageDimensions;
17
+ isImageFetching: boolean;
18
+ };
@@ -0,0 +1,74 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { Image } from 'react-native';
3
+
4
+ import { ConsoleLogger as Logger } from '@aws-amplify/core';
5
+ import { MessageImage, MessageLayout } from '@aws-amplify/ui-react-core';
6
+
7
+ import { ImageDimensions, ImagePrefetchStatus, UseMessageImage } from './types';
8
+ import { getLayoutImageDimensions, prefetchNetworkImage } from './utils';
9
+
10
+ const logger = new Logger('Notifications.InAppMessaging');
11
+
12
+ /**
13
+ * Handles prefetching and dimension setting for message images
14
+ *
15
+ * @param image contains image source
16
+ * @param layout message layout
17
+ * @returns message image dimensions and rendering related booleans
18
+ */
19
+ export default function useMessageImage(
20
+ image: MessageImage | undefined,
21
+ layout: MessageLayout
22
+ ): UseMessageImage {
23
+ const { src } = image ?? {};
24
+ const shouldPrefetch = !!src;
25
+
26
+ // set initial status to fetching if prefetch is required
27
+ const [prefetchStatus, setPrefetchStatus] =
28
+ useState<ImagePrefetchStatus | null>(
29
+ shouldPrefetch ? ImagePrefetchStatus.Fetching : null
30
+ );
31
+ const imageDimensions = useRef<ImageDimensions>({
32
+ height: undefined,
33
+ width: undefined,
34
+ }).current;
35
+
36
+ const isImageFetching = prefetchStatus === ImagePrefetchStatus.Fetching;
37
+ const hasRenderableImage = prefetchStatus === ImagePrefetchStatus.Success;
38
+
39
+ useEffect(() => {
40
+ if (!shouldPrefetch) {
41
+ return;
42
+ }
43
+
44
+ prefetchNetworkImage(src).then((prefetchResult) => {
45
+ if (prefetchResult === 'loaded') {
46
+ // get image size once loaded
47
+ Image.getSize(
48
+ src,
49
+ (imageWidth, imageHeight) => {
50
+ const { height, width } = getLayoutImageDimensions(
51
+ imageHeight,
52
+ imageWidth,
53
+ layout
54
+ );
55
+ imageDimensions.height = height;
56
+ imageDimensions.width = width;
57
+
58
+ setPrefetchStatus(ImagePrefetchStatus.Success);
59
+ },
60
+ (error) => {
61
+ // handle size retrieval error
62
+ logger.error(`Unable to retrieve size for image: ${error}`);
63
+ setPrefetchStatus(ImagePrefetchStatus.Failure);
64
+ }
65
+ );
66
+ } else {
67
+ // handle prefetch failure
68
+ setPrefetchStatus(ImagePrefetchStatus.Failure);
69
+ }
70
+ });
71
+ }, [imageDimensions, layout, shouldPrefetch, src]);
72
+
73
+ return { hasRenderableImage, imageDimensions, isImageFetching };
74
+ }