@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.
- package/.eslintrc.js +100 -0
- package/.lintstagedrc.js +6 -0
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +201 -0
- package/README.md +25 -0
- package/babel.config.js +3 -0
- package/dist/InAppMessaging/components/BannerMessage/BannerMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/BannerMessage/BannerMessage.js +16 -0
- package/dist/InAppMessaging/components/BannerMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/BannerMessage/index.js +1 -0
- package/dist/InAppMessaging/components/BannerMessage/styles.d.ts +7 -0
- package/dist/InAppMessaging/components/BannerMessage/styles.js +77 -0
- package/dist/InAppMessaging/components/BannerMessage/types.d.ts +12 -0
- package/dist/InAppMessaging/components/BannerMessage/types.js +1 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessage.js +20 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.d.ts +3 -0
- package/dist/InAppMessaging/components/CarouselMessage/CarouselMessageItem.js +18 -0
- package/dist/InAppMessaging/components/CarouselMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/CarouselMessage/index.js +1 -0
- package/dist/InAppMessaging/components/CarouselMessage/styles.d.ts +5 -0
- package/dist/InAppMessaging/components/CarouselMessage/styles.js +98 -0
- package/dist/InAppMessaging/components/CarouselMessage/types.d.ts +18 -0
- package/dist/InAppMessaging/components/CarouselMessage/types.js +1 -0
- package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/FullScreenMessage/FullScreenMessage.js +18 -0
- package/dist/InAppMessaging/components/FullScreenMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/FullScreenMessage/index.js +1 -0
- package/dist/InAppMessaging/components/FullScreenMessage/styles.d.ts +3 -0
- package/dist/InAppMessaging/components/FullScreenMessage/styles.js +86 -0
- package/dist/InAppMessaging/components/FullScreenMessage/types.d.ts +6 -0
- package/dist/InAppMessaging/components/FullScreenMessage/types.js +1 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.d.ts +10 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.js +29 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.d.ts +3 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.js +24 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/index.d.ts +2 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/index.js +1 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/types.d.ts +24 -0
- package/dist/InAppMessaging/components/InAppMessageDisplay/types.js +1 -0
- package/dist/InAppMessaging/components/MessageLayout/MessageLayout.d.ts +3 -0
- package/dist/InAppMessaging/components/MessageLayout/MessageLayout.js +34 -0
- package/dist/InAppMessaging/components/MessageLayout/index.d.ts +1 -0
- package/dist/InAppMessaging/components/MessageLayout/index.js +1 -0
- package/dist/InAppMessaging/components/MessageLayout/types.d.ts +7 -0
- package/dist/InAppMessaging/components/MessageLayout/types.js +1 -0
- package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.d.ts +3 -0
- package/dist/InAppMessaging/components/MessageWrapper/MessageWrapper.js +20 -0
- package/dist/InAppMessaging/components/MessageWrapper/index.d.ts +2 -0
- package/dist/InAppMessaging/components/MessageWrapper/index.js +1 -0
- package/dist/InAppMessaging/components/MessageWrapper/styles.d.ts +2 -0
- package/dist/InAppMessaging/components/MessageWrapper/styles.js +5 -0
- package/dist/InAppMessaging/components/MessageWrapper/types.d.ts +10 -0
- package/dist/InAppMessaging/components/MessageWrapper/types.js +1 -0
- package/dist/InAppMessaging/components/ModalMessage/ModalMessage.d.ts +3 -0
- package/dist/InAppMessaging/components/ModalMessage/ModalMessage.js +18 -0
- package/dist/InAppMessaging/components/ModalMessage/index.d.ts +2 -0
- package/dist/InAppMessaging/components/ModalMessage/index.js +1 -0
- package/dist/InAppMessaging/components/ModalMessage/styles.d.ts +4 -0
- package/dist/InAppMessaging/components/ModalMessage/styles.js +99 -0
- package/dist/InAppMessaging/components/ModalMessage/types.d.ts +6 -0
- package/dist/InAppMessaging/components/ModalMessage/types.js +1 -0
- package/dist/InAppMessaging/components/index.d.ts +6 -0
- package/dist/InAppMessaging/components/index.js +2 -0
- package/dist/InAppMessaging/components/withInAppMessaging/index.d.ts +1 -0
- package/dist/InAppMessaging/components/withInAppMessaging/index.js +1 -0
- package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.d.ts +5 -0
- package/dist/InAppMessaging/components/withInAppMessaging/withInAppMessaging.js +11 -0
- package/dist/InAppMessaging/constants.d.ts +31 -0
- package/dist/InAppMessaging/constants.js +43 -0
- package/dist/InAppMessaging/hooks/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/index.js +2 -0
- package/dist/InAppMessaging/hooks/useMessageImage/constants.d.ts +8 -0
- package/dist/InAppMessaging/hooks/useMessageImage/constants.js +18 -0
- package/dist/InAppMessaging/hooks/useMessageImage/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/useMessageImage/index.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageImage/types.d.ts +15 -0
- package/dist/InAppMessaging/hooks/useMessageImage/types.js +6 -0
- package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.d.ts +10 -0
- package/dist/InAppMessaging/hooks/useMessageImage/useMessageImage.js +50 -0
- package/dist/InAppMessaging/hooks/useMessageImage/utils.d.ts +4 -0
- package/dist/InAppMessaging/hooks/useMessageImage/utils.js +56 -0
- package/dist/InAppMessaging/hooks/useMessageProps/index.d.ts +2 -0
- package/dist/InAppMessaging/hooks/useMessageProps/index.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageProps/types.d.ts +109 -0
- package/dist/InAppMessaging/hooks/useMessageProps/types.js +1 -0
- package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.d.ts +12 -0
- package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.js +49 -0
- package/dist/InAppMessaging/hooks/useMessageProps/utils.d.ts +43 -0
- package/dist/InAppMessaging/hooks/useMessageProps/utils.js +192 -0
- package/dist/InAppMessaging/index.d.ts +2 -0
- package/dist/InAppMessaging/index.js +2 -0
- package/dist/__mocks__/react-native-safe-area-context.d.ts +3 -0
- package/dist/__mocks__/react-native-safe-area-context.js +4 -0
- package/dist/assets/close.png +0 -0
- package/dist/assets/index.d.ts +5 -0
- package/dist/assets/index.js +4 -0
- package/dist/assets/index.ts +7 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useDeviceOrientation/index.d.ts +1 -0
- package/dist/hooks/useDeviceOrientation/index.js +1 -0
- package/dist/hooks/useDeviceOrientation/useDeviceOrientation.d.ts +6 -0
- package/dist/hooks/useDeviceOrientation/useDeviceOrientation.js +33 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/primitives/Button/Button.d.ts +3 -0
- package/dist/primitives/Button/Button.js +8 -0
- package/dist/primitives/Button/index.d.ts +2 -0
- package/dist/primitives/Button/index.js +1 -0
- package/dist/primitives/Button/styles.d.ts +2 -0
- package/dist/primitives/Button/styles.js +4 -0
- package/dist/primitives/Button/types.d.ts +7 -0
- package/dist/primitives/Button/types.js +1 -0
- package/dist/primitives/Carousel/Carousel.d.ts +3 -0
- package/dist/primitives/Carousel/Carousel.js +58 -0
- package/dist/primitives/Carousel/CarouselPageIndicator.d.ts +3 -0
- package/dist/primitives/Carousel/CarouselPageIndicator.js +10 -0
- package/dist/primitives/Carousel/constants.d.ts +9 -0
- package/dist/primitives/Carousel/constants.js +18 -0
- package/dist/primitives/Carousel/index.d.ts +3 -0
- package/dist/primitives/Carousel/index.js +2 -0
- package/dist/primitives/Carousel/styles.d.ts +2 -0
- package/dist/primitives/Carousel/styles.js +11 -0
- package/dist/primitives/Carousel/types.d.ts +19 -0
- package/dist/primitives/Carousel/types.js +1 -0
- package/dist/primitives/IconButton/IconButton.d.ts +3 -0
- package/dist/primitives/IconButton/IconButton.js +9 -0
- package/dist/primitives/IconButton/index.d.ts +2 -0
- package/dist/primitives/IconButton/index.js +1 -0
- package/dist/primitives/IconButton/styles.d.ts +2 -0
- package/dist/primitives/IconButton/styles.js +9 -0
- package/dist/primitives/IconButton/types.d.ts +18 -0
- package/dist/primitives/IconButton/types.js +1 -0
- package/dist/primitives/index.d.ts +3 -0
- package/dist/primitives/index.js +3 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +4 -0
- package/jest.config.js +20 -0
- package/package.json +55 -0
- package/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx +37 -0
- package/src/InAppMessaging/components/BannerMessage/__tests__/BannerMessage.spec.tsx +138 -0
- package/src/InAppMessaging/components/BannerMessage/__tests__/__snapshots__/BannerMessage.spec.tsx.snap +224 -0
- package/src/InAppMessaging/components/BannerMessage/index.ts +2 -0
- package/src/InAppMessaging/components/BannerMessage/styles.ts +105 -0
- package/src/InAppMessaging/components/BannerMessage/types.ts +15 -0
- package/src/InAppMessaging/components/CarouselMessage/CarouselMessage.tsx +42 -0
- package/src/InAppMessaging/components/CarouselMessage/CarouselMessageItem.tsx +37 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessage.spec.tsx +55 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/CarouselMessageItem.spec.tsx +56 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessage.spec.tsx.snap +86 -0
- package/src/InAppMessaging/components/CarouselMessage/__tests__/__snapshots__/CarouselMessageItem.spec.tsx.snap +248 -0
- package/src/InAppMessaging/components/CarouselMessage/index.ts +2 -0
- package/src/InAppMessaging/components/CarouselMessage/styles.ts +125 -0
- package/src/InAppMessaging/components/CarouselMessage/types.ts +28 -0
- package/src/InAppMessaging/components/FullScreenMessage/FullScreenMessage.tsx +38 -0
- package/src/InAppMessaging/components/FullScreenMessage/__tests__/FullScreenMessage.spec.tsx +53 -0
- package/src/InAppMessaging/components/FullScreenMessage/__tests__/__snapshots__/FullScreenMessage.spec.tsx.snap +236 -0
- package/src/InAppMessaging/components/FullScreenMessage/index.ts +2 -0
- package/src/InAppMessaging/components/FullScreenMessage/styles.ts +106 -0
- package/src/InAppMessaging/components/FullScreenMessage/types.ts +7 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/InAppMessageDisplay.tsx +48 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/InAppMessageDisplay.spec.tsx +33 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/__snapshots__/InAppMessageDisplay.spec.tsx.snap +9 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/handleMessageLinkAction.spec.ts +51 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/handleMessageLinkAction.ts +30 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/index.ts +2 -0
- package/src/InAppMessaging/components/InAppMessageDisplay/types.ts +32 -0
- package/src/InAppMessaging/components/MessageLayout/MessageLayout.tsx +102 -0
- package/src/InAppMessaging/components/MessageLayout/index.ts +1 -0
- package/src/InAppMessaging/components/MessageLayout/types.ts +15 -0
- package/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx +34 -0
- package/src/InAppMessaging/components/MessageWrapper/__tests__/MessageWrapper.spec.tsx +19 -0
- package/src/InAppMessaging/components/MessageWrapper/__tests__/__snapshots__/MessageWrapper.spec.tsx.snap +35 -0
- package/src/InAppMessaging/components/MessageWrapper/index.ts +2 -0
- package/src/InAppMessaging/components/MessageWrapper/styles.ts +7 -0
- package/src/InAppMessaging/components/MessageWrapper/types.ts +12 -0
- package/src/InAppMessaging/components/ModalMessage/ModalMessage.tsx +37 -0
- package/src/InAppMessaging/components/ModalMessage/__tests__/ModalMessage.spec.tsx +155 -0
- package/src/InAppMessaging/components/ModalMessage/__tests__/__snapshots__/ModalMessage.spec.tsx.snap +323 -0
- package/src/InAppMessaging/components/ModalMessage/index.ts +2 -0
- package/src/InAppMessaging/components/ModalMessage/styles.ts +132 -0
- package/src/InAppMessaging/components/ModalMessage/types.ts +8 -0
- package/src/InAppMessaging/components/index.ts +6 -0
- package/src/InAppMessaging/components/withInAppMessaging/__tests__/__snapshots__/withInAppMessaging.spec.tsx.snap +3 -0
- package/src/InAppMessaging/components/withInAppMessaging/__tests__/withInAppMessaging.spec.tsx +15 -0
- package/src/InAppMessaging/components/withInAppMessaging/index.ts +1 -0
- package/src/InAppMessaging/components/withInAppMessaging/withInAppMessaging.tsx +18 -0
- package/src/InAppMessaging/constants.ts +56 -0
- package/src/InAppMessaging/hooks/index.ts +9 -0
- package/src/InAppMessaging/hooks/useMessageImage/__tests__/useMessageImage.spec.ts +141 -0
- package/src/InAppMessaging/hooks/useMessageImage/__tests__/utils.spec.ts +107 -0
- package/src/InAppMessaging/hooks/useMessageImage/constants.ts +27 -0
- package/src/InAppMessaging/hooks/useMessageImage/index.ts +2 -0
- package/src/InAppMessaging/hooks/useMessageImage/types.ts +18 -0
- package/src/InAppMessaging/hooks/useMessageImage/useMessageImage.ts +74 -0
- package/src/InAppMessaging/hooks/useMessageImage/utils.ts +80 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/__snapshots__/utils.spec.ts.snap +223 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/useMessageProps.spec.ts +162 -0
- package/src/InAppMessaging/hooks/useMessageProps/__tests__/utils.spec.ts +354 -0
- package/src/InAppMessaging/hooks/useMessageProps/index.ts +8 -0
- package/src/InAppMessaging/hooks/useMessageProps/types.ts +131 -0
- package/src/InAppMessaging/hooks/useMessageProps/useMessageProps.ts +70 -0
- package/src/InAppMessaging/hooks/useMessageProps/utils.ts +274 -0
- package/src/InAppMessaging/index.ts +14 -0
- package/src/__mocks__/react-native-safe-area-context.ts +6 -0
- package/src/__tests__/__snapshots__/index.spec.ts.snap +15 -0
- package/src/__tests__/index.spec.ts +8 -0
- package/src/assets/close.png +0 -0
- package/src/assets/index.ts +7 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useDeviceOrientation/__tests__/useDeviceOrientation.spec.ts +87 -0
- package/src/hooks/useDeviceOrientation/index.ts +4 -0
- package/src/hooks/useDeviceOrientation/useDeviceOrientation.ts +47 -0
- package/src/index.ts +1 -0
- package/src/primitives/Button/Button.tsx +21 -0
- package/src/primitives/Button/__tests__/Button.spec.tsx +24 -0
- package/src/primitives/Button/__tests__/__snapshots__/Button.spec.tsx.snap +52 -0
- package/src/primitives/Button/index.ts +2 -0
- package/src/primitives/Button/styles.ts +6 -0
- package/src/primitives/Button/types.ts +9 -0
- package/src/primitives/Carousel/Carousel.tsx +115 -0
- package/src/primitives/Carousel/CarouselPageIndicator.tsx +39 -0
- package/src/primitives/Carousel/__tests__/Carousel.spec.tsx +185 -0
- package/src/primitives/Carousel/__tests__/CarouselPageIndicator.spec.tsx +71 -0
- package/src/primitives/Carousel/__tests__/__snapshots__/Carousel.spec.tsx.snap +216 -0
- package/src/primitives/Carousel/__tests__/__snapshots__/CarouselPageIndicator.spec.tsx.snap +191 -0
- package/src/primitives/Carousel/constants.ts +25 -0
- package/src/primitives/Carousel/index.ts +3 -0
- package/src/primitives/Carousel/styles.ts +14 -0
- package/src/primitives/Carousel/types.ts +22 -0
- package/src/primitives/IconButton/IconButton.tsx +20 -0
- package/src/primitives/IconButton/__tests__/IconButton.spec.tsx +13 -0
- package/src/primitives/IconButton/__tests__/__snapshots__/IconButton.spec.tsx.snap +34 -0
- package/src/primitives/IconButton/index.ts +2 -0
- package/src/primitives/IconButton/styles.ts +16 -0
- package/src/primitives/IconButton/types.ts +27 -0
- package/src/primitives/index.ts +3 -0
- package/src/utils/index.ts +6 -0
- package/tsconfig.dist.json +4 -0
- package/tsconfig.json +21 -0
|
Binary file
|
|
@@ -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,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
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InAppMessaging';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InAppMessaging';
|
|
@@ -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 @@
|
|
|
1
|
+
export { default as Button } from './Button';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,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,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,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 @@
|
|
|
1
|
+
export { default as IconButton } from './IconButton';
|
|
@@ -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 @@
|
|
|
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
|
+
});
|