forked from TanStack/table
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCodeBlock.js
More file actions
125 lines (116 loc) · 3.93 KB
/
CodeBlock.js
File metadata and controls
125 lines (116 loc) · 3.93 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
114
115
116
117
118
119
120
121
122
123
124
125
import React, { useState } from 'react';
import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
import { mdx } from '@mdx-js/react';
import { TWButton } from './TWButton';
import { useClipboard } from './useClipboard';
import Component from '@reactions/component';
export const liveEditorStyle = {
fontSize: 14,
overflowX: 'auto',
color: '#f8f8f2',
fontFamily: 'SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace',
height: '100%',
background: '#161e2e'
};
export const liveErrorStyle = {
fontFamily: 'SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace',
fontSize: 12,
padding: '1em',
overflowX: 'auto',
color: 'white',
backgroundColor: 'red'
};
const LiveCodePreview = props => <div className="font-sans text-gray-900 rounded-md p-4 overflow-x-scroll">
<LivePreview {...props} />
</div>;
const EditableNotice = props => {
return <div className="absolute right-0 top-0 p-3 text-gray-400 text-xs font-sans uppercase">
Editable Example
</div>;
};
const CodeBlock = ({
className,
live = false,
noInline = false,
collapsed = false,
isManual,
render,
children,
...props
}) => {
const initialCode = React.useRef(children.trim());
const [editorCode, setEditorCode] = useState(children.trim());
const language = className && className.replace(/language-/, '');
const [hasCopied, onCopy] = useClipboard(editorCode);
const [isCollapsed, setCollapse] = React.useState(collapsed);
const liveProviderProps = {
theme: {
plain: {},
styles: []
},
language,
code: editorCode,
transformCode: code => `<>${code}</>`,
scope: {
mdx,
Component
},
noInline,
...props
};
const handleCodeChange = newCode => setEditorCode(newCode ? newCode.trim() : '');
if (language === 'jsx' && live === true) {
return <LiveProvider {...liveProviderProps}>
<div className="border relative rounded shadow-sm">
<LiveCodePreview />
<EditableNotice />
{isCollapsed ? <div className="border-t">
<button className="text-gray-600 py-2 bg-gray-100 font-semibold w-full text-sm hover:bg-gray-200 transition duration-100 ease-in-out" onClick={() => setCollapse(false)}>
Show Code
</button>
</div> : <>
<div className="relative">
<LiveEditor onChange={handleCodeChange} style={liveEditorStyle} className="outline-none " />
<div className="absolute right-0 top-0 p-2">
<TWButton size="xs" className="font-sans mr-2" onClick={onCopy}>
{hasCopied ? 'Copied' : 'Copy'}
</TWButton>
<TWButton size="xs" className="font-sans" onClick={() => setEditorCode(initialCode.current)}>
Reset
</TWButton>
</div>
</div>
<LiveError style={liveErrorStyle} />
<div className="border-t">
<button className="text-gray-600 py-2 bg-gray-100 font-semibold w-full text-sm hover:bg-gray-200 transition duration-100 ease-in-out" onClick={() => setCollapse(true)}>
Hide Code
</button>
</div>
</>}
</div>
</LiveProvider>;
}
if (render) {
return <div style={{
marginTop: '40px'
}}>
<LiveProvider {...liveProviderProps}>
<LiveCodePreview className="font-sans" />
</LiveProvider>
</div>;
}
return <LiveProvider disabled {...liveProviderProps}>
<div className="relative">
<LiveEditor style={liveEditorStyle} className="rounded shadow-sm" />
<div className="absolute right-0 top-0 p-2">
<TWButton size="xs" className="font-sans" onClick={onCopy}>
{hasCopied ? 'Copied' : 'Copy'}
</TWButton>
</div>
</div>
</LiveProvider>;
};
CodeBlock.defaultProps = {
mountStylesheet: false
};
export default CodeBlock;