From 436e6836430a24352c646a9ce0755c9d946236cd Mon Sep 17 00:00:00 2001 From: Caleb Pollman Date: Wed, 27 Oct 2021 12:10:03 -0700 Subject: [PATCH 1/2] feat(in-app-messaging): add BannerMessage UI component --- .../BannerMessage/BannerMessage.tsx | 92 +++++++++++++++ .../components/BannerMessage/index.ts | 1 + .../components/BannerMessage/styles.ts | 110 ++++++++++++++++++ .../components/BannerMessage/types.ts | 21 ++++ .../MessageWrapper/MessageWrapper.tsx | 22 ++++ .../components/MessageWrapper/index.ts | 2 + .../components/MessageWrapper/styles.ts | 21 ++++ .../components/MessageWrapper/types.ts | 24 ++++ .../InAppMessaging/components/constants.ts | 67 +++++++++++ .../src/InAppMessaging/components/index.ts | 2 +- .../src/InAppMessaging/components/types.ts | 4 +- .../src/InAppMessaging/components/utils.ts | 16 +++ .../hooks/useInAppMessage/useInAppMessage.ts | 12 +- .../useInAppMessageButtonStyle.ts | 6 +- .../useInAppMessageImage.ts | 3 +- .../src/InAppMessaging/index.ts | 1 + .../src/InAppMessaging/ui/index.ts | 1 + .../src/icons/close.png | Bin 0 -> 3118 bytes .../src/icons/index.ts | 5 +- 19 files changed, 396 insertions(+), 14 deletions(-) create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/styles.ts create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/types.ts create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts create mode 100644 packages/aws-amplify-react-native/src/InAppMessaging/components/utils.ts create mode 100644 packages/aws-amplify-react-native/src/icons/close.png diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx new file mode 100644 index 00000000000..1343068de8b --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx @@ -0,0 +1,92 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import React from 'react'; +import { Image, Text, View } from 'react-native'; + +import icons from '../../../icons'; +import { ICON_BUTTON_HIT_SLOP, ICON_BUTTON_SIZE } from '../constants'; +import { useInAppMessageButtonStyle, useInAppMessageImage } from '../../hooks'; +import { Button, IconButton } from '../../ui'; + +import { MessageWrapper } from '../MessageWrapper'; +import { styles } from './styles'; +import { BannerMessageProps } from './types'; + +export default function BannerMessage({ + body, + container, + header, + image, + layout, + onClose, + position, + primaryButton, + secondaryButton, + style, +}: BannerMessageProps) { + const { imageStyle, shouldDelayMessageRendering, shouldRenderImage } = useInAppMessageImage(image, layout); + const { primaryButtonStyle, secondaryButtonStyle } = useInAppMessageButtonStyle({ + baseButtonStyle: styles, + messageButtonStyle: { primaryButton: primaryButton?.style, secondaryButton: secondaryButton?.style }, + overrideButtonStyle: style, + }); + + return shouldDelayMessageRendering ? null : ( + + + + + {shouldRenderImage && ( + + + + )} + + {header?.content && {header.content}} + {body?.content && {body.content}} + + + + {primaryButton && ( + + {secondaryButton && ( + + )} + + + )} + + + + ); +} diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/index.ts index 31d036fc8c8..6b0dfc6aeee 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/index.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/index.ts @@ -1 +1,2 @@ +export { default } from './BannerMessage'; export { BannerMessageProps } from './types'; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts new file mode 100644 index 00000000000..0462c81d2ef --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts @@ -0,0 +1,110 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { StyleSheet } from 'react-native'; + +import { getLineHeight } from '../utils'; +import { + BANNER_ELEVATION, + BANNER_SHADOW_HEIGHT, + BANNER_SHADOW_OPACITY, + BANNER_SHADOW_RADIUS, + BANNER_SHADOW_WIDTH, + BASE_SPACING, + BASE_FONT_SIZE, + BASE_FONT_WEIGHT, + BLACK, + BUTTON_BORDER_RADIUS, + EXTRA_LARGE_SPACING, + LARGE_SPACING, + LARGE_FONT_SIZE, + LIGHT_GREY, + SMALL_SPACING, + WHITE, +} from '../constants'; +import { BannerMessageStyle } from './types'; + +export const styles: BannerMessageStyle = StyleSheet.create({ + // position style + positionContainer: { + flex: 1, + backgroundColor: 'transparent', + }, + bottom: { + justifyContent: 'flex-end', + }, + middle: { + justifyContent: 'center', + }, + top: { + justifyContent: 'flex-start', + }, + + // shared style + buttonContainer: { + backgroundColor: LIGHT_GREY, + borderRadius: BUTTON_BORDER_RADIUS, + flex: 1, + margin: BASE_SPACING, + padding: LARGE_SPACING, + }, + buttonsContainer: { + flexDirection: 'row', + justifyContent: 'center', + paddingHorizontal: SMALL_SPACING, + }, + buttonText: { + fontSize: BASE_FONT_SIZE, + fontWeight: BASE_FONT_WEIGHT, + lineHeight: getLineHeight(BASE_FONT_SIZE), + textAlign: 'center', + }, + container: { + backgroundColor: WHITE, + elevation: BANNER_ELEVATION, + margin: EXTRA_LARGE_SPACING, + shadowColor: BLACK, + shadowOffset: { + width: BANNER_SHADOW_WIDTH, + height: BANNER_SHADOW_HEIGHT, + }, + shadowOpacity: BANNER_SHADOW_OPACITY, + shadowRadius: BANNER_SHADOW_RADIUS, + }, + contentContainer: { + flexDirection: 'row', + padding: LARGE_SPACING, + }, + header: { + fontSize: LARGE_FONT_SIZE, + fontWeight: BASE_FONT_WEIGHT, + lineHeight: getLineHeight(LARGE_FONT_SIZE), + }, + iconButton: { + alignSelf: 'flex-start', + marginLeft: 'auto', + }, + imageContainer: { + justifyContent: 'center', + }, + message: { + fontSize: BASE_FONT_SIZE, + fontWeight: BASE_FONT_WEIGHT, + lineHeight: getLineHeight(BASE_FONT_SIZE), + }, + textContainer: { + marginHorizontal: SMALL_SPACING, + paddingLeft: BASE_SPACING, + flex: 1, + }, +}); diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/types.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/types.ts index 5d34c9167ca..b5499557ab0 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/types.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/types.ts @@ -11,8 +11,29 @@ * and limitations under the License. */ +import { TextStyle, ViewStyle } from 'react-native'; import { InAppMessageComponentPosition, InAppMessageComponentBaseProps } from '../types'; export interface BannerMessageProps extends InAppMessageComponentBaseProps { position: InAppMessageComponentPosition; } + +export interface BannerMessageStyle { + // position specific style + bottom: ViewStyle; + middle: ViewStyle; + top: ViewStyle; + + // component style + buttonContainer: ViewStyle; + buttonsContainer: ViewStyle; + buttonText: TextStyle; + container: ViewStyle; + contentContainer: ViewStyle; + header: TextStyle; + iconButton: ViewStyle; + imageContainer: ViewStyle; + message: TextStyle; + positionContainer: ViewStyle; + textContainer: ViewStyle; +} diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx new file mode 100644 index 00000000000..2079bd79191 --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import React from 'react'; +import { SafeAreaView } from 'react-native'; + +import { styles } from './styles'; +import { MessageWrapperProps } from './types'; + +export function MessageWrapper({ children, style }: MessageWrapperProps) { + return {children}; +} diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts new file mode 100644 index 00000000000..00b51808420 --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts @@ -0,0 +1,2 @@ +export * from './MessageWrapper'; +export * from './types'; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/styles.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/styles.ts new file mode 100644 index 00000000000..6d2a95714b7 --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/styles.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { StyleSheet } from 'react-native'; +import { MessageWrapperStyle } from './types'; + +export const styles: MessageWrapperStyle = StyleSheet.create({ + safeArea: { + ...StyleSheet.absoluteFillObject, + }, +}); diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/types.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/types.ts new file mode 100644 index 00000000000..a1f7b41ff85 --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/types.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { ReactNode } from 'react'; +import { StyleProp, ViewStyle } from 'react-native'; + +export interface MessageWrapperProps { + children: ReactNode; + style?: StyleProp; +} + +export interface MessageWrapperStyle { + safeArea: ViewStyle; +} diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts new file mode 100644 index 00000000000..83ee2197d4d --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +/** + * Style constants either match or approximate the values used in the Pinpoint console preview. + * Some values, such as spacing, are slightly different to allow for a more mobile friendly UX + */ + +// color +export const BLACK = '#000'; +export const LIGHT_GREY = '#e8e8e8'; +export const WHITE = '#fff'; + +// spacing +export const SMALL_SPACING = 4; +export const BASE_SPACING = 8; +export const LARGE_SPACING = 12; +export const EXTRA_LARGE_SPACING = 16; + +// button +export const BUTTON_BORDER_RADIUS = 4; + +// font +export const BASE_FONT_SIZE = 16; +export const LARGE_FONT_SIZE = 18; +export const BASE_FONT_WEIGHT = '400'; + +export const LINE_HEIGHT_MULTIPLIER = 1.5; + +// icon +export const ICON_BUTTON_SIZE = 20; +export const ICON_BUTTON_HIT_SLOP = 10; + +// component specific constants + +// BannerMessage +// iOS shadow values +export const BANNER_SHADOW_HEIGHT = 2; +export const BANNER_SHADOW_WIDTH = 2; +export const BANNER_SHADOW_OPACITY = 0.1; +export const BANNER_SHADOW_RADIUS = 2; + +// android shadow values +export const BANNER_ELEVATION = 3; + +// TODO: delete these once they are no longer needed +// pinpoint max chars 150 +export const MAX_MESSAGE = + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,'; + +// pinpoint max chars 64 +export const MAX_HEADER = + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum'; + +// pinpoint max chars 30 +export const MAX_BUTTON = + 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis,'; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/index.ts index 57210cd4687..25bb2d0a74b 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/index.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/index.ts @@ -1,4 +1,4 @@ -export { BannerMessageProps } from './BannerMessage'; +export { default as BannerMessage, BannerMessageProps } from './BannerMessage'; export { CarouselMessageProps } from './CarouselMessage'; export { FullScreenMessageProps } from './FullScreenMessage'; export { default as InAppMessageDisplay } from './InAppMessageDisplay'; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/types.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/types.ts index 991309bd912..070c0082ac6 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/types.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/types.ts @@ -12,7 +12,8 @@ */ import { ColorValue, StyleProp, TextStyle, ViewStyle } from 'react-native'; -import { InAppMessageButton, InAppMessageContent } from '@aws-amplify/notifications'; + +import { InAppMessageButton, InAppMessageContent, InAppMessageLayout } from '@aws-amplify/notifications'; export type InAppMessageComponentButtonStyle = { container?: StyleProp; @@ -49,6 +50,7 @@ export interface InAppMessageComponentContentProps } export interface InAppMessageComponentBaseProps extends InAppMessageComponentContentProps { + layout: InAppMessageLayout; id: string; onClose?: () => void; style?: InAppMessageComponentStyle; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/utils.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/utils.ts new file mode 100644 index 00000000000..9eb0c1edbdf --- /dev/null +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/utils.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { LINE_HEIGHT_MULTIPLIER } from './constants'; + +export const getLineHeight = (fontSize: number) => fontSize * LINE_HEIGHT_MULTIPLIER; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessage/useInAppMessage.ts b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessage/useInAppMessage.ts index a33cc86b009..fa364f389a9 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessage/useInAppMessage.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessage/useInAppMessage.ts @@ -13,13 +13,8 @@ import { ConsoleLogger as Logger } from '@aws-amplify/core'; -import { - BannerMessageProps, - CarouselMessageProps, - FullScreenMessageProps, - InAppMessageComponents, - useInAppMessaging, -} from '../..'; +import { BannerMessageProps, CarouselMessageProps, FullScreenMessageProps } from '../../components'; +import { InAppMessageComponents, useInAppMessaging } from '../../context'; import { InAppMessageComponent, InAppMessageComponentProps } from './types'; import { getInAppMessage, getContentProps, getPositionProp } from './utils'; @@ -61,6 +56,7 @@ export default function useInAppMessage(): { const props: BannerMessageProps = { ...getContentProps(content?.[0], onActionCallback), id, + layout, onClose, position: getPositionProp(layout), style: style?.BannerMessage, @@ -71,6 +67,7 @@ export default function useInAppMessage(): { const props: CarouselMessageProps = { data: content?.map((item) => getContentProps(item, onActionCallback)), id, + layout, onClose, style: style?.CarouselMessage, }; @@ -80,6 +77,7 @@ export default function useInAppMessage(): { const props: FullScreenMessageProps = { ...getContentProps(content?.[0], onActionCallback), id, + layout, onClose, style: style?.FullScreenMessage, }; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageButtonStyle/useInAppMessageButtonStyle.ts b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageButtonStyle/useInAppMessageButtonStyle.ts index 646899e960a..ef92b3ca65b 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageButtonStyle/useInAppMessageButtonStyle.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageButtonStyle/useInAppMessageButtonStyle.ts @@ -27,14 +27,14 @@ const getButtonComponentStyle = ( const { buttonContainer, buttonText } = baseStyle; // message specific styles in the in-app message payload, overrides default component styles - const { backgroundColor, color, textAlign } = messageStyle ?? {}; + const { backgroundColor, borderRadius, color } = messageStyle ?? {}; // custom component override styles passed as style prop, overrides all previous styles const { container, text } = overrideStyle ?? {}; return { - container: [buttonContainer, { backgroundColor }, container], - text: [buttonText, { color, textAlign }, text], + container: [buttonContainer, { backgroundColor, borderRadius }, container], + text: [buttonText, { color }, text], }; }; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageImage/useInAppMessageImage.ts b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageImage/useInAppMessageImage.ts index 53c8b1b4cd1..80862cd56e0 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageImage/useInAppMessageImage.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/hooks/useInAppMessageImage/useInAppMessageImage.ts @@ -30,9 +30,10 @@ const inAppMessageImageSizes: Record = { }; export default function useInAppMessageImage( - { src }: InAppMessageImage, + image: InAppMessageImage, layout: InAppMessageLayout ): UseInAppMessageImage { + const { src } = image ?? {}; const hasImage = !!src; const [imageLoadingState, setImageLoadingState] = useState(hasImage ? 'loading' : null); diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/index.ts index 16e4fec9012..24a99750664 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/index.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/index.ts @@ -7,6 +7,7 @@ export { useInAppMessaging, } from './context'; export { + BannerMessage, BannerMessageProps, CarouselMessageProps, FullScreenMessageProps, diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/ui/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/ui/index.ts index 3f3851cb299..ca5a64fea87 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/ui/index.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/ui/index.ts @@ -1,2 +1,3 @@ +export { default as Button, ButtonProps } from './Button'; export { default as IconButton, IconButtonProps, IconButtonStyles } from './IconButton'; export { default as Paragraph, ParagraphProps } from './Paragraph'; diff --git a/packages/aws-amplify-react-native/src/icons/close.png b/packages/aws-amplify-react-native/src/icons/close.png new file mode 100644 index 0000000000000000000000000000000000000000..abf708b234b577d06878d448dbd300c0468e098a GIT binary patch literal 3118 zcmd5;e@Gj56o0qtxKZn!UD@b1ZIr=AyA3*Uptvs4D%LV3(=x_zHL}5^RF-L5g^k@| zTSB2wJInfmLT+rW8+65v+0G#~BAxBlE~(0pYG;DoOu<@LGHoxreD}Uyyvs!sZP*{p zKY90leBS%M@B6;@4%jP7(^o#b5&+W6wiH(atUz)FJi+4MmcEg5_?K^gb6W}ir}pdK zW8Z|9Yj#yuR6*^NYaGqwH{UMrd%tE}U45?V^1p1*j|%1KyO@4yd~oKK`@2Uo9Xp7(w0^pt zxY(!~huy|NKlQsN)c{a5j<$N1ku2pwW& zG1HN%j8A}h@RS(m?=h3>*3Ehpt)&|I^mQxVaM?I09Ot9t0W6CsnKPl2y-Y~pr^QL- z!>2U0Ifg7^IqYSF?%GTn@tc)(8IxFMF+?o7HetrdG?5puS~PzPWP&E@6JB2mC8~)* z>mb7)DXuglk|cpt8)-@&tH36SwK0LLc9JGJ_KX>(vOg%i^*trOhmL0m0t) zE6GcObIh?`CA-OkhrKN6&y?<1N?TSL;C=ePPwt>?u{)Q^L>G?6c2*|;Ou2bak*V%( z8NOploS0acQVH$$Bv)_zWUWrpcFj4X<3OJVOk5N9#Tdsocpm{1nlWtLm(0^fhhI2| zoumVal>b4TC8A>63`fvtl;xSV8dO=V)@xr6S3LQ6B0$B3qX^UBUUbJ_V?m&nyAt`nm@Y_7Vw9CxP^ zkuP7Ey^Cv)y$!dh)8aQ*a3>kG4&if^Z(DXW5Z)IO9@cDo|BN@%$vi5% Date: Thu, 28 Oct 2021 15:49:48 -0700 Subject: [PATCH 2/2] address feedback --- .../BannerMessage/BannerMessage.tsx | 34 ++++++++----- .../components/BannerMessage/styles.ts | 50 +++++++++---------- .../MessageWrapper/MessageWrapper.tsx | 2 +- .../components/MessageWrapper/index.ts | 4 +- .../InAppMessaging/components/constants.ts | 32 ++++-------- 5 files changed, 59 insertions(+), 63 deletions(-) diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx index 1343068de8b..ea1355cf350 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/BannerMessage.tsx @@ -13,13 +13,14 @@ import React from 'react'; import { Image, Text, View } from 'react-native'; +import isEmpty from 'lodash/isEmpty'; import icons from '../../../icons'; -import { ICON_BUTTON_HIT_SLOP, ICON_BUTTON_SIZE } from '../constants'; import { useInAppMessageButtonStyle, useInAppMessageImage } from '../../hooks'; import { Button, IconButton } from '../../ui'; -import { MessageWrapper } from '../MessageWrapper'; +import { ICON_BUTTON_HIT_SLOP, ICON_BUTTON_SIZE } from '../constants'; +import MessageWrapper from '../MessageWrapper'; import { styles } from './styles'; import { BannerMessageProps } from './types'; @@ -36,12 +37,17 @@ export default function BannerMessage({ style, }: BannerMessageProps) { const { imageStyle, shouldDelayMessageRendering, shouldRenderImage } = useInAppMessageImage(image, layout); + + const messageButtonStyle = { primaryButton: primaryButton?.style, secondaryButton: secondaryButton?.style }; const { primaryButtonStyle, secondaryButtonStyle } = useInAppMessageButtonStyle({ baseButtonStyle: styles, - messageButtonStyle: { primaryButton: primaryButton?.style, secondaryButton: secondaryButton?.style }, + messageButtonStyle, overrideButtonStyle: style, }); + const hasPrimaryButton = !isEmpty(primaryButton); + const hasSecondaryButton = !isEmpty(secondaryButton); + return shouldDelayMessageRendering ? null : ( @@ -49,7 +55,7 @@ export default function BannerMessage({ {shouldRenderImage && ( - + )} @@ -65,9 +71,9 @@ export default function BannerMessage({ style={[styles.iconButton, style?.closeIconButton]} /> - {primaryButton && ( + {(hasPrimaryButton || hasSecondaryButton) && ( - {secondaryButton && ( + {hasSecondaryButton && ( + {hasPrimaryButton && ( + + )} )} diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts index 0462c81d2ef..696846a17f2 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/BannerMessage/styles.ts @@ -20,16 +20,16 @@ import { BANNER_SHADOW_OPACITY, BANNER_SHADOW_RADIUS, BANNER_SHADOW_WIDTH, - BASE_SPACING, - BASE_FONT_SIZE, - BASE_FONT_WEIGHT, BLACK, - BUTTON_BORDER_RADIUS, - EXTRA_LARGE_SPACING, - LARGE_SPACING, - LARGE_FONT_SIZE, + BORDER_RADIUS_BASE, + FONT_SIZE_BASE, + FONT_SIZE_LARGE, + FONT_WEIGHT_BASE, LIGHT_GREY, - SMALL_SPACING, + SPACING_EXTRA_LARGE, + SPACING_LARGE, + SPACING_MEDIUM, + SPACING_SMALL, WHITE, } from '../constants'; import { BannerMessageStyle } from './types'; @@ -53,26 +53,26 @@ export const styles: BannerMessageStyle = StyleSheet.create({ // shared style buttonContainer: { backgroundColor: LIGHT_GREY, - borderRadius: BUTTON_BORDER_RADIUS, + borderRadius: BORDER_RADIUS_BASE, flex: 1, - margin: BASE_SPACING, - padding: LARGE_SPACING, + margin: SPACING_MEDIUM, + padding: SPACING_LARGE, }, buttonsContainer: { flexDirection: 'row', justifyContent: 'center', - paddingHorizontal: SMALL_SPACING, + paddingHorizontal: SPACING_SMALL, }, buttonText: { - fontSize: BASE_FONT_SIZE, - fontWeight: BASE_FONT_WEIGHT, - lineHeight: getLineHeight(BASE_FONT_SIZE), + fontSize: FONT_SIZE_BASE, + fontWeight: FONT_WEIGHT_BASE, + lineHeight: getLineHeight(FONT_SIZE_BASE), textAlign: 'center', }, container: { backgroundColor: WHITE, elevation: BANNER_ELEVATION, - margin: EXTRA_LARGE_SPACING, + margin: SPACING_EXTRA_LARGE, shadowColor: BLACK, shadowOffset: { width: BANNER_SHADOW_WIDTH, @@ -83,12 +83,12 @@ export const styles: BannerMessageStyle = StyleSheet.create({ }, contentContainer: { flexDirection: 'row', - padding: LARGE_SPACING, + padding: SPACING_LARGE, }, header: { - fontSize: LARGE_FONT_SIZE, - fontWeight: BASE_FONT_WEIGHT, - lineHeight: getLineHeight(LARGE_FONT_SIZE), + fontSize: FONT_SIZE_LARGE, + fontWeight: FONT_WEIGHT_BASE, + lineHeight: getLineHeight(FONT_SIZE_LARGE), }, iconButton: { alignSelf: 'flex-start', @@ -98,13 +98,13 @@ export const styles: BannerMessageStyle = StyleSheet.create({ justifyContent: 'center', }, message: { - fontSize: BASE_FONT_SIZE, - fontWeight: BASE_FONT_WEIGHT, - lineHeight: getLineHeight(BASE_FONT_SIZE), + fontSize: FONT_SIZE_BASE, + fontWeight: FONT_WEIGHT_BASE, + lineHeight: getLineHeight(FONT_SIZE_BASE), }, textContainer: { - marginHorizontal: SMALL_SPACING, - paddingLeft: BASE_SPACING, + marginHorizontal: SPACING_SMALL, + paddingLeft: SPACING_MEDIUM, flex: 1, }, }); diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx index 2079bd79191..0ffa3ddc45a 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/MessageWrapper.tsx @@ -17,6 +17,6 @@ import { SafeAreaView } from 'react-native'; import { styles } from './styles'; import { MessageWrapperProps } from './types'; -export function MessageWrapper({ children, style }: MessageWrapperProps) { +export default function MessageWrapper({ children, style }: MessageWrapperProps) { return {children}; } diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts index 00b51808420..f70050fdcee 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/MessageWrapper/index.ts @@ -1,2 +1,2 @@ -export * from './MessageWrapper'; -export * from './types'; +export { default } from './MessageWrapper'; +export { MessageWrapperProps, MessageWrapperStyle } from './types'; diff --git a/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts b/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts index 83ee2197d4d..087966fc224 100644 --- a/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts +++ b/packages/aws-amplify-react-native/src/InAppMessaging/components/constants.ts @@ -22,18 +22,19 @@ export const LIGHT_GREY = '#e8e8e8'; export const WHITE = '#fff'; // spacing -export const SMALL_SPACING = 4; -export const BASE_SPACING = 8; -export const LARGE_SPACING = 12; -export const EXTRA_LARGE_SPACING = 16; +export const SPACING_SMALL = 4; +export const SPACING_MEDIUM = 8; +export const SPACING_LARGE = 12; +export const SPACING_EXTRA_LARGE = 16; -// button -export const BUTTON_BORDER_RADIUS = 4; +// border radius +export const BORDER_RADIUS_BASE = 4; // font -export const BASE_FONT_SIZE = 16; -export const LARGE_FONT_SIZE = 18; -export const BASE_FONT_WEIGHT = '400'; +export const FONT_SIZE_BASE = 16; +export const FONT_SIZE_LARGE = 18; + +export const FONT_WEIGHT_BASE = '400'; export const LINE_HEIGHT_MULTIPLIER = 1.5; @@ -52,16 +53,3 @@ export const BANNER_SHADOW_RADIUS = 2; // android shadow values export const BANNER_ELEVATION = 3; - -// TODO: delete these once they are no longer needed -// pinpoint max chars 150 -export const MAX_MESSAGE = - 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,'; - -// pinpoint max chars 64 -export const MAX_HEADER = - 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum'; - -// pinpoint max chars 30 -export const MAX_BUTTON = - 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis,';