optimize: Sticky CopyButton in CodeBlock (#4205)

This commit is contained in:
Yuzhong Zhang 2025-03-31 21:11:28 +08:00 committed by GitHub
parent a5b0480418
commit 3dc4947e26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 29 additions and 8 deletions

View File

@ -75,6 +75,7 @@ const Container = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 8px; gap: 8px;
padding-bottom: 10px;
` `
export default Artifacts export default Artifacts

View File

@ -98,12 +98,20 @@ const CodeBlock: React.FC<CodeBlockProps> = ({ children, className }) => {
)} )}
<CodeLanguage>{'<' + language.toUpperCase() + '>'}</CodeLanguage> <CodeLanguage>{'<' + language.toUpperCase() + '>'}</CodeLanguage>
</div> </div>
<HStack gap={12} alignItems="center">
</CodeHeader>
<StickyWrapper>
<HStack
position="absolute"
gap={12}
alignItems="center"
style={{ bottom: '0.2rem', right: '1rem', height: "27px" }}
>
{showDownloadButton && <DownloadButton language={language} data={children} />} {showDownloadButton && <DownloadButton language={language} data={children} />}
{codeWrappable && <UnwrapButton unwrapped={isUnwrapped} onClick={() => setIsUnwrapped(!isUnwrapped)} />} {codeWrappable && <UnwrapButton unwrapped={isUnwrapped} onClick={() => setIsUnwrapped(!isUnwrapped)} />}
<CopyButton text={children} /> <CopyButton text={children} />
</HStack> </HStack>
</CodeHeader> </StickyWrapper>
<CodeContent <CodeContent
ref={codeContentRef} ref={codeContentRef}
isShowLineNumbers={codeShowLineNumbers} isShowLineNumbers={codeShowLineNumbers}
@ -211,7 +219,9 @@ const DownloadButton = ({ language, data }: { language: string; data: string })
) )
} }
const CodeBlockWrapper = styled.div`` const CodeBlockWrapper = styled.div`
position: relative;
`
const CodeContent = styled.div<{ isShowLineNumbers: boolean; isUnwrapped: boolean; isCodeWrappable: boolean }>` const CodeContent = styled.div<{ isShowLineNumbers: boolean; isUnwrapped: boolean; isCodeWrappable: boolean }>`
.shiki { .shiki {
@ -376,4 +386,10 @@ const DownloadWrapper = styled.div`
} }
` `
const StickyWrapper = styled.div`
position: sticky;
top: 28px;
z-index: 10;
`
export default memo(CodeBlock) export default memo(CodeBlock)

View File

@ -64,7 +64,8 @@ const Markdown: FC<Props> = ({ message, citationsData }) => {
return <Link {...props} /> return <Link {...props} />
}, },
code: CodeBlock, code: CodeBlock,
img: ImagePreview img: ImagePreview,
pre: (props: any) => <pre style={{ overflow: 'visible' }} {...props} />
} as Partial<Components> } as Partial<Components>
if (messageContent.includes('<style>')) { if (messageContent.includes('<style>')) {

View File

@ -143,7 +143,7 @@ const MessageItem: FC<Props> = ({
<MessageHeader message={message} assistant={assistant} model={model} key={getModelUniqId(model)} /> <MessageHeader message={message} assistant={assistant} model={model} key={getModelUniqId(model)} />
<MessageContentContainer <MessageContentContainer
className="message-content-container" className="message-content-container"
style={{ fontFamily, fontSize, background: messageBackground }}> style={{ fontFamily, fontSize, background: messageBackground, overflowY: 'visible' }}>
<MessageErrorBoundary> <MessageErrorBoundary>
<MessageContent message={message} model={model} /> <MessageContent message={message} model={model} />
</MessageErrorBoundary> </MessageErrorBoundary>

View File

@ -286,6 +286,7 @@ const GridContainer = styled.div<{ $count: number; $layout: MultiModelMessageSty
grid-template-rows: auto; grid-template-rows: auto;
gap: 16px; gap: 16px;
`} `}
overflow-y: visible;
` `
interface MessageWrapperProps { interface MessageWrapperProps {
@ -327,14 +328,14 @@ const MessageWrapper = styled(Scrollbar)<MessageWrapperProps>`
return $layout === 'grid' && $isGrouped return $layout === 'grid' && $isGrouped
? css` ? css`
max-height: ${$isInPopover ? '50vh' : '300px'}; max-height: ${$isInPopover ? '50vh' : '300px'};
overflow-y: ${$isInPopover ? 'auto' : 'hidden'}; overflow-y: ${$isInPopover ? 'visible' : 'hidden'};
border: 0.5px solid ${$isInPopover ? 'transparent' : 'var(--color-border)'}; border: 0.5px solid ${$isInPopover ? 'transparent' : 'var(--color-border)'};
padding: 10px; padding: 10px;
border-radius: 6px; border-radius: 6px;
background-color: var(--color-background); background-color: var(--color-background);
` `
: css` : css`
overflow-y: auto; overflow-y: visible;
border-radius: 6px; border-radius: 6px;
` `
}} }}

View File

@ -256,7 +256,9 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
hasMore={hasMore} hasMore={hasMore}
loader={null} loader={null}
scrollableTarget="messages" scrollableTarget="messages"
inverse> inverse
style={{ overflow: 'visible' }}
>
<ScrollContainer> <ScrollContainer>
<LoaderContainer $loading={isLoadingMore}> <LoaderContainer $loading={isLoadingMore}>
<BeatLoader size={8} color="var(--color-text-2)" /> <BeatLoader size={8} color="var(--color-text-2)" />