Skip to content

Commit 9e54abc

Browse files
chore(docs/chat-composer): Update the documentation for the new Chat Composer elements (#3981)
* feat(composer): wip base elements * feat(composer): addition of all attatchment components * feat(composer): lint fix * feat(composer): fix disabled styling * feat(composer): responsive columns and JS doc * feat(composer-docs): wip examples * feat(composer): add new plugin to access state * feat(composer): fix lint issues * feat(docs-composer): added in stories for log types * chore(docs): update AI Chat Log page name * chore(chat-composer): clenaup unused imports * chore(chat-composer): remove duplicate story * chore(docs/chat-composer): content changes for latest component updates * chore(chat-composer): remove attachment * chore(chat-composer): remove unused component * chore(chat-composer): pr cleanup * chore(docs/ai-chat-log): correct storybook link * chore(docs/chat-composer): type fix * chore(docs/chat-composer): formatting fix * chore(docs/chat-composer): lint fix * chore(docs/chat-composer): story update * Update packages/paste-website/src/pages/components/chat-composer/index.mdx Co-authored-by: Sarah <sali@twilio.com> * Apply suggestions from code review Co-authored-by: Sarah <sali@twilio.com> * chore(docs/chat-composer): remove redundant changeset * chore(docs/chat-composer): update docs AI story example * chore(chat-composer): updated typedoc * Update packages/paste-website/src/pages/components/chat-composer/index.mdx Co-authored-by: Sarah <sali@twilio.com> * chore(docs/chat-composer): show default contained variant * chore(docs/chat-composer): formatting fix --------- Co-authored-by: Sarah <sali@twilio.com>
1 parent 7779a24 commit 9e54abc

File tree

10 files changed

+632
-176
lines changed

10 files changed

+632
-176
lines changed

.changeset/cold-apes-leave.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@twilio-paste/chat-composer": patch
3+
"@twilio-paste/core": patch
4+
---
5+
6+
[ChatComposer] updated JS Doc used for tpye gen in docs website

packages/paste-core/components/ai-chat-log/stories/composer.stories.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,7 @@ export const AIChatLogComposer = (): React.ReactNode => {
130130
content: (
131131
<AIChatMessage variant="user">
132132
<AIChatMessageAuthor aria-label="you said at 2:36pm">Gibby Radki</AIChatMessageAuthor>
133-
<AIChatMessageBody>
134-
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt delectus fuga, necessitatibus eligendi
135-
iure adipisci facilis exercitationem officiis dolorem laborum, ex fugiat quisquam itaque, earum sit nesciunt
136-
impedit repellat assumenda.
137-
</AIChatMessageBody>
133+
<AIChatMessageBody>Hi, I am getting errors codes when sending an SMS.</AIChatMessageBody>
138134
</AIChatMessage>
139135
),
140136
},
@@ -144,9 +140,7 @@ export const AIChatLogComposer = (): React.ReactNode => {
144140
<AIChatMessage variant="bot">
145141
<AIChatMessageAuthor aria-label="AI said">Good Bot</AIChatMessageAuthor>
146142
<AIChatMessageBody>
147-
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt delectus fuga, necessitatibus
148-
eligendiiure adipisci facilis exercitationem officiis dolorem laborum, ex fugiat quisquam itaque, earum sit
149-
nesciunt impedit repellat assumenda.
143+
Error codes can be returned from various parts of the process. What error codes are you encountering?
150144
<Box marginTop="space50">
151145
<ButtonGroup>
152146
<Button variant="secondary" onClick={() => {}} size="rounded_small">

packages/paste-core/components/chat-composer/src/ChatComposerAttachmentGroup.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface ChatComposerAttachmentGroupProps {
1313
*/
1414
element?: BoxProps["element"];
1515
/**
16-
* Sets the number of columns in the attachement grid
16+
* Sets the number of columns in the attachment grid
1717
* @default 2
1818
* @type number
1919
* @memberof ChatComposerAttachmentGroupProps

packages/paste-core/components/chat-composer/stories/logs.stories.tsx

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -263,38 +263,14 @@ const BotMessage = (props): JSX.Element => {
263263
);
264264
};
265265

266-
// eslint-disable-next-line storybook/prefer-pascal-case
267-
const createNewAIMessage = (message: string): Omit<AIChat, "id"> => {
268-
const messageDirection = getRandomInt(2) === 1 ? "user" : "bot";
269-
270-
return {
271-
variant: messageDirection,
272-
content:
273-
messageDirection === "user" ? (
274-
<AIChatMessage variant="user">
275-
<AIChatMessageAuthor aria-label="You said at 2:39pm">Gibby Radki</AIChatMessageAuthor>
276-
<AIChatMessageBody>{message}</AIChatMessageBody>
277-
</AIChatMessage>
278-
) : (
279-
<AIChatMessage variant="bot">
280-
<BotMessage message={message} />
281-
</AIChatMessage>
282-
),
283-
};
284-
};
285-
286266
export const AIChatLogComposer = (): React.ReactNode => {
287267
const { aiChats, push } = useAIChatLogger(
288268
{
289269
variant: "user",
290270
content: (
291271
<AIChatMessage variant="user">
292272
<AIChatMessageAuthor aria-label="you said at 2:36pm">Gibby Radki</AIChatMessageAuthor>
293-
<AIChatMessageBody>
294-
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt delectus fuga, necessitatibus eligendi
295-
iure adipisci facilis exercitationem officiis dolorem laborum, ex fugiat quisquam itaque, earum sit nesciunt
296-
impedit repellat assumenda.
297-
</AIChatMessageBody>
273+
<AIChatMessageBody>Hi, I am getting errors codes when sending an SMS.</AIChatMessageBody>
298274
</AIChatMessage>
299275
),
300276
},
@@ -304,9 +280,7 @@ export const AIChatLogComposer = (): React.ReactNode => {
304280
<AIChatMessage variant="bot">
305281
<AIChatMessageAuthor aria-label="AI said">Good Bot</AIChatMessageAuthor>
306282
<AIChatMessageBody>
307-
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt delectus fuga, necessitatibus
308-
eligendiiure adipisci facilis exercitationem officiis dolorem laborum, ex fugiat quisquam itaque, earum sit
309-
nesciunt impedit repellat assumenda.
283+
Error codes can be returned from various parts of the process. What error codes are you encountering?
310284
<Box marginTop="space50">
311285
<ButtonGroup>
312286
<Button variant="secondary" onClick={() => {}} size="rounded_small">
@@ -362,7 +336,15 @@ export const AIChatLogComposer = (): React.ReactNode => {
362336

363337
const submitMessage = (): void => {
364338
if (message === "") return;
365-
push(createNewAIMessage(message));
339+
push({
340+
variant: "user",
341+
content: (
342+
<AIChatMessage variant="user">
343+
<AIChatMessageAuthor aria-label="You said at 2:39pm">Gibby Radki</AIChatMessageAuthor>
344+
<AIChatMessageBody>{message}</AIChatMessageBody>
345+
</AIChatMessage>
346+
),
347+
});
366348
};
367349

368350
const editorInstanceRef = React.useRef<LexicalEditor>(null);

packages/paste-core/components/chat-composer/type-docs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2324,7 +2324,7 @@
23242324
"defaultValue": "2",
23252325
"required": false,
23262326
"externalProp": false,
2327-
"description": "Sets the number of columns in the attachement grid"
2327+
"description": "Sets the number of columns in the attachment grid"
23282328
},
23292329
"element": {
23302330
"type": "string",

packages/paste-website/src/component-examples/ChatComposerExamples.tsx

Lines changed: 144 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import { Box } from "@twilio-paste/box";
2-
import { Button } from "@twilio-paste/button";
31
import { ChatBubble, ChatMessage, ChatMessageMeta, ChatMessageMetaItem } from "@twilio-paste/chat-log";
42
import type { Chat } from "@twilio-paste/chat-log";
5-
import { SendIcon } from "@twilio-paste/icons/esm/SendIcon";
63
import {
74
CLEAR_EDITOR_COMMAND,
85
COMMAND_PRIORITY_HIGH,
@@ -94,23 +91,6 @@ export const createNewMessage = (message: string): Omit<Chat, "id"> => {
9491
};
9592
};
9693

97-
export const SendButtonPlugin = ({ onClick }: { onClick: () => void }): JSX.Element => {
98-
const [editor] = useLexicalComposerContext();
99-
100-
const handleSend = (): void => {
101-
onClick();
102-
editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined);
103-
};
104-
105-
return (
106-
<Box position="absolute" top="space30" right="space30">
107-
<Button variant="primary_icon" size="reset" onClick={handleSend}>
108-
<SendIcon decorative={false} title="Send message" />
109-
</Button>
110-
</Box>
111-
);
112-
};
113-
11494
export const EnterKeySubmitPlugin = ({ onKeyDown }: { onKeyDown: () => void }): null => {
11595
const [editor] = useLexicalComposerContext();
11696

@@ -134,7 +114,7 @@ export const EnterKeySubmitPlugin = ({ onKeyDown }: { onKeyDown: () => void }):
134114
};
135115

136116
export const ChatDialogExample = `const ChatDialog = () => {
137-
const {chats, push} = useChatLogger(
117+
const { chats, push } = useChatLogger(
138118
{
139119
content: (
140120
<ChatBookend>
@@ -146,7 +126,7 @@ export const ChatDialogExample = `const ChatDialog = () => {
146126
),
147127
},
148128
{
149-
variant: 'inbound',
129+
variant: "inbound",
150130
content: (
151131
<ChatMessage variant="inbound">
152132
<ChatBubble>Quisque ullamcorper ipsum vitae lorem euismod sodales.</ChatBubble>
@@ -170,7 +150,7 @@ export const ChatDialogExample = `const ChatDialog = () => {
170150
),
171151
},
172152
{
173-
variant: 'inbound',
153+
variant: "inbound",
174154
content: (
175155
<ChatMessage variant="inbound">
176156
<ChatBubble>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</ChatBubble>
@@ -182,9 +162,9 @@ export const ChatDialogExample = `const ChatDialog = () => {
182162
</ChatMessageMeta>
183163
</ChatMessage>
184164
),
185-
}
165+
},
186166
);
187-
const [message, setMessage] = React.useState('');
167+
const [message, setMessage] = React.useState("");
188168
189169
const [mounted, setMounted] = React.useState(false);
190170
const loggerRef = React.useRef(null);
@@ -196,7 +176,7 @@ export const ChatDialogExample = `const ChatDialog = () => {
196176
197177
React.useEffect(() => {
198178
if (!mounted || !loggerRef.current) return;
199-
scrollerRef.current?.scrollTo({top: loggerRef.current.scrollHeight, behavior: 'smooth'});
179+
scrollerRef.current?.scrollTo({ top: loggerRef.current.scrollHeight, behavior: "smooth" });
200180
}, [chats, mounted]);
201181
202182
const handleComposerChange = (editorState) => {
@@ -207,10 +187,12 @@ export const ChatDialogExample = `const ChatDialog = () => {
207187
};
208188
209189
const submitMessage = () => {
210-
if (message === '') return;
190+
if (message === "") return;
211191
push(createNewMessage(message));
212192
};
213193
194+
const editorInstanceRef = React.useRef<LexicalEditor>(null);
195+
214196
return (
215197
<Box>
216198
<Box ref={scrollerRef} overflowX="hidden" overflowY="auto" maxHeight="size50" tabIndex={0}>
@@ -221,31 +203,148 @@ export const ChatDialogExample = `const ChatDialog = () => {
221203
borderWidth="borderWidth0"
222204
borderTopWidth="borderWidth10"
223205
borderColor="colorBorderWeak"
224-
display="flex"
225-
flexDirection="row"
226206
columnGap="space30"
227207
paddingX="space70"
228208
paddingTop="space50"
229209
>
230-
<ChatComposer
231-
maxHeight="size10"
232-
config={{
233-
namespace: 'foo',
234-
onError: (error) => {
235-
throw error;
236-
},
237-
}}
238-
ariaLabel="Message"
239-
placeholder="Type here..."
240-
onChange={handleComposerChange}
241-
>
242-
<ClearEditorPlugin />
243-
<SendButtonPlugin onClick={submitMessage} />
244-
<EnterKeySubmitPlugin onKeyDown={submitMessage} />
245-
</ChatComposer>
210+
<ChatComposerContainer>
211+
<ChatComposer
212+
maxHeight="size10"
213+
config={{
214+
namespace: "foo",
215+
onError: (error) => {
216+
throw error;
217+
},
218+
}}
219+
ariaLabel="Message"
220+
placeholder="Type here..."
221+
onChange={handleComposerChange}
222+
editorInstanceRef={editorInstanceRef}
223+
>
224+
<ClearEditorPlugin />
225+
<EnterKeySubmitPlugin onKeyDown={submitMessage} />
226+
</ChatComposer>
227+
<ChatComposerActionGroup>
228+
<Button variant="secondary_icon" size="reset">
229+
<AttachIcon decorative={false} title="attach files to the message" />
230+
</Button>
231+
<Button
232+
variant="primary_icon"
233+
size="reset"
234+
onClick={() => {
235+
submitMessage();
236+
editorInstanceRef.current?.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined);
237+
}}
238+
>
239+
<SendIcon decorative={false} title="Send" />
240+
</Button>
241+
</ChatComposerActionGroup>
242+
</ChatComposerContainer>
246243
</Box>
247244
</Box>
248245
);
249246
};
250247
251248
render(<ChatDialog />)`.trim();
249+
250+
export const ResponsiveContainedAttachmentsExample = `const ResponsiveContainedAttachmentsExample = () => {
251+
const ExampleAttachment = () => (
252+
<ChatComposerAttachmentCard onDismiss={() => {}} attachmentIcon={<DownloadIcon decorative />}>
253+
<ChatComposerAttachmentLink href="www.google.com">Document-FINAL.doc</ChatComposerAttachmentLink>
254+
<ChatComposerAttachmentDescription>123 MB</ChatComposerAttachmentDescription>
255+
</ChatComposerAttachmentCard>
256+
)
257+
258+
return (
259+
<ChatComposerContainer>
260+
<ChatComposer
261+
ariaLabel="A chat with attachments"
262+
initialValue="This is my initial value"
263+
config={{
264+
namespace: "customer-chat",
265+
onError: (e) => {
266+
throw e;
267+
},
268+
}}
269+
/>
270+
<ChatComposerActionGroup>
271+
<Button variant="secondary_icon" size="reset">
272+
<AttachIcon decorative={false} title="attach files to the message" />
273+
</Button>
274+
<Button variant="primary_icon" size="reset">
275+
<SendIcon decorative={false} title="Send" />
276+
</Button>
277+
</ChatComposerActionGroup>
278+
<ChatComposerAttachmentGroup columns={[1, 1, 2, 3]}>
279+
{Array.from({ length: 6 }).map((_, index) => (
280+
<ExampleAttachment key={index} />
281+
))}
282+
</ChatComposerAttachmentGroup>
283+
</ChatComposerContainer>
284+
)
285+
}
286+
287+
render(<ResponsiveContainedAttachmentsExample />)`.trim();
288+
289+
export const ContainedDisabledExample = `const ContainedDisabledExample = () => {
290+
const [isDisabled, setIsDisabled] = React.useState(true);
291+
return (
292+
<>
293+
<Box marginBottom="space50">
294+
<Checkbox checked={isDisabled} onClick={() => setIsDisabled((disabled) => !disabled)}>
295+
Disable Input
296+
</Checkbox>
297+
</Box>
298+
<ChatComposerContainer variant="contained">
299+
<ChatComposer
300+
ariaLabel="A chat that is disabled"
301+
initialValue="This is my initial value"
302+
config={{
303+
namespace: "customer-chat",
304+
onError: (e) => {
305+
throw e;
306+
},
307+
}}
308+
disabled={isDisabled}
309+
/>
310+
<ChatComposerActionGroup>
311+
<Button variant="secondary_icon" size="reset" aria-disabled={isDisabled} disabled={isDisabled}>
312+
<AttachIcon decorative={false} title="attach files to the message" />
313+
</Button>
314+
<Button variant="primary_icon" size="reset" aria-disabled={isDisabled} disabled={isDisabled}>
315+
<SendIcon decorative={false} title="Send" />
316+
</Button>
317+
</ChatComposerActionGroup>
318+
</ChatComposerContainer>
319+
</>
320+
);
321+
}
322+
323+
render(<ContainedDisabledExample />)`.trim();
324+
325+
export const ContainedExample = `const ContainedExample = () => {
326+
return (
327+
<ChatComposerContainer variant="contained">
328+
<ChatComposer
329+
ariaLabel="A chat with attachments"
330+
initialValue="This is my initial value"
331+
config={{
332+
namespace: "customer-chat",
333+
onError: (e) => {
334+
throw e;
335+
},
336+
}}
337+
/>
338+
<ChatComposerActionGroup>
339+
<Button variant="secondary_icon" size="reset">
340+
<AttachIcon decorative={false} title="attach files to the message" />
341+
</Button>
342+
<Button variant="primary_icon" size="reset">
343+
<SendIcon decorative={false} title="Send" />
344+
</Button>
345+
</ChatComposerActionGroup>
346+
</ChatComposerContainer>
347+
);
348+
}
349+
350+
render(<ContainedExample />)`.trim();

packages/paste-website/src/pages/components/ai-chat-log/api.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ export const getStaticProps = async () => {
2424
data: {
2525
...packageJson,
2626
...feature,
27+
nameOverride: 'AI Chat Log',
2728
},
2829
componentApi,
2930
mdxHeadings: [...mdxHeadings, ...componentApiTocData],
3031
navigationData,
3132
pageHeaderData: {
3233
categoryRoute: SidebarCategoryRoutes.COMPONENTS,
3334
githubUrl: "https://github.com/twilio-labs/paste/tree/main/packages/paste-core/components/ai-chat-log",
34-
storybookUrl: "/?path=/story/components-chatlog--example-chat-log",
35+
storybookUrl: "/?path=/story/components-ai-chat-log--example-ai-chat-log",
3536
},
3637
},
3738
};

0 commit comments

Comments
 (0)