import {module} from '../module'; import './style.css'; directive.$inject = ['vnPopover']; export function directive(vnPopover) { return { restrict: 'A', link: function($scope, $element, $attrs) { $element.on('click', function(event) { vnPopover.showComponent($attrs.vnDialog, $scope, $element); event.preventDefault(); }); } }; } module.directive('vnPopover', directive); export class Popover { constructor($document, $compile) { this.document = $document[0]; this.$compile = $compile; } show(childElement, parent) { let popover = this.document.createElement('div'); popover.className = 'vn-popover'; popover.addEventListener('mousedown', e => this.onPopoverMouseDown(e)); popover.appendChild(childElement); this.popover = popover; let style = popover.style; let spacing = 0; let screenMargin = 20; let dblMargin = screenMargin * 2; let width = popover.offsetWidth; let height = popover.offsetHeight; let innerWidth = window.innerWidth; let innerHeight = window.innerHeight; if (width + dblMargin > innerWidth) { width = innerWidth - dblMargin; style.width = width + 'px'; } if (height + dblMargin > innerHeight) { height = innerHeight - dblMargin; style.height = height + 'px'; } if (parent) { let parentNode = parent; let rect = parentNode.getBoundingClientRect(); let left = rect.left; let top = rect.top + spacing + parentNode.offsetHeight; if (left + width > innerWidth) left -= (left + width) - innerWidth + margin; if (top + height > innerHeight) top -= height + parentNode.offsetHeight + spacing * 2; if (left < 0) left = screenMargin; if (top < 0) top = screenMargin; style.top = (top) + 'px'; style.left = (left) + 'px'; style.minWidth = (rect.width) + 'px'; } this.document.body.appendChild(popover); this.docMouseDownHandler = e => this.onDocMouseDown(e); this.document.addEventListener('mousedown', this.docMouseDownHandler); this.docKeyDownHandler = e => this.onDocKeyDown(e); this.document.addEventListener('keydown', this.docKeyDownHandler); } showComponent(childComponent, $scope, parent) { let childElement = this.document.createElement(childComponent); this.$compile(childElement)($scope); this.show(childElement, parent); } hide() { if (!this.popover) return; this.document.removeEventListener('mousedown', this.docMouseDownHandler); this.document.removeEventListener('keydown', this.docKeyDownHandler); this.document.body.removeChild(this.popover); this.popover = null; this.lastEvent = null; this.docMouseDownHandler = null; this.docKeyDownHandler = null; } onDocMouseDown(event) { if (event != this.lastEvent) this.hide(); } onDocKeyDown(event) { if (event.keyCode === 27) this.hide(); } onPopoverMouseDown(event) { this.lastEvent = event; } } Popover.$inject = ['$document', '$compile']; module.service('vnPopover', Popover);