Closed huozhi closed 6 years ago
Here's how I used it in my project:
Placeholder.js
// tools
import React from "react"
import { Placeholder } from "slate"
// return
export default class extends React.Component {
render(){
const { node, state, parent } = this.props
return (
<Placeholder
firstOnly={ true }
parent={ parent }
node={ node }
state={ state }
style={{ opacity: "0.65" }}
>
{ this.props.children }
</Placeholder>
)
}
}
schema.js
// tools
import React from "react"
// components
import Placeholder from "./containers/Placeholder"
// return
export const schema = {
nodes: {
paragraph: props => <p { ...props.attributes } style={{ position: "relative" }}><Placeholder { ...props }>Write your story...</Placeholder>{ props.children }</p>
}
}
... Then added this schema to the state.
Thanks for @dmitrizzle 's example. But I think that it is a little bit obscure to know use Placeholder
in editor schema. And the props parent
and node
are should not be cared by developers. Using in schema is more like customizing the content paragraph.
Why not just give the customized component as prop placeholder={<MyComponent />}
? It might be easier for user to learn.
@dmitrizzle example misses two things. The first one is that Placeholder
is implemented in slate-react
, not slate
; the second is that style
needs position: 'inherit'
, because typically, the first few elements are occupied with block/mark controls, and position: absolute; top: 0; left: 0
will place the placeholder at wrong place
UPD. I've implemented my own version of Placeholder wrapper (in TypeScript), which solves a problem with remaining Placeholder in a focused Editor (until one element is added). Hope it will be usefull
import * as React from 'react';
import { Component } from 'react';
// Components
import { Placeholder } from 'slate-react';
interface SlatePlaceholderProps {
firstOnly?: boolean;
node: React.ReactNode;
parent?: React.ReactNode;
style?: any;
state: any;
editor?: any;
className?: string;
}
interface SlatePlaceholderState {
visible: boolean;
}
export class SlatePlaceholder extends Component<SlatePlaceholderProps, SlatePlaceholderState> {
static defaultProps = {
firstOnly: true
}
state = {
visible: true
}
private _isMounted: boolean = false;
componentDidMount() {
const editor = this.props.editor;
if (editor != undefined) {
editor.onFocus = this.hidePlaceholder;
editor.onBlur = this.showPlaceholder;
this._isMounted = true;
}
}
componentWillUnmount() {
this._isMounted = false;
const editor = this.props.editor;
if (editor != undefined) {
editor.forceUpdate(); // this is important to allow the placeholder to be hidden after editor is focused the first time
}
}
private hidePlaceholder = () => {
if (this._isMounted) {
this.setState({ visible: false });
}
}
private showPlaceholder = () => {
if (this._isMounted) {
this.setState({ visible: true });
}
}
render() {
const { children, ...props } = this.props;
return (
this.state.visible ?
<Placeholder { ...props }>{children}</Placeholder> :
null
);
}
}
and is used in Schema as
export const Schema = (options: { placeholder?} = {}) => ({
nodes: {
...
'paragraph': props => <p {...props.attributes}>
{options && options.placeholder ?
<SlatePlaceholder
firstOnly={true}
editor={props.editor}
node={props.node}
parent={props.parent}
state={props.state}
style={{ opacity: '0.65', position: 'inherit' }}>{options.placeholder}</Placeholder> :
null}
{props.children}</p>,
'underlined': props => <u {...props.attributes}>{props.children}</u>
},
marks: {
...
}
});
<Editor
state={this.state.state}
schema={Schema.Schema({this.props.placeholder})}
...
Closing this as the Placeholder component was removed in slate-react@0.7.0
I found that there was only illustration for placeholder component props in https://docs.slatejs.org/reference/components/placeholder.html. And I couldn't find out some examples in slate codebase.
Now I use the default paragraph type placeholder in my app, which works well in
examples/rtl
.I would like to know if slate could provide some demo or example code for
Placeholder
component ? Then I can do more customized things.Thanks a lot. : )