summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/components/h-split-box.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/components/h-split-box.js')
-rw-r--r--devtools/client/shared/components/h-split-box.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/devtools/client/shared/components/h-split-box.js b/devtools/client/shared/components/h-split-box.js
new file mode 100644
index 000000000..d804a6ba1
--- /dev/null
+++ b/devtools/client/shared/components/h-split-box.js
@@ -0,0 +1,154 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* eslint-env browser */
+"use strict";
+
+// A box with a start and a end pane, separated by a dragable splitter that
+// allows the user to resize the relative widths of the panes.
+//
+// +-----------------------+---------------------+
+// | | |
+// | | |
+// | S |
+// | Start Pane p End Pane |
+// | l |
+// | i |
+// | t |
+// | t |
+// | e |
+// | r |
+// | | |
+// | | |
+// +-----------------------+---------------------+
+
+const {
+ DOM: dom,
+ createClass,
+ PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { assert } = require("devtools/shared/DevToolsUtils");
+
+module.exports = createClass({
+ displayName: "HSplitBox",
+
+ propTypes: {
+ // The contents of the start pane.
+ start: PropTypes.any.isRequired,
+
+ // The contents of the end pane.
+ end: PropTypes.any.isRequired,
+
+ // The relative width of the start pane, expressed as a number between 0 and
+ // 1. The relative width of the end pane is 1 - startWidth. For example,
+ // with startWidth = .5, both panes are of equal width; with startWidth =
+ // .25, the start panel will take up 1/4 width and the end panel will take
+ // up 3/4 width.
+ startWidth: PropTypes.number,
+
+ // A minimum css width value for the start and end panes.
+ minStartWidth: PropTypes.any,
+ minEndWidth: PropTypes.any,
+
+ // A callback fired when the user drags the splitter to resize the relative
+ // pane widths. The function is passed the startWidth value that would put
+ // the splitter underneath the users mouse.
+ onResize: PropTypes.func.isRequired,
+ },
+
+ getDefaultProps() {
+ return {
+ startWidth: 0.5,
+ minStartWidth: "20px",
+ minEndWidth: "20px",
+ };
+ },
+
+ getInitialState() {
+ return {
+ mouseDown: false
+ };
+ },
+
+ componentDidMount() {
+ document.defaultView.top.addEventListener("mouseup", this._onMouseUp,
+ false);
+ document.defaultView.top.addEventListener("mousemove", this._onMouseMove,
+ false);
+ },
+
+ componentWillUnmount() {
+ document.defaultView.top.removeEventListener("mouseup", this._onMouseUp,
+ false);
+ document.defaultView.top.removeEventListener("mousemove", this._onMouseMove,
+ false);
+ },
+
+ _onMouseDown(event) {
+ if (event.button !== 0) {
+ return;
+ }
+
+ this.setState({ mouseDown: true });
+ event.preventDefault();
+ },
+
+ _onMouseUp(event) {
+ if (event.button !== 0 || !this.state.mouseDown) {
+ return;
+ }
+
+ this.setState({ mouseDown: false });
+ event.preventDefault();
+ },
+
+ _onMouseMove(event) {
+ if (!this.state.mouseDown) {
+ return;
+ }
+
+ const rect = this.refs.box.getBoundingClientRect();
+ const { left, right } = rect;
+ const width = right - left;
+ const relative = event.clientX - left;
+ this.props.onResize(relative / width);
+
+ event.preventDefault();
+ },
+
+ render() {
+ /* eslint-disable no-shadow */
+ const { start, end, startWidth, minStartWidth, minEndWidth } = this.props;
+ assert(startWidth => 0 && startWidth <= 1,
+ "0 <= this.props.startWidth <= 1");
+ /* eslint-enable */
+ return dom.div(
+ {
+ className: "h-split-box",
+ ref: "box",
+ },
+
+ dom.div(
+ {
+ className: "h-split-box-pane",
+ style: { flex: startWidth, minWidth: minStartWidth },
+ },
+ start
+ ),
+
+ dom.div({
+ className: "devtools-side-splitter",
+ onMouseDown: this._onMouseDown,
+ }),
+
+ dom.div(
+ {
+ className: "h-split-box-pane",
+ style: { flex: 1 - startWidth, minWidth: minEndWidth },
+ },
+ end
+ )
+ );
+ }
+});