1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-31 19:01:54 +02:00

remove keyboard data.* properties (#1235)

* update examples and walkthroughs

* deprecate data keyboard properties

* update examples

* add is-hotkey to resources doc

* udpate docs

* update docs

* fix split-block test
This commit is contained in:
Ian Storm Taylor
2017-10-15 19:23:07 -07:00
committed by GitHub
parent c2ba87d327
commit f69d2c4a12
19 changed files with 200 additions and 296 deletions

View File

@@ -49,9 +49,9 @@ class App extends React.Component {
this.setState({ state })
}
// Define a new handler which prints the key code that was pressed.
// Define a new handler which prints the key that was pressed.
onKeyDown = (event, data, change) => {
console.log(event.which)
console.log(event.key)
}
render() {
@@ -85,8 +85,8 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
// Return with no changes if it's not the "7" key with shift pressed.
if (event.which != 55 || !event.shiftKey) return
// Return with no changes if it's not the "&" key.
if (event.key != '&') return
// Prevent the ampersand character from being inserted.
event.preventDefault()

View File

@@ -28,7 +28,7 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
if (event.which != 67 || !event.metaKey || !event.altKey) return
if (event.key != '`' || !event.metaKey) return
event.preventDefault()
const isCode = change.state.blocks.some(block => block.type == 'code')
@@ -72,16 +72,15 @@ class App extends React.Component {
if (!event.metaKey) return
// Decide what to do based on the key code...
switch (event.which) {
switch (event.key) {
// When "B" is pressed, add a "bold" mark to the text.
case 66: {
case 'b': {
event.preventDefault()
change.addMark('bold')
return true
}
// When "`" is pressed, keep our existing code block logic.
case 67: {
if (!event.altKey) return
case '`': {
const isCode = change.state.blocks.some(block => block.type == 'code')
event.preventDefault()
change.setBlock(isCode ? 'paragraph' : 'code')
@@ -148,14 +147,13 @@ class App extends React.Component {
onKeyDown = (event, data, change) => {
if (!event.metaKey) return
switch (event.which) {
case 66: {
switch (event.key) {
case 'b': {
event.preventDefault()
change.toggleMark('bold')
return true
}
case 67: {
if (!event.altKey) return
case '`': {
const isCode = change.state.blocks.some(block => block.type == 'code')
event.preventDefault()
state.setBlock(isCode ? 'paragraph' : 'code')

View File

@@ -23,10 +23,8 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
if (event.which != 55 || !event.shiftKey) return
if (event.key != '&') return
event.preventDefault()
change.insertText('and');
return true
}
@@ -87,10 +85,8 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
if (event.which != 55 || !event.shiftKey) return
if (event.key != '&') return
event.preventDefault()
change.insertText('and')
return true
}
@@ -110,7 +106,7 @@ class App extends React.Component {
}
```
Okay, but now we'll need a way for the user to actually turn a block into a code block. So let's change our `onKeyDown` function to add a `⌘-Alt-C` shortcut that does just that:
Okay, but now we'll need a way for the user to actually turn a block into a code block. So let's change our `onKeyDown` function to add a `⌘-\`` shortcut that does just that:
```js
function CodeNode(props) {
@@ -134,7 +130,7 @@ class App extends React.Component {
onKeyDown = (event, data, change) => {
// Return with no changes if it's not the "`" key with cmd/ctrl pressed.
if (event.which != 67 || !event.metaKey || !event.altKey) return
if (event.key != '`' || !event.metaKey) return
// Prevent the "`" from being inserted by default.
event.preventDefault()
@@ -158,9 +154,9 @@ class App extends React.Component {
}
```
Now, if you press `⌘-Alt-C`, the block your cursor is in should turn into a code block! Magic!
Now, if you press `⌘-\`` the block your cursor is in should turn into a code block! Magic!
But we forgot one thing. When you hit `⌘-Alt-C` again, it should change the code block back into a paragraph. To do that, we'll need to add a bit of logic to change the type we set based on whether any of the currently selected blocks are already a code block:
But we forgot one thing. When you hit `⌘-\`` again, it should change the code block back into a paragraph. To do that, we'll need to add a bit of logic to change the type we set based on whether any of the currently selected blocks are already a code block:
```js
function CodeNode(props) {
@@ -183,7 +179,7 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
if (event.which != 67 || !event.metaKey || !event.altKey) return
if (event.key != '`' || !event.metaKey) return
event.preventDefault()
@@ -209,7 +205,7 @@ class App extends React.Component {
}
```
And there you have it! If you press `⌘-Alt-C` while inside a code block, it should turn back into a paragraph!
And there you have it! If you press `⌘-\`` while inside a code block, it should turn back into a paragraph!
<br/>
<p align="center"><strong>Next:</strong><br/><a href="./applying-custom-formatting.md">Applying Custom Formatting</a></p>

View File

@@ -30,7 +30,7 @@ class App extends React.Component {
}
onKeyDown = (event, data, change) => {
if (!event.metaKey || event.which != 66) return
if (event.key != 'b' || !event.metaKey) return
event.preventDefault()
change.toggleMark('bold')
return true
@@ -50,12 +50,12 @@ class App extends React.Component {
}
```
Let's write a new function, that takes a set of options: the mark `type` to toggle and the key `code` to press.
Let's write a new function, that takes a set of options: the mark `type` to toggle and the `key` to press.
```js
function MarkHotkey(options) {
// Grab our options from the ones passed in.
const { type, code, isAltKey = false } = options
const { type, key } = options
}
```
@@ -67,13 +67,13 @@ In this case our plugin object will have one property: a `onKeyDown` handler, wi
```js
function MarkHotkey(options) {
const { type, code, isAltKey = false } = options
const { type, key } = options
// Return our "plugin" object, containing the `onKeyDown` handler.
return {
onKeyDown(event, data, change) {
// Check that the key pressed matches our `code` option.
if (!event.metaKey || event.which != code || event.altKey != isAltKey) return
// Check that the key pressed matches our `key` option.
if (!event.metaKey || event.key != key) return
// Prevent the default characters from being inserted.
event.preventDefault()
@@ -94,7 +94,7 @@ Now that we have our plugin, let's remove the hard-coded logic from our app, and
// Initialize our bold-mark-adding plugin.
const boldPlugin = MarkHotkey({
type: 'bold',
code: 66
key: 'b'
})
// Create an array of plugins.
@@ -139,11 +139,11 @@ Let's add _italic_, `code`, ~~strikethrough~~ and underline marks:
```js
// Initialize a plugin for each mark...
const plugins = [
MarkHotkey({ code: 66, type: 'bold' }),
MarkHotkey({ code: 67, type: 'code', isAltKey: true }),
MarkHotkey({ code: 73, type: 'italic' }),
MarkHotkey({ code: 68, type: 'strikethrough' }),
MarkHotkey({ code: 85, type: 'underline' })
MarkHotkey({ key: 'b', type: 'bold' }),
MarkHotkey({ key: '`', type: 'code' }),
MarkHotkey({ key: 'i', type: 'italic' }),
MarkHotkey({ key: '~', type: 'strikethrough' }),
MarkHotkey({ key: 'u', type: 'underline' })
]
class App extends React.Component {
@@ -182,87 +182,6 @@ class App extends React.Component {
And there you have it! We just added a ton of functionality to the editor with very little work. And we can keep all of our mark hotkey logic tested and isolated in a single place, making maintaining the code easier.
Of course... now that it's reusable, we could actually make our `MarkHotkey` plugin a little easier to use. What if instead of a `code` argument it took the text of the `key` itself? That would make the calling code a lot clearer, since key codes are really obtuse.
In fact, unless you have weirdly good keycode knowledge, you probably have no idea what our current hotkeys actually are.
Let's fix that.
Using the `keycode` module in npm makes this dead simple.
First install it:
```
npm install keycode
```
And then we can add it our plugin:
```js
// Import the keycode module.
import keycode from `keycode`
function MarkHotkey(options) {
// Change the options to take a `key`.
const { type, key, isAltKey = false } = options
return {
onKeyDown(event, data, change) {
// Change the comparison to use the key name.
if (!event.metaKey || keycode(event.which) != key || event.altKey != isAltKey) return
event.preventDefault()
change.toggleMark(type)
return true
}
}
}
```
And now we can make our app code much clearer for the next person who reads it:
```js
// Use the much clearer key names instead of key codes!
const plugins = [
MarkHotkey({ key: 'b', type: 'bold' }),
MarkHotkey({ key: 'c', type: 'code', isAltKey: true }),
MarkHotkey({ key: 'i', type: 'italic' }),
MarkHotkey({ key: 'd', type: 'strikethrough' }),
MarkHotkey({ key: 'u', type: 'underline' })
]
class App extends React.Component {
state = {
state: initialState,
schema: {
marks: {
bold: props => <strong>{props.children}</strong>,
code: props => <code>{props.children}</code>,
italic: props => <em>{props.children}</em>,
strikethrough: props => <del>{props.children}</del>,
underline: props => <u>{props.children}</u>,
}
}
}
onChange = ({ state }) => {
this.setState({ state })
}
render() {
return (
<Editor
plugins={plugins}
schema={this.state.schema}
state={this.state.state}
onChange={this.onChange}
/>
)
}
}
```
That's why plugins are awesome. They let you get really expressive while also making your codebase easier to manage. And since Slate is built with plugins as a primary consideration, using them is dead simple!