From c5899e08167fa0d30508da75b91b28ac0b93f825 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 18 Feb 2019 13:41:36 +0200 Subject: [PATCH] Improved dialog stack handling of scrolling while the stack is open --- app/imports/ui/dialogStack/DialogBase.vue | 18 +++++++- app/imports/ui/dialogStack/DialogStack.vue | 54 +++++++++++++++++++--- app/imports/ui/dialogStack/mockElement.js | 4 +- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/app/imports/ui/dialogStack/DialogBase.vue b/app/imports/ui/dialogStack/DialogBase.vue index 967e86fd..443e3e4f 100644 --- a/app/imports/ui/dialogStack/DialogBase.vue +++ b/app/imports/ui/dialogStack/DialogBase.vue @@ -7,9 +7,24 @@ + - + + + + + + + + @@ -26,6 +41,7 @@ }, data(){ return { offsetTop: 0, + isEditing: false, }}, methods: { onScroll(e){ diff --git a/app/imports/ui/dialogStack/DialogStack.vue b/app/imports/ui/dialogStack/DialogStack.vue index 56b46834..d65ce97f 100644 --- a/app/imports/ui/dialogStack/DialogStack.vue +++ b/app/imports/ui/dialogStack/DialogStack.vue @@ -68,12 +68,16 @@ return `left:${left}px; top:${top}px;`; }, enter(target, done){ - if (!target.attributes['data-element-id']){ + if (!target || !target.attributes['data-element-id']){ done(); return; - } + } let elementId = target.attributes['data-element-id'].value; let source = document.getElementById(elementId); + if (!source){ + done(); + return; + } // Get the original styles so we can repair them later let originalStyle = { transform: target.style.transform, @@ -87,6 +91,7 @@ // hide the source source.style.transition = "none"; source.style.opacity = "0"; + this.hiddenElement = source; // Instantly mock the source target.style.transition = 'none'; @@ -105,16 +110,20 @@ }, leave(target, done){ let elementId; - if (target.attributes['data-return-element-id']) { + if (target && target.attributes['data-return-element-id']) { elementId = target.attributes['data-return-element-id'].value; } else { - if (!target.attributes['data-element-id']){ + if (!target || !target.attributes['data-element-id']){ done(); return; } elementId = target.attributes['data-element-id'].value; } let source = document.getElementById(elementId); + if (!source){ + done(); + return; + } let index = target.attributes['data-index'].value; if (index != 0){ // If we aren't the only dialog, we'll need compensate for offset @@ -122,21 +131,54 @@ } else { mockElement({source, target}); } + // If the source and the hidden Element are different + // hide the source and reveal the hidden element + let originalSourceTransition = source.style.transition; + if (this.hiddenElement !== source){ + source.style.transition = "none"; + source.style.opacity = "0"; + this.hiddenElement.style.opacity = null; + } setTimeout(() => { - let originalTransition = source.style.transition; source.style.opacity = null; source.style.transition = 'none'; target.style.transition = `opacity ${MOCK_DURATION / 4}ms, pointer-events 0s` requestAnimationFrame(() => { - source.style.transition = originalTransition; + source.style.transition = originalSourceTransition; target.style.opacity = "0"; target.style.pointerEvents = "none"; target.style.setProperty('box-shadow', "none", 'important'); setTimeout(done, MOCK_DURATION / 4); }); }, MOCK_DURATION); + }, + noScroll(e){ + console.log(e); + e.preventDefault(); } }, + watch:{ + dialogs(newDialogs) { + let el = document.documentElement; + if (newDialogs.length) { + this.top = el.scrollTop; + if (el.scrollHeight > el.clientHeight){ + el.style.position = 'fixed'; + el.style.top = `${-this.top}px`; + el.style.left = 0; + el.style.right = 0; + el.style.overflowY = 'scroll'; + } + } else { + el.style.position = null; + el.style.top = null; + el.style.left = null; + el.style.right = null; + el.style.overflowY = null; + el.scrollTop = this.top; + } + } + } }; diff --git a/app/imports/ui/dialogStack/mockElement.js b/app/imports/ui/dialogStack/mockElement.js index c20f6a22..fdf1c7c0 100644 --- a/app/imports/ui/dialogStack/mockElement.js +++ b/app/imports/ui/dialogStack/mockElement.js @@ -37,8 +37,8 @@ const transformedBoxShadow = (shadowString, deltaWidth, deltaHeight) => { export default function mockElement({source, target, offset = {x: 0, y: 0}}){ if (!source || !target) throw `Can't mock without ${source ? 'target' : 'source'}` ; - sourceRect = source.getBoundingClientRect(); - targetRect = target.getBoundingClientRect(); + let sourceRect = source.getBoundingClientRect(); + let targetRect = target.getBoundingClientRect(); // Get how must the target change to become the source const deltaWidth = sourceRect.width / targetRect.width;