@ -90,12 +90,16 @@ export default class BlockInsert extends Component {
|
|||||||
this.left = Math.round(boxRect.left + window.scrollX - 20);
|
this.left = Math.round(boxRect.left + window.scrollX - 20);
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickBlock = (
|
insertBlock = (
|
||||||
ev: SyntheticEvent,
|
ev: SyntheticEvent,
|
||||||
|
options: {
|
||||||
type: string | Object,
|
type: string | Object,
|
||||||
wrapBlock?: string
|
wrapper?: string | Object,
|
||||||
|
append?: string | Object,
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
const { type, wrapper, append } = options;
|
||||||
let { state } = this.props;
|
let { state } = this.props;
|
||||||
let transform = state.transform();
|
let transform = state.transform();
|
||||||
const { document } = state;
|
const { document } = state;
|
||||||
@ -112,7 +116,8 @@ export default class BlockInsert extends Component {
|
|||||||
|
|
||||||
transform = transform.insertBlock(type);
|
transform = transform.insertBlock(type);
|
||||||
|
|
||||||
if (wrapBlock) transform = transform.wrapBlock(wrapBlock);
|
if (wrapper) transform = transform.wrapBlock(wrapper);
|
||||||
|
if (append) transform = transform.insertBlock(append);
|
||||||
|
|
||||||
state = transform.focus().apply();
|
state = transform.focus().apply();
|
||||||
this.props.onChange(state);
|
this.props.onChange(state);
|
||||||
@ -134,6 +139,7 @@ export default class BlockInsert extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const style = { top: `${this.top}px`, left: `${this.left}px` };
|
const style = { top: `${this.top}px`, left: `${this.left}px` };
|
||||||
const todo = { type: 'list-item', data: { checked: false } };
|
const todo = { type: 'list-item', data: { checked: false } };
|
||||||
|
const rule = { type: 'horizontal-rule', isVoid: true };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal isOpened>
|
<Portal isOpened>
|
||||||
@ -148,9 +154,14 @@ export default class BlockInsert extends Component {
|
|||||||
label={<Icon type="PlusCircle" />}
|
label={<Icon type="PlusCircle" />}
|
||||||
onPickImage={this.onPickImage}
|
onPickImage={this.onPickImage}
|
||||||
onInsertList={ev =>
|
onInsertList={ev =>
|
||||||
this.onClickBlock(ev, 'list-item', 'bulleted-list')}
|
this.insertBlock(ev, {
|
||||||
onInsertTodoList={ev => this.onClickBlock(ev, todo, 'todo-list')}
|
type: 'list-item',
|
||||||
onInsertBreak={ev => this.onClickBlock(ev, 'horizontal-rule')}
|
wrapper: 'bulleted-list',
|
||||||
|
})}
|
||||||
|
onInsertTodoList={ev =>
|
||||||
|
this.insertBlock(ev, { type: todo, wrapper: 'todo-list' })}
|
||||||
|
onInsertBreak={ev =>
|
||||||
|
this.insertBlock(ev, { type: rule, append: 'paragraph' })}
|
||||||
onOpen={this.handleMenuOpen}
|
onOpen={this.handleMenuOpen}
|
||||||
onClose={this.handleMenuClose}
|
onClose={this.handleMenuClose}
|
||||||
/>
|
/>
|
||||||
|
17
frontend/components/Editor/components/HorizontalRule.js
Normal file
17
frontend/components/Editor/components/HorizontalRule.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import type { Props } from '../types';
|
||||||
|
import { color } from 'styles/constants';
|
||||||
|
|
||||||
|
function HorizontalRule(props: Props) {
|
||||||
|
const { state, node } = this.props;
|
||||||
|
const active = state.isFocused && state.selection.hasEdgeIn(node);
|
||||||
|
return <StyledHr active={active} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledHr = styled.hr`
|
||||||
|
border-bottom: 1px solid ${props => (props.active ? color.slate : color.slateLight)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default HorizontalRule;
|
@ -112,19 +112,17 @@ export default function MarkdownShortcuts() {
|
|||||||
|
|
||||||
if (chars === '--') {
|
if (chars === '--') {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const transform = state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
.extendToStartOf(startBlock)
|
.extendToStartOf(startBlock)
|
||||||
.delete()
|
.delete()
|
||||||
.setBlock({
|
.setBlock({
|
||||||
type: 'horizontal-rule',
|
type: 'horizontal-rule',
|
||||||
isVoid: true,
|
isVoid: true,
|
||||||
});
|
})
|
||||||
state = transform
|
|
||||||
.collapseToStartOfNextBlock()
|
.collapseToStartOfNextBlock()
|
||||||
.insertBlock('paragraph')
|
.insertBlock('paragraph')
|
||||||
.apply();
|
.apply();
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Code from './components/Code';
|
import Code from './components/Code';
|
||||||
|
import HorizontalRule from './components/HorizontalRule';
|
||||||
import InlineCode from './components/InlineCode';
|
import InlineCode from './components/InlineCode';
|
||||||
import Image from './components/Image';
|
import Image from './components/Image';
|
||||||
import Link from './components/Link';
|
import Link from './components/Link';
|
||||||
@ -33,7 +34,7 @@ const createSchema = () => {
|
|||||||
'block-quote': (props: Props) => (
|
'block-quote': (props: Props) => (
|
||||||
<blockquote>{props.children}</blockquote>
|
<blockquote>{props.children}</blockquote>
|
||||||
),
|
),
|
||||||
'horizontal-rule': (props: Props) => <hr />,
|
'horizontal-rule': HorizontalRule,
|
||||||
'bulleted-list': (props: Props) => <ul>{props.children}</ul>,
|
'bulleted-list': (props: Props) => <ul>{props.children}</ul>,
|
||||||
'ordered-list': (props: Props) => <ol>{props.children}</ol>,
|
'ordered-list': (props: Props) => <ol>{props.children}</ol>,
|
||||||
'todo-list': (props: Props) => <TodoList>{props.children}</TodoList>,
|
'todo-list': (props: Props) => <TodoList>{props.children}</TodoList>,
|
||||||
|
Reference in New Issue
Block a user