diff --git a/app/components/Editor/Editor.js b/app/components/Editor/Editor.js index fdb35519d..ea8fd1b9e 100644 --- a/app/components/Editor/Editor.js +++ b/app/components/Editor/Editor.js @@ -2,8 +2,9 @@ import React, { Component } from 'react'; import { observable } from 'mobx'; import { observer } from 'mobx-react'; +import { Value, Change } from 'slate'; import { Editor } from 'slate-react'; -import type { state, props, change } from 'slate-prop-types'; +import type { SlateNodeProps } from './types'; import Plain from 'slate-plain-serializer'; import keydown from 'react-keydown'; import getDataTransferFiles from 'utils/getDataTransferFiles'; @@ -22,7 +23,7 @@ import styled from 'styled-components'; type Props = { text: string, - onChange: change => *, + onChange: Change => *, onSave: (redirect?: boolean) => *, onCancel: () => void, onImageUploadStart: () => void, @@ -31,18 +32,13 @@ type Props = { readOnly: boolean, }; -type KeyData = { - isMeta: boolean, - key: string, -}; - @observer class MarkdownEditor extends Component { props: Props; editor: Editor; - renderNode: props => *; + renderNode: SlateNodeProps => *; plugins: Object[]; - @observable editorValue: state; + @observable editorValue: Value; constructor(props: Props) { super(props); @@ -79,7 +75,7 @@ class MarkdownEditor extends Component { } } - onChange = (change: change) => { + onChange = (change: Change) => { if (this.editorValue !== change.value) { this.props.onChange(Markdown.serialize(change.value)); } @@ -146,17 +142,17 @@ class MarkdownEditor extends Component { } // Handling of keyboard shortcuts within editor focus - onKeyDown = (ev: SyntheticKeyboardEvent, data: KeyData, change: change) => { - if (!data.isMeta) return; + onKeyDown = (ev: SyntheticKeyboardEvent, change: Change) => { + if (!ev.metaKey) return; - switch (data.key) { + switch (ev.key) { case 's': this.onSave(ev); return change; - case 'enter': + case 'Enter': this.onSaveAndExit(ev); return change; - case 'escape': + case 'Escape': this.onCancel(); return change; default: diff --git a/app/components/Editor/components/BlockInsert.js b/app/components/Editor/components/BlockInsert.js index 02673b0e6..8eab208fe 100644 --- a/app/components/Editor/components/BlockInsert.js +++ b/app/components/Editor/components/BlockInsert.js @@ -13,10 +13,10 @@ type Props = { editor: Editor, }; -function findClosestRootNode(state, ev) { +function findClosestRootNode(value, ev) { let previous; - for (const node of state.document.nodes) { + for (const node of value.document.nodes) { const element = findDOMNode(node); const bounds = element.getBoundingClientRect(); if (bounds.top > ev.clientY) return previous; diff --git a/app/components/Editor/components/Code.js b/app/components/Editor/components/Code.js index 7c2118eeb..f2396b545 100644 --- a/app/components/Editor/components/Code.js +++ b/app/components/Editor/components/Code.js @@ -1,11 +1,16 @@ // @flow import React from 'react'; import styled from 'styled-components'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; import CopyButton from './CopyButton'; import { color } from 'shared/styles/constants'; -export default function Code({ children, node, readOnly, attributes }: props) { +export default function Code({ + children, + node, + readOnly, + attributes, +}: SlateNodeProps) { const language = node.data.get('language') || 'javascript'; return ( diff --git a/app/components/Editor/components/Contents.js b/app/components/Editor/components/Contents.js index 81dcfad0d..b9afe07bd 100644 --- a/app/components/Editor/components/Contents.js +++ b/app/components/Editor/components/Contents.js @@ -3,7 +3,7 @@ import React, { Component } from 'react'; import { observable } from 'mobx'; import { observer } from 'mobx-react'; import { Editor } from 'slate-react'; -import type { state, block } from 'slate-prop-types'; +import { Block } from 'slate'; import { List } from 'immutable'; import { color } from 'shared/styles/constants'; import headingToSlug from '../headingToSlug'; @@ -54,10 +54,10 @@ class Contents extends Component { return elements; } - get headings(): List { + get headings(): List { const { editor } = this.props; - return editor.value.document.nodes.filter((node: block) => { + return editor.value.document.nodes.filter((node: Block) => { if (!node.text) return false; return node.type.match(/^heading/); }); diff --git a/app/components/Editor/components/Heading.js b/app/components/Editor/components/Heading.js index 2a57279b1..03b03d168 100644 --- a/app/components/Editor/components/Heading.js +++ b/app/components/Editor/components/Heading.js @@ -1,22 +1,15 @@ // @flow import React from 'react'; import { Document } from 'slate'; -import { Editor } from 'slate-react'; +import type { SlateNodeProps } from '../types'; import styled from 'styled-components'; -import type { node } from 'slate-prop-types'; import headingToSlug from '../headingToSlug'; import Placeholder from './Placeholder'; -type Props = { - children: React$Element<*>, - placeholder?: boolean, - parent: node, - node: node, - editor: Editor, - readOnly: boolean, - component?: string, - attributes: Object, - className?: string, +type Props = SlateNodeProps & { + component: string, + className: string, + placeholder: string, }; function Heading(props: Props) { @@ -61,7 +54,7 @@ function Heading(props: Props) { const Wrapper = styled.div` display: inline; - margin-left: ${(props: Props) => (props.hasEmoji ? '-1.2em' : 0)}; + margin-left: ${(props: SlateNodeProps) => (props.hasEmoji ? '-1.2em' : 0)}; `; const Anchor = styled.a` @@ -84,21 +77,21 @@ export const StyledHeading = styled(Heading)` } } `; -export const Heading1 = (props: Props) => ( +export const Heading1 = (props: SlateNodeProps) => ( ); -export const Heading2 = (props: Props) => ( +export const Heading2 = (props: SlateNodeProps) => ( ); -export const Heading3 = (props: Props) => ( +export const Heading3 = (props: SlateNodeProps) => ( ); -export const Heading4 = (props: Props) => ( +export const Heading4 = (props: SlateNodeProps) => ( ); -export const Heading5 = (props: Props) => ( +export const Heading5 = (props: SlateNodeProps) => ( ); -export const Heading6 = (props: Props) => ( +export const Heading6 = (props: SlateNodeProps) => ( ); diff --git a/app/components/Editor/components/HorizontalRule.js b/app/components/Editor/components/HorizontalRule.js index 7efcbe998..4afd19448 100644 --- a/app/components/Editor/components/HorizontalRule.js +++ b/app/components/Editor/components/HorizontalRule.js @@ -1,12 +1,13 @@ // @flow import React from 'react'; import styled from 'styled-components'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; import { color } from 'shared/styles/constants'; -function HorizontalRule(props: props) { - const { state, node, attributes } = props; - const active = state.isFocused && state.selection.hasEdgeIn(node); +function HorizontalRule(props: SlateNodeProps) { + const { editor, node, attributes } = props; + const active = + editor.value.isFocused && editor.value.selection.hasEdgeIn(node); return ; } diff --git a/app/components/Editor/components/Image.js b/app/components/Editor/components/Image.js index 23ab022ed..c8f7cbab5 100644 --- a/app/components/Editor/components/Image.js +++ b/app/components/Editor/components/Image.js @@ -2,11 +2,11 @@ import React, { Component } from 'react'; import ImageZoom from 'react-medium-image-zoom'; import styled from 'styled-components'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; import { color } from 'shared/styles/constants'; class Image extends Component { - props: props; + props: SlateNodeProps; handleChange = (ev: SyntheticInputEvent) => { const alt = ev.target.value; @@ -26,11 +26,12 @@ class Image extends Component { }; render() { - const { attributes, state, node, readOnly } = this.props; + const { attributes, editor, node, readOnly } = this.props; const loading = node.data.get('loading'); const caption = node.data.get('alt'); const src = node.data.get('src'); - const active = state.isFocused && state.selection.hasEdgeIn(node); + const active = + editor.value.isFocused && editor.value.selection.hasEdgeIn(node); const showCaption = !readOnly || caption; return ( diff --git a/app/components/Editor/components/Link.js b/app/components/Editor/components/Link.js index 0938dd532..54302eb60 100644 --- a/app/components/Editor/components/Link.js +++ b/app/components/Editor/components/Link.js @@ -1,7 +1,7 @@ // @flow import React from 'react'; import { Link as InternalLink } from 'react-router-dom'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; function getPathFromUrl(href: string) { if (href[0] === '/') return href; @@ -26,7 +26,12 @@ function isInternalUrl(href: string) { } } -export default function Link({ attributes, node, children, readOnly }: props) { +export default function Link({ + attributes, + node, + children, + readOnly, +}: SlateNodeProps) { const href = node.data.get('href'); const path = getPathFromUrl(href); diff --git a/app/components/Editor/components/ListItem.js b/app/components/Editor/components/ListItem.js index 51fea4c03..7941f97e1 100644 --- a/app/components/Editor/components/ListItem.js +++ b/app/components/Editor/components/ListItem.js @@ -1,6 +1,6 @@ // @flow import React from 'react'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; import TodoItem from './TodoItem'; export default function ListItem({ @@ -8,7 +8,7 @@ export default function ListItem({ node, attributes, ...props -}: props) { +}: SlateNodeProps) { const checked = node.data.get('checked'); if (checked !== undefined) { diff --git a/app/components/Editor/components/Paragraph.js b/app/components/Editor/components/Paragraph.js index 07801e1f1..952ae174e 100644 --- a/app/components/Editor/components/Paragraph.js +++ b/app/components/Editor/components/Paragraph.js @@ -1,7 +1,7 @@ // @flow import React from 'react'; import { Document } from 'slate'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; import Placeholder from './Placeholder'; export default function Link({ @@ -11,7 +11,7 @@ export default function Link({ parent, children, readOnly, -}: props) { +}: SlateNodeProps) { const parentIsDocument = parent instanceof Document; const firstParagraph = parent && parent.nodes.get(1) === node; const lastParagraph = parent && parent.nodes.last() === node; diff --git a/app/components/Editor/components/TodoItem.js b/app/components/Editor/components/TodoItem.js index bb7a9cf22..a1e7fed12 100644 --- a/app/components/Editor/components/TodoItem.js +++ b/app/components/Editor/components/TodoItem.js @@ -2,10 +2,10 @@ import React, { Component } from 'react'; import styled from 'styled-components'; import { color } from 'shared/styles/constants'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../types'; export default class TodoItem extends Component { - props: props & { checked: boolean }; + props: SlateNodeProps & { checked: boolean }; handleChange = (ev: SyntheticInputEvent) => { const checked = ev.target.checked; diff --git a/app/components/Editor/components/Toolbar/BlockToolbar.js b/app/components/Editor/components/Toolbar/BlockToolbar.js index 615515612..e1aa29e33 100644 --- a/app/components/Editor/components/Toolbar/BlockToolbar.js +++ b/app/components/Editor/components/Toolbar/BlockToolbar.js @@ -13,14 +13,13 @@ import HorizontalRuleIcon from 'components/Icon/HorizontalRuleIcon'; import TodoListIcon from 'components/Icon/TodoListIcon'; import Flex from 'shared/components/Flex'; import ToolbarButton from './components/ToolbarButton'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from '../../types'; import { color } from 'shared/styles/constants'; import { fadeIn } from 'shared/styles/animations'; import { splitAndInsertBlock } from '../../transforms'; -type Props = props & { - onInsertImage: Function, - onChange: Function, +type Props = SlateNodeProps & { + onInsertImage: *, }; type Options = { diff --git a/app/components/Editor/components/Toolbar/Toolbar.js b/app/components/Editor/components/Toolbar/Toolbar.js index 1efb85529..75d978475 100644 --- a/app/components/Editor/components/Toolbar/Toolbar.js +++ b/app/components/Editor/components/Toolbar/Toolbar.js @@ -4,7 +4,7 @@ import { observable } from 'mobx'; import { observer } from 'mobx-react'; import { Portal } from 'react-portal'; import { Editor } from 'slate-react'; -import type { value } from 'slate-prop-types'; +import { Value } from 'slate'; import styled from 'styled-components'; import _ from 'lodash'; import FormattingToolbar from './components/FormattingToolbar'; @@ -20,7 +20,7 @@ export default class Toolbar extends Component { props: { editor: Editor, - value: value, + value: Value, }; menu: HTMLElement; diff --git a/app/components/Editor/components/Toolbar/components/LinkToolbar.js b/app/components/Editor/components/Toolbar/components/LinkToolbar.js index f0fd65a99..72623c0bb 100644 --- a/app/components/Editor/components/Toolbar/components/LinkToolbar.js +++ b/app/components/Editor/components/Toolbar/components/LinkToolbar.js @@ -4,10 +4,10 @@ import ReactDOM from 'react-dom'; import { observable, action } from 'mobx'; import { observer, inject } from 'mobx-react'; import { withRouter } from 'react-router-dom'; +import { Change } from 'slate'; import { Editor } from 'slate-react'; import styled from 'styled-components'; import ArrowKeyNavigation from 'boundless-arrow-key-navigation'; -import type { change } from 'slate-prop-types'; import ToolbarButton from './ToolbarButton'; import DocumentResult from './DocumentResult'; import DocumentsStore from 'stores/DocumentsStore'; @@ -28,7 +28,7 @@ class LinkToolbar extends Component { link: Object, documents: DocumentsStore, onBlur: () => void, - onChange: change => *, + onChange: Change => *, }; @observable isEditing: boolean = false; diff --git a/app/components/Editor/headingToSlug.js b/app/components/Editor/headingToSlug.js index cf46ab2b9..eb06dfcde 100644 --- a/app/components/Editor/headingToSlug.js +++ b/app/components/Editor/headingToSlug.js @@ -1,9 +1,9 @@ // @flow import { escape } from 'lodash'; -import type { node } from 'slate-prop-types'; +import { Node } from 'slate'; import slug from 'slug'; -export default function headingToSlug(node: node) { +export default function headingToSlug(node: Node) { const level = node.type.replace('heading', 'h'); return escape(`${level}-${slug(node.text)}-${node.key}`); } diff --git a/app/components/Editor/insertImage.js b/app/components/Editor/insertImage.js index 01480cc2e..2e0fb4c61 100644 --- a/app/components/Editor/insertImage.js +++ b/app/components/Editor/insertImage.js @@ -1,11 +1,11 @@ // @flow import uuid from 'uuid'; import uploadFile from 'utils/uploadFile'; +import { Change } from 'slate'; import { Editor } from 'slate-react'; -import type { change } from 'slate-prop-types'; export default async function insertImageFile( - change: change, + change: Change, file: window.File, editor: Editor, onImageUploadStart: () => void, @@ -22,14 +22,11 @@ export default async function insertImageFile( const src = reader.result; // insert into document as uploading placeholder - const state = change - .insertBlock({ - type: 'image', - isVoid: true, - data: { src, id, alt, loading: true }, - }) - .apply(); - editor.onChange(state); + change.insertBlock({ + type: 'image', + isVoid: true, + data: { src, id, alt, loading: true }, + }); }); reader.readAsDataURL(file); @@ -40,9 +37,8 @@ export default async function insertImageFile( // we dont use the original change provided to the callback here // as the state may have changed significantly in the time it took to // upload the file. - const state = editor.getState(); - const finalTransform = state.change(); - const placeholder = state.document.findDescendant( + const finalTransform = editor.value.change(); + const placeholder = editor.value.document.findDescendant( node => node.data && node.data.get('id') === id ); diff --git a/app/components/Editor/marks.js b/app/components/Editor/marks.js index 58d25c634..a88b6c279 100644 --- a/app/components/Editor/marks.js +++ b/app/components/Editor/marks.js @@ -1,9 +1,14 @@ // @flow import React from 'react'; import InlineCode from './components/InlineCode'; -import type { props } from 'slate-prop-types'; +import { Mark } from 'slate'; -export default function renderMark(props: props) { +type Props = { + children: React$Element<*>, + mark: Mark, +}; + +export default function renderMark(props: Props) { switch (props.mark.type) { case 'bold': return {props.children}; diff --git a/app/components/Editor/nodes.js b/app/components/Editor/nodes.js index b20e4de45..62a0dd966 100644 --- a/app/components/Editor/nodes.js +++ b/app/components/Editor/nodes.js @@ -16,14 +16,14 @@ import { Heading6, } from './components/Heading'; import Paragraph from './components/Paragraph'; -import type { props } from 'slate-prop-types'; +import type { SlateNodeProps } from './types'; type Options = { onInsertImage: *, }; export default function createRenderNode({ onChange, onInsertImage }: Options) { - return function renderNode(props: props) { + return function renderNode(props: SlateNodeProps) { const { attributes } = props; switch (props.node.type) { diff --git a/app/components/Editor/plugins/KeyboardShortcuts.js b/app/components/Editor/plugins/KeyboardShortcuts.js index e3b8c06c5..7ec48efca 100644 --- a/app/components/Editor/plugins/KeyboardShortcuts.js +++ b/app/components/Editor/plugins/KeyboardShortcuts.js @@ -1,20 +1,12 @@ // @flow -import type { change } from 'slate-prop-types'; +import { Change } from 'slate'; export default function KeyboardShortcuts() { return { - /** - * On key down, check for our specific key shortcuts. - * - * @param {Event} e - * @param {Data} data - * @param {State} state - * @return {State or Null} state - */ - onKeyDown(ev: SyntheticEvent, data: Object, change: change) { - if (!data.isMeta) return null; + onKeyDown(ev: SyntheticKeyboardEvent, change: Change) { + if (!ev.metaKey) return null; - switch (data.key) { + switch (ev.key) { case 'b': return this.toggleMark(change, 'bold'); case 'i': @@ -30,13 +22,13 @@ export default function KeyboardShortcuts() { } }, - toggleMark(change: change, type: string) { - const { state } = change; + toggleMark(change: Change, type: string) { + const { value } = change; // don't allow formatting of document title - const firstNode = state.document.nodes.first(); - if (firstNode === state.startBlock) return; + const firstNode = value.document.nodes.first(); + if (firstNode === value.startBlock) return; - return state.change().toggleMark(type); + change.toggleMark(type); }, }; } diff --git a/app/components/Editor/plugins/MarkdownShortcuts.js b/app/components/Editor/plugins/MarkdownShortcuts.js index 8800f4f56..651ae2074 100644 --- a/app/components/Editor/plugins/MarkdownShortcuts.js +++ b/app/components/Editor/plugins/MarkdownShortcuts.js @@ -1,10 +1,5 @@ // @flow -import type { change } from 'slate-prop-types'; - -type KeyData = { - isMeta: boolean, - key: string, -}; +import { Change } from 'slate'; const inlineShortcuts = [ { mark: 'bold', shortcut: '**' }, @@ -18,22 +13,19 @@ const inlineShortcuts = [ export default function MarkdownShortcuts() { return { - /** - * On key down, check for our specific key shortcuts. - */ - onKeyDown(ev: SyntheticEvent, data: KeyData, change: change) { - switch (data.key) { + onKeyDown(ev: SyntheticKeyboardEvent, change: Change) { + switch (ev.key) { case '-': return this.onDash(ev, change); case '`': return this.onBacktick(ev, change); - case 'tab': + case 'Tab': return this.onTab(ev, change); - case 'space': + case ' ': return this.onSpace(ev, change); - case 'backspace': + case 'Backspace': return this.onBackspace(ev, change); - case 'enter': + case 'Enter': return this.onEnter(ev, change); default: return null; @@ -44,10 +36,10 @@ export default function MarkdownShortcuts() { * On space, if it was after an auto-markdown shortcut, convert the current * node into the shortcut's corresponding type. */ - onSpace(ev: SyntheticEvent, change: change) { - const { state } = change; - if (state.isExpanded) return; - const { startBlock, startOffset } = state; + onSpace(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; + if (value.isExpanded) return; + const { startBlock, startOffset } = value; const chars = startBlock.text.slice(0, startOffset).trim(); const type = this.getType(chars); @@ -58,7 +50,7 @@ export default function MarkdownShortcuts() { let checked; if (chars === '[x]') checked = true; if (chars === '[ ]') checked = false; - const change = state.change().setBlock({ type, data: { checked } }); + change.setBlock({ type, data: { checked } }); if (type === 'list-item') { if (checked !== undefined) { @@ -99,40 +91,32 @@ export default function MarkdownShortcuts() { // if we have multiple tags then mark the text between as inline code if (inlineTags.length > 1) { - const change = state.change(); const firstText = startBlock.getFirstText(); const firstCodeTagIndex = inlineTags[0]; const lastCodeTagIndex = inlineTags[inlineTags.length - 1]; - change.removeTextByKey( - firstText.key, - lastCodeTagIndex, - shortcut.length - ); - change.removeTextByKey( - firstText.key, - firstCodeTagIndex, - shortcut.length - ); - change.moveOffsetsTo( - firstCodeTagIndex, - lastCodeTagIndex - shortcut.length - ); - change.addMark(mark); - return change.collapseToEnd().removeMark(mark); + change + .removeTextByKey(firstText.key, lastCodeTagIndex, shortcut.length) + .removeTextByKey(firstText.key, firstCodeTagIndex, shortcut.length) + .moveOffsetsTo( + firstCodeTagIndex, + lastCodeTagIndex - shortcut.length + ) + .addMark(mark) + .collapseToEnd() + .removeMark(mark); } } }, - onDash(ev: SyntheticEvent, change: change) { - const { state } = change; - if (state.isExpanded) return; - const { startBlock, startOffset } = state; + onDash(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; + if (value.isExpanded) return; + const { startBlock, startOffset } = value; const chars = startBlock.text.slice(0, startOffset).replace(/\s*/g, ''); if (chars === '--') { ev.preventDefault(); - return state - .change() + return change .extendToStartOf(startBlock) .delete() .setBlock({ @@ -144,16 +128,15 @@ export default function MarkdownShortcuts() { } }, - onBacktick(ev: SyntheticEvent, change: change) { - const { state } = change; - if (state.isExpanded) return; - const { startBlock, startOffset } = state; + onBacktick(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; + if (value.isExpanded) return; + const { startBlock, startOffset } = value; const chars = startBlock.text.slice(0, startOffset).replace(/\s*/g, ''); if (chars === '``') { ev.preventDefault(); - return state - .change() + return change .extendToStartOf(startBlock) .delete() .setBlock({ @@ -162,20 +145,22 @@ export default function MarkdownShortcuts() { } }, - onBackspace(ev: SyntheticEvent, change: change) { - const { state } = change; - if (change.isExpanded) return; - const { startBlock, selection, startOffset } = state; + onBackspace(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; + if (value.isExpanded) return; + const { startBlock, selection, startOffset } = value; // If at the start of a non-paragraph, convert it back into a paragraph if (startOffset === 0) { if (startBlock.type === 'paragraph') return; ev.preventDefault(); - const change = state.change().setBlock('paragraph'); + change.setBlock('paragraph'); - if (startBlock.type === 'list-item') + if (startBlock.type === 'list-item') { change.unwrapBlock('bulleted-list'); + } + return change; } @@ -195,14 +180,12 @@ export default function MarkdownShortcuts() { .reverse() .takeUntil((v, k) => !v.marks.some(mark => mark.type === 'code')); - return state - .change() - .removeMarkByKey( - textNode.key, - change.startOffset - charsInCodeBlock.size, - change.startOffset, - 'code' - ); + change.removeMarkByKey( + textNode.key, + change.startOffset - charsInCodeBlock.size, + change.startOffset, + 'code' + ); } } }, @@ -211,15 +194,12 @@ export default function MarkdownShortcuts() { * On tab, if at the end of the heading jump to the main body content * as if it is another input field (act the same as enter). */ - onTab(ev: SyntheticEvent, change: change) { - const { state } = change; + onTab(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; - if (state.startBlock.type === 'heading1') { + if (value.startBlock.type === 'heading1') { ev.preventDefault(); - return state - .change() - .splitBlock() - .setBlock('paragraph'); + change.splitBlock().setBlock('paragraph'); } }, @@ -227,10 +207,10 @@ export default function MarkdownShortcuts() { * On return, if at the end of a node type that should not be extended, * create a new paragraph below it. */ - onEnter(ev: SyntheticEvent, change: change) { - const { state } = change; - if (state.isExpanded) return; - const { startBlock, startOffset, endOffset } = state; + onEnter(ev: SyntheticKeyboardEvent, change: Change) { + const { value } = change; + if (value.isExpanded) return; + const { startBlock, startOffset, endOffset } = value; if (startOffset === 0 && startBlock.length === 0) return this.onBackspace(ev, change); if (endOffset !== startBlock.length) return; @@ -239,10 +219,7 @@ export default function MarkdownShortcuts() { // insert a new paragraph if (startBlock.type === 'image') { ev.preventDefault(); - return state - .change() - .collapseToEnd() - .insertBlock('paragraph'); + return change.collapseToEnd().insertBlock('paragraph'); } // Hitting enter in a heading or blockquote will split the node at that @@ -260,10 +237,7 @@ export default function MarkdownShortcuts() { } ev.preventDefault(); - return state - .change() - .splitBlock() - .setBlock('paragraph'); + change.splitBlock().setBlock('paragraph'); }, /** diff --git a/app/components/Editor/transforms.js b/app/components/Editor/transforms.js index e5c30184d..9acd47874 100644 --- a/app/components/Editor/transforms.js +++ b/app/components/Editor/transforms.js @@ -1,8 +1,8 @@ // @flow -import type { change } from 'slate-prop-types'; +import { Change } from 'slate'; import EditList from './plugins/EditList'; -const { transforms } = EditList; +const { changes } = EditList; type Options = { type: string | Object, @@ -10,7 +10,7 @@ type Options = { append?: string | Object, }; -export function splitAndInsertBlock(change: change, options: Options) { +export function splitAndInsertBlock(change: Change, options: Options) { const { type, wrapper, append } = options; const { value } = change; const { document } = value; @@ -18,8 +18,8 @@ export function splitAndInsertBlock(change: change, options: Options) { // lists get some special treatment if (parent && parent.type === 'list-item') { - change = transforms.unwrapList( - transforms + change = changes.unwrapList( + changes .splitListItem(change.collapseToStart()) .collapseToEndOfPreviousBlock() ); diff --git a/app/components/Editor/types.js b/app/components/Editor/types.js new file mode 100644 index 000000000..842ffd930 --- /dev/null +++ b/app/components/Editor/types.js @@ -0,0 +1,13 @@ +// @flow +import { Value, Node } from 'slate'; +import { Editor } from 'slate-react'; + +export type SlateNodeProps = { + children: React$Element<*>, + readOnly: boolean, + attributes: Object, + value: Value, + editor: Editor, + node: Node, + parent: Node, +}; diff --git a/package.json b/package.json index 9d0cfb21b..0dffb3c53 100644 --- a/package.json +++ b/package.json @@ -169,7 +169,6 @@ "slate-paste-linkify": "^0.5.0", "slate-plain-serializer": "^0.4.12", "slate-prism": "^0.4.0", - "slate-prop-types": "^0.4.12", "slate-react": "^0.10.19", "slate-trailing-block": "^0.4.0", "slug": "0.9.1",