Skip to content

Commit d03dd9e

Browse files
committed
Add mini editor spring
1 parent 014d9f0 commit d03dd9e

File tree

5 files changed

+262
-60
lines changed

5 files changed

+262
-60
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type EditorTransitionProps = {
2121
next?: EditorStep
2222
t: number
2323
backward: boolean
24-
codeProps: Partial<CodeProps>
24+
codeProps?: Partial<CodeProps>
2525
} & Omit<EditorFrameProps, "northPanel" | "southPanel">
2626

2727
const DEFAULT_STEP: EditorStep = {
@@ -34,7 +34,7 @@ function EditorTransition({
3434
next = DEFAULT_STEP,
3535
t,
3636
backward,
37-
codeProps,
37+
codeProps = {},
3838
...rest
3939
}: EditorTransitionProps) {
4040
const ref = React.createRef<HTMLDivElement>()

packages/mini-editor/src/index.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,21 @@ import {
44
MiniEditorHike,
55
MiniEditorHikeProps,
66
} from "./mini-editor-hike"
7-
import { MiniEditor, MiniEditorProps } from "./mini-editor"
87
import { EditorTransition } from "./editor-transition"
9-
import {
10-
FullMiniEditor,
11-
FullMiniEditorHike,
12-
} from "./new-mini-editor"
8+
import { FullMiniEditorHike } from "./new-mini-editor"
139
import { mdxToStep, mdxToSteps } from "./mdx"
10+
import {
11+
MiniEditor,
12+
MiniEditorProps,
13+
} from "./mini-editor-spring"
1414

1515
export {
1616
mdxToStep,
1717
mdxToSteps,
18-
MiniEditorHike,
1918
MiniEditor,
20-
MiniEditorHikeProps,
2119
MiniEditorProps,
20+
MiniEditorHike,
21+
MiniEditorHikeProps,
2222
EditorTransition,
23-
FullMiniEditor,
2423
FullMiniEditorHike,
2524
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import React from "react"
2+
import { useSpring } from "use-spring"
3+
import {
4+
EditorTransition,
5+
EditorTransitionProps,
6+
} from "./editor-transition"
7+
import { EditorStep, StepFile } from "./use-snapshots"
8+
import { CodeProps } from "./code"
9+
10+
export { MiniEditor, MiniEditorProps }
11+
12+
type SingleFileEditorProps = {
13+
code: string
14+
lang: string
15+
focus?: string
16+
filename?: string
17+
terminal?: string
18+
frameProps: Partial<EditorTransitionProps>
19+
codeProps: Partial<CodeProps>
20+
}
21+
type SinglePanelEditorProps = {
22+
files: StepFile[]
23+
active: string
24+
terminal?: string
25+
frameProps: Partial<EditorTransitionProps>
26+
codeProps: Partial<CodeProps>
27+
}
28+
type TwoPanelEditorProps = EditorStep & {
29+
frameProps: Partial<EditorTransitionProps>
30+
codeProps: Partial<CodeProps>
31+
}
32+
type MiniEditorProps =
33+
| SingleFileEditorProps
34+
| SinglePanelEditorProps
35+
| TwoPanelEditorProps
36+
37+
function MiniEditor(props: MiniEditorProps) {
38+
if ("northPanel" in props) {
39+
return <TwoPanelEditor {...props} />
40+
} else if ("active" in props) {
41+
return <SinglePanelEditor {...props} />
42+
} else {
43+
return <SingleFileEditor {...props} />
44+
}
45+
}
46+
47+
function SingleFileEditor({
48+
code = "",
49+
lang = "js",
50+
focus,
51+
filename = "",
52+
terminal,
53+
frameProps,
54+
codeProps,
55+
}: SingleFileEditorProps) {
56+
const step = React.useMemo(() => {
57+
const step: EditorStep = {
58+
files: [{ name: filename, code, lang, focus }],
59+
northPanel: {
60+
active: filename,
61+
tabs: [filename],
62+
heightRatio: 1,
63+
},
64+
terminal,
65+
}
66+
return step
67+
}, [code, lang, focus, filename, terminal])
68+
69+
const { prev, next, t } = useStepSpring(step)
70+
return (
71+
<EditorTransition
72+
{...frameProps}
73+
t={t}
74+
backward={false}
75+
prev={prev}
76+
next={next}
77+
codeProps={codeProps}
78+
/>
79+
)
80+
}
81+
function SinglePanelEditor({
82+
files,
83+
active,
84+
terminal,
85+
frameProps,
86+
codeProps,
87+
}: SinglePanelEditorProps) {
88+
const step = React.useMemo(() => {
89+
const tabs = files.map(file => file.name)
90+
const step: EditorStep = {
91+
files,
92+
northPanel: {
93+
active,
94+
tabs,
95+
heightRatio: 1,
96+
},
97+
terminal,
98+
}
99+
return step
100+
}, [files, active, terminal])
101+
102+
const { prev, next, t } = useStepSpring(step)
103+
return (
104+
<EditorTransition
105+
{...frameProps}
106+
t={t}
107+
backward={false}
108+
prev={prev}
109+
next={next}
110+
codeProps={codeProps}
111+
/>
112+
)
113+
}
114+
function TwoPanelEditor({
115+
frameProps,
116+
codeProps,
117+
northPanel,
118+
southPanel,
119+
files,
120+
terminal,
121+
}: TwoPanelEditorProps) {
122+
const step = React.useMemo(() => {
123+
return {
124+
northPanel,
125+
southPanel,
126+
files,
127+
terminal,
128+
}
129+
}, [northPanel, southPanel, files, terminal])
130+
131+
const { prev, next, t } = useStepSpring(step)
132+
return (
133+
<EditorTransition
134+
{...frameProps}
135+
t={t}
136+
backward={false}
137+
prev={prev}
138+
next={next}
139+
codeProps={codeProps}
140+
/>
141+
)
142+
}
143+
144+
function useStepSpring(step: EditorStep) {
145+
const [{ target, prev, next }, setState] = React.useState(
146+
{
147+
target: 0,
148+
prev: step,
149+
next: step,
150+
}
151+
)
152+
153+
React.useEffect(() => {
154+
if (next != step) {
155+
setState(s => ({
156+
target: s.target + 1,
157+
prev: next,
158+
next: step,
159+
}))
160+
}
161+
}, [step])
162+
163+
const [progress] = useSpring(target, {
164+
stiffness: 256,
165+
damping: 24,
166+
mass: 0.2,
167+
decimals: 3,
168+
})
169+
170+
const t = progress % 1
171+
172+
return { prev, next, t: t || 1 }
173+
}
Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
import React from "react"
2-
import { useSpring } from "use-spring"
32
import {
43
EditorTransition,
54
EditorTransitionProps,
65
} from "./editor-transition"
76
import { EditorStep } from "./use-snapshots"
87
import { CodeProps } from "./code"
98

10-
type FullMiniEditorProps = EditorStep
11-
12-
export { FullMiniEditor, FullMiniEditorHike }
13-
14-
function FullMiniEditor(step: FullMiniEditorProps) {
15-
// const { prev, next, t } = useStepSpring(step)
16-
// return (
17-
// <EditorTransition
18-
// t={t}
19-
// backward={false}
20-
// prev={prev}
21-
// next={next}
22-
// />
23-
// )
24-
return null
25-
}
9+
export { FullMiniEditorHike }
2610

2711
function FullMiniEditorHike({
2812
steps = [],
@@ -68,34 +52,3 @@ function FullMiniEditorHike({
6852
function clamp(a: number, min: number, max: number) {
6953
return Math.max(Math.min(a, max), min)
7054
}
71-
72-
function useStepSpring(step: EditorStep) {
73-
const [{ target, prev, next }, setState] = React.useState(
74-
{
75-
target: 0,
76-
prev: step,
77-
next: step,
78-
}
79-
)
80-
81-
React.useEffect(() => {
82-
if (next != step) {
83-
setState(s => ({
84-
target: s.target + 1,
85-
prev: next,
86-
next: step,
87-
}))
88-
}
89-
}, [step])
90-
91-
const [progress] = useSpring(target, {
92-
stiffness: 256,
93-
damping: 24,
94-
mass: 0.2,
95-
decimals: 3,
96-
})
97-
98-
const t = progress % 1
99-
100-
return { prev, next, t: t || 1 }
101-
}

packages/storybook/src/mini-editor.story.js

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ export const focusEditor = () => {
2727
Focus
2828
</button>
2929
</div>
30-
<Editor code={code1} file="index.js" focus={focus} />
30+
<Editor
31+
code={code1}
32+
filename="index.js"
33+
focus={focus}
34+
lang="js"
35+
/>
3136
</Page>
3237
)
3338
}
@@ -47,7 +52,79 @@ export const codeEditor = () => {
4752
Change
4853
</button>
4954
</div>
50-
<Editor code={code} file="index.js" />
55+
<Editor code={code} filename="index.js" lang="js" />
56+
</Page>
57+
)
58+
}
59+
60+
export const singlePanelEditor = () => {
61+
const [input, setInput] = React.useState(code1)
62+
const [code, setCode] = React.useState(code1)
63+
const files = [
64+
{ name: "index.js", lang: "js", code: "" },
65+
{ name: "app.js", lang: "js", code },
66+
]
67+
return (
68+
<Page>
69+
<div style={{ margin: "20px auto", display: "flex" }}>
70+
<textarea
71+
value={input}
72+
onChange={e => setInput(e.target.value)}
73+
rows={5}
74+
/>
75+
<button onClick={_ => setCode(input)}>
76+
Change
77+
</button>
78+
</div>
79+
<Editor
80+
files={files}
81+
active="app.js"
82+
codeProps={{ maxZoom: 4, minColumns: 10 }}
83+
/>
84+
</Page>
85+
)
86+
}
87+
88+
export const twoPanelEditor = () => {
89+
const [input, setInput] = React.useState(code1)
90+
const [code, setCode] = React.useState(code1)
91+
const files = [
92+
{
93+
name: "index.js",
94+
lang: "js",
95+
code: "console.log(1)",
96+
},
97+
{ name: "app.js", lang: "js", code },
98+
]
99+
const northPanel = {
100+
active: "app.js",
101+
tabs: ["app.js"],
102+
heightRatio: 0.5,
103+
}
104+
const southPanel = {
105+
active: "index.js",
106+
tabs: ["index.js"],
107+
heightRatio: 0.5,
108+
}
109+
return (
110+
<Page>
111+
<div style={{ margin: "20px auto", display: "flex" }}>
112+
<textarea
113+
value={input}
114+
onChange={e => setInput(e.target.value)}
115+
rows={5}
116+
/>
117+
<button onClick={_ => setCode(input)}>
118+
Change
119+
</button>
120+
</div>
121+
<Editor
122+
files={files}
123+
northPanel={northPanel}
124+
southPanel={southPanel}
125+
codeProps={{ maxZoom: 1.2, minColumns: 10 }}
126+
frameProps={{ height: 500 }}
127+
/>
51128
</Page>
52129
)
53130
}

0 commit comments

Comments
 (0)