Skip to content

Commit 0413d87

Browse files
author
Theodore Li
committed
Move to shared copy code button
1 parent e079c82 commit 0413d87

File tree

3 files changed

+44
-59
lines changed

3 files changed

+44
-59
lines changed

apps/sim/app/chat/components/message/components/markdown-renderer.tsx

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
import React, {
2-
type HTMLAttributes,
3-
memo,
4-
type ReactNode,
5-
useCallback,
6-
useMemo,
7-
useState,
8-
} from 'react'
1+
import React, { type HTMLAttributes, memo, type ReactNode, useMemo } from 'react'
92
import ReactMarkdown from 'react-markdown'
103
import remarkGfm from 'remark-gfm'
11-
import { Check, Copy, Tooltip } from '@/components/emcn'
4+
import { Tooltip } from '@/components/emcn'
5+
import { CopyCodeButton } from '@/components/ui/copy-code-button'
126

137
export function LinkWithPreview({ href, children }: { href: string; children: React.ReactNode }) {
148
return (
@@ -30,26 +24,6 @@ export function LinkWithPreview({ href, children }: { href: string; children: Re
3024
)
3125
}
3226

33-
function CopyCodeButton({ code }: { code: string }) {
34-
const [copied, setCopied] = useState(false)
35-
36-
const handleCopy = useCallback(() => {
37-
navigator.clipboard.writeText(code)
38-
setCopied(true)
39-
setTimeout(() => setCopied(false), 2000)
40-
}, [code])
41-
42-
return (
43-
<button
44-
type='button'
45-
onClick={handleCopy}
46-
className='flex items-center gap-1 rounded px-1.5 py-0.5 text-gray-400 text-xs transition-colors hover:bg-gray-700 hover:text-gray-200'
47-
>
48-
{copied ? <Check className='size-3.5' /> : <Copy className='size-3.5' />}
49-
</button>
50-
)
51-
}
52-
5327
const REMARK_PLUGINS = [remarkGfm]
5428

5529
function createCustomComponents(LinkComponent: typeof LinkWithPreview) {
@@ -131,6 +105,7 @@ function createCustomComponents(LinkComponent: typeof LinkWithPreview) {
131105
</span>
132106
<CopyCodeButton
133107
code={typeof codeContent === 'string' ? codeContent : String(codeContent ?? '')}
108+
className='text-gray-400 hover:bg-gray-700 hover:text-gray-200'
134109
/>
135110
</div>
136111
<pre className='overflow-x-auto p-4 font-mono text-gray-200 dark:text-gray-100'>

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
'use client'
22

3-
import {
4-
Children,
5-
type ComponentPropsWithoutRef,
6-
isValidElement,
7-
useCallback,
8-
useMemo,
9-
useState,
10-
} from 'react'
3+
import { Children, type ComponentPropsWithoutRef, isValidElement, useMemo } from 'react'
114
import ReactMarkdown from 'react-markdown'
125
import remarkGfm from 'remark-gfm'
136
import 'prismjs/components/prism-typescript'
147
import 'prismjs/components/prism-bash'
158
import 'prismjs/components/prism-css'
169
import 'prismjs/components/prism-markup'
1710
import '@/components/emcn/components/code/code.css'
18-
import { Check, Checkbox, Copy, highlight, languages } from '@/components/emcn'
11+
import { Checkbox, highlight, languages } from '@/components/emcn'
12+
import { CopyCodeButton } from '@/components/ui/copy-code-button'
1913
import { cn } from '@/lib/core/utils/cn'
2014
import {
2115
PendingTagIndicator,
@@ -50,26 +44,6 @@ function extractTextContent(node: React.ReactNode): string {
5044
return ''
5145
}
5246

53-
function CopyCodeButton({ code }: { code: string }) {
54-
const [copied, setCopied] = useState(false)
55-
56-
const handleCopy = useCallback(() => {
57-
navigator.clipboard.writeText(code)
58-
setCopied(true)
59-
setTimeout(() => setCopied(false), 2000)
60-
}, [code])
61-
62-
return (
63-
<button
64-
type='button'
65-
onClick={handleCopy}
66-
className='flex items-center gap-1 rounded px-1.5 py-0.5 text-[var(--text-tertiary)] text-xs transition-colors hover:bg-[var(--surface-4)] hover:text-[var(--text-secondary)]'
67-
>
68-
{copied ? <Check className='size-3.5' /> : <Copy className='size-3.5' />}
69-
</button>
70-
)
71-
}
72-
7347
const PROSE_CLASSES = cn(
7448
'prose prose-base dark:prose-invert max-w-none',
7549
'font-[family-name:var(--font-inter)] antialiased break-words font-[430] tracking-[0]',
@@ -154,7 +128,10 @@ const MARKDOWN_COMPONENTS: React.ComponentProps<typeof ReactMarkdown>['component
154128
<div className='not-prose my-6 overflow-hidden rounded-lg border border-[var(--divider)]'>
155129
<div className='flex items-center justify-between border-[var(--divider)] border-b bg-[var(--surface-4)] px-4 py-2 dark:bg-[var(--surface-4)]'>
156130
<span className='text-[var(--text-tertiary)] text-xs'>{language || 'code'}</span>
157-
<CopyCodeButton code={codeString} />
131+
<CopyCodeButton
132+
code={codeString}
133+
className='text-[var(--text-tertiary)] hover:bg-[var(--surface-4)] hover:text-[var(--text-secondary)]'
134+
/>
158135
</div>
159136
<div className='code-editor-theme bg-[var(--surface-5)] dark:bg-[var(--code-bg)]'>
160137
<pre
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use client'
2+
3+
import { useCallback, useState } from 'react'
4+
import { Check, Copy } from '@/components/emcn'
5+
import { cn } from '@/lib/core/utils/cn'
6+
7+
interface CopyCodeButtonProps {
8+
code: string
9+
className?: string
10+
}
11+
12+
export function CopyCodeButton({ code, className }: CopyCodeButtonProps) {
13+
const [copied, setCopied] = useState(false)
14+
15+
const handleCopy = useCallback(() => {
16+
navigator.clipboard.writeText(code)
17+
setCopied(true)
18+
setTimeout(() => setCopied(false), 2000)
19+
}, [code])
20+
21+
return (
22+
<button
23+
type='button'
24+
onClick={handleCopy}
25+
className={cn(
26+
'flex items-center gap-1 rounded px-1.5 py-0.5 text-xs transition-colors',
27+
className
28+
)}
29+
>
30+
{copied ? <Check className='size-3.5' /> : <Copy className='size-3.5' />}
31+
</button>
32+
)
33+
}

0 commit comments

Comments
 (0)