Skip to content

Commit 059c384

Browse files
committed
Refactor scrollycoding
1 parent 54a3ff3 commit 059c384

18 files changed

+558
-528
lines changed

packages/mini-editor/src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import {
88
MiniEditorHike,
99
MiniEditorHikeProps,
10+
EditorStep,
1011
} from "./mini-editor-hike"
1112
import {
1213
MiniEditor,
@@ -23,4 +24,5 @@ export {
2324
MiniEditorProps,
2425
MiniEditorHike,
2526
MiniEditorHikeProps,
27+
EditorStep,
2628
}

packages/mini-editor/src/mini-editor-hike.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import { EditorStep } from "./use-snapshots"
44
import { CodeProps } from "./code"
55
import { EditorFrameProps } from "./editor-frame"
66

7-
export { MiniEditorHike, MiniEditorHikeProps }
7+
export { MiniEditorHike, MiniEditorHikeProps, EditorStep }
88

99
type MiniEditorHikeProps = {
1010
steps: EditorStep[]
1111
progress: number
1212
backward: boolean
13-
frameProps: Partial<EditorFrameProps>
14-
codeProps: Partial<CodeProps>
13+
frameProps?: Partial<EditorFrameProps>
14+
codeProps?: Partial<CodeProps>
1515
}
1616

1717
function MiniEditorHike({

packages/mini-editor/src/mini-editor-spring.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ type SingleFileEditorProps = {
1313
focus?: string
1414
filename?: string
1515
terminal?: string
16-
frameProps: Partial<EditorFrameProps>
17-
codeProps: Partial<CodeProps>
16+
frameProps?: Partial<EditorFrameProps>
17+
codeProps?: Partial<CodeProps>
1818
}
1919
type SinglePanelEditorProps = {
2020
files: StepFile[]
2121
active: string
2222
terminal?: string
23-
frameProps: Partial<EditorFrameProps>
24-
codeProps: Partial<CodeProps>
23+
frameProps?: Partial<EditorFrameProps>
24+
codeProps?: Partial<CodeProps>
2525
}
2626
type TwoPanelEditorProps = EditorStep & {
27-
frameProps: Partial<EditorFrameProps>
28-
codeProps: Partial<CodeProps>
27+
frameProps?: Partial<EditorFrameProps>
28+
codeProps?: Partial<CodeProps>
2929
}
3030
type MiniEditorProps =
3131
| SingleFileEditorProps
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React from "react"
2+
import { useClasser } from "@code-hike/classer"
3+
import {
4+
Scroller,
5+
Step as ScrollerStep,
6+
} from "@code-hike/scroller"
7+
import { useFluidContext, HikeStep } from "./hike-context"
8+
import { EditorStep } from "@code-hike/mini-editor"
9+
10+
export const StepContext = React.createContext<{
11+
stepIndex: number
12+
editorStep: EditorStep
13+
} | null>(null)
14+
15+
export function ContentColumn({
16+
steps,
17+
onStepChange,
18+
}: {
19+
steps: HikeStep[]
20+
onStepChange: (index: number) => void
21+
}) {
22+
const c = useClasser("ch")
23+
const contentSteps = steps.map(s => s.content)
24+
return (
25+
<div className={c("hike-content")}>
26+
<Scroller onStepChange={onStepChange}>
27+
{contentSteps.map((children, index) => (
28+
<StepContext.Provider
29+
value={{
30+
stepIndex: index,
31+
editorStep:
32+
steps[index].editorProps.contentProps,
33+
}}
34+
key={index}
35+
>
36+
<StepContent
37+
children={children}
38+
stepIndex={index}
39+
/>
40+
</StepContext.Provider>
41+
))}
42+
</Scroller>
43+
</div>
44+
)
45+
}
46+
47+
function StepContent({
48+
children,
49+
stepIndex,
50+
}: {
51+
children: React.ReactNode
52+
stepIndex: number
53+
}) {
54+
const c = useClasser("ch-hike-step")
55+
const { dispatch, hikeState } = useFluidContext()
56+
const focusStepIndex =
57+
hikeState.focusStepIndex ?? hikeState.scrollStepIndex
58+
const isOn = stepIndex === focusStepIndex
59+
return (
60+
<ScrollerStep
61+
as="div"
62+
index={stepIndex}
63+
onClick={() =>
64+
dispatch({
65+
type: "set-focus",
66+
stepIndex,
67+
editorStep: null,
68+
})
69+
}
70+
className={c("", isOn ? "focused" : "unfocused")}
71+
>
72+
{stepIndex > 0 && <div className={c("gap")} />}
73+
<div
74+
className={c(
75+
"content",
76+
isOn ? "content-focused" : "content-unfocused"
77+
)}
78+
>
79+
{children}
80+
</div>
81+
</ScrollerStep>
82+
)
83+
}
84+
85+
export function useStepData() {
86+
return React.useContext(StepContext)!
87+
}

packages/scrollycoding/src/demo-context.tsx

Lines changed: 0 additions & 94 deletions
This file was deleted.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import React from "react"
2+
import {
3+
SandpackProvider,
4+
SandpackPredefinedTemplate,
5+
SandpackProviderProps,
6+
SandpackSetup,
7+
SandpackFile,
8+
} from "@codesandbox/sandpack-react"
9+
import { EditorProps } from "./editor"
10+
import { PreviewProps } from "./preview"
11+
12+
export {
13+
DemoProvider,
14+
PreviewPreset,
15+
usePreviewProps,
16+
useEditorProps,
17+
}
18+
19+
interface PreviewPreset {
20+
template?: SandpackPredefinedTemplate
21+
customSetup?: SandpackSetup
22+
}
23+
24+
type DemoProviderProps = {
25+
editorProps: EditorProps
26+
previewProps: PreviewProps
27+
previewPreset: PreviewPreset
28+
children?: React.ReactNode
29+
}
30+
31+
type DemoContext = {
32+
editorProps: EditorProps
33+
previewProps: PreviewProps
34+
}
35+
36+
export const DemoContext = React.createContext<DemoContext | null>(
37+
null
38+
)
39+
40+
function DemoProvider({
41+
children,
42+
editorProps,
43+
previewProps,
44+
previewPreset,
45+
}: DemoProviderProps) {
46+
const sandpackProps = useSandpackProps(
47+
previewPreset,
48+
editorProps
49+
)
50+
const previewAndEditorProps = React.useMemo(
51+
() => ({
52+
previewProps,
53+
editorProps,
54+
}),
55+
[previewProps, editorProps]
56+
)
57+
return (
58+
<SandpackProvider {...sandpackProps}>
59+
<DemoContext.Provider value={previewAndEditorProps}>
60+
{children}
61+
</DemoContext.Provider>
62+
</SandpackProvider>
63+
)
64+
}
65+
66+
function useSandpackProps(
67+
previewPreset: PreviewPreset,
68+
editorProps: EditorProps
69+
): SandpackProviderProps {
70+
// TODO useMemo
71+
const files = {
72+
...previewPreset?.customSetup?.files,
73+
} as Record<string, SandpackFile>
74+
const codeFiles = editorProps?.contentProps?.files || []
75+
codeFiles.forEach(file => {
76+
files["/" + file.name] = {
77+
code: file.code,
78+
}
79+
})
80+
81+
return {
82+
recompileMode: "immediate",
83+
...previewPreset,
84+
customSetup: {
85+
...previewPreset?.customSetup,
86+
files,
87+
},
88+
}
89+
}
90+
91+
function useEditorProps() {
92+
return React.useContext(DemoContext)!.editorProps
93+
}
94+
function usePreviewProps() {
95+
return React.useContext(DemoContext)!.previewProps
96+
}

packages/scrollycoding/src/code.tsx renamed to packages/scrollycoding/src/editor.tsx

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
import * as React from "react"
2-
import { MiniEditor } from "@code-hike/mini-editor"
3-
import { CodeProps } from "./hike-context"
2+
import {
3+
MiniEditor,
4+
MiniEditorProps,
5+
EditorStep,
6+
} from "@code-hike/mini-editor"
47
import { useCodeSandboxLink } from "@codesandbox/sandpack-react"
58

6-
export { Code }
9+
export { Editor, EditorProps }
710

8-
function Code({ files, activeFile, ...props }: CodeProps) {
9-
const file = files[activeFile]
10-
const tabs = Object.keys(files).filter(
11-
filename => !files[filename].hideTab
12-
)
11+
type EditorProps = {
12+
contentProps: EditorStep
13+
frameProps: MiniEditorProps["frameProps"]
14+
codeProps: MiniEditorProps["codeProps"]
15+
}
16+
17+
function Editor({
18+
contentProps,
19+
codeProps,
20+
frameProps,
21+
}: EditorProps) {
22+
const finalFrameProps = {
23+
button: <CodeSandboxIcon url={useCodeSandboxLink()} />,
24+
...frameProps,
25+
style: { height: "100%", ...frameProps?.style },
26+
}
27+
const finalCodeProps = {
28+
minColumns: 46,
29+
...codeProps,
30+
}
1331
return (
1432
<MiniEditor
15-
key={activeFile}
16-
style={{ height: "100%" }}
17-
button={
18-
<CodeSandboxIcon url={useCodeSandboxLink()} />
19-
}
20-
file={activeFile}
21-
tabs={tabs}
22-
lang={file.lang}
23-
code={file.code}
24-
{...props}
33+
{...contentProps}
34+
frameProps={finalFrameProps}
35+
codeProps={finalCodeProps}
2536
/>
2637
)
2738
}

0 commit comments

Comments
 (0)