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;
flex-direction: row;
gap: 8px;
padding-bottom: 10px;
`
export default Artifacts

View File

@ -98,12 +98,20 @@ const CodeBlock: React.FC<CodeBlockProps> = ({ children, className }) => {
)}
<CodeLanguage>{'<' + language.toUpperCase() + '>'}</CodeLanguage>
</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} />}
{codeWrappable && <UnwrapButton unwrapped={isUnwrapped} onClick={() => setIsUnwrapped(!isUnwrapped)} />}
<CopyButton text={children} />
</HStack>
</CodeHeader>
</StickyWrapper>
<CodeContent
ref={codeContentRef}
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 }>`
.shiki {
@ -376,4 +386,10 @@ const DownloadWrapper = styled.div`
}
`
const StickyWrapper = styled.div`
position: sticky;
top: 28px;
z-index: 10;
`
export default memo(CodeBlock)

View File

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

View File

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

View File

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

View File

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