Skip to content

Commit 30e993d

Browse files
author
Zaydek Michels-Gualtieri
committed
Prototyped handlers
1 parent 68784d2 commit 30e993d

2 files changed

Lines changed: 298 additions & 3 deletions

File tree

src/Editor/Editor.js

Lines changed: 289 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,300 @@
11
import React from "react"
2+
import ReactDOM from "react-dom"
3+
4+
// const MemoElements = React.memo(({ elements }) => (
5+
// elements.map(each => (
6+
// React.createElement(componentMap[each.type], {
7+
// ...each.props,
8+
// key: each.key, // For React
9+
// id: each.key, // For the DOM
10+
// })
11+
// ))
12+
// ))
213

314
const Editor = ({
15+
id,
16+
className,
17+
style,
18+
419
state,
520
dispatch,
621
}) => {
7-
// ...
22+
const articleRef = React.useRef(null)
23+
const isPointerDownRef = React.useRef(false)
24+
25+
// Rerenders on state.shouldRerender.
26+
//
27+
// eslint-disable-next-line react-hooks/exhaustive-deps
28+
React.useLayoutEffect(
29+
React.useCallback(() => {
30+
// https://bugs.chromium.org/p/chromium/issues/detail?id=138439#c10
31+
const selection = document.getSelection()
32+
if (selection.rangeCount) {
33+
selection.removeAllRanges()
34+
}
35+
ReactDOM.render(
36+
// <MemoElements elements={state.elements} />,
37+
"Hello, world!",
38+
articleRef.current,
39+
() => {
40+
if (!state.focused) {
41+
// No-op
42+
return
43+
}
44+
// try {
45+
// const userRange = convRangeToUserLiteral(state.range)
46+
// selection.addRange(userRange)
47+
// } catch (error) {
48+
// console.error(error)
49+
// }
50+
},
51+
)
52+
}, [state]),
53+
[state.shouldRerender],
54+
)
855

956
return (
10-
"Hello, world!"
57+
<article
58+
ref={articleRef}
59+
60+
id={id}
61+
className={["em-context", className].filter(Boolean).join(" ")}
62+
style={style}
63+
64+
onFocus={e => {
65+
// dispatch({
66+
// type: "FOCUS",
67+
// })
68+
}}
69+
70+
onBlur={e => {
71+
// dispatch({
72+
// type: "BLUR",
73+
// })
74+
}}
75+
76+
onPointerDown={e => {
77+
// isPointerDownRef.current = true
78+
}}
79+
80+
onPointerMove={e => {
81+
// if (!state.focused || !isPointerDownRef.current) {
82+
// if (!state.focused && isPointerDownRef.current) {
83+
// isPointerDownRef.current = false
84+
// }
85+
// return
86+
// }
87+
// const range = getCurrentRange(ref.current)
88+
// if (!range) {
89+
// // No-op
90+
// return
91+
// }
92+
// dispatch({
93+
// type: "SELECT",
94+
// range,
95+
// })
96+
}}
97+
98+
onPointerUp={e => {
99+
// isPointerDownRef.current = false
100+
}}
101+
102+
// TODO: Add COMPAT guard for select-all or prevent
103+
// default?
104+
onSelect={e => {
105+
// try {
106+
// const range = getCurrentRange(ref.current)
107+
// if (!range) {
108+
// // No-op
109+
// return
110+
// }
111+
// dispatch({
112+
// type: "SELECT",
113+
// range,
114+
// })
115+
// } catch (error) {
116+
// console.error(error)
117+
// }
118+
}}
119+
120+
onKeyDown={e => {
121+
// let formatType = ""
122+
// let text = ""
123+
// let deleteType = ""
124+
//
125+
// const keyDownType = keyDownTypeFor(e)
126+
// if (keyDownType) {
127+
// console.log(keyDownType)
128+
// }
129+
//
130+
// switch (keyDownType) {
131+
// case "apply-format-plaintext":
132+
// case "apply-format-em":
133+
// case "apply-format-strong":
134+
// case "apply-format-code":
135+
// case "apply-format-strike":
136+
// case "apply-format-a":
137+
// // NOTE: Formatting events must always be
138+
// // prevented.
139+
// e.preventDefault()
140+
// if (testForSelection(state)) {
141+
// formatType = keyDownType.slice("apply-format-".length)
142+
// const types = {}
143+
// if (formatType !== "plaintext") {
144+
// types[formatType] = {} // TODO
145+
// }
146+
// dispatch({
147+
// type: "APPLY_TYPES",
148+
// types,
149+
// })
150+
// }
151+
// break
152+
// case "apply-format-markdown-em":
153+
// case "apply-format-markdown-strong":
154+
// case "apply-format-markdown-code":
155+
// case "apply-format-markdown-strike":
156+
// case "apply-format-markdown-a":
157+
//
158+
// // // NOTE: Formatting events must always be
159+
// // // prevented.
160+
// // e.preventDefault()
161+
//
162+
// if (testForSelection(state)) {
163+
// e.preventDefault()
164+
// formatType = keyDownType.slice("apply-format-markdown-".length)
165+
// const types = {}
166+
// if (formatType !== "plaintext") {
167+
// // types[formatType] = {}
168+
// types[formatType] = formatType !== "a" ? {} : {
169+
// href: "TODO",
170+
// }
171+
// }
172+
// dispatch({
173+
// type: "APPLY_TYPES",
174+
// types,
175+
// })
176+
// }
177+
// break
178+
// case "insert-text":
179+
// if (testForSelection(state)) {
180+
// e.preventDefault()
181+
// text = e.key
182+
// dispatch({
183+
// type: "INSERT_TEXT",
184+
// text,
185+
// })
186+
// }
187+
// break
188+
// case "insert-composed-text-unidentified":
189+
// case "insert-composed-text-identified":
190+
// if (testForSelection(state) && state.range.start.key !== state.range.end.key) {
191+
// e.preventDefault()
192+
// // COMPAT: e.preventDefault(...) on
193+
// // "insert-composed-text-unidentified" breaks
194+
// // composition and oncompositionend is never
195+
// // emitted. In Chrome 84, use of
196+
// // document.activeElement.blur(...) appears to
197+
// // emit oncompositionend.
198+
// const selection = document.getSelection()
199+
// if (selection.rangeCount) {
200+
// document.activeElement.blur()
201+
// const range = {
202+
// ...state.range,
203+
// end: state.range.start,
204+
// }
205+
// setTimeout(() => {
206+
// const userRange = convRangeToUserLiteral(range)
207+
// selection.addRange(userRange)
208+
// }, 0)
209+
// }
210+
// dispatch({
211+
// type: "INSERT_TEXT",
212+
// text: "",
213+
// })
214+
// }
215+
// break
216+
// case "insert-tab":
217+
// e.preventDefault()
218+
// text = "\t"
219+
// dispatch({
220+
// type: "INSERT_TEXT",
221+
// text,
222+
// })
223+
// break
224+
// case "insert-soft-paragraph":
225+
// case "insert-hard-paragraph":
226+
// case "insert-horizontal-rule":
227+
// e.preventDefault()
228+
// dispatch({
229+
// type: "INSERT_HARD_PARAGRAPH",
230+
// })
231+
// break
232+
// case "delete-rtl-rune":
233+
// case "delete-rtl-word":
234+
// case "delete-rtl-line":
235+
// case "delete-ltr-rune":
236+
// case "delete-ltr-word":
237+
// e.preventDefault()
238+
// deleteType = keyDownType.slice("delete-".length)
239+
// dispatch({
240+
// type: "DELETE",
241+
// deleteType,
242+
// })
243+
// break
244+
// case "undo":
245+
// case "redo":
246+
// e.preventDefault()
247+
// // TODO
248+
// break
249+
// default:
250+
// // No-op
251+
// break
252+
// }
253+
}}
254+
255+
onCompositionEnd={e => {
256+
// const range = getCurrentRange(ref.current)
257+
// const children = parseRenderedChildren(document.getElementById(range.start.key))
258+
// dispatch({
259+
// type: "UNCONTROLLED_INPUT",
260+
// range,
261+
// children,
262+
// noopRender: false, // onCompositionEnd must rerender
263+
// })
264+
}}
265+
266+
onInput={e => {
267+
// const range = getCurrentRange(ref.current)
268+
// const children = parseRenderedChildren(document.getElementById(range.start.key))
269+
// dispatch({
270+
// type: "UNCONTROLLED_INPUT",
271+
// range,
272+
// children,
273+
// noopRender: e.nativeEvent.isComposing,
274+
// })
275+
}}
276+
277+
// onCut={e => {
278+
// // TODO
279+
// }}
280+
281+
// onCopy={e => {
282+
// // TODO
283+
// }}
284+
285+
// onPaste={e => {
286+
// // TODO
287+
// }}
288+
289+
onDragStart={e => {
290+
e.preventDefault()
291+
}}
292+
293+
contentEditable
294+
suppressContentEditableWarning
295+
296+
data-codex-root
297+
/>
11298
)
12299
}
13300

src/EditorApp/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ const EditorApp = () => {
1616
)
1717
}
1818

19-
export default EditorApp
19+
const Layout = () => (
20+
<div className="px-4 py-24 flex flex-row justify-center">
21+
<div className="w-full max-w-3xl">
22+
<EditorApp />
23+
</div>
24+
</div>
25+
)
26+
27+
export default Layout

0 commit comments

Comments
 (0)