Resizable split pane (#190)
* Integrating with react-split-pane * block event while resizing panels * bring scrollsync back * fixed footer position
This commit is contained in:
@ -4,34 +4,37 @@
|
||||
}
|
||||
|
||||
.root {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: 0;
|
||||
padding: 10px 20px;
|
||||
border-top: 1px solid var(--defaultColorLight);
|
||||
background: var(--backgroundColor);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.controlPane {
|
||||
flex: 1;
|
||||
height: calc(100% - 55px);
|
||||
overflow: auto;
|
||||
padding: 0 20px;
|
||||
border-right: 1px solid var(--defaultColorLight);
|
||||
}
|
||||
|
||||
.previewPane {
|
||||
flex: 1;
|
||||
height: calc(100% - 55px);
|
||||
}
|
||||
|
||||
.blocker {
|
||||
}
|
||||
|
||||
.blocker > * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.footer {
|
||||
height: 55px;
|
||||
padding: 10px 20px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-top: 1px solid var(--defaultColorLight);
|
||||
background: var(--backgroundColor);
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -1,59 +1,86 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import { ScrollSync, ScrollSyncPane } from '../ScrollSync';
|
||||
import ControlPane from '../ControlPanel/ControlPane';
|
||||
import PreviewPane from '../PreviewPane/PreviewPane';
|
||||
import Toolbar from './EntryEditorToolbar';
|
||||
import styles from './EntryEditor.css';
|
||||
|
||||
export default function EntryEditor(
|
||||
{
|
||||
collection,
|
||||
entry,
|
||||
fields,
|
||||
getMedia,
|
||||
onChange,
|
||||
onAddMedia,
|
||||
onRemoveMedia,
|
||||
onPersist,
|
||||
onCancelEdit,
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<ScrollSync>
|
||||
<div className={styles.container}>
|
||||
<ScrollSyncPane>
|
||||
<div className={styles.controlPane}>
|
||||
<ControlPane
|
||||
collection={collection}
|
||||
entry={entry}
|
||||
fields={fields}
|
||||
getMedia={getMedia}
|
||||
onChange={onChange}
|
||||
onAddMedia={onAddMedia}
|
||||
onRemoveMedia={onRemoveMedia}
|
||||
/>
|
||||
</div>
|
||||
</ScrollSyncPane>
|
||||
<div className={styles.previewPane}>
|
||||
<PreviewPane
|
||||
collection={collection}
|
||||
entry={entry}
|
||||
fields={fields}
|
||||
getMedia={getMedia}
|
||||
/>
|
||||
class EntryEditor extends Component {
|
||||
state = {
|
||||
showEventBlocker: false,
|
||||
};
|
||||
|
||||
handleSplitPaneDragStart = () => {
|
||||
this.setState({ showEventBlocker: true });
|
||||
};
|
||||
|
||||
handleSplitPaneDragFinished = () => {
|
||||
this.setState({ showEventBlocker: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
collection,
|
||||
entry,
|
||||
fields,
|
||||
getMedia,
|
||||
onChange,
|
||||
onAddMedia,
|
||||
onRemoveMedia,
|
||||
onPersist,
|
||||
onCancelEdit,
|
||||
} = this.props;
|
||||
|
||||
const controlClassName = `${ styles.controlPane } ${ this.state.showEventBlocker && styles.blocker }`;
|
||||
const previewClassName = `${ styles.previewPane } ${ this.state.showEventBlocker && styles.blocker }`;
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<ScrollSync>
|
||||
<div className={styles.container}>
|
||||
<SplitPane
|
||||
defaultSize="50%"
|
||||
onDragStarted={this.handleSplitPaneDragStart}
|
||||
onDragFinished={this.handleSplitPaneDragFinished}
|
||||
>
|
||||
<ScrollSyncPane>
|
||||
<div className={controlClassName}>
|
||||
|
||||
<ControlPane
|
||||
collection={collection}
|
||||
entry={entry}
|
||||
fields={fields}
|
||||
getMedia={getMedia}
|
||||
onChange={onChange}
|
||||
onAddMedia={onAddMedia}
|
||||
onRemoveMedia={onRemoveMedia}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</ScrollSyncPane>
|
||||
<div className={previewClassName}>
|
||||
<PreviewPane
|
||||
collection={collection}
|
||||
entry={entry}
|
||||
fields={fields}
|
||||
getMedia={getMedia}
|
||||
/>
|
||||
</div>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</ ScrollSync>
|
||||
<div className={styles.footer}>
|
||||
<Toolbar
|
||||
isPersisting={entry.get('isPersisting')}
|
||||
onPersist={onPersist}
|
||||
onCancelEdit={onCancelEdit}
|
||||
/>
|
||||
</div>
|
||||
</ScrollSync>
|
||||
<div className={styles.footer}>
|
||||
<Toolbar
|
||||
isPersisting={entry.get('isPersisting')}
|
||||
onPersist={onPersist}
|
||||
onCancelEdit={onCancelEdit}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EntryEditor.propTypes = {
|
||||
@ -67,3 +94,6 @@ EntryEditor.propTypes = {
|
||||
onRemoveMedia: PropTypes.func.isRequired,
|
||||
onCancelEdit: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
||||
export default EntryEditor;
|
||||
|
Reference in New Issue
Block a user