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
2 changes: 1 addition & 1 deletion docs/chat-ui-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
| [ChatInput({ placeholder, stream, inputAutoFocus, handleError, sendButtonIcon, customCssClasses, onSend, onRetry, })](./chat-ui-react.chatinput.md) | A component that allows user to input message and send to Chat API. |
| [ChatPanel(props)](./chat-ui-react.chatpanel.md) | A component that renders a full panel for chat bot interactions. This includes the message bubbles for the conversation, input box with send button, and header (if provided). |
| [ChatPopUp(props)](./chat-ui-react.chatpopup.md) | A component that renders a popup button that displays and hides a panel for chat bot interactions. |
| [MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, })](./chat-ui-react.messagebubble.md) | A component that displays the provided message. |
| [MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, renderMarkdown, })](./chat-ui-react.messagebubble.md) | A component that displays the provided message. |
| [useComposedCssClasses(builtInClasses, customClasses)](./chat-ui-react.usecomposedcssclasses.md) | useComposedCssClasses merges a component's built-in tailwind classes with custom tailwind classes. |
| [useReportAnalyticsEvent()](./chat-ui-react.usereportanalyticsevent.md) | Returns a function to send requests to Yext Analytics API. |

Expand Down
4 changes: 2 additions & 2 deletions docs/chat-ui-react.messagebubble.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ A component that displays the provided message.
**Signature:**

```typescript
export declare function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, }: MessageBubbleProps): React.JSX.Element;
export declare function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, renderMarkdown, }: MessageBubbleProps): React.JSX.Element;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| { message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, } | [MessageBubbleProps](./chat-ui-react.messagebubbleprops.md) | |
| { message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, renderMarkdown, } | [MessageBubbleProps](./chat-ui-react.messagebubbleprops.md) | |

**Returns:**

Expand Down
1 change: 1 addition & 0 deletions docs/chat-ui-react.messagebubbleprops.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface MessageBubbleProps
| [linkTarget?](./chat-ui-react.messagebubbleprops.linktarget.md) | | string | _(Optional)_ Link target open behavior on click. |
| [message](./chat-ui-react.messagebubbleprops.message.md) | | Message | The message to display. |
| [onLinkClick?](./chat-ui-react.messagebubbleprops.onlinkclick.md) | | (href?: string) => void | _(Optional)_ A callback which is called when user clicks a link. |
| [renderMarkdown?](./chat-ui-react.messagebubbleprops.rendermarkdown.md) | | boolean | _(Optional)_ Whether to render the message text as markdown. Defaults to true. |
| [showFeedbackButtons?](./chat-ui-react.messagebubbleprops.showfeedbackbuttons.md) | | boolean | _(Optional)_ Whether to show the feedback buttons on the message bubble. Defaults to true. |
| [showTimestamp?](./chat-ui-react.messagebubbleprops.showtimestamp.md) | | boolean | _(Optional)_ Whether to show the timestamp of the message with the message bubble. Defaults to true. |

13 changes: 13 additions & 0 deletions docs/chat-ui-react.messagebubbleprops.rendermarkdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/chat-ui-react](./chat-ui-react.md) &gt; [MessageBubbleProps](./chat-ui-react.messagebubbleprops.md) &gt; [renderMarkdown](./chat-ui-react.messagebubbleprops.rendermarkdown.md)

## MessageBubbleProps.renderMarkdown property

Whether to render the message text as markdown. Defaults to true.

**Signature:**

```typescript
renderMarkdown?: boolean;
```
3 changes: 2 additions & 1 deletion etc/chat-ui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export interface InitialMessagePopUpCssClasses {
}

// @public
export function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, }: MessageBubbleProps): React_2.JSX.Element;
export function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, linkTarget, onLinkClick, renderMarkdown, }: MessageBubbleProps): React_2.JSX.Element;

// @public
export interface MessageBubbleCssClasses {
Expand Down Expand Up @@ -219,6 +219,7 @@ export interface MessageBubbleProps {
linkTarget?: string;
message: Message;
onLinkClick?: (href?: string) => void;
renderMarkdown?: boolean;
showFeedbackButtons?: boolean;
showTimestamp?: boolean;
}
Expand Down
24 changes: 17 additions & 7 deletions src/components/MessageBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export interface MessageBubbleProps {
linkTarget?: string;
/** A callback which is called when user clicks a link. */
onLinkClick?: (href?: string) => void;
/**
* Whether to render the message text as markdown.
* Defaults to true.
*/
renderMarkdown?: boolean;
}

/**
Expand All @@ -96,6 +101,7 @@ export function MessageBubble({
formatTimestamp = defaultFormatTimestamp,
linkTarget,
onLinkClick,
renderMarkdown = true,
}: MessageBubbleProps) {
const cssClasses = useComposedCssClasses(builtInCssClasses, customCssClasses);
const bubbleCssClasses = twMerge(
Expand Down Expand Up @@ -140,13 +146,17 @@ export function MessageBubble({
responseId={message.responseId}
/>
)}
<Markdown
content={message.text}
responseId={message.responseId}
customCssClasses={markdownCssClasses}
linkTarget={linkTarget}
onLinkClick={onLinkClick}
/>
{renderMarkdown ? (
<Markdown
content={message.text}
responseId={message.responseId}
customCssClasses={markdownCssClasses}
linkTarget={linkTarget}
onLinkClick={onLinkClick}
/>
) : (
<div className={textCssClasses}>{message.text}</div>
)}
</div>
{/* fallback on empty space here to perserve the height for timestamp div */}
{showTimestamp && (
Expand Down
50 changes: 50 additions & 0 deletions tests/components/MessageBubble.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,53 @@ it("applies link target setting (parent)", async () => {

expect(screen.getByText("msg link")).toHaveAttribute("target", "_parent");
});

it("renders markdown by default", () => {
const linkMessage: Message = {
text: "Test [msg link](msglink)",
timestamp: "2023-06-01T15:26:55.362Z",
source: MessageSource.USER,
};

render(
<ChatHeadlessProvider config={dummyConfig}>
<MessageBubble message={linkMessage} />
</ChatHeadlessProvider>
);

expect(screen.getByText("msg link")).toHaveAttribute("href", "msglink");
});

it("renders raw message text when renderMarkdown is false", () => {
const linkMessage: Message = {
text: "Test [msg link](msglink)",
timestamp: "2023-06-01T15:26:55.362Z",
source: MessageSource.USER,
};

render(
<ChatHeadlessProvider config={dummyConfig}>
<MessageBubble message={linkMessage} renderMarkdown={false} />
</ChatHeadlessProvider>
);

expect(screen.getByText(linkMessage.text)).toBeInTheDocument();
expect(screen.queryByRole("link")).not.toBeInTheDocument();
});

it("escapes html when renderMarkdown is false", () => {
const htmlMessage: Message = {
text: "<strong>Test</strong>",
timestamp: "2023-06-01T15:26:55.362Z",
source: MessageSource.USER,
};

render(
<ChatHeadlessProvider config={dummyConfig}>
<MessageBubble message={htmlMessage} renderMarkdown={false} />
</ChatHeadlessProvider>
);

expect(screen.getByText(htmlMessage.text)).toBeInTheDocument();
expect(screen.queryByText("Test")).not.toBeInTheDocument();
});
Loading