Scroll position management

This commit is contained in:
Jiang Yio 2023-05-29 18:23:01 -04:00
parent ffc2d4c6fa
commit 56662efed2
2 changed files with 58 additions and 2 deletions

View File

@ -26,7 +26,7 @@
<span>{{doctitle(selection_text) || 'Document'}}</span> <span>{{doctitle(selection_text) || 'Document'}}</span>
<router-link class="close" :to="'/patient/' + patient_dfn + '/document'" replace></router-link> <router-link class="close" :to="'/patient/' + patient_dfn + '/document'" replace></router-link>
</div> </div>
<div class="detail card-body">{{selection_text}}</div> <div class="detail card-body" ref="detail">{{selection_text}}</div>
</div> </div>
</div> </div>
</div> </div>
@ -46,10 +46,14 @@
cursor: default; cursor: default;
border-top: 1px solid #dee2e6; border-top: 1px solid #dee2e6;
padding: 0.25rem 0.75rem; padding: 0.25rem 0.75rem;
scroll-margin-top: 3.6875rem;
} }
li.record:nth-child(even) { li.record:nth-child(even) {
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05);
} }
ul.scroller.list-skinny li.record {
scroll-margin-top: 0;
}
li.record a { li.record a {
color: inherit; color: inherit;
} }
@ -70,6 +74,7 @@
text-decoration: none; text-decoration: none;
} }
div.detail { div.detail {
scroll-margin-top: calc(3.6875rem + 2.5625rem + 25vh);
font-family: monospace; font-family: monospace;
white-space: pre-wrap; white-space: pre-wrap;
} }
@ -85,6 +90,7 @@
} }
div.detail { div.detail {
max-height: 75vh; max-height: 75vh;
scroll-margin-top: 0;
overflow-y: auto; overflow-y: auto;
} }
} }
@ -192,6 +198,27 @@
this.selection_text = null; this.selection_text = null;
console.warn(ex); console.warn(ex);
} }
if(this.$refs.scroller) {
if(this.selection_text) { // scroll to selected item
await this.$nextTick();
var active = this.$refs.scroller.querySelectorAll(':scope > .active');
if(active.length > 0) (Element.prototype.scrollIntoViewIfNeeded || Element.prototype.scrollIntoView).call(active[0]);
if(this.$refs.detail) { // scroll to top of detail panel
this.$refs.detail.scrollIntoView();
this.$refs.detail.scrollTop = 0;
}
} else { // scroll to topmost item
var offset = this.$refs.scroller.getBoundingClientRect().top;
for(var children = this.$refs.scroller.children, count = children.length, i = 0; i < count; ++i) if(children[i].getBoundingClientRect().top >= offset) {
await this.$nextTick();
var behavior = document.documentElement.style.scrollBehavior;
document.documentElement.style.scrollBehavior = 'auto'; // inhibit Bootstrap smooth scrolling
children[i].scrollIntoView();
document.documentElement.style.scrollBehavior = behavior;
break;
}
}
}
}, },
{ immediate: true } { immediate: true }
); );

View File

@ -34,7 +34,7 @@
<span>{{selection.title.join(' - ')}}</span> <span>{{selection.title.join(' - ')}}</span>
<span class="close" @click="selection = null"></span> <span class="close" @click="selection = null"></span>
</div> </div>
<div class="detail card-body" v-html="selection.highlight || selection.detail" /> <div class="detail card-body" v-html="selection.highlight || selection.detail" ref="detail" />
</div> </div>
</div> </div>
</div> </div>
@ -74,10 +74,14 @@
cursor: default; cursor: default;
border-top: 1px solid #dee2e6; border-top: 1px solid #dee2e6;
padding: 0.25rem 0.75rem; padding: 0.25rem 0.75rem;
scroll-margin-top: 10.5rem;
} }
li.record:nth-child(even) { li.record:nth-child(even) {
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05);
} }
ul.scroller.list-skinny li.record {
scroll-margin-top: 0;
}
li.record.active { li.record.active {
color: #fff; color: #fff;
background-color: #0d6efd; background-color: #0d6efd;
@ -149,6 +153,7 @@
cursor: default; cursor: default;
} }
div.detail { div.detail {
scroll-margin-top: calc(3.6875rem + 2.5625rem + 25vh);
font-family: monospace; font-family: monospace;
white-space: pre-wrap; white-space: pre-wrap;
} }
@ -161,6 +166,7 @@
} }
div.detail { div.detail {
max-height: 75vh; max-height: 75vh;
scroll-margin-top: 0;
overflow-y: auto; overflow-y: auto;
} }
} }
@ -481,6 +487,29 @@
for(var i = 0; i < value.length; ++i) if(value[i].id == id) return this.selection = value[i]; for(var i = 0; i < value.length; ++i) if(value[i].id == id) return this.selection = value[i];
this.selection = null; this.selection = null;
} }
},
async selection(value) {
if(this.$refs.scroller) {
if(value) { // scroll to selected item
await this.$nextTick();
var active = this.$refs.scroller.querySelectorAll(':scope > .active');
if(active.length > 0) (Element.prototype.scrollIntoViewIfNeeded || Element.prototype.scrollIntoView).call(active[0]);
if(this.$refs.detail) { // scroll to top of detail panel
this.$refs.detail.scrollIntoView();
this.$refs.detail.scrollTop = 0;
}
} else { // scroll to topmost item
var offset = this.$refs.scroller.getBoundingClientRect().top;
for(var children = this.$refs.scroller.children, count = children.length, i = 0; i < count; ++i) if(children[i].getBoundingClientRect().top >= offset) {
await this.$nextTick();
var behavior = document.documentElement.style.scrollBehavior;
document.documentElement.style.scrollBehavior = 'auto'; // inhibit Bootstrap smooth scrolling
children[i].scrollIntoView();
document.documentElement.style.scrollBehavior = behavior;
break;
}
}
}
} }
}, },
methods: { methods: {