-
-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathEmbed.js
137 lines (123 loc) · 4.49 KB
/
Embed.js
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
126
127
128
129
130
131
132
133
134
135
136
137
import React, { useState } from 'react';
import Input from './Input';
import CopyButton from './CopyButton';
import Embedded from './Embedded';
import { XIcon } from '@primer/octicons-react';
function TabButton({ children, active, onClick, disabled }) {
return (
<button
disabled={disabled}
className={[
'text-xs select-none border-b-2',
disabled ? '' : 'hover:text-blue-400 hover:border-blue-400',
active
? 'border-blue-600 text-blue-600'
: 'border-transparent text-gray-800',
].join(' ')}
onClick={disabled ? undefined : onClick}
>
{children}
</button>
);
}
const possiblePanes = ['markup', 'preview', 'query', 'result'];
function Embed({ dirty, gistId, gistVersion }) {
const [panes, setPanes] = useState(['preview', 'result']);
const width = 850;
const height = 300;
const embedUrl =
[location.origin, 'embed', gistId, gistVersion].filter(Boolean).join('/') +
`?panes=${panes.join(',')}`;
const embedCode = `<iframe src="${embedUrl}" height="${height}" width="100%" scrolling="no" frameBorder="0" allowTransparency="true" title="Testing Playground" style="overflow: hidden; display: block; width: 100%"></iframe>`;
const canAddPane = panes.length < 3;
return (
<div className="settings text-sm pb-2">
<div className="space-y-6">
{dirty && (
<section className="bg-blue-100 p-2 text-xs rounded my-2 text-blue-800">
Please note that this playground has
<strong> unsaved changes </strong>. The embed
<strong> will not include </strong> your latest changes!
</section>
)}
<section className="flex flex-col space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-sm font-bold">Configure</h3>
<TabButton
onClick={() =>
setPanes([
...panes,
possiblePanes.find((x) => !panes.includes(x)),
])
}
disabled={!canAddPane}
>
add pane
</TabButton>
</div>
{/* overflow-hidden is required hide the hidden preview panel */}
<div className="bg-gray-200 px-4 pb-4 -mx-4 overflow-hidden">
<div className="px-4 gap-4 grid grid-flow-col py-1">
{panes.map((selected, idx) => (
<div key={idx} className="flex items-center justify-between">
<div className="text-left space-x-2">
{possiblePanes.map((name) => (
<TabButton
key={name}
onClick={() =>
setPanes((current) => {
const next = [...current];
next[idx] = name;
return next;
})
}
active={selected === name}
>
{name}
</TabButton>
))}
</div>
<TabButton
disabled={panes.length === 1}
onClick={() => setPanes(panes.filter((_, i) => i !== idx))}
>
<span>
<XIcon size={12} />
</span>
</TabButton>
</div>
))}
</div>
<div style={{ width, height }}>
<Embedded
panes={panes}
gistId={gistId}
gistVersion={gistVersion}
/>
</div>
</div>
</section>
<section className="flex flex-col space-y-4" style={{ width }}>
<h3 className="text-sm font-bold">Copy & Paste</h3>
<label className="text-xs">
embed link:
<div className="flex space-x-4">
<Input value={embedUrl} onChange={() => {}} readOnly name="url" />
<CopyButton text={embedUrl} />
</div>
</label>
<label className="text-xs">
embed code:
<div className="w-full flex space-x-4">
<code className="p-4 rounded bg-gray-200 text-gray-800 font-mono text-xs">
{embedCode}
</code>
<CopyButton text={embedCode} />
</div>
</label>
</section>
</div>
</div>
);
}
export default Embed;