mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-23 07:22:55 +02:00
refactor placeholder to use schema (#1253)
* refactor placeholder to use schema * update placeholder, remove old export * add maxWidth to prevent overflow * update docs
This commit is contained in:
@@ -48,7 +48,6 @@
|
||||
## Slate React
|
||||
|
||||
- [Editor](./reference/slate-react/editor.md)
|
||||
- [Placeholder](./reference/slate-react/placeholder.md)
|
||||
- [Plugins](./reference/slate-react/plugins.md)
|
||||
- [Custom Nodes](./reference/slate-react/custom-nodes.md)
|
||||
- [Core Plugins](./reference/slate-react/core-plugins.md)
|
||||
|
@@ -1,58 +0,0 @@
|
||||
|
||||
# `<Placeholder>`
|
||||
|
||||
```js
|
||||
import { Placeholder } from 'slate-react'
|
||||
```
|
||||
|
||||
A simple component that adds a placeholder to a node. It encapsulates all of the Slate-related logic that determines when to render the placeholder, so you don't have to think about it.
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
```js
|
||||
<Placeholder
|
||||
className={String}
|
||||
node={Node}
|
||||
parent={Node}
|
||||
state={State}
|
||||
style={Object}
|
||||
>
|
||||
{children}
|
||||
</Placeholder>
|
||||
```
|
||||
|
||||
### `children`
|
||||
`Any`
|
||||
|
||||
React child elements to render inside the placeholder `<span>` element.
|
||||
|
||||
### `className`
|
||||
`String`
|
||||
|
||||
An optional class name string to add to the placeholder `<span>` element.
|
||||
|
||||
### `firstOnly`
|
||||
`Boolean`
|
||||
|
||||
An optional toggle that allows the Placeholder to render even if it is not the first node of the parent. This is useful for cases where the Placeholder should show up at every empty instance of the node. Defaults to `true`.
|
||||
|
||||
### `node`
|
||||
`Node`
|
||||
|
||||
The node to render the placeholder element on top of. The placeholder is positioned absolutely, covering the entire node.
|
||||
|
||||
### `parent`
|
||||
`Node`
|
||||
|
||||
The node to check for non-empty content, to determine whether the placeholder should be shown or not, if `firstOnly` is set to `false`.
|
||||
|
||||
### `state`
|
||||
`State`
|
||||
|
||||
The current state of the editor.
|
||||
|
||||
### `style`
|
||||
`Object`
|
||||
|
||||
An optional dictionary of styles to pass to the placeholder `<span>` element.
|
@@ -84,6 +84,7 @@ Internally, the `marks` and `nodes` properties of a schema are simply converted
|
||||
match: Function,
|
||||
decorate: Function,
|
||||
normalize: Function,
|
||||
placeholder: Component || Function,
|
||||
render: Component || Function || Object || String,
|
||||
validate: Function
|
||||
}
|
||||
@@ -140,6 +141,18 @@ The `decorate` property allows you define a function that will apply extra marks
|
||||
|
||||
The `normalize` property is a function to run that recovers the editor's state after the `validate` property of a rule has determined that an object is invalid. It is passed a [`Change`](./change.md) that it can use to make modifications. It is also passed the return value of the `validate` function, which makes it easy to quickly determine the failure reason from the validation.
|
||||
|
||||
### `placeholder`
|
||||
`Component` <br/>
|
||||
`Function`
|
||||
|
||||
```js
|
||||
{
|
||||
placeholder: (props) => <span>{props.editor.props.placeholder}</span>
|
||||
}
|
||||
```
|
||||
|
||||
The `placeholder` property determines which React component Slate will use to render a placeholder for the editor.
|
||||
|
||||
### `render`
|
||||
`Component` <br/>
|
||||
`Function` <br/>
|
||||
|
@@ -145,7 +145,7 @@ class CheckLists extends React.Component {
|
||||
<div className="editor">
|
||||
<Editor
|
||||
spellCheck
|
||||
placeholder={'Enter some text...'}
|
||||
placeholder="Get to work..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -190,6 +190,7 @@ class CodeHighlighting extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Write some code..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onKeyDown={this.onKeyDown}
|
||||
|
@@ -56,6 +56,7 @@ class Embeds extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -129,6 +129,7 @@ class Emojis extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Write some 😍👋🎉..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -101,6 +101,7 @@ class ForcedLayout extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
placeholder="Enter a title..."
|
||||
state={this.state.state}
|
||||
schema={this.state.schema}
|
||||
onChange={this.onChange}
|
||||
|
@@ -165,6 +165,7 @@ class HoveringMenu extends React.Component {
|
||||
/>
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -105,7 +105,7 @@ class HugeDocument extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
placeholder={'Enter some text...'}
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
spellCheck={false}
|
||||
state={this.state.state}
|
||||
|
@@ -152,6 +152,7 @@ class Images extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -187,6 +187,7 @@ class Links extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -155,6 +155,7 @@ class MarkdownPreview extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Write some markdown..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -77,6 +77,7 @@ class MarkdownShortcuts extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Write some markdown..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -196,6 +196,7 @@ class PasteHtml extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Paste in some HTML..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onPaste={this.onPaste}
|
||||
|
@@ -41,7 +41,7 @@ class PlainText extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
placeholder={'Enter some plain text...'}
|
||||
placeholder="Enter some plain text..."
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
|
@@ -83,7 +83,7 @@ The third is an example of using the plugin.render property to create a higher-o
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
placeholder={'Enter some text...'}
|
||||
placeholder="Enter some text..."
|
||||
plugins={plugins}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -42,7 +42,7 @@ class ReadOnly extends React.Component {
|
||||
return (
|
||||
<Editor
|
||||
readOnly
|
||||
placeholder={'Enter some text...'}
|
||||
placeholder="Enter some text..."
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
|
@@ -295,12 +295,12 @@ class RichTextExample extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some rich text..."
|
||||
schema={schema}
|
||||
spellCheck
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
schema={schema}
|
||||
placeholder={'Enter some rich text...'}
|
||||
spellCheck
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@@ -69,7 +69,7 @@ class PlainText extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
placeholder={'Enter some plain text...'}
|
||||
placeholder="Enter some plain text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
|
@@ -133,7 +133,7 @@ class SearchHighlighting extends React.Component {
|
||||
state={this.state.state}
|
||||
onChange={this.onChange}
|
||||
schema={schema}
|
||||
placeholder={'Enter some rich text...'}
|
||||
placeholder="Enter some rich text..."
|
||||
spellCheck
|
||||
/>
|
||||
</div>
|
||||
|
@@ -209,7 +209,7 @@ class SyncingEditor extends React.Component {
|
||||
onChange={this.onChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
schema={schema}
|
||||
placeholder={'Enter some rich text...'}
|
||||
placeholder="Enter some text..."
|
||||
spellCheck
|
||||
/>
|
||||
</div>
|
||||
|
@@ -134,6 +134,7 @@ class Tables extends React.Component {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
schema={schema}
|
||||
state={this.state.state}
|
||||
onKeyDown={this.onKeyDown}
|
||||
|
51
packages/slate-react/src/components/default-node.js
Normal file
51
packages/slate-react/src/components/default-node.js
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
import React from 'react'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import Types from 'prop-types'
|
||||
|
||||
/**
|
||||
* Default node.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class DefaultNode extends React.Component {
|
||||
|
||||
/**
|
||||
* Prop types.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
static propTypes = {
|
||||
attributes: Types.object.isRequired,
|
||||
editor: Types.object.isRequired,
|
||||
isSelected: Types.bool.isRequired,
|
||||
node: SlateTypes.node.isRequired,
|
||||
parent: SlateTypes.node.isRequired,
|
||||
readOnly: Types.bool.isRequired,
|
||||
state: SlateTypes.state.isRequired,
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
render() {
|
||||
const { attributes, children, node } = this.props
|
||||
const Tag = node.kind == 'block' ? 'div' : 'span'
|
||||
const style = { position: 'relative' }
|
||||
return <Tag {...attributes} style={style}>{children}</Tag>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
export default DefaultNode
|
64
packages/slate-react/src/components/default-placeholder.js
Normal file
64
packages/slate-react/src/components/default-placeholder.js
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
import React from 'react'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import Types from 'prop-types'
|
||||
|
||||
/**
|
||||
* Default placeholder.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class DefaultPlaceholder extends React.Component {
|
||||
|
||||
/**
|
||||
* Property types.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
static propTypes = {
|
||||
editor: Types.object.isRequired,
|
||||
isSelected: Types.bool.isRequired,
|
||||
node: SlateTypes.node.isRequired,
|
||||
parent: SlateTypes.node.isRequired,
|
||||
readOnly: Types.bool.isRequired,
|
||||
state: SlateTypes.state.isRequired,
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
render() {
|
||||
const { editor, state } = this.props
|
||||
if (state.document.nodes.size > 1) return null
|
||||
if (!editor.props.placeholder) return null
|
||||
|
||||
const style = {
|
||||
pointerEvents: 'none',
|
||||
display: 'inline-block',
|
||||
width: '0',
|
||||
maxWidth: '100%',
|
||||
whiteSpace: 'nowrap',
|
||||
opacity: '0.333',
|
||||
}
|
||||
|
||||
return (
|
||||
<span contentEditable={false} style={style}>
|
||||
{editor.props.placeholder}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
export default DefaultPlaceholder
|
@@ -54,6 +54,7 @@ class Node extends React.Component {
|
||||
const { node, schema } = props
|
||||
this.state = {}
|
||||
this.state.Component = node.getComponent(schema)
|
||||
this.state.Placeholder = node.getPlaceholder(schema)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +79,8 @@ class Node extends React.Component {
|
||||
componentWillReceiveProps = (props) => {
|
||||
if (props.node == this.props.node) return
|
||||
const Component = props.node.getComponent(props.schema)
|
||||
this.setState({ Component })
|
||||
const Placeholder = props.node.getPlaceholder(props.schema)
|
||||
this.setState({ Component, Placeholder })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +156,7 @@ class Node extends React.Component {
|
||||
this.debug('render', { props })
|
||||
|
||||
const { editor, isSelected, node, parent, readOnly, state } = props
|
||||
const { Component } = this.state
|
||||
const { Component, Placeholder } = this.state
|
||||
const { selection } = state
|
||||
const indexes = node.getSelectionIndexes(selection, isSelected)
|
||||
const children = node.nodes.toArray().map((child, i) => {
|
||||
@@ -173,17 +175,19 @@ class Node extends React.Component {
|
||||
if (direction == 'rtl') attributes.dir = 'rtl'
|
||||
}
|
||||
|
||||
const p = {
|
||||
editor,
|
||||
isSelected,
|
||||
key: node.key,
|
||||
node,
|
||||
parent,
|
||||
readOnly,
|
||||
state
|
||||
}
|
||||
|
||||
const element = (
|
||||
<Component
|
||||
attributes={attributes}
|
||||
editor={editor}
|
||||
isSelected={isSelected}
|
||||
key={node.key}
|
||||
node={node}
|
||||
parent={parent}
|
||||
readOnly={readOnly}
|
||||
state={state}
|
||||
>
|
||||
<Component {...p} attributes={attributes}>
|
||||
{Placeholder && <Placeholder {...p} />}
|
||||
{children}
|
||||
</Component>
|
||||
)
|
||||
|
@@ -1,125 +0,0 @@
|
||||
|
||||
import React from 'react'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import Types from 'prop-types'
|
||||
|
||||
/**
|
||||
* Placeholder.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class Placeholder extends React.Component {
|
||||
|
||||
/**
|
||||
* Property types.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
static propTypes = {
|
||||
children: Types.any.isRequired,
|
||||
className: Types.string,
|
||||
firstOnly: Types.bool,
|
||||
node: SlateTypes.node.isRequired,
|
||||
parent: SlateTypes.node,
|
||||
state: SlateTypes.state.isRequired,
|
||||
style: Types.object,
|
||||
}
|
||||
|
||||
/**
|
||||
* Default properties.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
static defaultProps = {
|
||||
firstOnly: true,
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the placeholder update?
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Object} state
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
shouldComponentUpdate = (props, state) => {
|
||||
return (
|
||||
props.children != this.props.children ||
|
||||
props.className != this.props.className ||
|
||||
props.firstOnly != this.props.firstOnly ||
|
||||
props.parent != this.props.parent ||
|
||||
props.node != this.props.node ||
|
||||
props.style != this.props.style
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the placeholder visible?
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
isVisible = () => {
|
||||
const { firstOnly, node, parent } = this.props
|
||||
if (node.text) return false
|
||||
|
||||
if (firstOnly) {
|
||||
if (parent.nodes.size > 1) return false
|
||||
if (parent.nodes.first() === node) return true
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* If the placeholder is a string, and no `className` or `style` has been
|
||||
* passed, give it a default style of lowered opacity.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
render() {
|
||||
const isVisible = this.isVisible()
|
||||
if (!isVisible) return null
|
||||
|
||||
const { children, className } = this.props
|
||||
let { style } = this.props
|
||||
|
||||
if (typeof children === 'string' && style == null && className == null) {
|
||||
style = { opacity: '0.333' }
|
||||
} else if (style == null) {
|
||||
style = {}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
position: 'absolute',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
pointerEvents: 'none',
|
||||
...style
|
||||
}
|
||||
|
||||
return (
|
||||
<span contentEditable={false} className={className} style={styles}>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
export default Placeholder
|
@@ -1,6 +1,5 @@
|
||||
|
||||
import Editor from './components/editor'
|
||||
import Placeholder from './components/placeholder'
|
||||
import findDOMNode from './utils/find-dom-node'
|
||||
import findDOMRange from './utils/find-dom-range'
|
||||
import findNode from './utils/find-node'
|
||||
@@ -17,7 +16,6 @@ import setEventTransfer from './utils/set-event-transfer'
|
||||
|
||||
export {
|
||||
Editor,
|
||||
Placeholder,
|
||||
findDOMNode,
|
||||
findDOMRange,
|
||||
findNode,
|
||||
@@ -29,7 +27,6 @@ export {
|
||||
|
||||
export default {
|
||||
Editor,
|
||||
Placeholder,
|
||||
findDOMNode,
|
||||
findDOMRange,
|
||||
findNode,
|
||||
|
@@ -4,12 +4,13 @@ import Debug from 'debug'
|
||||
import Plain from 'slate-plain-serializer'
|
||||
import React from 'react'
|
||||
import getWindow from 'get-window'
|
||||
import { Block, Inline, coreSchema } from 'slate'
|
||||
import { Block, Inline, Text, coreSchema } from 'slate'
|
||||
|
||||
import EVENT_HANDLERS from '../constants/event-handlers'
|
||||
import HOTKEYS from '../constants/hotkeys'
|
||||
import Content from '../components/content'
|
||||
import Placeholder from '../components/placeholder'
|
||||
import DefaultNode from '../components/default-node'
|
||||
import DefaultPlaceholder from '../components/default-placeholder'
|
||||
import findDOMNode from '../utils/find-dom-node'
|
||||
import findNode from '../utils/find-node'
|
||||
import findPoint from '../utils/find-point'
|
||||
@@ -31,19 +32,10 @@ const debug = Debug('slate:core:after')
|
||||
* The after plugin.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @property {Element} placeholder
|
||||
* @property {String} placeholderClassName
|
||||
* @property {Object} placeholderStyle
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
function AfterPlugin(options = {}) {
|
||||
const {
|
||||
placeholder,
|
||||
placeholderClassName,
|
||||
placeholderStyle,
|
||||
} = options
|
||||
|
||||
let isDraggingInternally = null
|
||||
|
||||
/**
|
||||
@@ -726,55 +718,6 @@ function AfterPlugin(options = {}) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A default schema rule to render block nodes.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const BLOCK_RENDER_RULE = {
|
||||
match: (node) => {
|
||||
return node.kind == 'block'
|
||||
},
|
||||
render: (props) => {
|
||||
return (
|
||||
<div {...props.attributes} style={{ position: 'relative' }}>
|
||||
{props.children}
|
||||
{placeholder
|
||||
? <Placeholder
|
||||
className={placeholderClassName}
|
||||
node={props.node}
|
||||
parent={props.state.document}
|
||||
state={props.state}
|
||||
style={placeholderStyle}
|
||||
>
|
||||
{placeholder}
|
||||
</Placeholder>
|
||||
: null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A default schema rule to render inline nodes.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const INLINE_RENDER_RULE = {
|
||||
match: (node) => {
|
||||
return node.kind == 'inline'
|
||||
},
|
||||
render: (props) => {
|
||||
return (
|
||||
<span {...props.attributes} style={{ position: 'relative' }}>
|
||||
{props.children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add default rendering rules to the schema.
|
||||
*
|
||||
@@ -783,8 +726,14 @@ function AfterPlugin(options = {}) {
|
||||
|
||||
const schema = {
|
||||
rules: [
|
||||
BLOCK_RENDER_RULE,
|
||||
INLINE_RENDER_RULE
|
||||
{
|
||||
match: obj => obj.kind == 'block' || obj.kind == 'inline',
|
||||
render: DefaultNode,
|
||||
},
|
||||
{
|
||||
match: obj => obj.kind == 'block' && Text.isTextList(obj.nodes) && obj.text == '',
|
||||
placeholder: DefaultPlaceholder,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -1328,6 +1328,17 @@ class Node {
|
||||
return path
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the placeholder for the node from a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {Component|Void}
|
||||
*/
|
||||
|
||||
getPlaceholder(schema) {
|
||||
return schema.__getPlaceholder(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block node before a descendant text node by `key`.
|
||||
*
|
||||
@@ -2142,6 +2153,7 @@ memoize(Node.prototype, [
|
||||
'getOffsetAtRange',
|
||||
'getParent',
|
||||
'getPath',
|
||||
'getPlaceholder',
|
||||
'getPreviousBlock',
|
||||
'getPreviousSibling',
|
||||
'getPreviousText',
|
||||
|
@@ -110,22 +110,39 @@ class Schema extends Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the renderer for an `object`.
|
||||
* Return the component for an `object`.
|
||||
*
|
||||
* This method is private, because it should always be called on one of the
|
||||
* often-changing immutable objects instead, since it will be memoized for
|
||||
* much better performance.
|
||||
*
|
||||
* @param {Mixed} object
|
||||
* @return {Component|Void}
|
||||
* @return {Component|Null}
|
||||
*/
|
||||
|
||||
__getComponent(object) {
|
||||
const match = find(this.rules, rule => rule.render && rule.match(object))
|
||||
if (!match) return
|
||||
if (!match) return null
|
||||
return match.render
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the placeholder for an `object`.
|
||||
*
|
||||
* This method is private, because it should always be called on one of the
|
||||
* often-changing immutable objects instead, since it will be memoized for
|
||||
* much better performance.
|
||||
*
|
||||
* @param {Mixed} object
|
||||
* @return {Component|Null}
|
||||
*/
|
||||
|
||||
__getPlaceholder(object) {
|
||||
const match = find(this.rules, rule => rule.placeholder && rule.match(object))
|
||||
if (!match) return null
|
||||
return match.placeholder
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the decorations for an `object`.
|
||||
*
|
||||
|
Reference in New Issue
Block a user