-
-
Notifications
You must be signed in to change notification settings - Fork 175
Expand file tree
/
Copy pathdeck-code-surfer.js
More file actions
125 lines (114 loc) · 3.29 KB
/
deck-code-surfer.js
File metadata and controls
125 lines (114 loc) · 3.29 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 CodeSurfer from "code-surfer";
import React from "react";
import { withContext } from "@mdx-deck/components";
import { withTheme } from "emotion-theming";
import memoizeOne from "memoize-one";
const Notes = ({ notes }) =>
!notes || typeof notes === "string" ? (
<p style={{ height: "50px" }}>{notes || "\u00A0"}</p>
) : (
notes()
);
const Title = ({ title }) =>
typeof title === "string" ? <h1>{title}</h1> : title();
class InnerCodeSurfer extends React.Component {
constructor(props) {
super(props);
const { register, index } = props.context;
if (typeof register !== "function") return;
const parsedSteps = this.parseSteps(props.steps);
register(index, { steps: parsedSteps.length - 1 });
}
parseSteps = memoizeOne((steps, notes) => {
if (!steps) {
return [{ notes }];
}
if (typeof steps === "string") {
return steps
.trim()
.split("\n")
.map(stepAndNoteString => {
const [step, notes] = stepAndNoteString.split("> ");
return {
step,
notes
};
});
}
return steps.map(({ notes, title, ...step }) => ({ step, notes, title }));
});
render() {
let {
context,
code,
steps,
title,
notes,
theme,
prismTheme,
showNumbers,
...rest
} = this.props;
const { step } = context;
const stepIndex = step || 0;
const mdxDeckTheme = theme;
prismTheme = prismTheme || mdxDeckTheme.codeSurfer;
showNumbers = showNumbers || (prismTheme && prismTheme.showNumbers);
const stepsWithNotes = this.parseSteps(steps, notes);
const current =
stepsWithNotes[stepIndex >= stepsWithNotes.length ? 0 : stepIndex];
const currentStep = current.step;
const currentTitle = current.title || title;
const currentNotes = current.notes;
const anyNotes = stepsWithNotes.some(s => s.notes);
return (
<div
style={{
height: "100vh",
width: "100vw",
background: prismTheme && prismTheme.plain.backgroundColor,
color: prismTheme && prismTheme.plain.color,
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div
style={{
height: "100vh",
display: "flex",
flexDirection: "column",
justifyContent: "center"
}}
>
{currentTitle && <Title title={currentTitle} />}
<div
style={{
flexGrow: 1,
display: "flex",
alignItems: "center",
overflow: "hidden"
}}
key="code"
>
<CodeSurfer
{...rest}
code={code}
showNumbers={showNumbers}
step={currentStep}
theme={prismTheme}
monospace={mdxDeckTheme && mdxDeckTheme.monospace}
/>
</div>
{anyNotes && <Notes notes={currentNotes} />}
<div style={{ height: "35px" }} />
</div>
</div>
);
}
}
// Things I need to do to avoid props name collisions
const EnhancedCodeSurfer = withContext(withTheme(InnerCodeSurfer));
export default ({ theme, ...rest }) => (
<EnhancedCodeSurfer {...rest} prismTheme={theme} />
);