1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-04-21 13:51:59 +02:00

add read-only mode, closes #108 #106

This commit is contained in:
Ian Storm Taylor 2016-07-17 15:57:27 -07:00
parent 6140386f2e
commit c489eee418
6 changed files with 89 additions and 3 deletions

View File

@ -11,6 +11,7 @@ The top-level React component that renders the Slate editor itself.
- [`className`](#classname)
- [`onChange`](#onchange)
- [`plugins`](#plugins)
- [`readOnly`](#readonly)
- [`state`](#state)
- [`style`](#style)
- [Placeholder Properties](#placeholder-properties)
@ -36,6 +37,7 @@ The top-level React component that renders the Slate editor itself.
className={string}
onChange={Function}
plugins={Array}
readOnly={Boolean}
state={State}
style={Object}
/>
@ -56,6 +58,11 @@ A change handler that will be called with the newly-changed editor `state`. You
An array of [`Plugins`](../plugins) that define the editor's behavior.
### `readOnly`
`Boolean`
Whether the editor should be in "read-only" mode, where all of the rendering is the same, but the user is prevented from editing the editor's content.
### `state`
`State`

View File

@ -14,6 +14,7 @@ import Images from './images'
import Links from './links'
import PasteHtml from './paste-html'
import PlainText from './plain-text'
import ReadOnly from './read-only'
import RichText from './rich-text'
import Tables from './tables'
@ -66,6 +67,7 @@ class App extends React.Component {
{this.renderTab('Tables', 'tables')}
{this.renderTab('Code Highlighting', 'code-highlighting')}
{this.renderTab('Paste HTML', 'paste-html')}
{this.renderTab('Read Only', 'read-only')}
</div>
)
}
@ -116,6 +118,7 @@ const router = (
<Route path="links" component={Links} />
<Route path="paste-html" component={PasteHtml} />
<Route path="plain-text" component={PlainText} />
<Route path="read-only" component={ReadOnly} />
<Route path="rich-text" component={RichText} />
<Route path="tables" component={Tables} />
</Route>

View File

@ -0,0 +1,8 @@
# Plain Text Example
![](../../docs/images/plain-text-example.png)
This is the most basic Slate example. It's basically a glorified `<textarea>`. But it gives you a sense for the absolute basics of Slate.
Check out the [Examples readme](..) to see how to run it!

View File

@ -0,0 +1,56 @@
import { Editor, Plain } from '../..'
import React from 'react'
/**
* The read-only example.
*
* @type {Component}
*/
class ReadOnly extends React.Component {
/**
* Deserialize the initial editor state.
*
* @type {Object}
*/
state = {
state: Plain.deserialize('This is read-only text. You should not be able to edit it, which is useful for scenarios where you want to render via Slate, without giving the user editing persmissions.')
};
/**
* On change.
*
* @param {State} state
*/
onChange = (state) => {
this.setState({ state })
}
/**
* Render the editor.
*
* @return {Component} component
*/
render = () => {
return (
<Editor
readOnly
placeholder={'Enter some text...'}
state={this.state.state}
onChange={this.onChange}
/>
)
}
}
/**
* Export.
*/
export default ReadOnly

View File

@ -33,6 +33,7 @@ class Content extends React.Component {
onKeyDown: React.PropTypes.func,
onPaste: React.PropTypes.func,
onSelect: React.PropTypes.func,
readOnly: React.PropTypes.bool,
renderMark: React.PropTypes.func.isRequired,
renderNode: React.PropTypes.func.isRequired,
state: React.PropTypes.object.isRequired,
@ -44,6 +45,7 @@ class Content extends React.Component {
*/
static defaultProps = {
readOnly: false,
style: {}
};
@ -98,6 +100,7 @@ class Content extends React.Component {
*/
onBeforeInput = (e) => {
if (this.props.readOnly) return
this.props.onBeforeInput(e)
}
@ -108,6 +111,7 @@ class Content extends React.Component {
*/
onBlur = (e) => {
if (this.props.readOnly) return
if (this.tmp.isCopying) return
let { state } = this.props
@ -146,6 +150,7 @@ class Content extends React.Component {
*/
onCut = (e) => {
if (this.props.readOnly) return
this.onCutCopy(e)
// Once the cut has successfully executed, delete the current selection.
@ -216,6 +221,7 @@ class Content extends React.Component {
*/
onKeyDown = (e) => {
if (this.props.readOnly) return
const key = keycode(e.which)
if (
@ -240,6 +246,7 @@ class Content extends React.Component {
*/
onPaste = (e) => {
if (this.props.readOnly) return
e.preventDefault()
const data = e.clipboardData
const paste = {}
@ -298,6 +305,7 @@ class Content extends React.Component {
*/
onSelect = (e) => {
if (this.props.readOnly) return
if (this.tmp.isRendering) return
if (this.tmp.isCopying) return
@ -337,7 +345,7 @@ class Content extends React.Component {
*/
render = () => {
const { className, state } = this.props
const { className, readOnly, state } = this.props
const { document } = state
const children = document.nodes
.map(node => this.renderNode(node))
@ -353,7 +361,8 @@ class Content extends React.Component {
return (
<div
className={className}
contentEditable suppressContentEditableWarning
contentEditable={!readOnly}
suppressContentEditableWarning
style={style}
onBeforeInput={this.onBeforeInput}
onBlur={this.onBlur}

View File

@ -24,6 +24,7 @@ class Editor extends React.Component {
placeholderClassName: React.PropTypes.string,
placeholderStyle: React.PropTypes.object,
plugins: React.PropTypes.array,
readOnly: React.PropTypes.bool,
renderDecorations: React.PropTypes.func,
renderMark: React.PropTypes.func,
renderNode: React.PropTypes.func,
@ -32,7 +33,8 @@ class Editor extends React.Component {
};
static defaultProps = {
plugins: []
plugins: [],
readOnly: false
};
/**
@ -175,6 +177,7 @@ class Editor extends React.Component {
editor={this}
state={this.state.state}
onChange={this.onChange}
readOnly={this.props.readOnly}
renderMark={this.renderMark}
renderNode={this.renderNode}
onPaste={this.onPaste}