-
Notifications
You must be signed in to change notification settings - Fork 10
/
typist-editor-decorator.tsx
106 lines (91 loc) · 3.92 KB
/
typist-editor-decorator.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { forwardRef, useCallback, useEffect, useState } from 'react'
import { Box, Column, Columns } from '@doist/reactist'
import classNames from 'classnames'
import { TypistEditorToolbar } from './typist-editor-toolbar'
import styles from './typist-editor-decorator.module.css'
import type { PartialStoryFn } from '@storybook/csf'
import type { ReactRenderer } from '@storybook/react'
import type { CoreEditor, TypistEditorProps, TypistEditorRef, UpdateProps } from '../../../../src'
type TypistEditorPropsWithRef = Partial<
TypistEditorProps & {
ref: React.LegacyRef<TypistEditorRef>
}
>
type TypistEditorDecoratorProps = {
Story: PartialStoryFn<ReactRenderer, TypistEditorPropsWithRef>
args: TypistEditorProps
withToolbar?: boolean
renderBottomFunctions?: () => JSX.Element
}
const TypistEditorDecorator = forwardRef<TypistEditorRef, TypistEditorDecoratorProps>(
function TypistEditorDecorator(
{ Story, args, withToolbar = false, renderBottomFunctions },
forwardedRef,
) {
const [typistEditor, setTypistEditor] = useState<CoreEditor | null>(null)
const [markdownOutput, setMarkdownOutput] = useState(args.content)
const storyClassName = classNames('markdown-body', args.className)
const shouldRenderToolbar = typistEditor && withToolbar
const handleUpdate = useCallback((props: UpdateProps) => {
setMarkdownOutput(props.getMarkdown())
}, [])
useEffect(
function updateMarkdownOutputOnContentControlChange() {
setMarkdownOutput(args.content)
},
[args.content],
)
return (
<Box display="flex" flexDirection="column" height="full">
<Columns exceptionallySetClassName={styles.topContainer}>
<Column width="1/2">
<h3>Typist Editor</h3>
{shouldRenderToolbar ? <TypistEditorToolbar editor={typistEditor} /> : null}
<Box
className={styles.editorContainer}
marginX="large"
marginBottom="large"
>
<Story
args={{
...args,
className: storyClassName,
onUpdate: handleUpdate,
ref: (instance) => {
setTypistEditor(instance?.getEditor() || null)
if (typeof forwardedRef === 'function') {
forwardedRef(instance)
} else if (forwardedRef) {
forwardedRef.current = instance
}
},
}}
/>
</Box>
</Column>
<Column width="1/2">
<h3>Markdown Output</h3>
<Box
className={styles.outputContainer}
marginX="large"
marginBottom="large"
>
<pre>{markdownOutput}</pre>
</Box>
</Column>
</Columns>
{renderBottomFunctions ? (
<Box
display="flex"
justifyContent="center"
flexWrap="wrap"
className={styles.bottomFunctionsContainer}
>
{renderBottomFunctions()}
</Box>
) : null}
</Box>
)
},
)
export { TypistEditorDecorator }