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
26 changes: 26 additions & 0 deletions docs/chat-ui-react.aisignposticon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- 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; [AISignpostIcon](./chat-ui-react.aisignposticon.md)

## AISignpostIcon() function

Default icon for the AI signpost.

**Signature:**

```typescript
export declare function AISignpostIcon({ className, }: {
className?: string;
}): React.JSX.Element;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| { className, } | { className?: string; } | |

**Returns:**

React.JSX.Element

13 changes: 13 additions & 0 deletions docs/chat-ui-react.aisignpostprops.icon.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; [AISignpostProps](./chat-ui-react.aisignpostprops.md) &gt; [icon](./chat-ui-react.aisignpostprops.icon.md)

## AISignpostProps.icon property

Icon displayed before the signpost label. Defaults to the SDK's AI signpost icon.

**Signature:**

```typescript
icon?: React.JSX.Element;
```
13 changes: 13 additions & 0 deletions docs/chat-ui-react.aisignpostprops.label.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; [AISignpostProps](./chat-ui-react.aisignpostprops.md) &gt; [label](./chat-ui-react.aisignpostprops.label.md)

## AISignpostProps.label property

Label displayed in the signpost button. Defaults to "AI-Powered".

**Signature:**

```typescript
label?: string;
```
23 changes: 23 additions & 0 deletions docs/chat-ui-react.aisignpostprops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- 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; [AISignpostProps](./chat-ui-react.aisignpostprops.md)

## AISignpostProps interface

Props for the built-in AI signpost component.

**Signature:**

```typescript
export interface AISignpostProps
```

## Properties

| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [icon?](./chat-ui-react.aisignpostprops.icon.md) | | React.JSX.Element | _(Optional)_ Icon displayed before the signpost label. Defaults to the SDK's AI signpost icon. |
| [label?](./chat-ui-react.aisignpostprops.label.md) | | string | _(Optional)_ Label displayed in the signpost button. Defaults to "AI-Powered". |
| [popoverBody?](./chat-ui-react.aisignpostprops.popoverbody.md) | | string | _(Optional)_ Body displayed in the signpost popover. |
| [popoverHeader?](./chat-ui-react.aisignpostprops.popoverheader.md) | | string | _(Optional)_ Header displayed in the signpost popover. Defaults to "AI-Generated Content". |

13 changes: 13 additions & 0 deletions docs/chat-ui-react.aisignpostprops.popoverbody.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; [AISignpostProps](./chat-ui-react.aisignpostprops.md) &gt; [popoverBody](./chat-ui-react.aisignpostprops.popoverbody.md)

## AISignpostProps.popoverBody property

Body displayed in the signpost popover.

**Signature:**

```typescript
popoverBody?: string;
```
13 changes: 13 additions & 0 deletions docs/chat-ui-react.aisignpostprops.popoverheader.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; [AISignpostProps](./chat-ui-react.aisignpostprops.md) &gt; [popoverHeader](./chat-ui-react.aisignpostprops.popoverheader.md)

## AISignpostProps.popoverHeader property

Header displayed in the signpost popover. Defaults to "AI-Generated Content".

**Signature:**

```typescript
popoverHeader?: string;
```
4 changes: 2 additions & 2 deletions docs/chat-ui-react.chatheader.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ A component that renders the header of a chat bot panel, including the title and
**Signature:**

```typescript
export declare function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): React.JSX.Element;
export declare function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, hideAISignpost, aiSignpostProps, onClose, customCssClasses, }: ChatHeaderProps): React.JSX.Element;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| { title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, } | [ChatHeaderProps](./chat-ui-react.chatheaderprops.md) | |
| { title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, hideAISignpost, aiSignpostProps, onClose, customCssClasses, } | [ChatHeaderProps](./chat-ui-react.chatheaderprops.md) | |

**Returns:**

Expand Down
13 changes: 13 additions & 0 deletions docs/chat-ui-react.chatheaderprops.aisignpostprops.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; [ChatHeaderProps](./chat-ui-react.chatheaderprops.md) &gt; [aiSignpostProps](./chat-ui-react.chatheaderprops.aisignpostprops.md)

## ChatHeaderProps.aiSignpostProps property

The props to pass to the built-in AI signpost component.

**Signature:**

```typescript
aiSignpostProps?: AISignpostProps;
```
13 changes: 13 additions & 0 deletions docs/chat-ui-react.chatheaderprops.hideaisignpost.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; [ChatHeaderProps](./chat-ui-react.chatheaderprops.md) &gt; [hideAISignpost](./chat-ui-react.chatheaderprops.hideaisignpost.md)

## ChatHeaderProps.hideAISignpost property

Whether to hide the AI signpost. Defaults to false.

**Signature:**

```typescript
hideAISignpost?: boolean;
```
2 changes: 2 additions & 0 deletions docs/chat-ui-react.chatheaderprops.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ export interface ChatHeaderProps

| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [aiSignpostProps?](./chat-ui-react.chatheaderprops.aisignpostprops.md) | | [AISignpostProps](./chat-ui-react.aisignpostprops.md) | _(Optional)_ The props to pass to the built-in AI signpost component. |
| [closeButtonIcon?](./chat-ui-react.chatheaderprops.closebuttonicon.md) | | JSX.Element | _(Optional)_ Custom icon for for close button. |
| [customCssClasses?](./chat-ui-react.chatheaderprops.customcssclasses.md) | | [ChatHeaderCssClasses](./chat-ui-react.chatheadercssclasses.md) | _(Optional)_ CSS classes for customizing the component styling. |
| [hideAISignpost?](./chat-ui-react.chatheaderprops.hideaisignpost.md) | | boolean | _(Optional)_ Whether to hide the AI signpost. Defaults to false. |
| [onClose?](./chat-ui-react.chatheaderprops.onclose.md) | | () =&gt; void | _(Optional)_ A function which is called when the close button is clicked. |
| [restartButtonIcon?](./chat-ui-react.chatheaderprops.restartbuttonicon.md) | | JSX.Element | _(Optional)_ Custom icon for for restart button. |
| [showCloseButton?](./chat-ui-react.chatheaderprops.showclosebutton.md) | | boolean | _(Optional)_ Displays a close button which will invoke [ChatHeaderProps.onClose](./chat-ui-react.chatheaderprops.onclose.md) on click. Default to false. |
Expand Down
4 changes: 3 additions & 1 deletion docs/chat-ui-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

| Function | Description |
| --- | --- |
| [ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, })](./chat-ui-react.chatheader.md) | A component that renders the header of a chat bot panel, including the title and a button to reset the conversation. |
| [AISignpostIcon({ className, })](./chat-ui-react.aisignposticon.md) | Default icon for the AI signpost. |
| [ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, hideAISignpost, aiSignpostProps, onClose, customCssClasses, })](./chat-ui-react.chatheader.md) | A component that renders the header of a chat bot panel, including the title and a button to reset the conversation. |
| [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. |
Expand All @@ -20,6 +21,7 @@

| Interface | Description |
| --- | --- |
| [AISignpostProps](./chat-ui-react.aisignpostprops.md) | Props for the built-in AI signpost component. |
| [ChatHeaderCssClasses](./chat-ui-react.chatheadercssclasses.md) | The CSS class interface for the [ChatHeader()](./chat-ui-react.chatheader.md) component. |
| [ChatHeaderProps](./chat-ui-react.chatheaderprops.md) | The props for the [ChatHeader()](./chat-ui-react.chatheader.md) component. |
| [ChatInputCssClasses](./chat-ui-react.chatinputcssclasses.md) | The CSS class interface for the [ChatInput()](./chat-ui-react.chatinput.md) component. |
Expand Down
17 changes: 16 additions & 1 deletion etc/chat-ui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@ import { default as React_2 } from 'react';
import { ReactNode } from 'react';

// @public
export function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): React_2.JSX.Element;
export function AISignpostIcon({ className, }: {
className?: string;
}): React_2.JSX.Element;

// @public
export interface AISignpostProps {
icon?: React_2.JSX.Element;
label?: string;
popoverBody?: string;
popoverHeader?: string;
}

// @public
export function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, hideAISignpost, aiSignpostProps, onClose, customCssClasses, }: ChatHeaderProps): React_2.JSX.Element;

// @public
export interface ChatHeaderCssClasses {
Expand All @@ -30,8 +43,10 @@ export interface ChatHeaderCssClasses {

// @public
export interface ChatHeaderProps {
aiSignpostProps?: AISignpostProps;
closeButtonIcon?: JSX.Element;
customCssClasses?: ChatHeaderCssClasses;
hideAISignpost?: boolean;
onClose?: () => void;
restartButtonIcon?: JSX.Element;
showCloseButton?: boolean;
Expand Down
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@
"rehype-raw": "^5.0.0",
"rehype-sanitize": "^4.0.0",
"remark-gfm": "^1.0.0",
"tailwind-merge": "^1.12.0"
"tailwind-merge": "^1.12.0",
"use-isomorphic-layout-effect": "^1.1.2"
},
"overrides": {
"handlebars": "^4.7.9",
Expand Down
101 changes: 100 additions & 1 deletion src/components/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import React, { useCallback, useRef, useState } from "react";
import { twMerge } from "tailwind-merge";
import { CrossIcon } from "../icons/Cross";
import { withStylelessCssClasses } from "../utils/withStylelessCssClasses";
import { AISignpostIcon } from "../icons/AISignpostIcon";
import { useId } from "../hooks/useId";

/**
* The CSS class interface for the {@link ChatHeader} component.
Expand Down Expand Up @@ -32,6 +34,14 @@ const builtInCssClasses: Readonly<ChatHeaderCssClasses> =
closeButtonIcon: "text-white w-[26px] h-[26px]",
});

const aiSignpostDefaults = {
label: "AI-Powered",
popoverHeader: "AI-Generated Content",
popoverBody:
"This content is generated by AI from language models and previous responses. It may be" +
" incomplete or inaccurate. Please check statements for accuracy.",
};

/**
* The props for the {@link ChatHeader} component.
*
Expand All @@ -58,10 +68,30 @@ export interface ChatHeaderProps {
restartButtonIcon?: JSX.Element;
/** Custom icon for for close button. */
closeButtonIcon?: JSX.Element;
/** Whether to hide the AI signpost. Defaults to false. */
hideAISignpost?: boolean;
/** The props to pass to the built-in AI signpost component. */
aiSignpostProps?: AISignpostProps;
/** CSS classes for customizing the component styling. */
customCssClasses?: ChatHeaderCssClasses;
}

/**
* Props for the built-in AI signpost component.
*
* @public
*/
export interface AISignpostProps {
/** Icon displayed before the signpost label. Defaults to the SDK's AI signpost icon. */
icon?: React.JSX.Element;
/** Label displayed in the signpost button. Defaults to "AI-Powered". */
label?: string;
/** Header displayed in the signpost popover. Defaults to "AI-Generated Content". */
popoverHeader?: string;
/** Body displayed in the signpost popover. */
popoverBody?: string;
}

/**
* A component that renders the header of a chat bot panel,
* including the title and a button to reset the conversation.
Expand All @@ -76,6 +106,8 @@ export function ChatHeader({
restartButtonIcon,
showCloseButton,
closeButtonIcon,
hideAISignpost = false,
aiSignpostProps,
onClose,
customCssClasses,
}: ChatHeaderProps) {
Expand All @@ -101,7 +133,10 @@ export function ChatHeader({

return (
<div className={cssClasses.container}>
<h1 className={cssClasses.title}>{title}</h1>
<div className="relative flex min-w-0 items-center gap-2 pr-1">
<h1 className={twMerge("min-w-0", cssClasses.title)}>{title}</h1>
{!hideAISignpost && <AISignpost {...aiSignpostProps} />}
</div>
{showRestartButton && (
<button
aria-label="Restart Conversation"
Expand All @@ -127,3 +162,67 @@ export function ChatHeader({
</div>
);
}

function AISignpost({
icon,
label,
popoverHeader,
popoverBody,
}: AISignpostProps): React.JSX.Element {
const [isOpen, setIsOpen] = useState(false);
const popoverId = useId("ai-signpost-popover");
const popoverHeaderId = useId("ai-signpost-popover-header");
const popoverDescriptionId = useId("ai-signpost-popover-description");
const handleSignpostClick = useCallback(() => {
setIsOpen((current) => !current);
}, []);
const onSignpostClose = useCallback(() => {
setIsOpen(false);
}, []);

return (
<div className="relative shrink-0 text-sm text-blue-800">
<button
type="button"
aria-expanded={isOpen}
aria-controls={popoverId}
className="inline-flex items-center gap-1.5 rounded-lg border border-blue-100 bg-white px-2 py-1 text-xs font-medium text-blue-800 shadow-sm transition-colors hover:bg-blue-50"
onClick={handleSignpostClick}
>
{icon ?? <AISignpostIcon className="h-4 w-4" />}
<span>{label ?? aiSignpostDefaults.label}</span>
</button>
{isOpen && (
<div
id={popoverId}
role="dialog"
aria-labelledby={popoverHeaderId}
aria-describedby={popoverDescriptionId}
className="absolute left-0 top-full z-10 mt-2 w-80 max-w-[calc(100vw-2rem)] rounded-lg border border-gray-200 bg-white text-gray-700 shadow-lg"
>
<div className="flex flex-col gap-3 px-4 py-3">
<div className="flex items-center justify-between gap-3">
<div
id={popoverHeaderId}
className="text-sm font-semibold text-gray-900"
>
{popoverHeader ?? aiSignpostDefaults.popoverHeader}
</div>
<button
type="button"
className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-gray-500 hover:bg-gray-100 hover:text-gray-700"
aria-label="Dismiss"
onClick={onSignpostClose}
>
<CrossIcon className="h-3 w-3" />
</button>
</div>
<div id={popoverDescriptionId} className="text-sm text-gray-700">
{popoverBody ?? aiSignpostDefaults.popoverBody}
</div>
</div>
</div>
)}
</div>
);
}
4 changes: 4 additions & 0 deletions src/components/ChatPopUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ export function ChatPopUp(props: ChatPopUpProps) {
title,
footer,
isOpen,
hideAISignpost,
aiSignpostProps,
} = props;

const reportAnalyticsEvent = useReportAnalyticsEvent();
Expand Down Expand Up @@ -230,6 +232,8 @@ export function ChatPopUp(props: ChatPopUpProps) {
title={title}
showRestartButton={showRestartButton}
showCloseButton={true}
hideAISignpost={hideAISignpost}
aiSignpostProps={aiSignpostProps}
onClose={onClose}
customCssClasses={cssClasses.headerCssClasses}
/>
Expand Down
Loading
Loading