Improved dialog stack handling of scrolling while the stack is open

This commit is contained in:
Stefan Zermatten
2019-02-18 13:41:36 +02:00
parent d30ee06e33
commit c5899e0816
3 changed files with 67 additions and 9 deletions

View File

@@ -7,9 +7,24 @@
</v-icon>
</v-btn>
<slot name="toolbar"></slot>
<template v-if="$slots.edit">
<v-spacer/>
<v-btn icon flat @click="isEditing = !isEditing">
<v-icon>
{{isEditing ? 'check' : 'create'}}
</v-icon>
</v-btn>
</template>
</v-toolbar>
<v-card-text id="base-dialog-body" v-scroll:#base-dialog-body="onScroll">
<slot></slot>
<v-tabs-items :value="isEditing ? 1 : 0">
<v-tab-item>
<slot/>
</v-tab-item>
<v-tab-item lazy>
<slot name="edit"/>
</v-tab-item>
</v-tabs-items>
</v-card-text>
<v-card-actions>
<slot name="actions"></slot>
@@ -26,6 +41,7 @@
},
data(){ return {
offsetTop: 0,
isEditing: false,
}},
methods: {
onScroll(e){

View File

@@ -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;
}
}
}
};
</script>

View File

@@ -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;