diff --git a/src/components/EntryEditor/EntryEditor.js b/src/components/EntryEditor/EntryEditor.js
index 01fc0198..ac68c2c0 100644
--- a/src/components/EntryEditor/EntryEditor.js
+++ b/src/components/EntryEditor/EntryEditor.js
@@ -6,6 +6,7 @@ import { ScrollSync, ScrollSyncPane } from '../ScrollSync';
import ControlPane from '../ControlPanel/ControlPane';
import PreviewPane from '../PreviewPane/PreviewPane';
import Toolbar from './EntryEditorToolbar';
+import { StickyContext } from '../UI/Sticky/Sticky';
import styles from './EntryEditor.css';
import stickyStyles from '../UI/Sticky/Sticky.css';
@@ -36,35 +37,6 @@ class EntryEditor extends Component {
localStorage.setItem(PREVIEW_VISIBLE, newPreviewVisible);
};
- setSticky = (contextTop, containerRect, sticky) => {
- if (contextTop >= containerRect.top) {
- if (contextTop < containerRect.bottom - 60) {
- sticky.classList.add(stickyStyles.top);
- sticky.classList.remove(stickyStyles.bottom);
- } else if (contextTop >= containerRect.bottom - 60) {
- sticky.classList.remove(stickyStyles.top);
- sticky.classList.add(stickyStyles.bottom);
- }
- } else {
- sticky.classList.remove(stickyStyles.top);
- sticky.classList.remove(stickyStyles.bottom);
- }
- };
-
- handleControlPaneRef = (ref) => {
- const sticky = ref.querySelector('.cms__index__editorControlBar');
- const stickyContainer = ref.querySelector('.stickyContainer');
- stickyContainer.style.paddingTop = `${ sticky.offsetHeight }px`;
- sticky.style.position = 'absolute';
- sticky.style.top = `${ -sticky.offsetHeight }px`;
- sticky.style.width = `${ stickyContainer.getBoundingClientRect().width }px`;
-
- ref && ref.addEventListener('scroll', (e) => {
- const contextTop = e.target.getBoundingClientRect().top;
- this.setSticky(contextTop, stickyContainer.getBoundingClientRect(), sticky);
- });
- };
-
render() {
const {
collection,
@@ -90,7 +62,7 @@ class EntryEditor extends Component {
);
const editor = (
-
+
{ collectionPreviewEnabled ? togglePreviewButton : null }
this.controlPaneRef = c} // eslint-disable-line
/>
-
+
);
const editorWithPreview = (
diff --git a/src/components/UI/Sticky/Sticky.css b/src/components/UI/Sticky/Sticky.css
index 7f6b8378..37259174 100644
--- a/src/components/UI/Sticky/Sticky.css
+++ b/src/components/UI/Sticky/Sticky.css
@@ -1,9 +1,18 @@
-.top {
+.stickyContainer {
+ position: relative !important;
+}
+
+.sticky {
+ position: relative !important;
+}
+
+.stickyActive:not(.stickyAtBottom) {
position: fixed !important;
top: 64px !important;
}
-.bottom {
+.stickyAtBottom {
+ position: absolute !important;
top: auto !important;
bottom: 30px !important;
}
diff --git a/src/components/UI/Sticky/Sticky.js b/src/components/UI/Sticky/Sticky.js
new file mode 100644
index 00000000..af89f34a
--- /dev/null
+++ b/src/components/UI/Sticky/Sticky.js
@@ -0,0 +1,116 @@
+import React, { Component, PropTypes } from 'react';
+import classnames from 'classnames';
+import styles from './Sticky.css';
+
+export class StickyContext extends Component {
+ static childContextTypes = { subscribeToStickyContext: PropTypes.func };
+
+ constructor(props) {
+ super(props);
+ this.subscriptions = [];
+ }
+
+ getChildContext() {
+ return { subscribeToStickyContext: (fn) => { this.subscriptions.push(fn); } };
+ }
+
+ updateStickies = (ref) => {
+ const stickyContextTop = ref.getBoundingClientRect().top;
+ this.subscriptions.forEach((fn) => { fn(stickyContextTop); });
+ };
+
+ componentDidMount() {
+ this.updateStickies(this.ref);
+ }
+
+ handleScroll = (event) => {
+ this.updateStickies(event.target);
+ };
+
+ render() {
+ return (
+ { this.ref = ref; }}>
+ {this.props.children}
+
+ );
+ }
+}
+
+export class StickyContainer extends Component {
+ constructor(props) {
+ super(props);
+ this.subscriptions = [];
+ }
+
+ static contextTypes = { subscribeToStickyContext: PropTypes.func };
+ static childContextTypes = { subscribeToStickyContainer: PropTypes.func };
+
+ getChildContext() {
+ return { subscribeToStickyContainer: (fn) => { this.subscriptions.push(fn); } };
+ }
+
+ getPosition = (contextTop) => {
+ const rect = this.ref.getBoundingClientRect();
+ const shouldStick = rect.top < contextTop;
+ const shouldStickAtBottom = rect.bottom - 60 < contextTop;
+ this.subscriptions.forEach((fn) => { fn(shouldStick, shouldStickAtBottom, rect.width) });
+ };
+
+ componentDidMount() {
+ this.context.subscribeToStickyContext(this.getPosition);
+ }
+
+ render() {
+ return (
+ { this.ref = ref }}
+ >
+ {this.props.children}
+
+ );
+ }
+}
+
+export class Sticky extends Component {
+ static contextTypes = { subscribeToStickyContainer: PropTypes.func };
+
+ constructor(props, context) {
+ super(props, context);
+ this.state = {};
+ }
+
+ updateSticky = (shouldStick, shouldStickAtBottom, containerWidth) => {
+ this.setState({ shouldStick, shouldStickAtBottom, containerWidth });
+ };
+
+ componentDidMount() {
+ this.context.subscribeToStickyContainer(this.updateSticky);
+ }
+
+ render() {
+ const { props, state } = this;
+ const stickyPlaceholderHeight = state.shouldStick ? this.ref.getBoundingClientRect().height : 0;
+
+ return (
+
+
+
{this.ref = ref}}
+ >
+ {props.children}
+
+
+ );
+ }
+}
diff --git a/src/components/Widgets/MarkdownControl.js b/src/components/Widgets/MarkdownControl.js
index 4f829e0d..205d8bc7 100644
--- a/src/components/Widgets/MarkdownControl.js
+++ b/src/components/Widgets/MarkdownControl.js
@@ -3,6 +3,7 @@ import registry from '../../lib/registry';
import RawEditor from './MarkdownControlElements/RawEditor';
import VisualEditor from './MarkdownControlElements/VisualEditor';
import { processEditorPlugins } from './richText';
+import { StickyContainer } from '../UI/Sticky/Sticky';
const MODE_STORAGE_KEY = 'cms.md-mode';
@@ -32,23 +33,20 @@ export default class MarkdownControl extends React.Component {
render() {
const { onChange, onAddAsset, onRemoveAsset, getAsset, value } = this.props;
const { mode } = this.state;
- if (mode === 'visual') {
- return (
-
-
-
- );
- }
-
- return (
-
+ const visualEditor = (
+
+
+
+ );
+ const rawEditor = (
+
);
+ return
{ mode === 'visual' ? visualEditor : rawEditor };
}
}
diff --git a/src/components/Widgets/MarkdownControlElements/RawEditor/index.js b/src/components/Widgets/MarkdownControlElements/RawEditor/index.js
index b94b9358..b8ca39c2 100644
--- a/src/components/Widgets/MarkdownControlElements/RawEditor/index.js
+++ b/src/components/Widgets/MarkdownControlElements/RawEditor/index.js
@@ -7,6 +7,7 @@ import registry from '../../../../lib/registry';
import { createAssetProxy } from '../../../../valueObjects/AssetProxy';
import Toolbar from '../Toolbar';
import ToolbarPlugins from '../ToolbarPlugins';
+import { Sticky } from '../../../UI/Sticky/Sticky';
import styles from './index.css';
const HAS_LINE_BREAK = /\n/m;
@@ -319,7 +320,7 @@ export default class RawEditor extends React.Component {
onDragOver={this.handleDragOver}
onDrop={this.handleDrop}
>
-
+
-
+
);