Skip to content

Commit a2ef79a

Browse files
author
Zaydek Michels-Gualtieri
committed
Prototyped display markdown mode; contexts do not work for text components because of deeplySyncTrees
1 parent 6b3929b commit a2ef79a

9 files changed

Lines changed: 91 additions & 26 deletions

File tree

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
[data-root="true"] {
2-
/* subpixel-antialiased */
1+
[data-root] {
32
-webkit-font-smoothing: auto;
43
-moz-osx-font-smoothing: auto;
54

@@ -8,3 +7,15 @@
87

98
caret-color: var(--black);
109
}
10+
11+
/* Obscures markdown syntax. */
12+
[data-display-markdown-mode="false"] [data-type="markdown"] {
13+
display: none;
14+
}
15+
16+
/* Masks markdown syntax as text-blue-600. */
17+
[data-display-markdown-mode="true"] [data-type="strike"] [data-type="markdown"] {
18+
--text-opacity: 1;
19+
color: #9fa6b2;
20+
color: rgba(159, 166, 178, var(--text-opacity));
21+
}

src/RichTextEditor/RichTextEditor.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import * as Range from "./methods/Range"
22
import Debugger from "./components/Debugger"
3+
import isCtrlOrMetaKey from "lib/Client/isCtrlOrMetaKey"
34
import React from "react"
45
import Renderer from "./components/Renderer"
56
import useDOMContentLoadedCallback from "lib/x/useDOMContentLoadedCallback"
67
import useRichTextEditor from "./useRichTextEditor"
78
import { parseRenderedChildren } from "./parsers"
89

10+
import "./RichTextEditor.css"
11+
912
const RichTextEditor = ({ markup, children }) => {
1013
const ref = React.useRef(null)
1114
const pointerdownRef = React.useRef(false)
@@ -15,6 +18,28 @@ const RichTextEditor = ({ markup, children }) => {
1518
// Disables read-only mode on DOMContentLoaded.
1619
useDOMContentLoadedCallback(dispatch.disableReadOnlyMode)
1720

21+
// Binds ctrl-/ or cmd-/ to toggle display display
22+
// markdown mode. Does not use onKeyDown because of the
23+
// readWriteOnlyHandler pattern.
24+
React.useEffect(
25+
React.useCallback(() => {
26+
const handler = e => {
27+
if (isCtrlOrMetaKey(e) && e.key === "/") {
28+
let toggle = dispatch.enableDisplayMarkdownMode
29+
if (state.displayMarkdownModeEnabled) {
30+
toggle = dispatch.disableDisplayMarkdownMode
31+
}
32+
toggle()
33+
}
34+
}
35+
document.addEventListener("keydown", handler)
36+
return () => {
37+
document.removeEventListener("keydown", handler)
38+
}
39+
}, [state, dispatch]),
40+
[state.displayMarkdownModeEnabled],
41+
)
42+
1843
// Returns a handler when read-only mode is disabled.
1944
const readWriteOnlyHandler = handler => {
2045
if (state.readOnlyModeEnabled) {
@@ -173,6 +198,8 @@ const RichTextEditor = ({ markup, children }) => {
173198
suppressContentEditableWarning={!state.readOnlyModeEnabled}
174199

175200
data-root
201+
data-read-only-mode={state.readOnlyModeEnabled}
202+
data-display-markdown-mode={state.displayMarkdownModeEnabled}
176203
>
177204
<Renderer
178205
forwardedRef={ref}
@@ -190,8 +217,8 @@ const RichTextEditor = ({ markup, children }) => {
190217
// readOnlyModeEnabled
191218
// displayMarkdownModeEnabled
192219
// focused
193-
// elements
194-
// range
220+
elements
221+
range
195222
// shouldRerender
196223
/>
197224

src/RichTextEditor/components/Debugger.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const Debugger = ({
1212
range,
1313
shouldRerender,
1414
}) => (
15-
<div className="mt-6 whitespace-pre-wrap font-mono text-xs" style={{ MozTabSize: 2, tabSize: 2 }}>
15+
<div className="mt-6 whitespace-pre-wrap text-sm font-mono" style={{ MozTabSize: 2, tabSize: 2 }}>
1616
{JSON.stringify(
1717
{
1818
...state,

src/RichTextEditor/components/Node.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const Node = ({ id, style, children, ...props }) => {
2222

2323
// https://github.com/codex-src/codex-wysiwyg/commit/f0755661d24e900804ab43b9657ec584c00bbbca
2424
const imperativeStyles = {
25-
...style, // Takes precedence
25+
...style,
2626
whiteSpace: "pre-wrap",
2727
overflowWrap: "break-word",
2828
}

src/RichTextEditor/components/Renderer.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ const Elements = ({ state, dispatch }) => (
1414
)
1515

1616
// Rerenders the current state on state.shouldRerender.
17-
const Renderer = ({ forwardedRef, state, dispatch }) => {
17+
const Renderer = ({ forwardedRef: tree, state, dispatch }) => {
1818
React.useLayoutEffect(
1919
React.useCallback(() => {
20-
if (!forwardedRef.current) {
20+
if (!tree.current) {
2121
// No-op
2222
return
2323
}
@@ -26,7 +26,7 @@ const Renderer = ({ forwardedRef, state, dispatch }) => {
2626
if (selection.rangeCount) {
2727
selection.removeAllRanges()
2828
}
29-
ReactDOM.render(<Elements state={state} dispatch={dispatch} />, forwardedRef.current, () => {
29+
ReactDOM.render(<Elements state={state} dispatch={dispatch} />, tree.current, () => {
3030
if (state.readOnlyModeEnabled /* FIXME? */ || !state.focused) {
3131
// No-op
3232
return
@@ -38,8 +38,8 @@ const Renderer = ({ forwardedRef, state, dispatch }) => {
3838
console.error(error)
3939
}
4040
})
41-
}, [forwardedRef, state, dispatch]),
42-
[forwardedRef.current, state.shouldRerender],
41+
}, [tree, state, dispatch]),
42+
[tree.current, state.shouldRerender],
4343
)
4444
return null
4545
}
Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
import attrs from "./attrs"
22
import React from "react"
33
import T from "./T"
4+
import toArray from "lib/Array/toArray"
5+
6+
const Syntax = ({ children }) => (
7+
<span className="text-sm font-mono text-blue-600" data-type="markdown">
8+
{children}
9+
</span>
10+
)
11+
12+
const Markdown = ({ syntax, children }) => (
13+
<React.Fragment>
14+
<Syntax>
15+
{toArray(syntax)[0]}
16+
</Syntax>
17+
{children}
18+
<Syntax>
19+
{toArray(syntax).slice(-1)[0]}
20+
</Syntax>
21+
</React.Fragment>
22+
)
423

524
// Renders <em>.
625
export const Em = ({ children }) => (
726
<T type="em">
827
<span className="italic">
9-
{children}
28+
<Markdown syntax="_">
29+
{children}
30+
</Markdown>
1031
</span>
1132
</T>
1233
)
@@ -15,7 +36,9 @@ export const Em = ({ children }) => (
1536
export const Strong = ({ children }) => (
1637
<T type="strong">
1738
<span className="font-semibold">
18-
{children}
39+
<Markdown syntax="**">
40+
{children}
41+
</Markdown>
1942
</span>
2043
</T>
2144
)
@@ -24,7 +47,9 @@ export const Strong = ({ children }) => (
2447
export const Code = ({ children }) => (
2548
<T type="code">
2649
<span className="mx-px py-1 text-sm font-mono text-blue-600 border border-cool-gray-300" {...attrs.code}>
27-
{children}
50+
<Markdown syntax="`">
51+
{children}
52+
</Markdown>
2853
</span>
2954
</T>
3055
)
@@ -33,7 +58,9 @@ export const Code = ({ children }) => (
3358
export const Strike = ({ children }) => (
3459
<T type="strike">
3560
<span className="line-through text-gray-400">
36-
{children}
61+
<Markdown syntax="~~">
62+
{children}
63+
</Markdown>
3764
</span>
3865
</T>
3966
)
@@ -42,7 +69,9 @@ export const Strike = ({ children }) => (
4269
export const A = ({ href, children }) => (
4370
<T type="a" props={{ href }}>
4471
<span className="mx-px underline text-blue-600" {...attrs.a}>
72+
{/* <Markdown syntax="TODO"> */}
4573
{children}
74+
{/* </Markdown> */}
4675
</span>
4776
</T>
4877
)

src/RichTextEditor/useRichTextEditor.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ function parseElements({ markup, children }) {
5353
return parseSemanticElements(tree)
5454
}
5555

56+
// TODO: Add support for read-only mode enabled and display
57+
// markdown mode enabled
5658
function useRichTextEditor({ markup, children }) {
5759
const initialState = React.useMemo(() => {
5860
const elements = parseElements({ markup, children })

src/lib/Client/isCtrlOrMetaKey/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import userAgent from "lib/Client/userAgent"
55
//
66
// https://css-tricks.com/snippets/javascript/test-mac-pc-javascript
77
function isCtrlOrMetaKey(e) {
8-
let AAPL = userAgent.AAPL
8+
let isAAPL = userAgent.isAAPL
99
if (process.env.NODE_ENV === "test") {
10-
AAPL = navigator.userAgent.indexOf("Mac OS X") >= 0
10+
isAAPL = navigator.userAgent.indexOf("Mac OS X") >= 0
1111
}
12-
if (!AAPL) {
12+
if (!isAAPL) {
1313
const ok = (
1414
e.ctrlKey &&
1515
!e.metaKey

src/lib/Client/userAgent/index.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ function testUserAgent(substr) {
55
return navigator.userAgent.indexOf(substr) >= 0
66
}
77

8-
// https://apple.com
9-
const isAAPL = testUserAgent("Mac OS X")
10-
11-
// https://android.com
12-
const isGOOG = testUserAgent("Android")
13-
148
const userAgent = {
15-
isAAPL,
16-
isGOOG,
9+
// https://apple.com
10+
isAAPL: testUserAgent("Mac OS X"),
11+
// https://android.com
12+
isGOOG: testUserAgent("Android"),
1713
}
1814

1915
export default userAgent

0 commit comments

Comments
 (0)