Floating button to add different block types

This commit is contained in:
Cássio Zen 2016-08-03 18:39:00 -03:00
parent d7c7ba4cdc
commit 62d6ece758
3 changed files with 55 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import Portal from 'react-portal';
import position from 'selection-position';
import Markdown from 'slate-markdown-serializer';
import { DEFAULT_NODE, NODES, MARKS } from './MarkdownControlElements/localRenderers';
import AddBlock from './MarkdownControlElements/AddBlock';
import { Icon } from '../UI';
import styles from './MarkdownControl.css';
@ -17,17 +18,22 @@ class MarkdownControl extends React.Component {
super(props);
this.blockEdit = false;
this.state = {
state: props.value ? markdown.deserialize(props.value) : Plain.deserialize('')
state: props.value ? markdown.deserialize(props.value) : Plain.deserialize(''),
addBlockButton:{
show: false
}
};
this.hasMark = this.hasMark.bind(this);
this.hasBlock = this.hasBlock.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleDocumentChange = this.handleDocumentChange.bind(this);
this.maybeShowBlockAddButton = this.maybeShowBlockAddButton.bind(this);
this.onClickMark = this.onClickMark.bind(this);
this.onClickBlock = this.onClickBlock.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.renderMenu = this.renderMenu.bind(this);
this.renderAddBlock = this.renderAddBlock.bind(this);
this.renderMarkButton = this.renderMarkButton.bind(this);
this.renderBlockButton = this.renderBlockButton.bind(this);
this.renderNode = this.renderNode.bind(this);
@ -69,7 +75,8 @@ class MarkdownControl extends React.Component {
if (this.blockEdit) {
this.blockEdit = false;
} else {
this.setState({ state });
this.setState({ state }, this.maybeShowBlockAddButton);
}
}
@ -77,6 +84,22 @@ class MarkdownControl extends React.Component {
this.props.onChange(markdown.serialize(state));
}
maybeShowBlockAddButton() {
if (this.state.state.blocks.get(0).isEmpty) {
const rect = document.querySelectorAll(`[data-key='${this.state.state.selection.focusKey}']`)[0].getBoundingClientRect();
this.setState({ addBlockButton: {
show: true,
top: rect.top + window.scrollY + 2,
left: rect.left + window.scrollX - 28
} });
} else {
this.setState({ addBlockButton: {
show: false
} });
}
}
/**
* Toggle marks / blocks when button is clicked
*/
@ -179,6 +202,12 @@ class MarkdownControl extends React.Component {
);
}
renderAddBlock() {
return (
this.state.addBlockButton.show ? <AddBlock top={this.state.addBlockButton.top} left={this.state.addBlockButton.left} /> : null
);
}
renderMarkButton(type, icon) {
const isActive = this.hasMark(type);
const onMouseDown = e => this.onClickMark(e, type);
@ -233,6 +262,7 @@ class MarkdownControl extends React.Component {
return (
<div>
{this.renderMenu()}
{this.renderAddBlock()}
<Editor
placeholder={'Enter some rich text...'}
state={this.state.state}

View File

@ -0,0 +1,10 @@
.root {
position: absolute;
color: #ddd;
transition: color 0.5s ease;
cursor: pointer;
}
.root:hover {
color: #aaa;
}

View File

@ -0,0 +1,13 @@
import React from 'react';
import { Icon } from '../../UI';
import styles from './AddBlock.css';
export default function AddBlock({top, left}) {
const style = {
top,
left
}
return (
<Icon type="plus-squared" className={styles.root} style={style} />
);
}