@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,354 @@
1
+ import { PressableStateCallbackType, StyleProp, ViewStyle } from 'react-native';
2
+
3
+ import {
4
+ MessageComponentBaseProps,
5
+ MessageLayout,
6
+ MessageTextAlign,
7
+ } from '@aws-amplify/ui-react-core';
8
+ import { BUTTON_PRESSED_OPACITY } from '../../../constants';
9
+ import { MessageDefaultStyle } from '../types';
10
+ import { StyleParams } from '../types';
11
+
12
+ import {
13
+ getComponentButtonStyle,
14
+ getContainerAndWrapperStyle,
15
+ getPayloadStyle,
16
+ getMessageStyles,
17
+ shouldFillDeviceScreen,
18
+ } from '../utils';
19
+
20
+ type ResolveContainerStyle = {
21
+ container: (state?: PressableStateCallbackType) => StyleProp<ViewStyle>;
22
+ };
23
+
24
+ const EMPTY_STYLE = Object.freeze({});
25
+
26
+ const baseDefaultStyle: MessageDefaultStyle = {
27
+ body: {},
28
+ buttonContainer: {},
29
+ buttonsContainer: {},
30
+ buttonText: {},
31
+ wrapper: {},
32
+ container: {},
33
+ contentContainer: {},
34
+ header: {},
35
+ iconButton: {},
36
+ image: {},
37
+ imageContainer: {},
38
+ textContainer: {},
39
+ };
40
+
41
+ describe('getComponentButtonStyle', () => {
42
+ const pressedOpacity = { opacity: BUTTON_PRESSED_OPACITY };
43
+
44
+ it.each(['primaryButton' as const, 'secondaryButton' as const])(
45
+ 'returns the expected output in the happy path for a %s',
46
+ (buttonType) => {
47
+ const defaultStyle = {
48
+ ...baseDefaultStyle,
49
+ buttonContainer: { backgroundColor: 'white' },
50
+ buttonText: { color: 'red' },
51
+ };
52
+ const payloadStyle = {
53
+ [buttonType]: {
54
+ backgroundColor: 'maroon',
55
+ borderRadius: 4,
56
+ color: 'teal',
57
+ },
58
+ };
59
+ const overrideStyle = {
60
+ [buttonType]: {
61
+ container: { backgroundColor: 'pink' },
62
+ text: { color: 'black' },
63
+ },
64
+ };
65
+ const styleParams = { defaultStyle, payloadStyle, overrideStyle };
66
+
67
+ const expectedContainerPressedStyle = [
68
+ pressedOpacity,
69
+ { backgroundColor: 'white' },
70
+ { backgroundColor: 'maroon', borderRadius: 4 },
71
+ { backgroundColor: 'pink' },
72
+ ];
73
+ const expectedContainerUnpressedStyle = [
74
+ EMPTY_STYLE,
75
+ { backgroundColor: 'white' },
76
+ { backgroundColor: 'maroon', borderRadius: 4 },
77
+ { backgroundColor: 'pink' },
78
+ ];
79
+
80
+ const expectedTextStyle = [
81
+ { color: 'red' },
82
+ { color: 'teal' },
83
+ { color: 'black' },
84
+ ];
85
+
86
+ const output = getComponentButtonStyle({ styleParams, buttonType });
87
+
88
+ const containerPressedStyle = (output as ResolveContainerStyle).container(
89
+ { pressed: true }
90
+ );
91
+ const containerUnpressedStyle = (
92
+ output as ResolveContainerStyle
93
+ ).container({ pressed: false });
94
+
95
+ expect(containerPressedStyle).toStrictEqual(
96
+ expectedContainerPressedStyle
97
+ );
98
+ expect(containerUnpressedStyle).toStrictEqual(
99
+ expectedContainerUnpressedStyle
100
+ );
101
+
102
+ expect(output.text).toStrictEqual(expectedTextStyle);
103
+ }
104
+ );
105
+
106
+ describe('button container style', () => {
107
+ it('returns unpressed button container style when press event is not provided', () => {
108
+ const defaultStyle = {
109
+ buttonContainer: { backgroundColor: 'white' },
110
+ buttonText: {},
111
+ } as MessageDefaultStyle;
112
+ const styleParams = {
113
+ defaultStyle,
114
+ payloadStyle: {},
115
+ overrideStyle: {},
116
+ };
117
+
118
+ const output = getComponentButtonStyle({
119
+ styleParams,
120
+ buttonType: 'primaryButton',
121
+ });
122
+
123
+ const buttonContainerStyle = (
124
+ output as ResolveContainerStyle
125
+ ).container();
126
+
127
+ const expectedButtonContainerStyle = [
128
+ EMPTY_STYLE,
129
+ { backgroundColor: 'white' },
130
+ EMPTY_STYLE,
131
+ EMPTY_STYLE,
132
+ ];
133
+
134
+ expect(buttonContainerStyle).toStrictEqual(expectedButtonContainerStyle);
135
+ });
136
+
137
+ it('correctly evaluates button container override style when it is a function', () => {
138
+ const pressedStyle = { backgroundColor: 'seafoam' };
139
+ const unpressedStyle = { backgroundColor: 'fuschia' };
140
+ const overrideStyle = {
141
+ primaryButton: {
142
+ container: ({ pressed }) => (pressed ? pressedStyle : unpressedStyle),
143
+ },
144
+ };
145
+ const styleParams = {
146
+ defaultStyle: baseDefaultStyle,
147
+ payloadStyle: {},
148
+ overrideStyle,
149
+ };
150
+
151
+ const output = getComponentButtonStyle({
152
+ styleParams,
153
+ buttonType: 'primaryButton',
154
+ });
155
+
156
+ const containerPressedStyle = (output as ResolveContainerStyle).container(
157
+ { pressed: true }
158
+ );
159
+ const containerUnpressedStyle = (
160
+ output as ResolveContainerStyle
161
+ ).container({ pressed: false });
162
+
163
+ const expectedContainerPressedStyle = [
164
+ pressedOpacity,
165
+ EMPTY_STYLE,
166
+ EMPTY_STYLE,
167
+ pressedStyle,
168
+ ];
169
+ const expectedContainerUnressedStyle = [
170
+ EMPTY_STYLE,
171
+ EMPTY_STYLE,
172
+ EMPTY_STYLE,
173
+ unpressedStyle,
174
+ ];
175
+
176
+ expect(containerPressedStyle).toStrictEqual(
177
+ expectedContainerPressedStyle
178
+ );
179
+ expect(containerUnpressedStyle).toStrictEqual(
180
+ expectedContainerUnressedStyle
181
+ );
182
+ });
183
+ });
184
+ });
185
+
186
+ describe('getContainerAndWrapperStyle', () => {
187
+ it('returns the expected output for a banner component in the happy path', () => {
188
+ const defaultStyle = {
189
+ ...baseDefaultStyle,
190
+ container: { backgroundColor: 'red' },
191
+ wrapper: { opacity: 0.4 },
192
+ };
193
+ const payloadStyle = { container: { backgroundColor: 'teal' } };
194
+ const overrideStyle = { container: { backgroundColor: 'pink' } };
195
+
196
+ const output = getContainerAndWrapperStyle({
197
+ layout: 'TOP_BANNER',
198
+ styleParams: { defaultStyle, payloadStyle, overrideStyle },
199
+ });
200
+
201
+ const expectedContainerStyle = [
202
+ { backgroundColor: 'red' },
203
+ { backgroundColor: 'teal' },
204
+ { backgroundColor: 'pink' },
205
+ ];
206
+
207
+ const expectedWrapperStyle = { opacity: 0.4 };
208
+
209
+ expect(output.container).toStrictEqual(expectedContainerStyle);
210
+ expect(output.wrapper).toStrictEqual(expectedWrapperStyle);
211
+ });
212
+
213
+ it('returns the expected output for a non-banner component in the happy path', () => {
214
+ const defaultStyle = {
215
+ ...baseDefaultStyle,
216
+ container: { backgroundColor: 'red' },
217
+ wrapper: { opacity: 0.4 },
218
+ };
219
+ const payloadStyle = { container: { backgroundColor: 'teal' } };
220
+ const overrideStyle = { container: { backgroundColor: 'pink' } };
221
+
222
+ const output = getContainerAndWrapperStyle({
223
+ layout: 'CAROUSEL',
224
+ styleParams: { defaultStyle, payloadStyle, overrideStyle },
225
+ });
226
+
227
+ const expectedContainerStyle = [{}, {}, {}];
228
+
229
+ const expectedWrapperStyle = [
230
+ { opacity: 0.4 },
231
+ { backgroundColor: 'red' },
232
+ { backgroundColor: 'teal' },
233
+ { backgroundColor: 'pink' },
234
+ ];
235
+
236
+ expect(output.container).toStrictEqual(expectedContainerStyle);
237
+ expect(output.wrapper).toStrictEqual(expectedWrapperStyle);
238
+ });
239
+
240
+ it('correctly handles a style array passed as the argument of overrideStyle.container', () => {
241
+ const defaultStyle = {
242
+ ...baseDefaultStyle,
243
+ container: { backgroundColor: 'red' },
244
+ wrapper: { opacity: 0.4 },
245
+ };
246
+ const payloadStyle = { container: { backgroundColor: 'teal' } };
247
+ const overrideStyle = {
248
+ container: [{ backgroundColor: 'pink' }, { flex: 5 }],
249
+ };
250
+
251
+ const output = getContainerAndWrapperStyle({
252
+ layout: 'CAROUSEL',
253
+ styleParams: { defaultStyle, payloadStyle, overrideStyle },
254
+ });
255
+
256
+ const expectedContainerStyle = [EMPTY_STYLE, EMPTY_STYLE, { flex: 5 }];
257
+
258
+ const expectedWrapperStyle = [
259
+ { opacity: 0.4 },
260
+ { backgroundColor: 'red' },
261
+ { backgroundColor: 'teal' },
262
+ { backgroundColor: 'pink' },
263
+ ];
264
+
265
+ expect(output.container).toStrictEqual(expectedContainerStyle);
266
+ expect(output.wrapper).toStrictEqual(expectedWrapperStyle);
267
+ });
268
+ });
269
+
270
+ describe('getPayloadStyle', () => {
271
+ it('returns the expected output in the happy path', () => {
272
+ const output = getPayloadStyle({
273
+ body: { style: { textAlign: 'left' as MessageTextAlign } },
274
+ container: { style: { backgroundColor: 'lightgray', borderRadius: 2 } },
275
+ header: { style: { textAlign: 'center' as MessageTextAlign } },
276
+ primaryButton: { style: { backgroundColor: 'salmon', color: 'olive' } },
277
+ secondaryButton: { style: { backgroundColor: 'sand', color: 'peru' } },
278
+ } as MessageComponentBaseProps);
279
+
280
+ expect(output).toMatchSnapshot();
281
+ });
282
+ });
283
+
284
+ describe('getMessageStyles', () => {
285
+ const defaultStyle = {
286
+ body: { color: 'fuschia' },
287
+ buttonContainer: { backgroundColor: 'chartreuse' },
288
+ buttonText: { color: 'pink' },
289
+ buttonsContainer: { backgroundColor: 'teal' },
290
+ contentContainer: { backgroundColor: 'lightblue' },
291
+ container: { backgroundColor: 'red', borderRadius: 1 },
292
+ header: { backgroundColor: 'purple' },
293
+ iconButton: { backgroundColor: 'blue' },
294
+ image: { backgroundColor: 'yellow' },
295
+ imageContainer: { backgroundColor: 'green' },
296
+ textContainer: { backgroundColor: 'antiquewhite' },
297
+ wrapper: { backgroundColor: 'gray' },
298
+ };
299
+
300
+ const payloadStyle: StyleParams['payloadStyle'] = {
301
+ body: { textAlign: 'left' as MessageTextAlign },
302
+ container: { backgroundColor: 'lightgray', borderRadius: 2 },
303
+ header: { textAlign: 'center' as MessageTextAlign },
304
+ primaryButton: { backgroundColor: 'salmon', color: 'olive' },
305
+ secondaryButton: { backgroundColor: 'sand', color: 'peru' },
306
+ };
307
+
308
+ const overrideStyle = {
309
+ body: { color: 'white' },
310
+ closeIconButton: { backgroundColor: 'turquoise' },
311
+ closeIconColor: 'darkcyan',
312
+ container: { backgroundColor: 'lawngreen', borderRadius: 3 },
313
+ header: { backgroundColor: 'lightpink' },
314
+ image: { backgroundColor: 'royalblue' },
315
+ primaryButton: {
316
+ container: { backgroundColor: 'seagreen' },
317
+ text: { color: 'black' },
318
+ },
319
+ secondaryButton: {
320
+ container: { backgroundColor: 'sienna' },
321
+ text: { color: 'orchid' },
322
+ },
323
+ };
324
+ it('returns the expected output in the happy path', () => {
325
+ const output = getMessageStyles({
326
+ layout: 'FULL_SCREEN',
327
+ styleParams: { defaultStyle, payloadStyle, overrideStyle },
328
+ });
329
+
330
+ expect(output).toMatchSnapshot();
331
+ });
332
+
333
+ it('adds a bottom padding for carousel page indicators', () => {
334
+ const output = getMessageStyles({
335
+ layout: 'CAROUSEL',
336
+ styleParams: { defaultStyle, payloadStyle: {}, overrideStyle: {} },
337
+ });
338
+
339
+ expect(output).toMatchSnapshot();
340
+ });
341
+ });
342
+
343
+ describe('shouldFillDeviceScreen', () => {
344
+ it.each([
345
+ ['BOTTOM_BANNER', false],
346
+ ['MIDDLE_BANNER', false],
347
+ ['TOP_BANNER', false],
348
+ ['MODAL', false],
349
+ ['CAROUSEL', true],
350
+ ['FULL_SCREEN', true],
351
+ ])('returns the expected output for a %s layout', (layout, expected) => {
352
+ expect(shouldFillDeviceScreen(layout as MessageLayout)).toBe(expected);
353
+ });
354
+ });
@@ -0,0 +1,8 @@
1
+ export { default as useMessageProps } from './useMessageProps';
2
+ export {
3
+ GetDefaultStyle,
4
+ MessageComponentStyles,
5
+ MessageDefaultStyle,
6
+ MessageOverrideStyle,
7
+ UseMessageProps,
8
+ } from './types';
@@ -0,0 +1,131 @@
1
+ import {
2
+ ColorValue,
3
+ ImageStyle,
4
+ StyleProp,
5
+ TextStyle,
6
+ ViewStyle,
7
+ } from 'react-native';
8
+ import { MessageLayout, MessagePayloadStyle } from '@aws-amplify/ui-react-core';
9
+
10
+ import { ButtonProps } from '../../../primitives';
11
+
12
+ import { ImageDimensions } from '../useMessageImage';
13
+
14
+ /**
15
+ * Resolved message types
16
+ */
17
+ export interface MessageComponentStyles {
18
+ body: StyleProp<TextStyle>;
19
+ buttonsContainer: StyleProp<ViewStyle>;
20
+ container: StyleProp<ViewStyle>;
21
+ contentContainer: StyleProp<ViewStyle>;
22
+ header: StyleProp<TextStyle>;
23
+ iconButton: { container: StyleProp<ViewStyle>; iconColor?: ColorValue };
24
+ imageContainer: StyleProp<ViewStyle>;
25
+ image: StyleProp<ImageStyle>;
26
+ primaryButton: MessageButtonStyleProps;
27
+ secondaryButton: MessageButtonStyleProps;
28
+ textContainer: StyleProp<ViewStyle>;
29
+ wrapper: StyleProp<ViewStyle>;
30
+ }
31
+
32
+ export type GetDefaultStyle<AdditionalStyle = unknown> = (
33
+ imageDimensions: ImageDimensions,
34
+ additionalStyle?: AdditionalStyle
35
+ ) => MessageDefaultStyle;
36
+
37
+ export interface UseMessageProps {
38
+ hasButtons: boolean;
39
+ hasPrimaryButton: boolean;
40
+ hasRenderableImage: boolean;
41
+ hasSecondaryButton: boolean;
42
+ shouldRenderMessage: boolean;
43
+ styles: MessageComponentStyles | null;
44
+ }
45
+
46
+ export interface MessageStyleParams {
47
+ /**
48
+ * message specific layout
49
+ */
50
+ layout: MessageLayout;
51
+
52
+ /**
53
+ * style params to derive resolved style from
54
+ */
55
+ styleParams: StyleParams;
56
+ }
57
+
58
+ export interface StyleParams {
59
+ /**
60
+ * default component styles defined at the UI component level
61
+ */
62
+ defaultStyle: MessageDefaultStyle;
63
+
64
+ /**
65
+ * message specific styles in the message payload
66
+ */
67
+ payloadStyle: MessagePayloadStyle;
68
+
69
+ /**
70
+ * custom component style passed as style prop to message UI components
71
+ */
72
+ overrideStyle: MessageOverrideStyle;
73
+ }
74
+
75
+ export interface MessageButtonStyleParams {
76
+ /**
77
+ * message button types
78
+ */
79
+ buttonType: 'primaryButton' | 'secondaryButton';
80
+
81
+ /**
82
+ * style params to derive resolved style from
83
+ */
84
+ styleParams: StyleParams;
85
+ }
86
+
87
+ /**
88
+ * Default Message UI component style props
89
+ */
90
+ export interface MessageDefaultStyle {
91
+ body: TextStyle;
92
+ buttonContainer: ViewStyle;
93
+ buttonsContainer: ViewStyle;
94
+ buttonText: TextStyle;
95
+ container: ViewStyle;
96
+ contentContainer: ViewStyle;
97
+ header: TextStyle;
98
+ iconButton: ViewStyle;
99
+ image: ImageStyle;
100
+ imageContainer: ViewStyle;
101
+ textContainer: ViewStyle;
102
+ wrapper: ViewStyle;
103
+ }
104
+
105
+ export interface MessageButtonStyleProps {
106
+ container?: ButtonProps['style'];
107
+ text?: ButtonProps['textStyle'];
108
+ }
109
+
110
+ export interface MessageContainerAndWrapperStyle {
111
+ container: [
112
+ defaultStyle: StyleProp<ViewStyle>,
113
+ messageStyle: StyleProp<ViewStyle>,
114
+ overrideStyle: StyleProp<ViewStyle>
115
+ ];
116
+ wrapper: StyleProp<ViewStyle>;
117
+ }
118
+
119
+ /**
120
+ * Override style props
121
+ */
122
+ export interface MessageOverrideStyle {
123
+ body?: StyleProp<TextStyle>;
124
+ closeIconButton?: StyleProp<ViewStyle>;
125
+ closeIconColor?: ColorValue;
126
+ container?: StyleProp<ViewStyle>;
127
+ header?: StyleProp<TextStyle>;
128
+ image?: StyleProp<ImageStyle>;
129
+ primaryButton?: MessageButtonStyleProps;
130
+ secondaryButton?: MessageButtonStyleProps;
131
+ }
@@ -0,0 +1,70 @@
1
+ import { useEffect, useMemo, useRef } from 'react';
2
+ import isEmpty from 'lodash/isEmpty';
3
+ import { MessageComponentBaseProps } from '@aws-amplify/ui-react-core';
4
+
5
+ import { useMessageImage } from '../useMessageImage';
6
+ import {
7
+ GetDefaultStyle,
8
+ MessageOverrideStyle,
9
+ UseMessageProps,
10
+ } from './types';
11
+ import { getPayloadStyle, getMessageStyles } from './utils';
12
+
13
+ /**
14
+ * Handle common message UI component prop logic including setting of image dimensions,
15
+ * render booleans, and style resolving
16
+ *
17
+ * @param {MessageComponentBaseProps} props - message UI component props
18
+ * @param {GetDefaultStyle} getDefaultStyle - returns default UI component style
19
+ *
20
+ * @returns {UseMessageProps} message UI component render related booleans and styles
21
+ */
22
+
23
+ export default function useMessageProps(
24
+ props: MessageComponentBaseProps<MessageOverrideStyle>,
25
+ getDefaultStyle: GetDefaultStyle
26
+ ): UseMessageProps {
27
+ const { image, layout, onDisplay, primaryButton, secondaryButton } = props;
28
+ const hasDisplayed = useRef(false);
29
+
30
+ const { hasRenderableImage, imageDimensions, isImageFetching } =
31
+ useMessageImage(image, layout);
32
+
33
+ const shouldRenderMessage = !isImageFetching;
34
+
35
+ useEffect(() => {
36
+ if (!hasDisplayed.current && shouldRenderMessage) {
37
+ onDisplay?.();
38
+ hasDisplayed.current = true;
39
+ }
40
+ }, [onDisplay, shouldRenderMessage]);
41
+
42
+ const hasPrimaryButton = !isEmpty(primaryButton);
43
+ const hasSecondaryButton = !isEmpty(secondaryButton);
44
+ const hasButtons = hasPrimaryButton || hasSecondaryButton;
45
+
46
+ const styles = useMemo(() => {
47
+ // prevent generating style if message rendering is delayed
48
+ if (!shouldRenderMessage) {
49
+ return null;
50
+ }
51
+
52
+ const defaultStyle = getDefaultStyle(imageDimensions);
53
+ const payloadStyle = getPayloadStyle(props);
54
+ const overrideStyle = props.style!;
55
+
56
+ return getMessageStyles({
57
+ styleParams: { defaultStyle, payloadStyle, overrideStyle },
58
+ layout,
59
+ });
60
+ }, [getDefaultStyle, layout, imageDimensions, props, shouldRenderMessage]);
61
+
62
+ return {
63
+ hasButtons,
64
+ hasPrimaryButton,
65
+ hasRenderableImage,
66
+ hasSecondaryButton,
67
+ shouldRenderMessage,
68
+ styles,
69
+ };
70
+ }