mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 15:31:48 +00:00
cody-ui chat refactors (#50682)
No behavior change. - extract cody-ui ChatMessages and add storybook - split apart cody-ui ChatMessages component - remove duplicate cody vscode CSS vars
This commit is contained in:
parent
df74999810
commit
476ca9e63d
5
client/cody-ui/BUILD.bazel
generated
5
client/cody-ui/BUILD.bazel
generated
@ -27,6 +27,10 @@ ts_project(
|
||||
"src/Chat.tsx",
|
||||
"src/Terms.tsx",
|
||||
"src/Tips.tsx",
|
||||
"src/chat/ChatMessageLoading.tsx",
|
||||
"src/chat/ChatMessageRow.tsx",
|
||||
"src/chat/ChatMessages.story.tsx",
|
||||
"src/chat/ChatMessages.tsx",
|
||||
"src/chat/CodeBlocks.tsx",
|
||||
"src/chat/ContextFiles.tsx",
|
||||
"src/globals.d.ts",
|
||||
@ -43,6 +47,7 @@ ts_project(
|
||||
deps = [
|
||||
":node_modules/@sourcegraph/cody-shared",
|
||||
"//:node_modules/@mdi/js",
|
||||
"//:node_modules/@storybook/react", #keep
|
||||
"//:node_modules/@types/classnames",
|
||||
"//:node_modules/@types/react",
|
||||
"//:node_modules/classnames",
|
||||
|
||||
@ -15,7 +15,8 @@
|
||||
"build": "tsc -b",
|
||||
"lint": "pnpm run lint:js",
|
||||
"lint:js": "eslint --cache '**/*.[tj]s?(x)'",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"storybook": "STORIES_GLOB='client/cody-ui/src/**/*.story.tsx' pnpm --filter @sourcegraph/storybook run start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sourcegraph/cody-shared": "workspace:*"
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
:root {
|
||||
--chat-bubble-border-radius: 16px;
|
||||
}
|
||||
|
||||
.inner-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -12,102 +8,6 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bubble-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bubble-row {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.human-bubble-row {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.bot-bubble-row {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
min-width: 0;
|
||||
max-width: min(93%, 800px);
|
||||
}
|
||||
|
||||
.bubble-content {
|
||||
padding: 1rem;
|
||||
border-top-right-radius: var(--chat-bubble-border-radius);
|
||||
border-top-left-radius: var(--chat-bubble-border-radius);
|
||||
word-break: break-word;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.bubble-content *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.bubble-content *:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.bubble-content pre {
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.human-bubble-content {
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: var(--chat-bubble-border-radius);
|
||||
}
|
||||
|
||||
.bot-bubble-content {
|
||||
border-bottom-right-radius: var(--chat-bubble-border-radius);
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.bubble-footer {
|
||||
display: flex;
|
||||
margin-top: 0.5rem;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.human-bubble-footer {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.bubble-footer-timestamp {
|
||||
margin-top: 0.5rem;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.bubble-loader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.bubble-loader-dot {
|
||||
animation: 1s blink infinite;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.bubble-loader-dot:nth-child(2) {
|
||||
animation-delay: 250ms;
|
||||
}
|
||||
|
||||
.bubble-loader-dot:nth-child(3) {
|
||||
animation-delay: 500ms;
|
||||
}
|
||||
|
||||
.input-row {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
|
||||
@ -2,11 +2,10 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { renderMarkdown } from '@sourcegraph/cody-shared/src/chat/markdown'
|
||||
import { ChatMessage } from '@sourcegraph/cody-shared/src/chat/transcript/messages'
|
||||
|
||||
import { CodeBlocks } from './chat/CodeBlocks'
|
||||
import { ContextFiles, FileLinkProps } from './chat/ContextFiles'
|
||||
import { ChatMessages, ChatMessagesClassNames } from './chat/ChatMessages'
|
||||
import { FileLinkProps } from './chat/ContextFiles'
|
||||
import { Tips } from './Tips'
|
||||
|
||||
import styles from './Chat.module.css'
|
||||
@ -28,16 +27,8 @@ interface ChatProps extends ChatClassNames {
|
||||
className?: string
|
||||
}
|
||||
|
||||
interface ChatClassNames {
|
||||
interface ChatClassNames extends ChatMessagesClassNames {
|
||||
transcriptContainerClassName?: string
|
||||
bubbleContentClassName?: string
|
||||
bubbleClassName?: string
|
||||
bubbleRowClassName?: string
|
||||
humanBubbleContentClassName?: string
|
||||
botBubbleContentClassName?: string
|
||||
codeBlocksCopyButtonClassName?: string
|
||||
bubbleFooterClassName?: string
|
||||
bubbleLoaderDotClassName?: string
|
||||
inputRowClassName?: string
|
||||
chatInputClassName?: string
|
||||
}
|
||||
@ -141,8 +132,6 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
|
||||
[inputHistory, onChatSubmit, formInput, historyIndex, setFormInput]
|
||||
)
|
||||
|
||||
const getBubbleClassName = (speaker: string): string => (speaker === 'human' ? 'human' : 'bot')
|
||||
|
||||
useEffect(() => {
|
||||
if (transcriptContainerRef.current) {
|
||||
// Only scroll if the user didn't scroll up manually more than the scrolling threshold.
|
||||
@ -172,103 +161,19 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
|
||||
<Tips recommendations={tipsRecommendations} after={afterTips} />
|
||||
)}
|
||||
{transcript.length > 0 && (
|
||||
<div className={styles.bubbleContainer}>
|
||||
{transcript.map((message, index) => (
|
||||
<div
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
key={`message-${index}`}
|
||||
className={classNames(
|
||||
styles.bubbleRow,
|
||||
bubbleRowClassName,
|
||||
styles[`${getBubbleClassName(message.speaker)}BubbleRow`]
|
||||
)}
|
||||
>
|
||||
<div className={classNames(styles.bubble, bubbleClassName)}>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleContent,
|
||||
styles[`${getBubbleClassName(message.speaker)}BubbleContent`],
|
||||
bubbleContentClassName,
|
||||
message.speaker === 'human'
|
||||
? humanBubbleContentClassName
|
||||
: botBubbleContentClassName
|
||||
)}
|
||||
>
|
||||
{message.displayText && (
|
||||
<CodeBlocks
|
||||
displayText={message.displayText}
|
||||
copyButtonClassName={codeBlocksCopyButtonClassName}
|
||||
/>
|
||||
)}
|
||||
{message.contextFiles && message.contextFiles.length > 0 && (
|
||||
<ContextFiles
|
||||
contextFiles={message.contextFiles}
|
||||
fileLinkComponent={fileLinkComponent}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleFooter,
|
||||
styles[`${getBubbleClassName(message.speaker)}BubbleFooter`],
|
||||
bubbleFooterClassName
|
||||
)}
|
||||
>
|
||||
<div className={styles.bubbleFooterTimestamp}>{`${
|
||||
message.speaker === 'assistant' ? 'Cody' : 'Me'
|
||||
} · ${message.timestamp}`}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{messageInProgress && messageInProgress.speaker === 'assistant' && (
|
||||
<div className={classNames(styles.bubbleRow, styles.botBubbleRow)}>
|
||||
<div className={styles.bubble}>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleContent,
|
||||
styles.botBubbleContent,
|
||||
bubbleContentClassName,
|
||||
botBubbleContentClassName
|
||||
)}
|
||||
>
|
||||
{messageInProgress.displayText ? (
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: renderMarkdown(messageInProgress.displayText),
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className={styles.bubbleLoader}>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleLoaderDot,
|
||||
bubbleLoaderDotClassName
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleLoaderDot,
|
||||
bubbleLoaderDotClassName
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleLoaderDot,
|
||||
bubbleLoaderDotClassName
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.bubbleFooter}>
|
||||
<span>Cody is typing...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ChatMessages
|
||||
messageInProgress={messageInProgress}
|
||||
transcript={transcript}
|
||||
fileLinkComponent={fileLinkComponent}
|
||||
bubbleContentClassName={bubbleContentClassName}
|
||||
bubbleClassName={bubbleClassName}
|
||||
bubbleRowClassName={bubbleRowClassName}
|
||||
humanBubbleContentClassName={humanBubbleContentClassName}
|
||||
botBubbleContentClassName={botBubbleContentClassName}
|
||||
codeBlocksCopyButtonClassName={codeBlocksCopyButtonClassName}
|
||||
bubbleFooterClassName={bubbleFooterClassName}
|
||||
bubbleLoaderDotClassName={bubbleLoaderDotClassName}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
25
client/cody-ui/src/chat/ChatMessageLoading.module.css
Normal file
25
client/cody-ui/src/chat/ChatMessageLoading.module.css
Normal file
@ -0,0 +1,25 @@
|
||||
@keyframes blink {
|
||||
50% {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.bubble-loader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.bubble-loader-dot {
|
||||
animation: 1s blink infinite;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.bubble-loader-dot:nth-child(2) {
|
||||
animation-delay: 250ms;
|
||||
}
|
||||
|
||||
.bubble-loader-dot:nth-child(3) {
|
||||
animation-delay: 500ms;
|
||||
}
|
||||
15
client/cody-ui/src/chat/ChatMessageLoading.tsx
Normal file
15
client/cody-ui/src/chat/ChatMessageLoading.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
|
||||
import classNames from 'classnames'
|
||||
|
||||
import styles from './ChatMessageLoading.module.css'
|
||||
|
||||
export const ChatMessageLoading: React.FunctionComponent<{ bubbleLoaderDotClassName?: string }> = ({
|
||||
bubbleLoaderDotClassName,
|
||||
}) => (
|
||||
<div className={styles.bubbleLoader}>
|
||||
<div className={classNames(styles.bubbleLoaderDot, bubbleLoaderDotClassName)} />
|
||||
<div className={classNames(styles.bubbleLoaderDot, bubbleLoaderDotClassName)} />
|
||||
<div className={classNames(styles.bubbleLoaderDot, bubbleLoaderDotClassName)} />
|
||||
</div>
|
||||
)
|
||||
69
client/cody-ui/src/chat/ChatMessageRow.module.css
Normal file
69
client/cody-ui/src/chat/ChatMessageRow.module.css
Normal file
@ -0,0 +1,69 @@
|
||||
:root {
|
||||
--chat-bubble-border-radius: 16px;
|
||||
}
|
||||
|
||||
.bubble-row {
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.human-bubble-row {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.bot-bubble-row {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
min-width: 0;
|
||||
max-width: min(93%, 800px);
|
||||
}
|
||||
|
||||
.bubble-content {
|
||||
padding: 1rem;
|
||||
border-top-right-radius: var(--chat-bubble-border-radius);
|
||||
border-top-left-radius: var(--chat-bubble-border-radius);
|
||||
word-break: break-word;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.bubble-content *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.bubble-content *:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.bubble-content pre {
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.human-bubble-content {
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: var(--chat-bubble-border-radius);
|
||||
}
|
||||
|
||||
.bot-bubble-content {
|
||||
border-bottom-right-radius: var(--chat-bubble-border-radius);
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.bubble-footer {
|
||||
display: flex;
|
||||
margin-top: 0.5rem;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.human-bubble-footer {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.bubble-footer-timestamp {
|
||||
margin-top: 0.5rem;
|
||||
align-self: center;
|
||||
}
|
||||
99
client/cody-ui/src/chat/ChatMessageRow.tsx
Normal file
99
client/cody-ui/src/chat/ChatMessageRow.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import React from 'react'
|
||||
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { ChatMessage } from '@sourcegraph/cody-shared/src/chat/transcript/messages'
|
||||
|
||||
import { ChatMessageLoading } from './ChatMessageLoading'
|
||||
import { CodeBlocks } from './CodeBlocks'
|
||||
import { ContextFiles, FileLinkProps } from './ContextFiles'
|
||||
|
||||
import styles from './ChatMessageRow.module.css'
|
||||
|
||||
export interface ChatMessageRowClassNames {
|
||||
bubbleContentClassName?: string
|
||||
bubbleClassName?: string
|
||||
bubbleRowClassName?: string
|
||||
humanBubbleContentClassName?: string
|
||||
botBubbleContentClassName?: string
|
||||
codeBlocksCopyButtonClassName?: string
|
||||
bubbleFooterClassName?: string
|
||||
bubbleLoaderDotClassName?: string
|
||||
}
|
||||
|
||||
export const ChatMessageRow: React.FunctionComponent<
|
||||
{
|
||||
message: ChatMessage
|
||||
inProgress: boolean
|
||||
fileLinkComponent: React.FunctionComponent<FileLinkProps>
|
||||
className?: string
|
||||
} & ChatMessageRowClassNames
|
||||
> = ({
|
||||
message,
|
||||
inProgress,
|
||||
fileLinkComponent,
|
||||
className,
|
||||
bubbleContentClassName,
|
||||
bubbleClassName,
|
||||
bubbleRowClassName,
|
||||
humanBubbleContentClassName,
|
||||
botBubbleContentClassName,
|
||||
codeBlocksCopyButtonClassName,
|
||||
bubbleFooterClassName,
|
||||
bubbleLoaderDotClassName,
|
||||
}) => {
|
||||
const classNamePrefix = message.speaker === 'human' ? 'human' : 'bot'
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
className,
|
||||
styles.bubbleRow,
|
||||
bubbleRowClassName,
|
||||
styles[`${classNamePrefix}BubbleRow`]
|
||||
)}
|
||||
>
|
||||
<div className={classNames(styles.bubble, bubbleClassName)}>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleContent,
|
||||
styles[`${classNamePrefix}BubbleContent`],
|
||||
bubbleContentClassName,
|
||||
message.speaker === 'human' ? humanBubbleContentClassName : botBubbleContentClassName
|
||||
)}
|
||||
>
|
||||
{message.displayText ? (
|
||||
<>
|
||||
<CodeBlocks
|
||||
displayText={message.displayText}
|
||||
copyButtonClassName={codeBlocksCopyButtonClassName}
|
||||
/>
|
||||
{message.contextFiles && message.contextFiles.length > 0 && (
|
||||
<ContextFiles
|
||||
contextFiles={message.contextFiles}
|
||||
fileLinkComponent={fileLinkComponent}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : inProgress ? (
|
||||
<ChatMessageLoading bubbleLoaderDotClassName={bubbleLoaderDotClassName} />
|
||||
) : null}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
styles.bubbleFooter,
|
||||
styles[`${classNamePrefix}BubbleFooter`],
|
||||
bubbleFooterClassName
|
||||
)}
|
||||
>
|
||||
{inProgress ? (
|
||||
<span>Cody is typing...</span>
|
||||
) : (
|
||||
<div className={styles.bubbleFooterTimestamp}>{`${
|
||||
message.speaker === 'assistant' ? 'Cody' : 'Me'
|
||||
} · ${message.timestamp}`}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
45
client/cody-ui/src/chat/ChatMessages.story.tsx
Normal file
45
client/cody-ui/src/chat/ChatMessages.story.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import { Meta, Story } from '@storybook/react'
|
||||
|
||||
import { ChatMessage } from '@sourcegraph/cody-shared/src/chat/transcript/messages'
|
||||
|
||||
import { ChatMessages } from './ChatMessages'
|
||||
import { FileLinkProps } from './ContextFiles'
|
||||
|
||||
import styles from '../../../cody-web/src/Chat.module.css'
|
||||
|
||||
const config: Meta = {
|
||||
title: 'cody-ui/ChatMessages',
|
||||
component: ChatMessages,
|
||||
|
||||
decorators: [story => <div className="container mt-3 pb-3">{story()}</div>],
|
||||
|
||||
parameters: {
|
||||
component: ChatMessages,
|
||||
chromatic: {
|
||||
enableDarkMode: true,
|
||||
disableSnapshot: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
const FIXTURE_TRANSCRIPT: ChatMessage[] = [
|
||||
{ speaker: 'human', text: 'Hello, world!', displayText: 'Hello, world!', timestamp: '2 min ago' },
|
||||
{ speaker: 'assistant', text: 'Thank you', displayText: 'Thank you', timestamp: 'now' },
|
||||
]
|
||||
|
||||
export const Simple: Story = () => (
|
||||
<ChatMessages
|
||||
messageInProgress={null}
|
||||
transcript={FIXTURE_TRANSCRIPT}
|
||||
fileLinkComponent={FileLink}
|
||||
bubbleContentClassName={styles.bubbleContent}
|
||||
humanBubbleContentClassName={styles.humanBubbleContent}
|
||||
botBubbleContentClassName={styles.botBubbleContent}
|
||||
bubbleFooterClassName={styles.bubbleFooter}
|
||||
bubbleLoaderDotClassName={styles.bubbleLoaderDot}
|
||||
/>
|
||||
)
|
||||
|
||||
const FileLink: React.FunctionComponent<FileLinkProps> = ({ path }) => <>{path}</>
|
||||
65
client/cody-ui/src/chat/ChatMessages.tsx
Normal file
65
client/cody-ui/src/chat/ChatMessages.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React from 'react'
|
||||
|
||||
import { ChatMessage } from '@sourcegraph/cody-shared/src/chat/transcript/messages'
|
||||
|
||||
import { ChatMessageRow, ChatMessageRowClassNames } from './ChatMessageRow'
|
||||
import { FileLinkProps } from './ContextFiles'
|
||||
|
||||
export interface ChatMessagesClassNames extends ChatMessageRowClassNames {}
|
||||
|
||||
export const ChatMessages: React.FunctionComponent<
|
||||
{
|
||||
messageInProgress: ChatMessage | null
|
||||
transcript: ChatMessage[]
|
||||
fileLinkComponent: React.FunctionComponent<FileLinkProps>
|
||||
className?: string
|
||||
} & ChatMessagesClassNames
|
||||
> = ({
|
||||
messageInProgress,
|
||||
transcript,
|
||||
fileLinkComponent,
|
||||
className,
|
||||
bubbleContentClassName,
|
||||
bubbleClassName,
|
||||
bubbleRowClassName,
|
||||
humanBubbleContentClassName,
|
||||
botBubbleContentClassName,
|
||||
codeBlocksCopyButtonClassName,
|
||||
bubbleFooterClassName,
|
||||
bubbleLoaderDotClassName,
|
||||
}) => (
|
||||
<div className={className}>
|
||||
{transcript.map((message, index) => (
|
||||
<ChatMessageRow
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
key={index}
|
||||
message={message}
|
||||
inProgress={false}
|
||||
fileLinkComponent={fileLinkComponent}
|
||||
bubbleContentClassName={bubbleContentClassName}
|
||||
bubbleClassName={bubbleClassName}
|
||||
bubbleRowClassName={bubbleRowClassName}
|
||||
humanBubbleContentClassName={humanBubbleContentClassName}
|
||||
botBubbleContentClassName={botBubbleContentClassName}
|
||||
codeBlocksCopyButtonClassName={codeBlocksCopyButtonClassName}
|
||||
bubbleFooterClassName={bubbleFooterClassName}
|
||||
bubbleLoaderDotClassName={bubbleLoaderDotClassName}
|
||||
/>
|
||||
))}
|
||||
{messageInProgress && messageInProgress.speaker === 'assistant' && (
|
||||
<ChatMessageRow
|
||||
message={messageInProgress}
|
||||
inProgress={true}
|
||||
fileLinkComponent={fileLinkComponent}
|
||||
bubbleContentClassName={bubbleContentClassName}
|
||||
bubbleClassName={bubbleClassName}
|
||||
bubbleRowClassName={bubbleRowClassName}
|
||||
humanBubbleContentClassName={humanBubbleContentClassName}
|
||||
botBubbleContentClassName={botBubbleContentClassName}
|
||||
codeBlocksCopyButtonClassName={codeBlocksCopyButtonClassName}
|
||||
bubbleFooterClassName={bubbleFooterClassName}
|
||||
bubbleLoaderDotClassName={bubbleLoaderDotClassName}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
@ -21,9 +21,6 @@ body[data-vscode-theme-kind='vscode-light'],
|
||||
body[data-vscode-theme-kind='vscode-high-contrast-light'] {
|
||||
--human-bubble-color: var(--vscode-button-background);
|
||||
--human-text-color: var(--vscode-button-foreground);
|
||||
--bot-bubble-color: var(--vscode-input-background);
|
||||
--bubble-text-color: var(--vscode-input-foreground);
|
||||
--code-background: var(--vscode-editor-background);
|
||||
}
|
||||
|
||||
html,
|
||||
|
||||
@ -43,7 +43,7 @@ const getStoriesGlob = (): string[] => {
|
||||
// Due to an issue with constant recompiling (https://github.com/storybookjs/storybook/issues/14342)
|
||||
// we need to make the globs more specific (`(web|shared..)` also doesn't work). Once the above issue
|
||||
// is fixed, this can be removed and watched for `client/**/*.story.tsx` again.
|
||||
const directoriesWithStories = ['branded', 'browser', 'jetbrains/webview', 'shared', 'web', 'wildcard']
|
||||
const directoriesWithStories = ['branded', 'browser', 'jetbrains/webview', 'shared', 'web', 'wildcard', 'cody-ui']
|
||||
const storiesGlobs = directoriesWithStories.map(packageDirectory =>
|
||||
path.resolve(ROOT_PATH, `client/${packageDirectory}/src/**/*.story.tsx`)
|
||||
)
|
||||
@ -184,8 +184,8 @@ const config: Config = {
|
||||
})
|
||||
|
||||
config.module?.rules.unshift({
|
||||
test: /\.(sass|scss)$/,
|
||||
include: /\.module\.(sass|scss)$/,
|
||||
test: /\.(sass|scss|css)$/,
|
||||
include: /\.module\.(sass|scss|css)$/,
|
||||
exclude: storybookPath,
|
||||
use: getCSSLoaders(
|
||||
'style-loader',
|
||||
@ -206,7 +206,7 @@ const config: Config = {
|
||||
// CSS rule for external plain CSS (skip SASS and PostCSS for build perf)
|
||||
test: /\.css$/,
|
||||
// Make sure Storybook styles get handled by the Storybook config
|
||||
exclude: [storybookPath, monacoEditorPath],
|
||||
exclude: [storybookPath, monacoEditorPath, /\.module\.css$/],
|
||||
use: ['@terminus-term/to-string-loader', getBasicCSSLoader()],
|
||||
})
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user