Skip to content

Commit 0672aff

Browse files
committed
Pick up block components from props
1 parent 5ad27f4 commit 0672aff

8 files changed

Lines changed: 71 additions & 62 deletions

File tree

packages/editor/src/components/Editor.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import { parseMDX, serializer } from '@blocks/serializer'
88
import { isUrl, isImageUrl } from '../lib/util'
99

1010
import ThemeEditorPlugin from '../plugins/theme-editor'
11+
import { Context } from './context'
1112
import defaultTheme from './theme'
1213
import defaultPlugins from '../plugins'
14+
import defaultBlocks from './blocks'
1315
import Toolbar from './Toolbar'
1416

1517
const insertImage = (change, src, target) => {
@@ -101,22 +103,31 @@ class BlockEditor extends Component {
101103
}
102104

103105
render() {
104-
const { plugins, theme } = this.props
105-
const allPlugins = [ThemeEditorPlugin({ theme }), ...plugins]
106+
const { plugins, theme, components } = this.props
107+
const allComponents = {
108+
...defaultBlocks,
109+
...components
110+
}
111+
const context = {
112+
components: allComponents
113+
}
106114

107115
return (
108116
<div style={{ minHeight: '100vh' }}>
109-
<Editor
110-
{...this.props}
111-
ref={editor => (this.editor = editor)}
112-
schema={schema}
113-
placeholder="Write some MDX..."
114-
plugins={allPlugins}
115-
value={this.state.value}
116-
onChange={this.handleChange}
117-
onKeyDown={this.handleKeyDown}
118-
onPaste={this.handlePaste}
119-
/>
117+
<Context.Provider value={context}>
118+
<Editor
119+
{...this.props}
120+
ref={editor => (this.editor = editor)}
121+
components={allComponents}
122+
schema={schema}
123+
placeholder="Write some MDX..."
124+
plugins={plugins}
125+
value={this.state.value}
126+
onChange={this.handleChange}
127+
onKeyDown={this.handleKeyDown}
128+
onPaste={this.handlePaste}
129+
/>
130+
</Context.Provider>
120131
</div>
121132
)
122133
}
@@ -125,7 +136,7 @@ class BlockEditor extends Component {
125136
BlockEditor.defaultProps = {
126137
components: {},
127138
theme: defaultTheme,
128-
plugins: defaultPlugins,
139+
plugins: [ThemeEditorPlugin({ theme: defaultTheme }), ...defaultPlugins],
129140
renderEditor: (props, editor, next) => {
130141
const children = next()
131142
return (

packages/editor/src/components/Toolbar.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,16 @@ const defaultChildren = (
152152
</>
153153
)
154154

155+
const getBlockComponentNames = components => {
156+
return Object.keys(components).filter(
157+
key => typeof components[key].propertyControls === 'object'
158+
)
159+
}
160+
155161
export const Toolbar = props => {
156162
const { editor, children, components } = props
157163

158-
console.log('components', Object.keys(components))
164+
const blocks = getBlockComponentNames(components)
159165

160166
return (
161167
<Context.Provider value={{ editor }}>
@@ -168,7 +174,7 @@ export const Toolbar = props => {
168174
onSelect={item => {
169175
editor.insertJSXBlock(item, {})
170176
}}
171-
options={['YouTube', 'Tweet', 'Gist']}
177+
options={blocks}
172178
/>
173179
</Root>
174180
</Context.Provider>
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import YouTube from './YouTube'
2+
import Tweet from './Tweet'
3+
import Gist from './Gist'
4+
5+
export default {
6+
YouTube,
7+
Tweet,
8+
Gist
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// internal context without styles applied
2+
import React from 'react'
3+
4+
export const Context = React.createContext(null)
Lines changed: 25 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
/** @jsx jsx */
22
import { jsx } from '@emotion/core'
3-
import React from 'react'
3+
import React, { useContext } from 'react'
44
import { Data } from 'slate'
5+
import { Context } from '../../components/context'
56
import Form from './Form'
67
import Overlay from './Overlay'
7-
import YouTube from './YouTube'
8-
import Tweet from './Tweet'
9-
import Gist from './Gist'
108

119
const hasJSXBlock = (editor, type) => {
1210
if (!editor.hasBlock('jsx-void') && !editor.hasBlock('jsx')) return false
@@ -30,24 +28,6 @@ const insertJSXBlock = (editor, type, props) => {
3028
})
3129
}
3230

33-
const insertYouTube = editor => {
34-
editor.insertJSXBlock('YouTube', {
35-
videoId: ''
36-
})
37-
}
38-
39-
const insertTweet = editor => {
40-
editor.insertJSXBlock('Tweet', {
41-
tweetId: ''
42-
})
43-
}
44-
45-
const insertGist = editor => {
46-
editor.insertJSXBlock('Gist', {
47-
id: ''
48-
})
49-
}
50-
5131
const getProps = node => {
5232
const map = node.data.get('props')
5333
if (typeof map.toJS !== 'function') return map
@@ -61,7 +41,7 @@ const Wrapper = ({
6141
component,
6242
Component,
6343
props,
64-
fields
44+
fields = {}
6545
}) => {
6646
return (
6747
<div>
@@ -91,11 +71,19 @@ const Wrapper = ({
9171
)
9272
}
9373

94-
// placeholder
95-
const components = {
96-
YouTube,
97-
Gist,
98-
Tweet
74+
const Node = ({ type, next, ...props }) => {
75+
const { components } = useContext(Context)
76+
const Component = components[type]
77+
if (!Component) return next()
78+
79+
return (
80+
<Wrapper
81+
{...props}
82+
Component={Component}
83+
component={type}
84+
fields={Component.propertyControls}
85+
/>
86+
)
9987
}
10088

10189
export default (opts = {}) => ({
@@ -104,30 +92,21 @@ export default (opts = {}) => ({
10492
},
10593
commands: {
10694
insertJSXBlock,
107-
insertYouTube,
108-
insertTweet,
109-
insertGist,
11095
setJSXProps
11196
},
11297
renderNode: (props, editor, next) => {
11398
const { node } = props
11499
if (node.type !== 'jsx-void') return next()
115100
const type = node.data.get('type')
116101

117-
if (components[type]) {
118-
const Component = components[type]
119-
return (
120-
<Wrapper
121-
{...props}
122-
editor={editor}
123-
Component={Component}
124-
component={type}
125-
props={getProps(node)}
126-
fields={Component.propertyControls}
127-
/>
128-
)
129-
}
130-
131-
return next()
102+
return (
103+
<Node
104+
{...props}
105+
next={next}
106+
editor={editor}
107+
type={type}
108+
props={getProps(node)}
109+
/>
110+
)
132111
}
133112
})

0 commit comments

Comments
 (0)