Skip to content

Commit a93193d

Browse files
authored
Merge pull request #221 from code-hike/more-preview
Add previews in steps
2 parents 91dead8 + c178263 commit a93193d

File tree

9 files changed

+139
-82
lines changed

9 files changed

+139
-82
lines changed

packages/mdx/dev/content/test.mdx

+24-52
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,51 @@
1-
### with width
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
22

3-
<CH.Code debug >
3+
<CH.Preview url="https://whatismyviewport.com/" />
44

5-
```js
6-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
7-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
8-
```
9-
10-
</CH.Code>
5+
## Bigger steps than code
116

12-
<CH.Code>
13-
14-
```js
15-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
16-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
17-
```
7+
<CH.Spotlight>
188

19-
</CH.Code>
9+
# Foo
2010

21-
### with width
11+
bar
2212

23-
<CH.Code debug style={{width: 400}}>
13+
<CH.Preview url="https://whatismyviewport.com/" />
2414

25-
```js
26-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
27-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
15+
```js foo.js
16+
function foo() {
17+
return "bar"
18+
}
2819
```
2920

30-
</CH.Code>
21+
---
3122

32-
<CH.Code style={{width: 400}}>
23+
```js foo.js focus=1
3324

34-
```js
35-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
36-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
3725
```
3826

39-
</CH.Code>
27+
Line 1
4028

41-
### with zoom
29+
---
4230

43-
<CH.Code debug maxZoom={0.7} minZoom={0.7}>
31+
```js foo.js focus=2
4432

45-
```js
46-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
47-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
4833
```
4934

50-
</CH.Code>
35+
Line 2
5136

52-
<CH.Code maxZoom={0.7} minZoom={0.7}>
37+
<CH.Preview>
5338

54-
```js
55-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
56-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
57-
```
39+
Line 2
5840

59-
</CH.Code>
41+
</CH.Preview>
6042

61-
### with line numbers
43+
---
6244

63-
<CH.Code debug lineNumbers>
45+
```js foo.js focus=3
6446

65-
```js
66-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
67-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
6847
```
6948

70-
</CH.Code>
71-
72-
<CH.Code lineNumbers>
73-
74-
```js
75-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
76-
const = "hello" + "hello" + "hello" + "hello" + "hello" + "hello"+ "hello" + "goodbye"
77-
```
49+
Line 3
7850

79-
</CH.Code>
51+
</CH.Spotlight>

packages/mdx/src/mdx-client/scrollycoding.tsx

+15-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { InnerCode, updateEditorStep } from "./code"
44
import { Scroller, Step as ScrollerStep } from "../scroller"
55
import { Preview, PresetConfig } from "./preview"
66
import { LinkableSection } from "./section"
7+
import { extractPreviewSteps } from "./steps"
78

89
export function Scrollycoding({
910
children,
@@ -13,6 +14,7 @@ export function Scrollycoding({
1314
start = 0,
1415
className,
1516
style,
17+
hasPreviewSteps,
1618
...rest
1719
}: {
1820
children: React.ReactNode
@@ -22,8 +24,12 @@ export function Scrollycoding({
2224
presetConfig?: PresetConfig
2325
className?: string
2426
style?: React.CSSProperties
27+
hasPreviewSteps?: boolean
2528
}) {
26-
const stepsChildren = React.Children.toArray(children)
29+
const { stepsChildren, previewChildren } =
30+
extractPreviewSteps(children, hasPreviewSteps)
31+
32+
const withPreview = presetConfig || hasPreviewSteps
2733

2834
const [state, setState] = React.useState({
2935
stepIndex: start,
@@ -61,7 +67,7 @@ export function Scrollycoding({
6167
return (
6268
<section
6369
className={`ch-scrollycoding ${
64-
presetConfig ? "ch-scrollycoding-with-preview" : ""
70+
withPreview ? "ch-scrollycoding-with-preview" : ""
6571
} ${className || ""}`}
6672
style={style}
6773
>
@@ -100,14 +106,19 @@ export function Scrollycoding({
100106
codeConfig={codeConfig}
101107
onTabClick={onTabClick}
102108
/>
103-
{presetConfig && (
109+
{presetConfig ? (
104110
<Preview
105111
className="ch-scrollycoding-preview"
106112
files={tab.files}
107113
presetConfig={presetConfig}
108114
codeConfig={codeConfig}
109115
/>
110-
)}
116+
) : hasPreviewSteps ? (
117+
<Preview
118+
className="ch-scrollycoding-preview"
119+
{...previewChildren[state.stepIndex]["props"]}
120+
/>
121+
) : null}
111122
</div>
112123
</section>
113124
)

packages/mdx/src/mdx-client/slideshow.tsx

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react"
22
import { EditorProps, EditorStep } from "../mini-editor"
33
import { InnerCode, updateEditorStep } from "./code"
44
import { Preview, PresetConfig } from "./preview"
5+
import { extractPreviewSteps } from "./steps"
56

67
export function Slideshow({
78
children,
@@ -11,6 +12,7 @@ export function Slideshow({
1112
code,
1213
className,
1314
style,
15+
hasPreviewSteps,
1416
...rest
1517
}: {
1618
children: React.ReactNode
@@ -20,8 +22,11 @@ export function Slideshow({
2022
code?: EditorProps["codeConfig"]
2123
className?: string
2224
style?: React.CSSProperties
25+
hasPreviewSteps?: boolean
2326
}) {
24-
const stepsChildren = React.Children.toArray(children)
27+
const { stepsChildren, previewChildren } =
28+
extractPreviewSteps(children, hasPreviewSteps)
29+
const withPreview = presetConfig || hasPreviewSteps
2530

2631
const hasNotes = stepsChildren.some(
2732
(child: any) => child.props?.children
@@ -45,7 +50,7 @@ export function Slideshow({
4550
return (
4651
<div
4752
className={`ch-slideshow ${
48-
presetConfig ? "ch-slideshow-with-preview" : ""
53+
withPreview ? "ch-slideshow-with-preview" : ""
4954
} ${className || ""}`}
5055
style={style}
5156
>
@@ -59,14 +64,19 @@ export function Slideshow({
5964
}}
6065
onTabClick={onTabClick}
6166
/>
62-
{presetConfig && (
67+
{presetConfig ? (
6368
<Preview
6469
className="ch-slideshow-preview"
6570
files={tab.files}
6671
presetConfig={presetConfig}
6772
codeConfig={codeConfig}
6873
/>
69-
)}
74+
) : hasPreviewSteps ? (
75+
<Preview
76+
className="ch-slideshow-preview"
77+
{...previewChildren[state.stepIndex]["props"]}
78+
/>
79+
) : null}
7080
</div>
7181

7282
<div className="ch-slideshow-notes">

packages/mdx/src/mdx-client/spotlight.tsx

+16-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react"
22
import { EditorProps, EditorStep } from "../mini-editor"
33
import { InnerCode, updateEditorStep } from "./code"
44
import { Preview, PresetConfig } from "./preview"
5+
import { extractPreviewSteps } from "./steps"
56

67
export function Spotlight({
78
children,
@@ -11,6 +12,7 @@ export function Spotlight({
1112
presetConfig,
1213
className,
1314
style,
15+
hasPreviewSteps,
1416
...rest
1517
}: {
1618
children: React.ReactNode
@@ -20,13 +22,18 @@ export function Spotlight({
2022
presetConfig?: PresetConfig
2123
className?: string
2224
style?: React.CSSProperties
25+
hasPreviewSteps?: boolean
2326
}) {
24-
const stepsChildren = React.Children.toArray(children)
27+
const { stepsChildren, previewChildren } =
28+
extractPreviewSteps(children, hasPreviewSteps)
29+
30+
const withPreview = presetConfig || hasPreviewSteps
2531

2632
const [state, setState] = React.useState({
2733
stepIndex: start,
2834
step: editorSteps[start],
2935
})
36+
3037
const tab = state.step
3138

3239
function onTabClick(filename: string) {
@@ -44,7 +51,7 @@ export function Spotlight({
4451
return (
4552
<section
4653
className={`ch-spotlight ${
47-
presetConfig ? "ch-spotlight-with-preview" : ""
54+
withPreview ? "ch-spotlight-with-preview" : ""
4855
} ${className || ""}`}
4956
style={style}
5057
>
@@ -79,14 +86,19 @@ export function Spotlight({
7986
codeConfig={codeConfig}
8087
onTabClick={onTabClick}
8188
/>
82-
{presetConfig && (
89+
{presetConfig ? (
8390
<Preview
8491
className="ch-spotlight-preview"
8592
files={tab.files}
8693
presetConfig={presetConfig}
8794
codeConfig={codeConfig}
8895
/>
89-
)}
96+
) : hasPreviewSteps ? (
97+
<Preview
98+
className="ch-spotlight-preview"
99+
{...previewChildren[state.stepIndex]["props"]}
100+
/>
101+
) : null}
90102
</div>
91103
</section>
92104
)

packages/mdx/src/mdx-client/steps.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from "react"
2+
3+
export function extractPreviewSteps(
4+
children: React.ReactNode,
5+
hasPreviewSteps?: boolean
6+
) {
7+
const allChildren = React.Children.toArray(children)
8+
9+
const stepsChildren = hasPreviewSteps
10+
? allChildren.slice(0, allChildren.length / 2)
11+
: allChildren
12+
13+
const previewChildren = hasPreviewSteps
14+
? allChildren.slice(allChildren.length / 2)
15+
: undefined
16+
17+
return { stepsChildren, previewChildren }
18+
}

packages/mdx/src/remark/steps.tsx

+31-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { EditorStep } from "../mini-editor"
22
import { isEditorNode, mapAnyCodeNode } from "./code"
33
import { reduceStep } from "./code-files-reducer"
44
import { CodeHikeConfig } from "./config"
5-
import { SuperNode } from "./nodes"
5+
import { JsxNode, SuperNode } from "./nodes"
66

77
// extract step info
8-
98
export async function extractStepsInfo(
109
parent: SuperNode,
1110
config: CodeHikeConfig,
@@ -15,6 +14,7 @@ export async function extractStepsInfo(
1514
) {
1615
const steps = [] as {
1716
editorStep?: EditorStep
17+
previewStep?: JsxNode
1818
children: SuperNode[]
1919
}[]
2020

@@ -29,6 +29,7 @@ export async function extractStepsInfo(
2929

3030
steps[stepIndex] = steps[stepIndex] || { children: [] }
3131
const step = steps[stepIndex]
32+
3233
if (!step.editorStep && isEditorNode(child, config)) {
3334
const editorStep = await mapAnyCodeNode(
3435
{ node: child, parent, index: i },
@@ -53,6 +54,13 @@ export async function extractStepsInfo(
5354
filter
5455
)
5556
}
57+
} else if (
58+
child.type === "mdxJsxFlowElement" &&
59+
child.name === "CH.Preview" &&
60+
// only add the preview if we have a preview in step 0
61+
(stepIndex === 0 || steps[0].previewStep != null)
62+
) {
63+
step.previewStep = child
5664
} else {
5765
step.children.push(child)
5866
}
@@ -66,7 +74,27 @@ export async function extractStepsInfo(
6674
}
6775
})
6876

69-
return steps.map(step => step.editorStep)
77+
const hasPreviewSteps = steps[0].previewStep !== undefined
78+
// if there is a CH.Preview in the first step
79+
// build the previewStep list
80+
if (hasPreviewSteps) {
81+
const previewSteps = steps.map(step => step.previewStep)
82+
// fill empties with previous step
83+
previewSteps.forEach((previewStep, i) => {
84+
if (!previewStep) {
85+
previewSteps[i] =
86+
merge === "merge steps with header"
87+
? previewSteps[0]
88+
: previewSteps[i - 1]
89+
}
90+
})
91+
parent.children = parent.children.concat(previewSteps)
92+
}
93+
94+
return {
95+
editorSteps: steps.map(step => step.editorStep),
96+
hasPreviewSteps,
97+
}
7098
}
7199

72100
/**

0 commit comments

Comments
 (0)