@aws-amplify/ui-react-notifications 1.0.14 → 2.0.1
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/dist/esm/components/InAppMessaging/Backdrop/Backdrop.mjs +9 -1
- package/dist/esm/components/InAppMessaging/Backdrop/withBackdrop.mjs +15 -1
- package/dist/esm/components/InAppMessaging/BannerMessage/BannerMessage.mjs +27 -1
- package/dist/esm/components/InAppMessaging/BannerMessage/constants.mjs +4 -1
- package/dist/esm/components/InAppMessaging/CloseIconButton/CloseIconButton.mjs +10 -1
- package/dist/esm/components/InAppMessaging/FullScreenMessage/FullScreenMessage.mjs +29 -1
- package/dist/esm/components/InAppMessaging/FullScreenMessage/constants.mjs +4 -1
- package/dist/esm/components/InAppMessaging/InAppMessageDisplay/InAppMessageDisplay.mjs +50 -1
- package/dist/esm/components/InAppMessaging/InAppMessageDisplay/handleMessageLinkAction.mjs +23 -1
- package/dist/esm/components/InAppMessaging/MessageLayout/MessageLayout.mjs +33 -1
- package/dist/esm/components/InAppMessaging/MessageLayout/constants.mjs +21 -1
- package/dist/esm/components/InAppMessaging/MessageLayout/utils.mjs +22 -1
- package/dist/esm/components/InAppMessaging/ModalMessage/ModalMessage.mjs +23 -1
- package/dist/esm/components/InAppMessaging/ModalMessage/constants.mjs +6 -1
- package/dist/esm/components/InAppMessaging/hooks/useMessageImage/types.mjs +9 -1
- package/dist/esm/components/InAppMessaging/hooks/useMessageImage/useMessageImage.mjs +40 -1
- package/dist/esm/components/InAppMessaging/hooks/useMessageProps/useMessageProps.mjs +33 -1
- package/dist/esm/components/InAppMessaging/hooks/useMessageProps/utils.mjs +62 -1
- package/dist/esm/components/InAppMessaging/withInAppMessaging/withInAppMessaging.mjs +13 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/version.mjs +3 -0
- package/dist/index.js +394 -1
- package/dist/styles.css +298 -684
- package/dist/types/components/InAppMessaging/MessageLayout/constants.d.ts +6 -6
- package/dist/types/components/InAppMessaging/MessageLayout/utils.d.ts +1 -1
- package/dist/types/components/InAppMessaging/ModalMessage/constants.d.ts +1 -1
- package/dist/types/components/InAppMessaging/hooks/useMessageImage/useMessageImage.d.ts +2 -2
- package/dist/types/components/InAppMessaging/index.d.ts +1 -1
- package/dist/types/version.d.ts +1 -0
- package/package.json +8 -31
- package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -1
|
@@ -1 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { View } from '@aws-amplify/ui-react';
|
|
3
|
+
|
|
4
|
+
const BACKDROP_TEST_ID = 'inappmessaging-backdrop';
|
|
5
|
+
function Backdrop({ onClick, ...rest }) {
|
|
6
|
+
return (React__default.createElement(View, { className: "amplify-inappmessaging-backdrop", "data-testid": BACKDROP_TEST_ID, onClick: onClick, ...rest }));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { BACKDROP_TEST_ID, Backdrop };
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Flex, View } from '@aws-amplify/ui-react';
|
|
3
|
+
import { Backdrop } from './Backdrop.mjs';
|
|
4
|
+
|
|
5
|
+
function withBackdrop(Content, options = {}) {
|
|
6
|
+
return function ContentWithBackdrop(props) {
|
|
7
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
8
|
+
React__default.createElement(Backdrop, { ...options }),
|
|
9
|
+
React__default.createElement(Flex, { className: "amplify-inappmessaging-backdrop-content-container" },
|
|
10
|
+
React__default.createElement(View, { className: "amplify-inappmessaging-backdrop-content" },
|
|
11
|
+
React__default.createElement(Content, { ...props })))));
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { withBackdrop };
|
|
@@ -1 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { classNames } from '@aws-amplify/ui';
|
|
3
|
+
import { useBreakpointValue, Flex } from '@aws-amplify/ui-react';
|
|
4
|
+
import '../hooks/useMessageImage/useMessageImage.mjs';
|
|
5
|
+
import useMessageProps from '../hooks/useMessageProps/useMessageProps.mjs';
|
|
6
|
+
import { MessageLayout } from '../MessageLayout/MessageLayout.mjs';
|
|
7
|
+
import { BLOCK_CLASS } from './constants.mjs';
|
|
8
|
+
|
|
9
|
+
function BannerMessage(props) {
|
|
10
|
+
const messageProps = useMessageProps(props);
|
|
11
|
+
const shouldBeFullWidth = useBreakpointValue([true, true, false]);
|
|
12
|
+
const { shouldRenderMessage, styles } = messageProps;
|
|
13
|
+
if (!shouldRenderMessage) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const { alignment = 'right', position = 'top' } = props;
|
|
17
|
+
const isCenterMiddle = alignment === 'center' && position === 'middle';
|
|
18
|
+
return (React__default.createElement(Flex, { className: classNames(BLOCK_CLASS, {
|
|
19
|
+
[`${BLOCK_CLASS}--${position}`]: !isCenterMiddle,
|
|
20
|
+
[`${BLOCK_CLASS}--${alignment}`]: !isCenterMiddle,
|
|
21
|
+
[`${BLOCK_CLASS}--center-middle`]: isCenterMiddle,
|
|
22
|
+
[`${BLOCK_CLASS}--full-width`]: shouldBeFullWidth,
|
|
23
|
+
}), role: "dialog", testId: `inappmessaging-${position}banner-dialog` },
|
|
24
|
+
React__default.createElement(MessageLayout, { ...props, ...messageProps, orientation: "horizontal", buttonSize: "small", styles: styles })));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { BannerMessage };
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button } from '@aws-amplify/ui-react';
|
|
3
|
+
import { IconClose } from '@aws-amplify/ui-react/internal';
|
|
4
|
+
|
|
5
|
+
function CloseIconButton({ className, dismissButtonLabel = 'Dismiss message', onClick, style, ...rest }) {
|
|
6
|
+
return (React.createElement(Button, { ariaLabel: dismissButtonLabel, className: className, onClick: onClick, style: style, variation: "link", ...rest },
|
|
7
|
+
React.createElement(IconClose, { "aria-hidden": "true", size: "1.5rem" })));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { CloseIconButton };
|
|
@@ -1 +1,29 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { classNames } from '@aws-amplify/ui';
|
|
3
|
+
import { useBreakpointValue, Flex } from '@aws-amplify/ui-react';
|
|
4
|
+
import { withBackdrop } from '../Backdrop/withBackdrop.mjs';
|
|
5
|
+
import '../hooks/useMessageImage/useMessageImage.mjs';
|
|
6
|
+
import useMessageProps from '../hooks/useMessageProps/useMessageProps.mjs';
|
|
7
|
+
import { MessageLayout } from '../MessageLayout/MessageLayout.mjs';
|
|
8
|
+
import { BLOCK_CLASS } from './constants.mjs';
|
|
9
|
+
|
|
10
|
+
function FullScreenMessage(props) {
|
|
11
|
+
const messageProps = useMessageProps(props);
|
|
12
|
+
const shouldBeFullScreen = useBreakpointValue([true, true, false]);
|
|
13
|
+
const { shouldRenderMessage, styles } = messageProps;
|
|
14
|
+
const { onClose: onClick } = props;
|
|
15
|
+
if (!shouldRenderMessage) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const Message = () => (React.createElement(Flex, { className: classNames(BLOCK_CLASS, {
|
|
19
|
+
[`${BLOCK_CLASS}--fullscreen`]: shouldBeFullScreen,
|
|
20
|
+
}), role: "dialog", testId: "inappmessaging-fullscreen-dialog" },
|
|
21
|
+
React.createElement(MessageLayout, { ...props, ...messageProps, styles: styles })));
|
|
22
|
+
if (shouldBeFullScreen) {
|
|
23
|
+
return React.createElement(Message, null);
|
|
24
|
+
}
|
|
25
|
+
const MessageWithBackdrop = withBackdrop(Message, { onClick });
|
|
26
|
+
return React.createElement(MessageWithBackdrop, null);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { FullScreenMessage };
|
|
@@ -1 +1,50 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { useMessage, handleMessageAction } from '@aws-amplify/ui-react-core-notifications';
|
|
3
|
+
import { ThemeProvider } from '@aws-amplify/ui-react';
|
|
4
|
+
import { useSetUserAgent } from '@aws-amplify/ui-react-core';
|
|
5
|
+
import { BannerMessage } from '../BannerMessage/BannerMessage.mjs';
|
|
6
|
+
import { FullScreenMessage } from '../FullScreenMessage/FullScreenMessage.mjs';
|
|
7
|
+
import { ModalMessage } from '../ModalMessage/ModalMessage.mjs';
|
|
8
|
+
import handleMessageLinkAction from './handleMessageLinkAction.mjs';
|
|
9
|
+
import { VERSION } from '../../../version.mjs';
|
|
10
|
+
|
|
11
|
+
// TODO: replace below components incrementally as they become available
|
|
12
|
+
function CarouselMessage(_) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const platformComponents = {
|
|
16
|
+
BannerMessage,
|
|
17
|
+
CarouselMessage,
|
|
18
|
+
FullScreenMessage,
|
|
19
|
+
ModalMessage,
|
|
20
|
+
};
|
|
21
|
+
const onMessageAction = ({ action, url }) => {
|
|
22
|
+
handleMessageAction({
|
|
23
|
+
action,
|
|
24
|
+
url,
|
|
25
|
+
handleMessageLinkAction,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
function InAppMessageDisplay({ components: overrideComponents, }) {
|
|
29
|
+
const components = React__default.useMemo(() => ({ ...platformComponents, ...overrideComponents }), [overrideComponents]);
|
|
30
|
+
const { Component, props } = useMessage({
|
|
31
|
+
components,
|
|
32
|
+
onMessageAction,
|
|
33
|
+
});
|
|
34
|
+
useSetUserAgent({
|
|
35
|
+
componentName: 'InAppMessaging',
|
|
36
|
+
packageName: 'react-notifications',
|
|
37
|
+
version: VERSION,
|
|
38
|
+
});
|
|
39
|
+
// There is currently no way to pass In-App Message payload variants so we
|
|
40
|
+
// will fix the theme around In-App Messaging components to always assume
|
|
41
|
+
// light mode
|
|
42
|
+
return (React__default.createElement(ThemeProvider, { colorMode: "light" },
|
|
43
|
+
React__default.createElement(Component, { ...props })));
|
|
44
|
+
}
|
|
45
|
+
InAppMessageDisplay.BannerMessage = BannerMessage;
|
|
46
|
+
InAppMessageDisplay.CarouselMessage = CarouselMessage;
|
|
47
|
+
InAppMessageDisplay.FullScreenMessage = FullScreenMessage;
|
|
48
|
+
InAppMessageDisplay.ModalMessage = ModalMessage;
|
|
49
|
+
|
|
50
|
+
export { InAppMessageDisplay as default };
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
import{ConsoleLogger
|
|
1
|
+
import { ConsoleLogger } from 'aws-amplify/utils';
|
|
2
|
+
|
|
3
|
+
const logger = new ConsoleLogger('InAppMessaging');
|
|
4
|
+
const handleMessageLinkAction = (input) => {
|
|
5
|
+
let url;
|
|
6
|
+
try {
|
|
7
|
+
url = new URL(input);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
logger.warn(`Unsupported url provided: ${input}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const { protocol } = url;
|
|
14
|
+
const isHttpProtocol = protocol === 'http:';
|
|
15
|
+
const isHttpsProtocol = protocol === 'https:';
|
|
16
|
+
if (!(isHttpProtocol || isHttpsProtocol)) {
|
|
17
|
+
logger.warn(`Unsupported url protocol provided: ${protocol}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
window.open(input);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { handleMessageLinkAction as default };
|
|
@@ -1 +1,33 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { classNames, isEmpty } from '@aws-amplify/ui';
|
|
3
|
+
import { Flex, Image, Heading, Text, ButtonGroup, Button } from '@aws-amplify/ui-react';
|
|
4
|
+
import { CloseIconButton } from '../CloseIconButton/CloseIconButton.mjs';
|
|
5
|
+
import { CLOSE_BUTTON_CLASS, BLOCK_CLASS, MESSAGE_LAYOUT_TEST_ID, CONTENT_CLASS, CONTENT_TEST_ID, IMAGE_CONTAINER_CLASS, IMAGE_CONTAINER_TEST_ID, TEXT_CONTAINER_CLASS, TEXT_CONTAINER_TEST_ID, HEADER_CLASS, HEADER_TEXT_TEST_ID, BODY_TEXT_TEST_ID, BUTTON_GROUP_TEST_ID, BUTTON_CLASS, SECONDARY_BUTTON_TEST_ID, PRIMARY_BUTTON_TEST_ID } from './constants.mjs';
|
|
6
|
+
import { getButtonModifier } from './utils.mjs';
|
|
7
|
+
|
|
8
|
+
const isMessageButton = (button) => !isEmpty(button);
|
|
9
|
+
function MessageLayout({ body, buttonSize, hasRenderableImage, header, image, onClose, orientation = 'vertical', primaryButton, secondaryButton, styles, }) {
|
|
10
|
+
const buttonModifiers = React.useMemo(() => ({
|
|
11
|
+
primary: getButtonModifier(styles.primaryButton),
|
|
12
|
+
secondary: getButtonModifier(styles.secondaryButton),
|
|
13
|
+
}), [styles]);
|
|
14
|
+
const isHorizontal = orientation === 'horizontal';
|
|
15
|
+
const closeButton = (React.createElement(CloseIconButton, { className: CLOSE_BUTTON_CLASS, onClick: onClose, style: styles.closeIconButton }));
|
|
16
|
+
const hasPrimaryButton = isMessageButton(primaryButton);
|
|
17
|
+
const hasSecondaryButton = isMessageButton(secondaryButton);
|
|
18
|
+
const hasButtons = hasPrimaryButton || hasSecondaryButton;
|
|
19
|
+
return (React.createElement(Flex, { className: BLOCK_CLASS, "data-testid": MESSAGE_LAYOUT_TEST_ID, style: styles.container },
|
|
20
|
+
!isHorizontal && React.createElement(Flex, { justifyContent: "flex-end" }, closeButton),
|
|
21
|
+
React.createElement(Flex, { className: classNames(CONTENT_CLASS, `${CONTENT_CLASS}--${orientation}`), "data-testid": CONTENT_TEST_ID },
|
|
22
|
+
hasRenderableImage && (React.createElement(Flex, { className: classNames(IMAGE_CONTAINER_CLASS, `${IMAGE_CONTAINER_CLASS}--${orientation}`), "data-testid": IMAGE_CONTAINER_TEST_ID },
|
|
23
|
+
React.createElement(Image, { alt: "In-App Message Image", src: image?.src, style: styles.image }))),
|
|
24
|
+
React.createElement(Flex, { className: classNames(TEXT_CONTAINER_CLASS, `${TEXT_CONTAINER_CLASS}--${orientation}`), "data-testid": TEXT_CONTAINER_TEST_ID },
|
|
25
|
+
header?.content && (React.createElement(Heading, { className: HEADER_CLASS, isTruncated: true, level: 2, style: styles.header, testId: HEADER_TEXT_TEST_ID }, header.content)),
|
|
26
|
+
body?.content && (React.createElement(Text, { style: styles.body, testId: BODY_TEXT_TEST_ID }, body.content))),
|
|
27
|
+
isHorizontal && React.createElement(Flex, { alignItems: "flex-start" }, closeButton)),
|
|
28
|
+
hasButtons && (React.createElement(ButtonGroup, { size: buttonSize, testId: BUTTON_GROUP_TEST_ID },
|
|
29
|
+
hasSecondaryButton && (React.createElement(Button, { className: classNames(BUTTON_CLASS, `${BUTTON_CLASS}--${buttonModifiers.secondary}`), onClick: secondaryButton.onAction, style: styles.secondaryButton, testId: SECONDARY_BUTTON_TEST_ID }, secondaryButton.title)),
|
|
30
|
+
hasPrimaryButton && (React.createElement(Button, { className: classNames(BUTTON_CLASS, `${BUTTON_CLASS}--${buttonModifiers.primary}`), onClick: primaryButton.onAction, style: styles.primaryButton, testId: PRIMARY_BUTTON_TEST_ID }, primaryButton.title))))));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { MessageLayout };
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
// Base block class for MessageLayout
|
|
2
|
+
const BLOCK_CLASS = 'amplify-inappmessaging-messagelayout';
|
|
3
|
+
// Element classes for MessageLayout
|
|
4
|
+
const BUTTON_CLASS = `${BLOCK_CLASS}__button`;
|
|
5
|
+
const CLOSE_BUTTON_CLASS = `${BLOCK_CLASS}__close-button`;
|
|
6
|
+
const CONTENT_CLASS = `${BLOCK_CLASS}__content`;
|
|
7
|
+
const HEADER_CLASS = `${BLOCK_CLASS}__header`;
|
|
8
|
+
const IMAGE_CONTAINER_CLASS = `${BLOCK_CLASS}__image-container`;
|
|
9
|
+
const TEXT_CONTAINER_CLASS = `${BLOCK_CLASS}__text-container`;
|
|
10
|
+
// Test IDs
|
|
11
|
+
const BODY_TEXT_TEST_ID = 'inappmessaging-messagelayout-bodytext';
|
|
12
|
+
const BUTTON_GROUP_TEST_ID = 'inappmessaging-messagelayout-buttongroup';
|
|
13
|
+
const CONTENT_TEST_ID = 'inappmessaging-messagelayout-content';
|
|
14
|
+
const HEADER_TEXT_TEST_ID = 'inappmessaging-messagelayout-headertext';
|
|
15
|
+
const IMAGE_CONTAINER_TEST_ID = 'inappmessaging-messagelayout-imagecontainer';
|
|
16
|
+
const MESSAGE_LAYOUT_TEST_ID = 'inappmessaging-messagelayout';
|
|
17
|
+
const PRIMARY_BUTTON_TEST_ID = 'inappmessaging-messagelayout-primarybutton';
|
|
18
|
+
const SECONDARY_BUTTON_TEST_ID = 'inappmessaging-messagelayout-secondarybutton';
|
|
19
|
+
const TEXT_CONTAINER_TEST_ID = 'inappmessaging-messagelayout-textcontainer';
|
|
20
|
+
|
|
21
|
+
export { BLOCK_CLASS, BODY_TEXT_TEST_ID, BUTTON_CLASS, BUTTON_GROUP_TEST_ID, CLOSE_BUTTON_CLASS, CONTENT_CLASS, CONTENT_TEST_ID, HEADER_CLASS, HEADER_TEXT_TEST_ID, IMAGE_CONTAINER_CLASS, IMAGE_CONTAINER_TEST_ID, MESSAGE_LAYOUT_TEST_ID, PRIMARY_BUTTON_TEST_ID, SECONDARY_BUTTON_TEST_ID, TEXT_CONTAINER_CLASS, TEXT_CONTAINER_TEST_ID };
|
|
@@ -1 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import tinycolor from 'tinycolor2';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility for determining the class modifier for an In-App Messaging button
|
|
5
|
+
* based on its background color
|
|
6
|
+
*
|
|
7
|
+
* @param buttonStyles button styles which should contain the background color
|
|
8
|
+
* @param defaultModifier modifier that should be returned in cases where
|
|
9
|
+
* background color is undefined
|
|
10
|
+
*
|
|
11
|
+
* @returns the modifier - either 'light' or 'dark'
|
|
12
|
+
*/
|
|
13
|
+
const getButtonModifier = (buttonStyles, defaultModifier = 'light') => {
|
|
14
|
+
const { backgroundColor } = buttonStyles ?? {};
|
|
15
|
+
if (!backgroundColor) {
|
|
16
|
+
return defaultModifier;
|
|
17
|
+
}
|
|
18
|
+
const color = tinycolor(backgroundColor);
|
|
19
|
+
return color.isDark() ? 'dark' : 'light';
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { getButtonModifier };
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { classNames } from '@aws-amplify/ui';
|
|
3
|
+
import { useBreakpointValue, Flex } from '@aws-amplify/ui-react';
|
|
4
|
+
import '../hooks/useMessageImage/useMessageImage.mjs';
|
|
5
|
+
import useMessageProps from '../hooks/useMessageProps/useMessageProps.mjs';
|
|
6
|
+
import { MessageLayout } from '../MessageLayout/MessageLayout.mjs';
|
|
7
|
+
import { BLOCK_CLASS, DIALOG_CLASS } from './constants.mjs';
|
|
8
|
+
|
|
9
|
+
function ModalMessage(props) {
|
|
10
|
+
const messageProps = useMessageProps(props);
|
|
11
|
+
const shouldBeFullWidth = useBreakpointValue([true, true, false]);
|
|
12
|
+
const { shouldRenderMessage, styles } = messageProps;
|
|
13
|
+
if (!shouldRenderMessage) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return (React.createElement(Flex, { className: BLOCK_CLASS },
|
|
17
|
+
React.createElement(Flex, { className: classNames(DIALOG_CLASS, {
|
|
18
|
+
[`${DIALOG_CLASS}--full-width`]: shouldBeFullWidth,
|
|
19
|
+
}), role: "dialog", testId: "inappmessaging-modal-dialog" },
|
|
20
|
+
React.createElement(MessageLayout, { ...props, ...messageProps, styles: styles }))));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { ModalMessage };
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Base block class for ModalMessage
|
|
2
|
+
const BLOCK_CLASS = 'amplify-inappmessaging-modalmessage';
|
|
3
|
+
// Element classes for ModalMessage
|
|
4
|
+
const DIALOG_CLASS = `${BLOCK_CLASS}__dialog`;
|
|
5
|
+
|
|
6
|
+
export { BLOCK_CLASS, DIALOG_CLASS };
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ImagePrefetchStatus;
|
|
2
|
+
(function (ImagePrefetchStatus) {
|
|
3
|
+
ImagePrefetchStatus["Aborted"] = "ABORTED";
|
|
4
|
+
ImagePrefetchStatus["Failure"] = "FAILURE";
|
|
5
|
+
ImagePrefetchStatus["Fetching"] = "FETCHING";
|
|
6
|
+
ImagePrefetchStatus["Success"] = "SUCCESS";
|
|
7
|
+
})(ImagePrefetchStatus || (ImagePrefetchStatus = {}));
|
|
8
|
+
|
|
9
|
+
export { ImagePrefetchStatus };
|
|
@@ -1 +1,40 @@
|
|
|
1
|
-
import{useState
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { ConsoleLogger } from 'aws-amplify/utils';
|
|
3
|
+
import { ImagePrefetchStatus } from './types.mjs';
|
|
4
|
+
|
|
5
|
+
const logger = new ConsoleLogger('InAppMessaging');
|
|
6
|
+
/**
|
|
7
|
+
* Handles prefetching for message images
|
|
8
|
+
*
|
|
9
|
+
* @param image contains image source
|
|
10
|
+
* @returns message image dimensions and fetching related booleans
|
|
11
|
+
*/
|
|
12
|
+
function useMessageImage(image) {
|
|
13
|
+
const { src } = image ?? {};
|
|
14
|
+
const shouldPrefetch = !!src;
|
|
15
|
+
// set initial status to fetching if prefetch is required
|
|
16
|
+
const [prefetchStatus, setPrefetchStatus] = useState(shouldPrefetch ? ImagePrefetchStatus.Fetching : null);
|
|
17
|
+
const isImageFetching = prefetchStatus === ImagePrefetchStatus.Fetching;
|
|
18
|
+
const hasRenderableImage = prefetchStatus === ImagePrefetchStatus.Success;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!shouldPrefetch) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const img = new Image();
|
|
24
|
+
img.onload = () => {
|
|
25
|
+
setPrefetchStatus(ImagePrefetchStatus.Success);
|
|
26
|
+
};
|
|
27
|
+
img.onabort = () => {
|
|
28
|
+
logger.error(`Image load aborted: ${src}`);
|
|
29
|
+
setPrefetchStatus(ImagePrefetchStatus.Aborted);
|
|
30
|
+
};
|
|
31
|
+
img.onerror = () => {
|
|
32
|
+
logger.error(`Image failed to load: ${src}`);
|
|
33
|
+
setPrefetchStatus(ImagePrefetchStatus.Failure);
|
|
34
|
+
};
|
|
35
|
+
img.src = src;
|
|
36
|
+
}, [shouldPrefetch, src]);
|
|
37
|
+
return { hasRenderableImage, isImageFetching };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { useMessageImage as default };
|
|
@@ -1 +1,33 @@
|
|
|
1
|
-
import{useRef
|
|
1
|
+
import { useRef, useEffect, useMemo } from 'react';
|
|
2
|
+
import useMessageImage from '../useMessageImage/useMessageImage.mjs';
|
|
3
|
+
import { getMessageStyles, getPayloadStyle } from './utils.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Handle common message UI component prop logic including render booleans, and
|
|
7
|
+
* style resolving
|
|
8
|
+
*
|
|
9
|
+
* @param props message UI component props
|
|
10
|
+
*
|
|
11
|
+
* @returns message UI component render related booleans and styles
|
|
12
|
+
*/
|
|
13
|
+
function useMessageProps(props) {
|
|
14
|
+
const { image, onDisplay } = props;
|
|
15
|
+
const hasDisplayed = useRef(false);
|
|
16
|
+
const { hasRenderableImage, isImageFetching } = useMessageImage(image);
|
|
17
|
+
const shouldRenderMessage = !isImageFetching;
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!hasDisplayed.current && shouldRenderMessage) {
|
|
20
|
+
onDisplay?.();
|
|
21
|
+
hasDisplayed.current = true;
|
|
22
|
+
}
|
|
23
|
+
}, [onDisplay, shouldRenderMessage]);
|
|
24
|
+
const styles = useMemo(() => getMessageStyles({
|
|
25
|
+
styleParams: {
|
|
26
|
+
payloadStyle: getPayloadStyle(props),
|
|
27
|
+
overrideStyle: props.style,
|
|
28
|
+
},
|
|
29
|
+
}), [props]);
|
|
30
|
+
return { hasRenderableImage, shouldRenderMessage, styles };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { useMessageProps as default };
|
|
@@ -1 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Utility for extracting message payload style
|
|
3
|
+
*
|
|
4
|
+
* @param props message props
|
|
5
|
+
*
|
|
6
|
+
* @returns message payload-specific styles
|
|
7
|
+
*/
|
|
8
|
+
const getPayloadStyle = ({ body, container, header, primaryButton, secondaryButton, }) => ({
|
|
9
|
+
body: body?.style ?? {},
|
|
10
|
+
container: container?.style ?? {},
|
|
11
|
+
header: header?.style ?? {},
|
|
12
|
+
primaryButton: primaryButton?.style ?? {},
|
|
13
|
+
secondaryButton: secondaryButton?.style ?? {},
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Receives message styling and returns style property values for use with in-app message
|
|
17
|
+
* UI components. Handles resolving style precedence between payload and custom styles
|
|
18
|
+
*
|
|
19
|
+
* Styles resolve precedence from lowest to highest:
|
|
20
|
+
* 1. Payload styles
|
|
21
|
+
* 2. Custom (override) styles
|
|
22
|
+
*
|
|
23
|
+
* @param params message style params
|
|
24
|
+
*
|
|
25
|
+
* @returns message component styles
|
|
26
|
+
*/
|
|
27
|
+
function getMessageStyles({ styleParams, }) {
|
|
28
|
+
const { payloadStyle, overrideStyle } = styleParams;
|
|
29
|
+
return {
|
|
30
|
+
// message body style
|
|
31
|
+
body: {
|
|
32
|
+
...payloadStyle?.body,
|
|
33
|
+
...overrideStyle?.body,
|
|
34
|
+
},
|
|
35
|
+
// close button style - not defined in payload, override only
|
|
36
|
+
closeIconButton: overrideStyle?.closeIconButton ?? {},
|
|
37
|
+
// message container style
|
|
38
|
+
container: {
|
|
39
|
+
...payloadStyle?.container,
|
|
40
|
+
...overrideStyle?.container,
|
|
41
|
+
},
|
|
42
|
+
// message header style
|
|
43
|
+
header: {
|
|
44
|
+
...payloadStyle?.header,
|
|
45
|
+
...overrideStyle?.header,
|
|
46
|
+
},
|
|
47
|
+
// image style - not defined in payload, override only
|
|
48
|
+
image: overrideStyle?.image ?? {},
|
|
49
|
+
// message primary button style
|
|
50
|
+
primaryButton: {
|
|
51
|
+
...payloadStyle?.primaryButton,
|
|
52
|
+
...overrideStyle?.primaryButton,
|
|
53
|
+
},
|
|
54
|
+
// message secondary button style
|
|
55
|
+
secondaryButton: {
|
|
56
|
+
...payloadStyle?.secondaryButton,
|
|
57
|
+
...overrideStyle?.secondaryButton,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { getMessageStyles, getPayloadStyle };
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { InAppMessagingProvider } from '@aws-amplify/ui-react-core-notifications';
|
|
3
|
+
import InAppMessageDisplay from '../InAppMessageDisplay/InAppMessageDisplay.mjs';
|
|
4
|
+
|
|
5
|
+
function withInAppMessaging(Component, options) {
|
|
6
|
+
return function WrappedWithInAppMessaging(props) {
|
|
7
|
+
return (React__default.createElement(InAppMessagingProvider, null,
|
|
8
|
+
React__default.createElement(InAppMessageDisplay, { ...options }),
|
|
9
|
+
React__default.createElement(Component, { ...props })));
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { withInAppMessaging as default };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
export{InAppMessagingProvider,useInAppMessaging}from
|
|
1
|
+
export { InAppMessagingProvider, useInAppMessaging } from '@aws-amplify/ui-react-core-notifications';
|
|
2
|
+
export { default as InAppMessageDisplay } from './components/InAppMessaging/InAppMessageDisplay/InAppMessageDisplay.mjs';
|
|
3
|
+
export { default as withInAppMessaging } from './components/InAppMessaging/withInAppMessaging/withInAppMessaging.mjs';
|