diff --git a/package.json b/package.json index 31316c3c..40be1ca5 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "@kadira/storybook": "^1.36.0", "autoprefixer": "^6.3.3", "bricks.js": "^1.7.0", + "textarea-caret-position": "^0.1.1", "dateformat": "^1.0.12", "fuzzy": "^0.1.1", "immutability-helper": "^2.0.0", diff --git a/src/components/Widgets/MarkdownControlElements/RawEditor/Toolbar.js b/src/components/Widgets/MarkdownControlElements/RawEditor/Toolbar.js index e7681526..4f539501 100644 --- a/src/components/Widgets/MarkdownControlElements/RawEditor/Toolbar.js +++ b/src/components/Widgets/MarkdownControlElements/RawEditor/Toolbar.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Component, PropTypes } from 'react'; import styles from './Toolbar.css'; function button(label, action) { @@ -7,15 +7,44 @@ function button(label, action) { ); } -export default class Toolbar extends React.Component { +export default class Toolbar extends Component { + static propTypes = { + isOpen: PropTypes.bool, + selectionPosition: PropTypes.node, + onBold: PropTypes.func.isRequired, + onItalic: PropTypes.func.isRequired, + onLink: PropTypes.func.isRequired, + }; + + componentDidUpdate() { + const { selectionPosition } = this.props; + if (selectionPosition) { + const rect = this.element.getBoundingClientRect(); + const parentRect = this.element.parentElement.getBoundingClientRect(); + const style = this.element.style; + const pos = { + top: selectionPosition.top - rect.height - 5, + left: Math.min(selectionPosition.left, parentRect.width - rect.width), + }; + style.setProperty('top', `${ pos.top }px`); + style.setProperty('left', `${ pos.left }px`); + } + } + + handleRef = (ref) => { + this.element = ref; + }; + render() { const { isOpen, onBold, onItalic, onLink } = this.props; const classNames = [styles.Toolbar]; + if (isOpen) { classNames.push(styles.Visible); } + return ( -