diff --git a/src/Editor.module.css b/src/Editor.module.css new file mode 100644 index 0000000..d3075af --- /dev/null +++ b/src/Editor.module.css @@ -0,0 +1,52 @@ +.EditorTextWrapper { + /* TODO: This flex should be in the parent */ + flex: 1; + flex-basis: 0; + position: relative; + background: white; + font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, + "DejaVu Sans Mono", monospace; + font-weight: normal; + font-size: 1.3rem; + text-align: initial; +} + +.EditorTextArea, +.EditorUnderlay { + font-family: inherit; + font-weight: inherit; + font-size: inherit; + padding: 5px; + box-sizing: border-box; + margin: 0; + line-height: normal; +} + +.EditorTextArea { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + box-sizing: border-box; + border: none; + background-color: transparent; + resize: none; + outline: none; +} + +.EditorUnderlay { + width: 100%; + height: 100%; + pointer-events: none; + color: transparent; + white-space: pre-wrap; + word-wrap: break-word; + overflow-y: scroll; + + .EditorHighlighted { + background: #ffff00; + } +} diff --git a/src/Editor.module.css.d.ts b/src/Editor.module.css.d.ts new file mode 100644 index 0000000..930d01a --- /dev/null +++ b/src/Editor.module.css.d.ts @@ -0,0 +1,4 @@ +export const EditorTextWrapper: string; +export const EditorTextArea: string; +export const EditorUnderlay: string; +export const EditorHighlighted: string; diff --git a/src/Editor.tsx b/src/Editor.tsx index e69de29..27d3816 100644 --- a/src/Editor.tsx +++ b/src/Editor.tsx @@ -0,0 +1,54 @@ +import React, { useEffect, useRef } from "react"; +import { Highlight } from "./highlight"; +import { buildShadow } from "./shadow"; +import styles from "./Editor.module.css"; + +interface EditorProps { + value: string; + setValue: Function; + highlights: Highlight[]; + clearHighlights: Function; +} +function Editor({ + value, + setValue, + highlights, + clearHighlights, +}: EditorProps): React.ReactNode { + function handleChange(event: React.ChangeEvent) { + setValue(event.target.value); + clearHighlights(); + } + + const textAreaRef = useRef(null); + const shadowRef = useRef(null); + function onTextAreaScroll() { + if (shadowRef.current !== null && textAreaRef.current !== null) { + const textAreaScrollTop = textAreaRef.current.scrollTop; + shadowRef.current.scrollTop = textAreaScrollTop; + } + } + + useEffect(() => { + // Make sure the text area and shadow div start out in sync. + onTextAreaScroll(); + }, []); + + return ( +
+