Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,26 @@ import {
} from './IterableEmbeddedBanner.styles';

/**
* TODO: figure out how default action works.
* The IterableEmbeddedBanner component is used to render a banner message.
*
* @param config - The config for the IterableEmbeddedBanner component.
* @param message - The message to render.
* @param onButtonClick - The function to call when a button is clicked.
* @param onMessageClick - The function to call when the message is clicked.
* @returns The IterableEmbeddedBanner component.
*
* @example
* ```tsx
* return (
* <IterableEmbeddedBanner
* config={config}
* message={message}
* onButtonClick={onButtonClick}
* onMessageClick={onMessageClick}
* />
* );
* ```
*/

export const IterableEmbeddedBanner = ({
config,
message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,39 @@ import type { IterableEmbeddedComponentProps } from '../../types/IterableEmbedde
import { IMAGE_HEIGHT, styles } from './IterableEmbeddedCard.styles';

/**
* TODO: Add default action click handler. See IterableEmbeddedView for functionality.
* The IterableEmbeddedCard component is used to render a card message.
*
* @param config - The config for the IterableEmbeddedCard component.
* @param message - The message to render.
* @param onButtonClick - The function to call when a button is clicked.
* @param onMessageClick - The function to call when the message is clicked.
* @returns The IterableEmbeddedCard component.
*
* @example
* ```tsx
* return (
* <IterableEmbeddedCard
* config={config}
* message={message}
* onButtonClick={onButtonClick}
* onMessageClick={onMessageClick}
* />
* );
* ```
*/

export const IterableEmbeddedCard = ({
config,
message,
onButtonClick = () => {},
onMessageClick = () => {},
}: IterableEmbeddedComponentProps) => {
const {
handleButtonClick,
handleMessageClick,
media,
parsedStyles,
} = useEmbeddedView(IterableEmbeddedViewType.Card, {
message,
config,
onButtonClick,
onMessageClick,
});
const { handleButtonClick, handleMessageClick, media, parsedStyles } =
useEmbeddedView(IterableEmbeddedViewType.Card, {
message,
config,
onButtonClick,
onMessageClick,
});
const buttons = message?.elements?.buttons ?? [];

return (
Expand Down Expand Up @@ -64,8 +77,7 @@ export const IterableEmbeddedCard = ({
uri: media.url as string,
height: PixelRatio.getPixelSizeForLayoutSize(IMAGE_HEIGHT),
}
:
IterableLogoGrey
: IterableLogoGrey
}
style={
media.shouldShow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ import { useEmbeddedView } from '../../hooks/useEmbeddedView';
import type { IterableEmbeddedComponentProps } from '../../types/IterableEmbeddedComponentProps';
import { styles } from './IterableEmbeddedNotification.styles';

/**
* The IterableEmbeddedNotification component is used to render a notification message.
*
* @param config - The config for the IterableEmbeddedNotification component.
* @param message - The message to render.
* @param onButtonClick - The function to call when a button is clicked.
* @param onMessageClick - The function to call when the message is clicked.
* @returns The IterableEmbeddedNotification component.
*
* @example
* ```tsx
* return (
* <IterableEmbeddedNotification
* config={config}
* message={message}
* onButtonClick={onButtonClick}
* onMessageClick={onMessageClick}
* />
* );
* ```
*/
export const IterableEmbeddedNotification = ({
config,
message,
Expand Down
75 changes: 72 additions & 3 deletions src/embedded/components/IterableEmbeddedView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { IterableEmbeddedNotification } from './IterableEmbeddedNotification';
/**
* The props for the IterableEmbeddedView component.
*/
interface IterableEmbeddedViewProps extends IterableEmbeddedComponentProps {
export interface IterableEmbeddedViewProps
extends IterableEmbeddedComponentProps {
/** The type of view to render. */
viewType: IterableEmbeddedViewType;
}
Expand All @@ -20,10 +21,78 @@ interface IterableEmbeddedViewProps extends IterableEmbeddedComponentProps {
* @param message - The message to render.
* @param config - The config for the IterableEmbeddedView component, most likely used to style the view.
* @param onButtonClick - The function to call when a button is clicked.
* @param onMessageClick - The function to call when the message is clicked.
* @returns The IterableEmbeddedView component.
*
* This component is used to render pre-created, customizable message displays
* included with Iterables RN SDK: cards, banners, and notifications.
* This component is used to render the following pre-created, customizable
* message displays included with Iterables RN SDK: cards, banners, and
* notifications.
*
* @example
* ```tsx
* import {
* IterableAction,
* IterableEmbeddedView,
* IterableEmbeddedViewType,
* type IterableEmbeddedMessage,
* type IterableEmbeddedMessageElementsButton,
* } from '@iterable/react-native-sdk';
*
* // See `IterableEmbeddedViewType` for available view types.
* const viewType = IterableEmbeddedViewType.Card;
*
* // Messages usually come from the embedded manager. `placementIds` is `number[] | null`
* // (use `null` to load messages for all placements), for example:
* // Iterable.embeddedManager.getMessages([101, 102]).then((messages) => { ... });
* const message: IterableEmbeddedMessage = {
* metadata: {
* messageId: 'test-message-123',
* placementId: 101,
* },
* elements: {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type IterableEmbeddedMessage has elements?: IterableEmbeddedMessageElements | null.

Same issue, a message with no elements is valid (e.g. a metadata-only message), but the example doesn’t reflect that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not exactly required for the view, but it would result in a very strange looking component as everything would be empty.

* title: 'Test Title',
* body: 'Test Body',
* buttons: [
* {
* id: 'button-1',
* title: 'Button 1',
* action: new IterableAction('openUrl', 'https://example.com/one'),
* },
* {
* id: 'button-2',
* title: 'Button 2',
* action: new IterableAction('openUrl', 'https://example.com/two'),
* },
* ],
* },
* };
*
* // The config is used to style the component.
* // See `IterableEmbeddedViewConfig` for available config options.
* const config = { backgroundColor: '#FFFFFF', borderRadius: 8 };
*
* // `onButtonClick` will be called when a button is clicked.
* // This callback allows you to add custom logic in addition to the SDK's default handling.
* const onButtonClick = (button: IterableEmbeddedMessageElementsButton) => {
* console.log('Button clicked', button.id, button.title, button.action);
* };
*
* // `onMessageClick` will be called when the message is clicked anywhere outside of a button.
* // If a default action is set, it will be handled prior to this callback.
* const onMessageClick = () => {
* console.log('Message clicked');
* };
*
* return (
* <IterableEmbeddedView
* viewType={viewType}
* message={message}
* config={config}
* onButtonClick={onButtonClick}
* onMessageClick={onMessageClick}
* />
* );
* ```
*/
export const IterableEmbeddedView = ({
viewType,
Expand Down
12 changes: 9 additions & 3 deletions src/embedded/enums/IterableEmbeddedViewType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
* The view type for an embedded message.
*/
export enum IterableEmbeddedViewType {
/** The embedded view is a banner */
/**
* [Banner](https://support.iterable.com/hc/en-us/articles/23230946708244-Out-of-the-Box-Views-for-Embedded-Messages#banners) Out of the Box (OOTB) view.
*/
Banner = 0,
/** The embedded view is a card */
/**
* [Card](https://support.iterable.com/hc/en-us/articles/23230946708244-Out-of-the-Box-Views-for-Embedded-Messages#cards) Out of the Box (OOTB) view.
*/
Card = 1,
/** The embedded view is a notification */
/**
* [Notification](https://support.iterable.com/hc/en-us/articles/23230946708244-Out-of-the-Box-Views-for-Embedded-Messages#notifications) Out of the Box (OOTB) view.
*/
Notification = 2,
}
2 changes: 2 additions & 0 deletions src/embedded/hooks/useEmbeddedView/getMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { IterableEmbeddedViewType } from '../../enums';
* @returns The media to render.
*
* @example
* ```ts
* const media = getMedia(IterableEmbeddedViewType.Notification, message);
* console.log(media.url);
* console.log(media.caption);
* console.log(media.shouldShow ? 'true' : 'false');
* ```
*/
export const getMedia = (
/** The type of view to render. */
Expand Down
2 changes: 2 additions & 0 deletions src/embedded/hooks/useEmbeddedView/getStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const getDefaultStyle = <T>(
* @returns The styles.
*
* @example
* ```ts
* const styles = getStyles(IterableEmbeddedViewType.Notification, {
* backgroundColor: '#000000',
* borderColor: '#000000',
Expand All @@ -45,6 +46,7 @@ const getDefaultStyle = <T>(
* primaryBtnBackgroundColor: '#000000',
* primaryBtnTextColor: '#000000',
* });
* ```
*/
export const getStyles = (
viewType: IterableEmbeddedViewType,
Expand Down
4 changes: 3 additions & 1 deletion src/embedded/hooks/useEmbeddedView/useEmbeddedView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const noop = () => {};
* @returns The embedded view.
*
* @example
* ```tsx
* const { handleButtonClick, handleMessageClick, media, parsedStyles } = useEmbeddedView(IterableEmbeddedViewType.Notification, {
* message,
* config,
Expand All @@ -30,6 +31,7 @@ const noop = () => {};
* <Text>{parsedStyles.backgroundColor}</Text>
* </View>
* );
* ```
*/
export const useEmbeddedView = (
/** The type of view to render. */
Expand All @@ -51,7 +53,7 @@ export const useEmbeddedView = (

const handleButtonClick = useCallback(
(button: IterableEmbeddedMessageElementsButton) => {
onButtonClick(button);
onButtonClick(button, message);
Iterable.embeddedManager.handleClick(message, button.id, button.action);
},
[onButtonClick, message]
Expand Down
5 changes: 4 additions & 1 deletion src/embedded/types/IterableEmbeddedComponentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export interface IterableEmbeddedComponentProps {
/** The config for the embedded view. */
config?: IterableEmbeddedViewConfig | null;
/** The function to call when a button is clicked. */
onButtonClick?: (button: IterableEmbeddedMessageElementsButton) => void;
onButtonClick?: (
button: IterableEmbeddedMessageElementsButton,
message: IterableEmbeddedMessage
) => void;
/** The function to call when the message is clicked. */
onMessageClick?: () => void;
}
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export {
type IterableEmbeddedMessageElementsButton,
type IterableEmbeddedMessageElementsText,
type IterableEmbeddedViewConfig,
type IterableEmbeddedViewProps,
} from './embedded';
export {
IterableHtmlInAppContent,
Expand Down
Loading