Skip to content
This repository has been archived by the owner on Oct 11, 2022. It is now read-only.

Commit

Permalink
Proof of concept side toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
mxstbr committed Sep 29, 2017
1 parent 01f968f commit 9c35f9a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 15 deletions.
74 changes: 74 additions & 0 deletions src/components/draftjs-editor/SideToolbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// @flow
// This file was copy-and-pasted from the draft-js-side-toolbar-plugin and adapted
// for our codebase.
import React from 'react';
import { findDOMNode } from 'react-dom';
// $FlowIssue
import DraftOffsetKey from 'draft-js/lib/DraftOffsetKey';

type EditorState = Object; // Draft.js editor state
type EditorRef = any; // A reference to the editor DOM node

type Props = {
editorState: EditorState,
children: Function,
editorRef: EditorRef,
};

type ToolbarPosition = {
top?: number,
left?: number,
};

type State = {
position: ?ToolbarPosition,
};

export default class Toolbar extends React.Component<Props, State> {
state = {
position: {},
};

componentDidMount() {
this.setPosition(this.props.editorState, this.props.editorRef);
}

componentDidUpdate() {
this.setPosition(this.props.editorState, this.props.editorRef);
}

setPosition = (editorState: EditorState, editorRef: EditorRef) => {
if (!editorRef) return;
const selection = editorState.getSelection();
if (!selection.getHasFocus()) return;

const currentContent = editorState.getCurrentContent();
const currentBlock = currentContent.getBlockForKey(selection.getStartKey());
if (!currentBlock) return;
const offsetKey = DraftOffsetKey.encode(currentBlock.getKey(), 0, 0);
if (!offsetKey) return;
// NOTE(@juliankrispel): Need to wait on tick to make sure the DOM node has been create by Draft.js
setTimeout(() => {
const node = document.querySelectorAll(
`[data-offset-key="${offsetKey}"]`
)[0];
if (!node) return;
const top = node.getBoundingClientRect().top;
const scrollY =
window.scrollY == null ? window.pageYOffset : window.scrollY;
const editor = findDOMNode(editorRef);
if (!editor) return;
this.setState({
position: {
top: top + scrollY,
left: editor.getBoundingClientRect().left - 80,
},
});
}, 0);
};

render() {
const { position } = this.state;
return this.props.children({ style: position });
}
}
37 changes: 22 additions & 15 deletions src/components/draftjs-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import prismGlobalCSS from '!!raw-loader!./prism-theme.css';
injectGlobal`${prismGlobalCSS}`;

import Image from './Image';
import { Wrapper, MediaRow, ComposerBase } from './style';
import { Wrapper, MediaRow, ComposerBase, SideToolbarWrapper } from './style';
import SideToolbar from './SideToolbar';
import MediaInput from '../mediaInput';
import { LinkPreview, LinkPreviewLoading } from '../linkPreview';

Expand Down Expand Up @@ -156,6 +157,16 @@ class Editor extends React.Component {
}}
{...rest}
/>
{images !== false &&
!rest.readOnly && (
<SideToolbar editorState={state} editorRef={this.editor}>
{({ style }) => (
<SideToolbarWrapper style={style}>
<MediaInput onChange={this.addImage} multiple />
</SideToolbarWrapper>
)}
</SideToolbar>
)}
{showLinkPreview && linkPreview && linkPreview.loading ? (
<LinkPreviewLoading margin={'16px 0 24px 0'} />
) : showLinkPreview && linkPreview && linkPreview.data ? (
Expand All @@ -168,12 +179,6 @@ class Editor extends React.Component {
margin={'16px 0 24px 0'}
/>
) : null}
{images !== false &&
!this.props.readOnly && (
<MediaInput onChange={this.addImage} multiple>
Add
</MediaInput>
)}
</ComposerBase>
);
} else {
Expand Down Expand Up @@ -201,6 +206,16 @@ class Editor extends React.Component {
}}
{...rest}
/>
{images !== false &&
!rest.readOnly && (
<SideToolbar editorState={state} editorRef={this.editor}>
{({ style }) => (
<SideToolbarWrapper style={style}>
<MediaInput onChange={this.addImage} multiple />
</SideToolbarWrapper>
)}
</SideToolbar>
)}
</Wrapper>
{showLinkPreview && linkPreview && linkPreview.loading ? (
<LinkPreviewLoading margin={'16px 0 24px 0'} />
Expand All @@ -214,14 +229,6 @@ class Editor extends React.Component {
margin={'16px 0 24px 0'}
/>
) : null}
{images !== false &&
!this.props.readOnly && (
<MediaRow>
<MediaInput onChange={this.addImage} multiple>
Add
</MediaInput>
</MediaRow>
)}
</div>
);
}
Expand Down
5 changes: 5 additions & 0 deletions src/components/draftjs-editor/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ export const ComposerBase = styled.div`
color: ${props => props.theme.text.placeholder};
}
`;

export const SideToolbarWrapper = styled.div`
position: fixed;
margin-top: -0.5em;
`;

0 comments on commit 9c35f9a

Please sign in to comment.