salix/front/core/components/popup/index.js

132 lines
3.2 KiB
JavaScript
Raw Normal View History

2019-10-26 23:30:01 +00:00
import ngModule from '../../module';
import Component from '../../lib/component';
import template from './index.html';
import './style.scss';
/**
* Base class for windows displayed over application content.
*/
export default class Popup extends Component {
constructor($element, $scope, $transclude) {
super($element, $scope);
this.$transclude = $transclude;
this._shown = false;
this.displayMode = 'centered';
this.template = template;
2019-10-26 23:30:01 +00:00
}
$onDestroy() {
this.hide();
}
/**
* @type {Boolean} Wether to show or hide the popup.
*/
get shown() {
return this._shown;
}
set shown(value) {
if (value)
this.show();
else
this.hide();
}
/**
* Displays the dialog to the user.
*/
show() {
if (this.shown) return;
this._shown = true;
2019-11-10 10:08:44 +00:00
if (this.closeTimeout) {
this.$timeout.cancel(this.closeTimeout);
this.onClose();
}
let linkFn = this.$compile(this.template);
2019-10-26 23:30:01 +00:00
this.$contentScope = this.$.$new();
this.popup = linkFn(this.$contentScope, null,
{parentBoundTranscludeFn: this.$transclude}
)[0];
this.windowEl = this.popup.querySelector('.window');
2020-04-01 14:05:43 +00:00
this.windowEl.focus();
2019-10-26 23:30:01 +00:00
let classList = this.popup.classList;
classList.add(this.displayMode);
classList.add(...this.constructor.$classNames);
2019-11-12 07:51:50 +00:00
this.document.body.appendChild(this.popup);
2019-10-26 23:30:01 +00:00
this.keyDownHandler = e => this.onkeyDown(e);
this.document.addEventListener('keydown', this.keyDownHandler);
this.deregisterCallback = this.$transitions.onStart({},
() => this.hide());
2019-11-10 10:08:44 +00:00
this.$timeout.cancel(this.showTimeout);
this.showTimeout = this.$timeout(() => {
this.showTimeout = null;
2019-10-26 23:30:01 +00:00
classList.add('shown');
}, 10);
this.emit('open');
}
/**
* Hides the dialog calling the response handler.
*/
hide() {
if (!this.shown) return;
2019-11-12 07:51:50 +00:00
this._shown = false;
2019-10-26 23:30:01 +00:00
this.document.removeEventListener('keydown', this.keyDownHandler);
this.keyDownHandler = null;
2019-11-10 10:08:44 +00:00
this.deregisterCallback();
this.deregisterCallback = null;
2019-10-26 23:30:01 +00:00
this.popup.classList.remove('shown');
2019-11-10 10:08:44 +00:00
this.closeTimeout = this.$timeout(
() => this.onClose(), 200);
2019-10-26 23:30:01 +00:00
this.lastEvent = null;
this.emit('closeStart');
}
onClose() {
2019-11-10 10:08:44 +00:00
this.closeTimeout = null;
this.popup.remove();
this.popup = null;
2019-11-10 13:13:55 +00:00
this.$contentScope.$destroy();
2019-11-12 08:24:01 +00:00
this.$contentScope = null;
this.windowEl = null;
this.emit('close');
}
2019-10-26 23:30:01 +00:00
onWindowMouseDown(event) {
this.lastEvent = event;
}
onBgMouseDown(event) {
if (!event.defaultPrevented && event != this.lastEvent)
this.hide();
}
onkeyDown(event) {
if (!event.defaultPrevented && event.key == 'Escape')
this.hide();
}
}
Popup.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('vnPopup', {
controller: Popup,
transclude: true,
bindings: {
shown: '=?'
}
});