@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,3 @@
1
+ declare const SafeAreaProvider = "SafeAreaProvider";
2
+ declare const SafeAreaView = "SafeAreaView";
3
+ export { SafeAreaProvider, SafeAreaView };
@@ -0,0 +1,4 @@
1
+ jest.mock('react-native-safe-area-context');
2
+ const SafeAreaProvider = 'SafeAreaProvider';
3
+ const SafeAreaView = 'SafeAreaView';
4
+ export { SafeAreaProvider, SafeAreaView };
Binary file
@@ -0,0 +1,5 @@
1
+ import { ImageSourcePropType } from 'react-native';
2
+ declare const icons: {
3
+ close: ImageSourcePropType;
4
+ };
5
+ export default icons;
@@ -0,0 +1,4 @@
1
+ const icons = {
2
+ close: require('./close.png'),
3
+ };
4
+ export default icons;
@@ -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 @@
1
+ export { DeviceOrientation, useDeviceOrientation, } from './useDeviceOrientation';
@@ -0,0 +1 @@
1
+ export { useDeviceOrientation, } from './useDeviceOrientation';
@@ -0,0 +1 @@
1
+ export { default as useDeviceOrientation, DeviceOrientation, } from './useDeviceOrientation';
@@ -0,0 +1 @@
1
+ export { default as useDeviceOrientation, } from './useDeviceOrientation';
@@ -0,0 +1,6 @@
1
+ export declare type DeviceOrientation = 'portrait' | 'landscape';
2
+ export default function useDeviceOrientation(): {
3
+ deviceOrientation: DeviceOrientation;
4
+ isLandscapeMode: boolean;
5
+ isPortraitMode: boolean;
6
+ };
@@ -0,0 +1,33 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Dimensions } from 'react-native';
3
+ const getDeviceOrientation = () => {
4
+ const { height, width } = Dimensions.get('screen');
5
+ return height >= width ? 'portrait' : 'landscape';
6
+ };
7
+ export default function useDeviceOrientation() {
8
+ const [deviceOrientation, setDeviceOrientation] = useState(getDeviceOrientation);
9
+ const isLandscapeMode = deviceOrientation === 'landscape';
10
+ const isPortraitMode = deviceOrientation === 'portrait';
11
+ useEffect(() => {
12
+ const handler = () => {
13
+ setDeviceOrientation(getDeviceOrientation);
14
+ };
15
+ // The below cast and conditional unsubscribe handling is due to subscription removal variation
16
+ // between `Dimensions.addEventListener` in React Native prior to and after v0.65.
17
+ //
18
+ // Beginning with v0.65, `Dimensions.addEventListener` returns an `EventSubscription` object,
19
+ // which includes a `remove` method for removing the subscription. Prior versions return
20
+ // `undefined`, and subscription removal is handled by `Dimensions.removeEventListener`,
21
+ // which is deprecated in v0.65
22
+ const subscription = Dimensions.addEventListener('change', handler);
23
+ return () => {
24
+ if (typeof subscription?.remove === 'function') {
25
+ subscription.remove();
26
+ }
27
+ else {
28
+ Dimensions.removeEventListener('change', handler);
29
+ }
30
+ };
31
+ }, []);
32
+ return { deviceOrientation, isLandscapeMode, isPortraitMode };
33
+ }
@@ -0,0 +1 @@
1
+ export * from './InAppMessaging';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './InAppMessaging';
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { ButtonProps } from './types';
3
+ export default function Button({ children, textStyle, ...pressableProps }: ButtonProps): JSX.Element;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Pressable, Text } from 'react-native';
3
+ import { styles } from './styles';
4
+ export default function Button({ children, textStyle, ...pressableProps }) {
5
+ return (<Pressable {...pressableProps}>
6
+ {typeof children === 'string' ? (<Text style={[styles.text, textStyle]}>{children}</Text>) : (children)}
7
+ </Pressable>);
8
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Button } from './Button';
2
+ export { ButtonProps, ButtonStyles } from './types';
@@ -0,0 +1 @@
1
+ export { default as Button } from './Button';
@@ -0,0 +1,2 @@
1
+ import { ButtonStyles } from './types';
2
+ export declare const styles: ButtonStyles;
@@ -0,0 +1,4 @@
1
+ import { StyleSheet } from 'react-native';
2
+ export const styles = StyleSheet.create({
3
+ text: { alignSelf: 'center' },
4
+ });
@@ -0,0 +1,7 @@
1
+ import { PressableProps, StyleProp, TextStyle } from 'react-native';
2
+ export interface ButtonProps extends PressableProps {
3
+ textStyle?: StyleProp<TextStyle>;
4
+ }
5
+ export interface ButtonStyles {
6
+ text: TextStyle;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { CarouselProps } from './types';
3
+ export default function Carousel<T>(props: CarouselProps<T>): JSX.Element | null;
@@ -0,0 +1,58 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { Dimensions, FlatList, View, } from 'react-native';
3
+ import CarouselPageIndicator from './CarouselPageIndicator';
4
+ import { VIEWABILITY_CONFIG } from './constants';
5
+ import { styles } from './styles';
6
+ export default function Carousel(props) {
7
+ const { data, indicatorActiveStyle, indicatorInactiveStyle, renderItem, style, } = props;
8
+ const flatListRef = useRef(null);
9
+ const indexRef = useRef(0);
10
+ const [currentIndex, setCurrentIndex] = useState(0);
11
+ const windowWidthRef = useRef(Dimensions.get('window').width);
12
+ const [width, setWidth] = useState(windowWidthRef.current);
13
+ const onViewableItemsChanged = useRef(({ viewableItems }) => {
14
+ if (viewableItems.length !== 1) {
15
+ return;
16
+ }
17
+ const [item] = viewableItems;
18
+ indexRef.current = item.index;
19
+ setCurrentIndex(indexRef.current);
20
+ });
21
+ const updateOrientation = useCallback((updatedWidth) => {
22
+ if (windowWidthRef.current !== updatedWidth) {
23
+ windowWidthRef.current = updatedWidth;
24
+ setWidth(updatedWidth);
25
+ }
26
+ }, []);
27
+ useEffect(() => {
28
+ // on width change (due to orientation change), jump to the new index offset
29
+ flatListRef?.current?.scrollToOffset({
30
+ offset: width * indexRef.current,
31
+ animated: false,
32
+ });
33
+ }, [width]);
34
+ useEffect(() => {
35
+ const orientationHandler = ({ window }) => {
36
+ updateOrientation(window.width);
37
+ };
38
+ const subscription = Dimensions.addEventListener('change', orientationHandler);
39
+ // Clean up listener. Dimensions.removeEventListener is deprecated as of React Native 0.65 but it is technically
40
+ // available so try to remove via a `EmitterSubscription` first before falling back to `removeEventListener`
41
+ return () => {
42
+ if (typeof subscription?.remove === 'function') {
43
+ subscription?.remove();
44
+ }
45
+ else {
46
+ Dimensions.removeEventListener('change', orientationHandler);
47
+ }
48
+ };
49
+ }, [updateOrientation]);
50
+ const carouselRenderItem = (renderInfo) => (<View style={{ width }}>{renderItem(renderInfo)}</View>);
51
+ if (!data?.length) {
52
+ return null;
53
+ }
54
+ return (<>
55
+ <FlatList bounces={false} data={data} decelerationRate="fast" disableIntervalMomentum horizontal onViewableItemsChanged={onViewableItemsChanged.current} ref={flatListRef} renderItem={carouselRenderItem} renderToHardwareTextureAndroid showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} snapToAlignment="start" snapToInterval={width} style={style} viewabilityConfig={VIEWABILITY_CONFIG}/>
56
+ <CarouselPageIndicator activeStyle={indicatorActiveStyle} currentIndex={currentIndex} inactiveStyle={indicatorInactiveStyle} numberOfItems={data.length} style={styles.indicator}/>
57
+ </>);
58
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { CarouselPageIndicatorProps } from './types';
3
+ export default function CarouselPageIndicator({ activeStyle, currentIndex, inactiveStyle, numberOfItems, style, }: CarouselPageIndicatorProps): JSX.Element;
@@ -0,0 +1,10 @@
1
+ import React, { useMemo } from 'react';
2
+ import { View } from 'react-native';
3
+ import { SafeAreaView } from 'react-native-safe-area-context';
4
+ import { DEFAULT_CAROUSEL_INDICATOR_ACTIVE_STYLE, DEFAULT_CAROUSEL_INDICATOR_INACTIVE_STYLE, } from './constants';
5
+ export default function CarouselPageIndicator({ activeStyle, currentIndex, inactiveStyle, numberOfItems, style, }) {
6
+ const items = useMemo(() => new Array(numberOfItems ?? 0)
7
+ .fill(null)
8
+ .map((_, index) => (currentIndex ?? 0) === index ? (<View style={[DEFAULT_CAROUSEL_INDICATOR_ACTIVE_STYLE, activeStyle]} key={`indicator-item-${index}`}/>) : (<View style={[DEFAULT_CAROUSEL_INDICATOR_INACTIVE_STYLE, inactiveStyle]} key={`indicator-item-${index}`}/>)), [activeStyle, currentIndex, inactiveStyle, numberOfItems]);
9
+ return <SafeAreaView style={style}>{items}</SafeAreaView>;
10
+ }
@@ -0,0 +1,9 @@
1
+ import { ViewStyle } from 'react-native';
2
+ export declare const DEFAULT_CAROUSEL_COLOR_ACTIVE = "#a1a1a1";
3
+ export declare const DEFAULT_CAROUSEL_COLOR_INACTIVE = "#d8d8d8";
4
+ export declare const DEFAULT_CAROUSEL_INDICATOR_SIZE = 12;
5
+ export declare const DEFAULT_CAROUSEL_INDICATOR_ACTIVE_STYLE: ViewStyle;
6
+ export declare const DEFAULT_CAROUSEL_INDICATOR_INACTIVE_STYLE: ViewStyle;
7
+ export declare const VIEWABILITY_CONFIG: {
8
+ itemVisiblePercentThreshold: number;
9
+ };
@@ -0,0 +1,18 @@
1
+ export const DEFAULT_CAROUSEL_COLOR_ACTIVE = '#a1a1a1';
2
+ export const DEFAULT_CAROUSEL_COLOR_INACTIVE = '#d8d8d8';
3
+ export const DEFAULT_CAROUSEL_INDICATOR_SIZE = 12;
4
+ const DEFAULT_CAROUSEL_INDICATOR_STYLE = {
5
+ borderRadius: DEFAULT_CAROUSEL_INDICATOR_SIZE / 2,
6
+ height: DEFAULT_CAROUSEL_INDICATOR_SIZE,
7
+ margin: DEFAULT_CAROUSEL_INDICATOR_SIZE / 3,
8
+ width: DEFAULT_CAROUSEL_INDICATOR_SIZE,
9
+ };
10
+ export const DEFAULT_CAROUSEL_INDICATOR_ACTIVE_STYLE = {
11
+ ...DEFAULT_CAROUSEL_INDICATOR_STYLE,
12
+ backgroundColor: DEFAULT_CAROUSEL_COLOR_ACTIVE,
13
+ };
14
+ export const DEFAULT_CAROUSEL_INDICATOR_INACTIVE_STYLE = {
15
+ ...DEFAULT_CAROUSEL_INDICATOR_STYLE,
16
+ backgroundColor: DEFAULT_CAROUSEL_COLOR_INACTIVE,
17
+ };
18
+ export const VIEWABILITY_CONFIG = { itemVisiblePercentThreshold: 60 };
@@ -0,0 +1,3 @@
1
+ export { default as Carousel } from './Carousel';
2
+ export { DEFAULT_CAROUSEL_INDICATOR_SIZE } from './constants';
3
+ export { CarouselProps } from './types';
@@ -0,0 +1,2 @@
1
+ export { default as Carousel } from './Carousel';
2
+ export { DEFAULT_CAROUSEL_INDICATOR_SIZE } from './constants';
@@ -0,0 +1,2 @@
1
+ import { CarouselStyles } from './types';
2
+ export declare const styles: CarouselStyles;
@@ -0,0 +1,11 @@
1
+ import { StyleSheet } from 'react-native';
2
+ export const styles = StyleSheet.create({
3
+ indicator: {
4
+ bottom: 0,
5
+ flexDirection: 'row',
6
+ justifyContent: 'center',
7
+ left: 0,
8
+ position: 'absolute',
9
+ right: 0,
10
+ },
11
+ });
@@ -0,0 +1,19 @@
1
+ import { ListRenderItem, StyleProp, ViewStyle } from 'react-native';
2
+ export interface CarouselProps<T> {
3
+ data: ReadonlyArray<T>;
4
+ indicatorActiveStyle?: StyleProp<ViewStyle>;
5
+ indicatorInactiveStyle?: StyleProp<ViewStyle>;
6
+ onClose?: () => void;
7
+ renderItem: ListRenderItem<T>;
8
+ style?: StyleProp<ViewStyle>;
9
+ }
10
+ export interface CarouselPageIndicatorProps {
11
+ activeStyle?: StyleProp<ViewStyle>;
12
+ currentIndex: number | null;
13
+ inactiveStyle?: StyleProp<ViewStyle>;
14
+ numberOfItems: number;
15
+ style?: StyleProp<ViewStyle>;
16
+ }
17
+ export interface CarouselStyles {
18
+ indicator: ViewStyle;
19
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { IconButtonProps } from './types';
3
+ export default function IconButton({ color, source, size, ...pressableProps }: IconButtonProps): JSX.Element;
@@ -0,0 +1,9 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Image, Pressable } from 'react-native';
3
+ import { getStyles } from './styles';
4
+ export default function IconButton({ color, source, size = 16, ...pressableProps }) {
5
+ const { icon } = useMemo(() => getStyles(color, size), [color, size]);
6
+ return (<Pressable {...pressableProps}>
7
+ <Image source={source} style={icon}/>
8
+ </Pressable>);
9
+ }
@@ -0,0 +1,2 @@
1
+ export { default as IconButton } from './IconButton';
2
+ export { IconButtonProps, IconButtonStyles } from './types';
@@ -0,0 +1 @@
1
+ export { default as IconButton } from './IconButton';
@@ -0,0 +1,2 @@
1
+ import { IconButtonProps, IconButtonStyles } from '.';
2
+ export declare const getStyles: (color: IconButtonProps['color'], size: IconButtonProps['size']) => IconButtonStyles;
@@ -0,0 +1,9 @@
1
+ import { StyleSheet } from 'react-native';
2
+ export const getStyles = (color, size) => StyleSheet.create({
3
+ icon: {
4
+ height: size,
5
+ resizeMode: 'contain',
6
+ tintColor: color,
7
+ width: size,
8
+ },
9
+ });
@@ -0,0 +1,18 @@
1
+ import { ColorValue, ImageSourcePropType, ImageStyle, PressableProps } from 'react-native';
2
+ export interface IconButtonStyles {
3
+ icon: ImageStyle;
4
+ }
5
+ export interface IconButtonProps extends PressableProps {
6
+ /**
7
+ * color to be applied to the icon
8
+ */
9
+ color?: ColorValue;
10
+ /**
11
+ * icon source, only supports images at this time
12
+ */
13
+ source: ImageSourcePropType;
14
+ /**
15
+ * icon size
16
+ */
17
+ size?: number;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './Button';
2
+ export * from './Carousel';
3
+ export * from './IconButton';
@@ -0,0 +1,3 @@
1
+ export * from './Button';
2
+ export * from './Carousel';
3
+ export * from './IconButton';
@@ -0,0 +1 @@
1
+ export declare const getLineHeight: (fontSize: number) => number;
@@ -0,0 +1,4 @@
1
+ // as a safeguard against known React Native lineHeight issues, e.g. https://github.com/facebook/react-native/issues/29507
2
+ // use a value of 1.5 as the default line height multiplier
3
+ const LINE_HEIGHT_MULTIPLIER = 1.5;
4
+ export const getLineHeight = (fontSize) => fontSize * LINE_HEIGHT_MULTIPLIER;
package/jest.config.js ADDED
@@ -0,0 +1,20 @@
1
+ module.exports = {
2
+ preset: 'react-native',
3
+ modulePathIgnorePatterns: ['<rootDir>/dist/'],
4
+ collectCoverageFrom: [
5
+ '<rootDir>/src/**/*.{js,jsx,ts,tsx}',
6
+ '!<rootDir>/src/**/*{c,C}onstants.ts',
7
+ ],
8
+ moduleNameMapper: {
9
+ '^react$': '<rootDir>/node_modules/react',
10
+ '^react-native$': '<rootDir>/node_modules/react-native',
11
+ },
12
+ coverageThreshold: {
13
+ global: {
14
+ branches: 90,
15
+ functions: 90,
16
+ lines: 90,
17
+ statements: 90,
18
+ },
19
+ },
20
+ };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@aws-amplify/ui-react-native",
3
+ "version": "0.0.0-in-app-messaging-20220826014803",
4
+ "main": "dist/index.js",
5
+ "module": "dist/esm/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "license": "Apache-2.0",
8
+ "scripts": {
9
+ "build": "yarn dist && cp -a src/assets dist",
10
+ "clean": "rimraf dist",
11
+ "dev": "yarn dist --watch",
12
+ "dist": "tsc --project tsconfig.dist.json",
13
+ "lint": "tsc --noEmit && eslint src",
14
+ "prebuild": "rimraf dist",
15
+ "test": "jest --coverage",
16
+ "test:watch": "yarn test --watch"
17
+ },
18
+ "devDependencies": {
19
+ "@babel/cli": "^7.17.10",
20
+ "@babel/core": "^7.17.10",
21
+ "@babel/preset-env": "^7.17.10",
22
+ "@testing-library/react-hooks": "^8.0.0",
23
+ "@types/react": "^17.0.2",
24
+ "@types/react-native": "^0.67.6",
25
+ "@types/react-test-renderer": "^17.0.1",
26
+ "@typescript-eslint/eslint-plugin": "^5.20.0",
27
+ "@typescript-eslint/parser": "^5.20.0",
28
+ "babel-jest": "^28.0.3",
29
+ "eslint": "^8.14.0",
30
+ "eslint-config-prettier": "^8.5.0",
31
+ "eslint-plugin-import": "^2.26.0",
32
+ "eslint-plugin-jest": "^26.1.4",
33
+ "eslint-plugin-prettier": "^4.0.0",
34
+ "eslint-plugin-react": "^7.29.4",
35
+ "eslint-plugin-react-hooks": "^4.4.0",
36
+ "metro-react-native-babel-preset": "^0.70.2",
37
+ "react": "^17.0.2",
38
+ "react-native": "^0.68.1",
39
+ "react-native-safe-area-context": "^4.2.5",
40
+ "react-test-renderer": "^17.0.2",
41
+ "rimraf": "^3.0.2"
42
+ },
43
+ "dependencies": {
44
+ "@aws-amplify/ui": "0.0.0-in-app-messaging-20220826014803",
45
+ "@aws-amplify/ui-react-core": "0.0.0-in-app-messaging-20220826014803"
46
+ },
47
+ "peerDependencies": {
48
+ "react": ">= 16.8.0",
49
+ "react-native": ">= 0.63.4",
50
+ "react-native-safe-area-context": ">= 4.2.5"
51
+ },
52
+ "resolutions": {
53
+ "@types/react": "^17.0.2"
54
+ }
55
+ }
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+
3
+ import { ImageDimensions, useMessageProps } from '../../hooks';
4
+ import { MessageWrapper } from '../MessageWrapper';
5
+ import { MessageLayout } from '../MessageLayout';
6
+
7
+ import { getStyles, positionStyle } from './styles';
8
+ import { BannerMessageProps } from './types';
9
+
10
+ export default function BannerMessage({
11
+ position = 'top',
12
+ ...props
13
+ }: BannerMessageProps): JSX.Element | null {
14
+ const messageProps = useMessageProps(
15
+ props,
16
+ (imageDimensions: ImageDimensions) =>
17
+ getStyles(imageDimensions, { position: { ...positionStyle[position] } })
18
+ );
19
+ const { shouldRenderMessage, styles } = messageProps;
20
+
21
+ if (!shouldRenderMessage) {
22
+ return null;
23
+ }
24
+
25
+ const { wrapper, ...messageStyles } = styles!;
26
+
27
+ return (
28
+ <MessageWrapper style={wrapper}>
29
+ <MessageLayout
30
+ {...props}
31
+ {...messageProps}
32
+ orientation="landscape"
33
+ styles={messageStyles}
34
+ />
35
+ </MessageWrapper>
36
+ );
37
+ }
@@ -0,0 +1,138 @@
1
+ import React from 'react';
2
+ import TestRenderer from 'react-test-renderer';
3
+
4
+ import { IN_APP_MESSAGING_TEST_ID } from '../../../constants';
5
+ import { useMessageImage } from '../../../hooks/useMessageImage';
6
+
7
+ import BannerMessage from '../BannerMessage';
8
+
9
+ jest.mock('../../../hooks/useMessageImage');
10
+ jest.mock('../../MessageWrapper', () => ({ MessageWrapper: 'MessageWrapper' }));
11
+
12
+ const mockUseMessageImage = useMessageImage as jest.Mock;
13
+ const onAction = jest.fn();
14
+ const onClose = jest.fn();
15
+
16
+ const baseProps = { layout: 'TOP_BANNER' as const, onClose };
17
+
18
+ describe('BannerMessage', () => {
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ });
22
+
23
+ it('renders a message as expected without an image', () => {
24
+ mockUseMessageImage.mockReturnValueOnce({
25
+ hasRenderableImage: false,
26
+ imageDimensions: { height: undefined, width: undefined },
27
+ isImageFetching: false,
28
+ });
29
+
30
+ const renderer = TestRenderer.create(<BannerMessage {...baseProps} />);
31
+
32
+ expect(renderer.toJSON()).toMatchSnapshot();
33
+ });
34
+
35
+ it('renders a message as expected with an image', () => {
36
+ mockUseMessageImage.mockReturnValueOnce({
37
+ hasRenderableImage: true,
38
+ imageDimensions: { height: 100, width: 100 },
39
+ isImageFetching: false,
40
+ });
41
+
42
+ const src = 'asset.png';
43
+ const props = { ...baseProps, image: { src } };
44
+
45
+ const renderer = TestRenderer.create(<BannerMessage {...props} />);
46
+
47
+ const image = renderer.root.findByProps({
48
+ testID: IN_APP_MESSAGING_TEST_ID.IMAGE,
49
+ });
50
+
51
+ expect(image.props).toEqual(
52
+ expect.objectContaining({ source: { uri: src } })
53
+ );
54
+ expect(renderer.toJSON()).toMatchSnapshot();
55
+ });
56
+
57
+ it('returns null while an image is fetching', () => {
58
+ mockUseMessageImage.mockReturnValueOnce({
59
+ hasRenderableImage: false,
60
+ imageDimensions: { height: undefined, width: undefined },
61
+ isImageFetching: true,
62
+ });
63
+
64
+ const renderer = TestRenderer.create(<BannerMessage {...baseProps} />);
65
+
66
+ expect(renderer.toJSON()).toBeNull();
67
+ });
68
+
69
+ it.each([
70
+ [
71
+ 'header',
72
+ IN_APP_MESSAGING_TEST_ID.HEADER,
73
+ {
74
+ testProps: { content: 'header content' },
75
+ expectedProps: { children: 'header content' },
76
+ },
77
+ ],
78
+ [
79
+ 'body',
80
+ IN_APP_MESSAGING_TEST_ID.BODY,
81
+ {
82
+ testProps: { content: 'body content' },
83
+ expectedProps: { children: 'body content' },
84
+ },
85
+ ],
86
+ [
87
+ 'primaryButton',
88
+ IN_APP_MESSAGING_TEST_ID.PRIMARY_BUTTON,
89
+ {
90
+ testProps: { onAction, title: 'primary button' },
91
+ expectedProps: { children: 'primary button', onPress: onAction },
92
+ },
93
+ ],
94
+ [
95
+ 'secondaryButton',
96
+ IN_APP_MESSAGING_TEST_ID.SECONDARY_BUTTON,
97
+ {
98
+ testProps: { onAction, title: 'secondary button' },
99
+ expectedProps: { children: 'secondary button', onPress: onAction },
100
+ },
101
+ ],
102
+ ])(
103
+ 'correctly handles a %s prop',
104
+ (key, testID, { testProps, expectedProps }) => {
105
+ mockUseMessageImage.mockReturnValueOnce({
106
+ hasRenderableImage: false,
107
+ imageDimensions: { height: undefined, width: undefined },
108
+ isImageFetching: false,
109
+ });
110
+
111
+ const props = { ...baseProps, [key]: testProps };
112
+
113
+ const renderer = TestRenderer.create(<BannerMessage {...props} />);
114
+ const testElement = renderer.root.findByProps({ testID });
115
+
116
+ expect(testElement.props).toEqual(expect.objectContaining(expectedProps));
117
+ }
118
+ );
119
+
120
+ it('calls onClose when the close button is pressed', () => {
121
+ mockUseMessageImage.mockReturnValueOnce({
122
+ hasRenderableImage: false,
123
+ imageDimensions: { height: undefined, width: undefined },
124
+ isImageFetching: false,
125
+ });
126
+
127
+ const renderer = TestRenderer.create(<BannerMessage {...baseProps} />);
128
+ const closeButton = renderer.root.findByProps({
129
+ testID: IN_APP_MESSAGING_TEST_ID.CLOSE_BUTTON,
130
+ });
131
+
132
+ TestRenderer.act(() => {
133
+ (closeButton.props as { onPress: () => void }).onPress();
134
+ });
135
+
136
+ expect(onClose).toHaveBeenCalledTimes(1);
137
+ });
138
+ });