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

141 lines
3.3 KiB
JavaScript
Raw Normal View History

2019-10-26 23:30:01 +00:00
import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
/**
* Base class for windows displayed over application content.
*/
export default class Popup extends Component {
2020-04-25 09:50:04 +00:00
constructor(...args) {
super(...args);
2019-10-26 23:30:01 +00:00
this._shown = false;
this.displayMode = 'centered';
}
$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 popup.
2019-10-26 23:30:01 +00:00
*/
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();
}
2019-10-26 23:30:01 +00:00
this.$contentScope = this.$.$new();
2020-05-06 12:38:09 +00:00
this.contentLinkFn(
this.$contentScope,
element => this.popup = element[0],
2019-10-26 23:30:01 +00:00
{parentBoundTranscludeFn: this.$transclude}
2020-05-06 12:38:09 +00:00
);
2020-04-25 09:50:04 +00:00
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 popup.
2019-10-26 23:30:01 +00:00
*/
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');
}
/**
* Called when closing transition ends and popup is not visible, it can
* be overriden by child classes (calling the super) to perform additional
* actions.
*/
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: '=?'
2020-04-25 09:50:04 +00:00
},
installClasses: false
2019-10-26 23:30:01 +00:00
});
2020-05-06 12:38:09 +00:00
ngModule.run(['$compile', function($compile) {
Popup.prototype.contentLinkFn = $compile(require('./index.html'));
}]);