Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Chat bubble #21

Merged
merged 39 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2cdbad5
feat: First iteration prototype of chat bubbles
cansuaa Aug 22, 2024
a8d871a
Merge branch 'main' into cansua/chat-bubble
cansuaa Aug 22, 2024
c802a34
chore: Update simple page and add bubble settings
cansuaa Aug 23, 2024
aea4084
chore: Add test util and test
cansuaa Aug 23, 2024
05d5200
fix: Chat bubble grey backgroundcolor
cansuaa Sep 6, 2024
cc65e30
add checkbox to set role to log
cansuaa Sep 9, 2024
528a147
fix: test
cansuaa Sep 9, 2024
0d2ca9d
update documenter
cansuaa Sep 9, 2024
6f497d9
fix documenter snapshot
cansuaa Sep 9, 2024
bd3d30a
add checkbox to focus on container
cansuaa Sep 11, 2024
cecff30
Add checkbox to focus on bubble
cansuaa Sep 11, 2024
80914bf
add loading bar
cansuaa Sep 12, 2024
fad0b26
update documenter
cansuaa Sep 12, 2024
4153e69
make container focus default
cansuaa Sep 12, 2024
7671225
update test
cansuaa Sep 12, 2024
ecd39ee
a11y suggestions and design sign-off changes
cansuaa Sep 23, 2024
6773d71
updated API
cansuaa Sep 27, 2024
17a9a43
update API and implementation
cansuaa Oct 4, 2024
1bac315
comment out code view in dev page and add chat bubble export
cansuaa Oct 7, 2024
ced9e0c
fix styles import in test
cansuaa Oct 7, 2024
19e5591
remove code-view from package.json
cansuaa Oct 7, 2024
a2a3799
update api and documenter
cansuaa Oct 7, 2024
e10c5da
update chat bubble test
cansuaa Oct 7, 2024
a563c91
update tests
cansuaa Oct 7, 2024
85507f9
address comments and change 'type' values
cansuaa Oct 14, 2024
c4a9dcb
fix test util function
cansuaa Oct 14, 2024
632f98c
Merge branch 'main' into cansua/chat-bubble
cansuaa Oct 14, 2024
be10e1d
add with-updates page
cansuaa Oct 14, 2024
f047801
update with-updates page
cansuaa Oct 14, 2024
1942d8b
use design tokens for spacing
cansuaa Oct 16, 2024
4a1445e
add temporary dark mode background color
cansuaa Oct 16, 2024
0adda07
use chat bubble design tokens
cansuaa Oct 18, 2024
cdd720d
address comments
cansuaa Oct 18, 2024
68ab393
update avatat API description
cansuaa Oct 18, 2024
c965849
move loading bar to bottom and remove cleanup from tests
cansuaa Oct 23, 2024
67dabb0
change inert implementation
cansuaa Oct 23, 2024
b51456c
fix test after inert change
cansuaa Oct 23, 2024
3b7904b
change isGeneratingContent to showLoadingBar API
cansuaa Oct 24, 2024
27cf2f6
update API descriptions to add links
cansuaa Oct 24, 2024
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"exports": {
".": "./index.js",
"./avatar": "./avatar/index.js",
"./chat-bubble": "./chat-bubble/index.js",
"./loading-bar": "./loading-bar/index.js",
"./test-utils/dom": "./test-utils/dom/index.js",
"./test-utils/selectors": "./test-utils/selectors/index.js",
Expand Down
242 changes: 242 additions & 0 deletions pages/chat-bubble/content-variants.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import BarChart from "@cloudscape-design/components/bar-chart";
import Box from "@cloudscape-design/components/box";
import ExpandableSection from "@cloudscape-design/components/expandable-section";
import Link from "@cloudscape-design/components/link";
import Steps from "@cloudscape-design/components/steps";
import Table, { TableProps } from "@cloudscape-design/components/table";

import { ChatBubble } from "../../lib/components";
import { Actions, ChatBubbleAvatarGenAI, ChatContainer } from "./util-components";

export default function ChatBubblesContentVariantsPage() {
return (
<>
<h1>Content variants in chat bubble</h1>

<ChatContainer>
<GenAIChatBubble>
Expandable section and list
<ol>
<li>In the Buckets list, choose the name of the bucket that you want.</li>
<li>Choose Properties.</li>
<li>Navigate to S3.</li>
</ol>
<ExpandableSection headerText="Sources" defaultExpanded={true}>
<div>
<Link href="https://cloudscape.aws.dev/components/link?tabId=playground&example=external-link">
Example link
</Link>
</div>
<div>
<Link href="https://cloudscape.aws.dev/components/link?tabId=playground&example=external-link">
Example link 2
</Link>
</div>
</ExpandableSection>
</GenAIChatBubble>

<GenAIChatBubble>
<span>Table with default variant</span>

<ChatBubbleTable />
</GenAIChatBubble>

<GenAIChatBubble>
<span>Bar chart</span>

<ChatBubbleChart />
</GenAIChatBubble>

<GenAIChatBubble>
<span>Steps</span>

<Steps
steps={[
{ status: "success", header: "Success step" },
{ status: "info", header: "Info step" },
{ status: "warning", header: "Warning step" },
{ status: "error", header: "Error step" },
{ status: "loading", header: "Loading step" },
{ status: "in-progress", header: "In progress step" },
{ status: "pending", header: "Pending step" },
{ status: "stopped", header: "Stopped step" },
]}
/>
</GenAIChatBubble>
</ChatContainer>
</>
);
}

function GenAIChatBubble({ children }: { children: React.ReactNode }) {
return (
<ChatBubble avatar={<ChatBubbleAvatarGenAI />} type="incoming" actions={<Actions />} ariaLabel="Message">
{children}
</ChatBubble>
);
}

function ChatBubbleTable({ variant }: { variant?: TableProps.Variant }) {
return (
<Table
variant={variant}
renderAriaLive={({ firstIndex, lastIndex, totalItemsCount }) =>
`Displaying items ${firstIndex} to ${lastIndex} of ${totalItemsCount}`
}
columnDefinitions={[
{
id: "variable",
header: "Variable name",
cell: (item) => <Link href="#">{item.name || "-"}</Link>,
isRowHeader: true,
},
{
id: "alt",
header: "Text value",
cell: (item) => item.alt || "-",
},
{
id: "description",
header: "Description",
cell: (item) => item.description || "-",
},
]}
enableKeyboardNavigation={true}
items={[
{
name: "Item 1",
alt: "First",
description: "This is the first item",
type: "1A",
size: "Small",
},
{
name: "Item 2",
alt: "Second",
description: "This is the second item",
type: "1B",
size: "Large",
},
{
name: "Item 3",
alt: "Third",
description: "-",
type: "1A",
size: "Large",
},
{
name: "Item 4",
alt: "Fourth",
description: "This is the fourth item",
type: "2A",
size: "Small",
},
{
name: "Item 5",
alt: "-",
description: "This is the fifth item with a longer description",
type: "2A",
size: "Large",
},
{
name: "Item 6",
alt: "Sixth",
description: "This is the sixth item",
type: "1A",
size: "Small",
},
]}
sortingDisabled={true}
/>
);
}

function ChatBubbleChart() {
return (
<BarChart
series={[
{
title: "Site 1",
type: "bar",
data: [
{ x: new Date(1601071200000), y: 34503 },
{ x: new Date(1601078400000), y: 25832 },
{ x: new Date(1601085600000), y: 4012 },
{ x: new Date(1601092800000), y: -5602 },
{ x: new Date(1601100000000), y: 17839 },
],
valueFormatter: (e) =>
"$" +
e.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
},
{
title: "Average revenue",
type: "threshold",
y: 19104,
valueFormatter: (e) =>
"$" +
e.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
},
]}
xDomain={[
new Date(1601071200000),
new Date(1601078400000),
new Date(1601085600000),
new Date(1601092800000),
new Date(1601100000000),
]}
yDomain={[-10000, 40000]}
i18nStrings={{
xTickFormatter: (e) =>
e
.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: !1,
})
.split(",")
.join("\n"),
yTickFormatter: function s(e) {
return Math.abs(e) >= 1e9
? (e / 1e9).toFixed(1).replace(/\.0$/, "") + "G"
: Math.abs(e) >= 1e6
? (e / 1e6).toFixed(1).replace(/\.0$/, "") + "M"
: Math.abs(e) >= 1e3
? (e / 1e3).toFixed(1).replace(/\.0$/, "") + "K"
: e.toFixed(2);
},
}}
ariaLabel="Bar chart"
height={300}
xTitle="Time (UTC)"
yTitle="Revenue (USD)"
empty={
<Box textAlign="center" color="inherit">
<b>No data available</b>
<Box variant="p" color="inherit">
There is no data available
</Box>
</Box>
}
noMatch={
<Box textAlign="center" color="inherit">
<b>No matching data</b>
<Box variant="p" color="inherit">
There is no matching data to display
</Box>
</Box>
}
/>
);
}
70 changes: 70 additions & 0 deletions pages/chat-bubble/simple.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import Box from "@cloudscape-design/components/box";

import { ChatBubble } from "../../lib/components";
import { TestBed } from "../app/test-bed";
import { ScreenshotArea } from "../screenshot-area";
import { Actions, ChatBubbleAvatarGenAI, ChatBubbleAvatarUser, ChatContainer, longText } from "./util-components";

export default function ChatBubblePage() {
return (
<ScreenshotArea>
<h1>Chat bubble</h1>

<TestBed>
<ChatContainer>
<ChatBubble type="outgoing" avatar={<ChatBubbleAvatarUser />} ariaLabel="User at 4:23:20pm">
What can I do with Amazon S3?
</ChatBubble>
<ChatBubble avatar={<ChatBubbleAvatarGenAI />} type="incoming" ariaLabel="Gen AI at at 4:23:23pm">
Amazon S3 provides a simple web service interface that you can use to store and retrieve any amount of data,
at any time, from anywhere.
</ChatBubble>

<ChatBubble type="outgoing" avatar={<ChatBubbleAvatarUser />} ariaLabel="User at 4:25:00pm">
Long text. {longText}
</ChatBubble>

<ChatBubble
avatar={<ChatBubbleAvatarGenAI />}
type="incoming"
actions={<Actions />}
ariaLabel="Gen AI at 4:25:05pm"
>
Long text. {longText}
</ChatBubble>
<ChatBubble
avatar={<ChatBubbleAvatarGenAI />}
type="incoming"
actions={<Actions />}
ariaLabel="Gen AI at 4:25:07pm"
hideAvatar={true}
>
Second consecutive message coming from the same author, avatar is hidden.
</ChatBubble>

<ChatBubble
avatar={<ChatBubbleAvatarGenAI loading={true} />}
type="incoming"
isGeneratingContent={true}
ariaLabel="Gen AI at 4:24:24pm"
>
<Box color="text-body-secondary">Generating a response (using Box)</Box>
</ChatBubble>

<ChatBubble
avatar={<ChatBubbleAvatarGenAI loading={true} />}
type="incoming"
isGeneratingContent={true}
actions={<Actions />}
ariaLabel="Gen AI at 4:24:25pm"
>
Generating a response with actions
</ChatBubble>
</ChatContainer>
</TestBed>
</ScreenshotArea>
);
}
Loading
Loading