mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 10:29:48 +02:00
add more docs
This commit is contained in:
170
docs/getting-started/adding-custom-formatting.md
Normal file
170
docs/getting-started/adding-custom-formatting.md
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
<br/>
|
||||
<p align="center"><strong>Previous:</strong><br/><a href="./adding-event-handlers.md">Adding Event Handlers</a></p>
|
||||
<br/>
|
||||
|
||||
### Adding Custom Formatting
|
||||
|
||||
In the last guide we learned how to use Slate's event handlers to change its content, but we didn't do anything really that useful with it.
|
||||
|
||||
In this guide, we'll show you how to add custom formatting options, like **bold**, _italic_, `code` or ~~strikethrough~~.
|
||||
|
||||
So we start with our app from earlier:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
onKeyDown={e, state => this.onKeyDown(e, state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onKeyDown(event, state) {
|
||||
if (event.which != 55 || !event.shiftKey) return
|
||||
|
||||
const newState = state
|
||||
.transform()
|
||||
.insertText('and')
|
||||
.apply()
|
||||
|
||||
return newState
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
But we'll get rid of that useless `onKeyDown` handler logic, and we'll replace it with logic that will add a **bold** format to the currently selected text.
|
||||
|
||||
Here's what that looks like:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
onKeyDown={e, state => this.onKeyDown(e, state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onKeyDown(event, state) {
|
||||
// Return with no changes if it's not the "B" key with cmd/ctrl pressed.
|
||||
if (event.which != 66 || !event.metaKey) return
|
||||
|
||||
// Otherwise, transform the state by adding a `bold` mark to the selection.
|
||||
const newState = state
|
||||
.transform()
|
||||
.mark('bold')
|
||||
.apply()
|
||||
|
||||
// Return the new state, which will cause the editor to update it.
|
||||
return newState
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Now if you read through `onKeyDown`, it should be fairly clear.
|
||||
|
||||
But! If you happen to now try selecting text and hitting **⌘-B**, you'll get an error in your console. That's because we haven't told Slate how to render a "bold" mark.
|
||||
|
||||
For every mark type you want to add to your schema, you need to give Slate a "renderer" for that mark, which is just an object of styles that will be passed to React's `style=` property.
|
||||
|
||||
So let's define our `bold` mark:
|
||||
|
||||
|
||||
```js
|
||||
// Define a simple dictionary of styles that make text bold.
|
||||
const BOLD_MARK = {
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
```
|
||||
|
||||
Pretty simple, right?
|
||||
|
||||
And now, let's tell Slate about that mark. To do that, we'll need to pass in a `renderMark` function to the `Editor`, which it will call with any mark it finds. And when it calls it with a bold mark, we'll return our `BOLD_MARK` styles. Like so:
|
||||
|
||||
```
|
||||
const BOLD_MARK = {
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
onKeyDown={e, state => this.onKeyDown(e, state)}
|
||||
renderMark={mark => this.renderMark(mark)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// Define a mark rendering function that knows about "bold" marks.
|
||||
renderMark(mark) {
|
||||
if (mark.type == 'bold') return BOLD_MARK
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onKeyDown(event, state) {
|
||||
if (event.which != 66 || !event.metaKey) return
|
||||
|
||||
const newState = state
|
||||
.transform()
|
||||
.mark('bold')
|
||||
.apply()
|
||||
|
||||
return newState
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Now, if you try selecting a piece of text and hitting **⌘-B** you should see it turn bold! Magic!
|
||||
|
||||
|
||||
<br/>
|
||||
<p align="center"><strong>Next:</strong><br/><a href="./adding-custom-block-types.md">Adding Custom Block Types</a></p>
|
||||
<br/>
|
129
docs/getting-started/adding-event-handlers.md
Normal file
129
docs/getting-started/adding-event-handlers.md
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
<br/>
|
||||
<p align="center"><strong>Previous:</strong><br/><a href="./installing-slate.md">Installing Slate</a></p>
|
||||
<br/>
|
||||
|
||||
### Adding Event Handlers
|
||||
|
||||
Okay, so you've got Slate installed and rendered on the page, and when you type in it, you can see the changes reflected. But you want to do more than just type a plaintext string.
|
||||
|
||||
What makes Slate great is how easy it is to customize. Just like other React components you're used it, Slate allows you to pass in handlers that are triggered on certain events. You've already seen on the `onChange` handler can be used to store the changed editor state, but let's try add something more...
|
||||
|
||||
We'll show you how to use the `onKeyDown` handler to change the editor's content when the user presses a button.
|
||||
|
||||
So we start with our app from earlier:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
And now we'll add an `onKeyDown` handler:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
onKeyDown={e, state => this.onKeyDown(e, state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
// Define a new handler which prints the key code that was pressed.
|
||||
onKeyDown(e, state) {
|
||||
console.log(e.which)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Okay cool, so now when you press a key in the editor, you'll see the key's code printed to the console. Not very useful, but at least we know it's working.
|
||||
|
||||
Now we want to make it actually change the content. For the purposes of our example, let's say we want to make it so that whenever a user types `&` we actually add `and` to the content.
|
||||
|
||||
Our `onKeyDown` handler might look like this:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={state => this.onChange(state)}
|
||||
onKeyDown={e, state => this.onKeyDown(e, state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onKeyDown(event, state) {
|
||||
// Return with no changes if it's not the "7" key with shift pressed.
|
||||
if (event.which != 55 || !event.shiftKey) return
|
||||
|
||||
// Otherwise, transform the state by insert "and" at the cursor's position.
|
||||
const newState = state
|
||||
.transform()
|
||||
.insertText('and')
|
||||
.apply()
|
||||
|
||||
// Return the new state, which will cause the editor to update it.
|
||||
return newState
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
With that added, try typing `&`, and you should see it automatically become `and` instead!
|
||||
|
||||
That gives you a sense for what you can do with Slate's event handlers. Each one will be called with the `event` object, and the current `state` of the editor.
|
||||
|
||||
<br/>
|
||||
<p align="center"><strong>Next:</strong><br/><a href="./adding-custom-formatting.md">Adding Custom Formatting</a></p>
|
||||
<br/>
|
@@ -28,10 +28,7 @@ To keep things simple, we'll use the `Raw` serializer that ships with Slate to c
|
||||
```js
|
||||
import { Editor, Raw } from 'slate'
|
||||
|
||||
/**
|
||||
* Create our initial state...
|
||||
*/
|
||||
|
||||
// Create our initial state...
|
||||
const initialState = Raw.deserialize([
|
||||
{
|
||||
kind: 'block',
|
||||
@@ -56,10 +53,6 @@ Once you've got a `State` object create, via the `Raw` serializer, or any other
|
||||
import React from 'react'
|
||||
import { Editor, Raw } from 'state'
|
||||
|
||||
/**
|
||||
* Create our initial state...
|
||||
*/
|
||||
|
||||
const initialState = Raw.deserialize([
|
||||
{
|
||||
kind: 'block',
|
||||
@@ -77,14 +70,13 @@ const initialState = Raw.deserialize([
|
||||
}
|
||||
])
|
||||
|
||||
/**
|
||||
* Our app.
|
||||
*/
|
||||
|
||||
// Define our app...
|
||||
class App extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
// Set the initial state when the app is first constructed.
|
||||
this.state = {
|
||||
state: initialState
|
||||
}
|
||||
@@ -94,13 +86,16 @@ class App extends React.Component {
|
||||
return (
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
onChange={(state) => {
|
||||
this.setState({ state })
|
||||
}}
|
||||
onChange={state => this.onChange(state)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onChange(state) {
|
||||
// Update the app's React state with the new editor state.
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -111,8 +106,8 @@ And that's it!
|
||||
That's the most basic example of Slate. If you render that onto the page, you should see a paragraph with the text `A line of text in a paragraph.`. And when you type, you should see the text change!
|
||||
|
||||
<br/>
|
||||
<p align="center"><strong>Next:</strong><br/><a href="./customizing-slates-behavior.md">Customizing Slate's Behavior</a></p>
|
||||
|
||||
<p align="center"><strong>Next:</strong><br/><a href="./adding-event-handlers.md">Adding Event Handlers</a></p>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
@@ -231,9 +231,11 @@ class Content extends React.Component {
|
||||
onPaste = (e) => {
|
||||
e.preventDefault()
|
||||
const data = e.clipboardData
|
||||
const types = Array.from(data.types)
|
||||
const paste = {}
|
||||
|
||||
// COMPAT: In Firefox, `types` is array-like.
|
||||
const types = Array.from(data.types)
|
||||
|
||||
// Handle files.
|
||||
if (data.files.length != 0) {
|
||||
paste.type = 'files'
|
||||
|
Reference in New Issue
Block a user