-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Expand file tree
/
Copy pathcode.js
More file actions
113 lines (100 loc) · 3.34 KB
/
Copy pathcode.js
File metadata and controls
113 lines (100 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import React from 'react'
import {Text, Button} from '@primer/react'
import {Highlight, themes, Prism} from 'prism-react-renderer'
import styled from 'styled-components'
import {CheckIcon, CopyIcon} from '@primer/octicons-react'
import copyToClipboard from 'copy-to-clipboard'
import {announce} from '../util/aria-live'
import * as styles from './code.module.css'
import {clsx} from 'clsx'
;(typeof global !== 'undefined' ? global : window).Prism = Prism
require('prismjs/components/prism-bash')
const ClipboardCopy = ({value, ...props}) => {
const [copied, setCopied] = React.useState(false)
React.useEffect(() => {
const timeout = setTimeout(() => {
if (copied) {
setCopied(false)
}
}, 1000)
return () => clearTimeout(timeout)
}, [copied])
return (
<Button
aria-label="Copy to clipboard"
size="small"
onClick={() => {
copyToClipboard(value)
setCopied(true)
announce(`Copied to clipboard`)
}}
className={clsx(styles.Button, props.className)}
>
{copied ? <CheckIcon fill="#1a7f37" /> : <CopyIcon fill="#656d76" />}
</Button>
)
}
export const InlineCode = styled.code`
padding: 0.2em 0.4em;
font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);
font-size: 80%;
background-color: var(--bgColor-neutral-muted, #afb8c133);
border-radius: 6px;
`
const colorMap = {
'token comment': '#747458',
'token function': '#cf3846',
'token parameter variable': '#277d7b',
'token assign-left variable': '#277d7b',
'token string': '#db1068',
}
const MonoText = props => <Text className={styles.Text} {...props} />
const CodeBlock = ({children, code, className, style}) => (
<div className={styles.Box}>
<div style={style} className={styles.Box_1}>
{code ? <ClipboardCopy value={code} className={styles.ClipboardCopy} /> : null}
<div className={styles.Box_2}>
<pre className={clsx(className, styles.Box_3)} tabIndex={0}>
{children}
</pre>
</div>
</div>
</div>
)
function Code({className = '', prompt, children}) {
if (prompt) {
return (
<CodeBlock style={themes.github.plain}>
<MonoText>{children}</MonoText>
</CodeBlock>
)
}
const code = children?.trim()
if (!code) {
return null
}
const isBlock = className.startsWith('language-') || code.includes('\n')
if (!isBlock) {
return <InlineCode className={className}>{code}</InlineCode>
}
return (
<Highlight code={code} language={className.replace(/language-/, '') || 'bash'} theme={themes.github}>
{({className: highlightClassName, style, tokens, getLineProps, getTokenProps}) => (
<CodeBlock className={highlightClassName} style={style} code={code}>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({line, key: i})}>
{line.map((token, key) => {
const tokenProps = getTokenProps({token, key})
const tokenStyle = colorMap[tokenProps.className]
? {...tokenProps.style, color: colorMap[tokenProps.className]}
: tokenProps.style
return <MonoText key={key} {...tokenProps} style={tokenStyle} />
})}
</div>
))}
</CodeBlock>
)}
</Highlight>
)
}
export default Code