aurelia-split-pane
Version:
A custom element for resizable split panes.
136 lines (135 loc) • 6.49 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
var aurelia_framework_1 = require("aurelia-framework");
var util_1 = require("./util");
var aurelia_event_aggregator_1 = require("aurelia-event-aggregator");
var SplitPaneDivider = /** @class */ (function () {
function SplitPaneDivider(element, events) {
var _this = this;
this.startCoordinate = 0;
this.previousSiblingSize = 0;
this.nextSiblingSize = 0;
this.mouseMove = function (event) {
_this.drag(event.clientX, event.clientY);
};
this.touchMove = function (event) {
event.preventDefault(); // stop page from scrolling
var touch = event.touches[0];
_this.drag(touch.clientX, touch.clientY);
};
this.stopDrag = function () {
_this.events.publish('split-pane:stop');
_this.removeListeners();
};
this.element = element;
this.events = events;
}
SplitPaneDivider_1 = SplitPaneDivider;
SplitPaneDivider.isDivider = function (element) {
return element.tagName.toLowerCase() === SplitPaneDivider_1.TAG_NAME;
};
SplitPaneDivider.prototype.bind = function (bindingContext) {
this.parent = bindingContext;
};
SplitPaneDivider.prototype.detached = function () {
this.removeListeners();
};
SplitPaneDivider.prototype.mouseDown = function (event) {
if (event.button === 0 && this.startDrag(event.clientX, event.clientY)) {
// style rules may have affected the flex-basis of the children,
// so recalculate them now we are starting a drag
this.parent.setChildrenFlexBasis();
aurelia_framework_1.DOM.addEventListener('mousemove', this.mouseMove, false);
aurelia_framework_1.DOM.addEventListener('mouseup', this.stopDrag, false);
}
};
SplitPaneDivider.prototype.touchStart = function (event) {
var touch = event.touches[0];
if (this.startDrag(touch.clientX, touch.clientY)) {
// style rules may have affected the flex-basis of the children,
// so recalculate them now we are starting a drag
this.parent.setChildrenFlexBasis();
aurelia_framework_1.DOM.addEventListener('touchmove', this.touchMove, false);
aurelia_framework_1.DOM.addEventListener('touchend', this.stopDrag, false);
}
};
SplitPaneDivider.prototype.startDrag = function (clientX, clientY) {
var prev = this.element.previousElementSibling;
var next = this.element.nextElementSibling;
if (prev !== null && next !== null) {
var prevRect = prev.getBoundingClientRect();
var nextRect = next.getBoundingClientRect();
switch (this.parent.direction) {
case 'horizontal':
this.startCoordinate = clientX;
this.previousSiblingSize = prevRect.width;
this.nextSiblingSize = nextRect.width;
this.events.publish('split-pane:start');
return true;
case 'vertical':
this.startCoordinate = clientY;
this.previousSiblingSize = prevRect.height;
this.nextSiblingSize = nextRect.height;
this.events.publish('split-pane:start');
return true;
default:
return false;
}
}
else {
return false;
}
};
SplitPaneDivider.prototype.drag = function (clientX, clientY) {
var currentCoordinate = this.parent.direction === 'horizontal' ? clientX : clientY;
var delta = currentCoordinate - this.startCoordinate;
var prev = this.element.previousElementSibling;
var next = this.element.nextElementSibling;
if (prev !== null && next !== null) {
var prevSize = void 0;
var nextSize = void 0;
if (delta < 0) {
prevSize = Math.max(0, this.previousSiblingSize + delta);
nextSize = this.nextSiblingSize - (prevSize - this.previousSiblingSize);
}
else if (delta > 0) {
nextSize = Math.max(0, this.nextSiblingSize - delta);
prevSize = this.previousSiblingSize - (nextSize - this.nextSiblingSize);
}
else {
return;
}
util_1.setFlexBasis(prev, prevSize);
util_1.setFlexBasis(next, nextSize);
var resizeEvent = {
clientX: clientX,
clientY: clientY
};
this.events.publish('split-pane:resize', resizeEvent);
}
};
SplitPaneDivider.prototype.removeListeners = function () {
aurelia_framework_1.DOM.removeEventListener('mousemove', this.mouseMove, false);
aurelia_framework_1.DOM.removeEventListener('mouseup', this.stopDrag, false);
aurelia_framework_1.DOM.removeEventListener('touchmove', this.touchMove, false);
aurelia_framework_1.DOM.removeEventListener('touchend', this.stopDrag, false);
};
SplitPaneDivider.TAG_NAME = 'split-pane-divider';
SplitPaneDivider = SplitPaneDivider_1 = __decorate([
aurelia_framework_1.inject(aurelia_framework_1.DOM.Element, aurelia_event_aggregator_1.EventAggregator),
aurelia_framework_1.customElement(SplitPaneDivider_1.TAG_NAME),
__metadata("design:paramtypes", [Object, aurelia_event_aggregator_1.EventAggregator])
], SplitPaneDivider);
return SplitPaneDivider;
var SplitPaneDivider_1;
}());
exports.SplitPaneDivider = SplitPaneDivider;