-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.js
More file actions
103 lines (92 loc) · 2.8 KB
/
Copy pathindex.js
File metadata and controls
103 lines (92 loc) · 2.8 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
import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
const SCRIPT_URL = 'https://static.codepen.io/assets/embed/ei.js'; // new embed
const LOAD_STATE = {
booting: '__booting__',
error: '__error__',
loading: '__loading__',
loaded: '__loaded__',
};
const ReactCodepen = ({
defaultTab = 'css,result',
height = 300,
preview = true,
editable = false,
themeId = 'dark',
version = 2,
loader,
user,
hash,
title,
}) => {
const [loadState, setLoadState] = useState(LOAD_STATE.booting);
const [error, setError] = useState();
const _isMounted = useRef(false);
const loadScript = () => {
// load the codepen embed script
const script = document.createElement('script');
script.src = SCRIPT_URL;
script.async = 1;
script.onload = () => {
// do not do anything if the component is already unmounted.
if (!_isMounted.current) return;
setLoadState(LOAD_STATE.loaded);
};
script.onerror = () => {
if (!_isMounted.current) return;
setLoadState(LOAD_STATE.error);
setError('Failed to load the pen');
};
setLoadState(LOAD_STATE.loading);
document.body.appendChild(script);
};
useEffect(() => {
if (_isMounted.current === false) _isMounted.current = true;
loadScript();
return () => (_isMounted.current = false);
}, []);
const showLoader = loadState === LOAD_STATE.loading && loader !== undefined;
const visibility = loadState === LOAD_STATE.loaded ? 'visible' : 'hidden';
const penLink = `https://codepen.io/${user}/pen/${hash}/`;
const userProfileLink = `https://codepen.io/${user}`;
const styles = { visibility };
return (
<React.Fragment>
{showLoader &&
React.createElement(loader, {
isLoading: loadState === LOAD_STATE.loading,
error,
})}
<p
data-height={height}
data-theme-id={themeId}
data-slug-hash={hash}
data-default-tab={defaultTab}
data-user={user}
data-embed-version={version}
data-pen-title={title}
data-preview={preview}
data-editable={editable}
className="codepen"
style={styles}
>
See the Pen <a href={penLink}>{title}</a>
by {user} (<a href={userProfileLink}>@{user}</a>) on{' '}
<a href="https://codepen.io">CodePen</a>.
</p>
</React.Fragment>
);
};
ReactCodepen.propTypes = {
defaultTab: PropTypes.string,
hash: PropTypes.string.isRequired,
height: PropTypes.number,
loader: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
preview: PropTypes.bool,
editable: PropTypes.bool,
title: PropTypes.string,
themeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
user: PropTypes.string.isRequired,
version: PropTypes.number,
};
export default ReactCodepen;