Skip to content

Commit 1ebbd0c

Browse files
committed
fix:code section
1 parent daf0d1a commit 1ebbd0c

File tree

1 file changed

+65
-45
lines changed

1 file changed

+65
-45
lines changed

apps/masterbots.ai/components/ui/codeblock.tsx

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
// Inspired by Chatbot-UI and modified to fit the needs of this project
2-
// @see https://github.com/mckaywrigley/chatbot-ui/blob/main/components/Markdown/CodeBlock.tsx
3-
41
'use client'
52

6-
import { FC, memo } from 'react'
3+
import { type FC, memo } from 'react'
74
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
85
import { coldarkDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
9-
106
import { Button } from '@/components/ui/button'
117
import { IconCheck, IconCopy, IconDownload } from '@/components/ui/icons'
128
import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard'
9+
import { cn } from '@/lib/utils'
1310

1411
interface Props {
1512
language: string
@@ -43,12 +40,19 @@ export const programmingLanguages: languageMap = {
4340
shell: '.sh',
4441
sql: '.sql',
4542
html: '.html',
46-
css: '.css'
47-
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
43+
css: '.css',
44+
solidity: '.sol',
45+
cairo: '.cairo',
46+
json: '.json',
47+
yaml: '.yaml',
48+
xml: '.xml',
49+
markdown: '.md',
50+
plaintext: '.txt',
51+
react: '.jsx'
4852
}
4953

50-
export const generateRandomString = (length: number, lowercase = false) => {
51-
const chars = 'ABCDEFGHJKLMNPQRSTUVWXY3456789' // excluding similar looking characters like Z, 2, I, 1, O, 0
54+
const generateRandomString = (length: number, lowercase = false) => {
55+
const chars = 'ABCDEFGHJKLMNPQRSTUVWXY3456789'
5256
let result = ''
5357
for (let i = 0; i < length; i++) {
5458
result += chars.charAt(Math.floor(Math.random() * chars.length))
@@ -64,14 +68,10 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
6468
return
6569
}
6670
const fileExtension = programmingLanguages[language] || '.file'
67-
const suggestedFileName = `file-${generateRandomString(
68-
3,
69-
true
70-
)}${fileExtension}`
71+
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`
7172
const fileName = window.prompt('Enter file name', suggestedFileName)
7273

7374
if (!fileName) {
74-
// User pressed cancel on prompt.
7575
return
7676
}
7777

@@ -93,56 +93,76 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
9393
}
9494

9595
return (
96-
<div className="relative w-full font-sans codeblock bg-zinc-950">
97-
<div className="flex items-center justify-between w-full px-6 py-2 pr-4 bg-zinc-800 text-zinc-100">
98-
<span className="text-xs lowercase">{language}</span>
99-
<div className="flex items-center space-x-1">
96+
<div className="relative w-full overflow-hidden font-sans text-sm rounded-md sm:text-base">
97+
<div
98+
className={cn(
99+
'flex items-center justify-between w-full bg-zinc-800 text-zinc-100',
100+
'px-2 py-1.5 sm:px-6 sm:py-2'
101+
)}
102+
>
103+
<span className="text-[11px] sm:text-xs lowercase">{language}</span>
104+
<div className="flex items-center gap-0.5 sm:gap-1">
100105
<Button
101106
variant="ghost"
102-
className="hover:bg-zinc-800 focus-visible:ring-1 focus-visible:ring-slate-700 focus-visible:ring-offset-0"
107+
className="h-7 w-7 sm:h-8 sm:w-8 hover:bg-zinc-800 focus-visible:ring-1 focus-visible:ring-slate-700 focus-visible:ring-offset-0"
103108
onClick={downloadAsFile}
104109
size="icon"
105110
>
106-
<IconDownload />
111+
<IconDownload className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
107112
<span className="sr-only">Download</span>
108113
</Button>
109114
<Button
110115
variant="ghost"
111116
size="icon"
112-
className="text-xs hover:bg-zinc-800 focus-visible:ring-1 focus-visible:ring-slate-700 focus-visible:ring-offset-0"
117+
className="h-7 w-7 sm:h-8 sm:w-8 hover:bg-zinc-800 focus-visible:ring-1 focus-visible:ring-slate-700 focus-visible:ring-offset-0"
113118
onClick={onCopy}
114119
>
115-
{isCopied ? <IconCheck /> : <IconCopy />}
120+
{isCopied ? (
121+
<IconCheck className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
122+
) : (
123+
<IconCopy className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
124+
)}
116125
<span className="sr-only">Copy code</span>
117126
</Button>
118127
</div>
119128
</div>
120-
<SyntaxHighlighter
121-
language={language}
122-
style={coldarkDark}
123-
PreTag="div"
124-
showLineNumbers
125-
customStyle={{
126-
margin: 0,
127-
width: '100%',
128-
background: 'transparent',
129-
padding: '1.5rem 1rem'
130-
}}
131-
lineNumberStyle={{
132-
userSelect: 'none'
133-
}}
134-
codeTagProps={{
135-
style: {
136-
fontSize: '0.9rem',
137-
fontFamily: 'var(--font-mono)'
138-
}
139-
}}
140-
>
141-
{value}
142-
</SyntaxHighlighter>
129+
<div className="relative w-full overflow-auto text-xs sm:text-sm">
130+
<SyntaxHighlighter
131+
language={language}
132+
style={coldarkDark}
133+
PreTag="div"
134+
showLineNumbers
135+
customStyle={{
136+
margin: 0,
137+
width: '100%',
138+
background: 'transparent',
139+
padding: '0.75rem 0.25rem'
140+
}}
141+
lineNumberStyle={{
142+
minWidth: '2em',
143+
paddingRight: '0.75em',
144+
userSelect: 'none',
145+
opacity: 0.5,
146+
fontSize: '11px'
147+
}}
148+
codeTagProps={{
149+
style: {
150+
fontFamily: 'var(--font-mono)',
151+
fontSize: 'inherit',
152+
lineHeight: '1.4'
153+
}
154+
}}
155+
className="text-xs sm:text-sm"
156+
wrapLines
157+
wrapLongLines
158+
>
159+
{value}
160+
</SyntaxHighlighter>
161+
</div>
143162
</div>
144163
)
145164
})
165+
146166
CodeBlock.displayName = 'CodeBlock'
147167

148168
export { CodeBlock }

0 commit comments

Comments
 (0)