Skip to content

Commit

Permalink
fix(VDialog): support horizontal scrolling
Browse files Browse the repository at this point in the history
fixes #3765
  • Loading branch information
KaelWD committed Nov 8, 2021
1 parent 99f77d9 commit bc82074
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions packages/vuetify/src/mixins/overlayable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,32 @@ export default Vue.extend<Vue & Toggleable & Stackable & options>().extend({
if (!el || el.nodeType !== Node.ELEMENT_NODE) return false

const style = window.getComputedStyle(el)
return (['auto', 'scroll'].includes(style.overflowY!) || el.tagName === 'SELECT') && el.scrollHeight > el.clientHeight
return ((['auto', 'scroll'].includes(style.overflowY!) || el.tagName === 'SELECT') && el.scrollHeight > el.clientHeight) ||
((['auto', 'scroll'].includes(style.overflowX!)) && el.scrollWidth > el.clientWidth)
},
shouldScroll (el: Element, delta: number): boolean {
shouldScroll (el: Element, e: WheelEvent): boolean {
if (el.hasAttribute('data-app')) return false

const alreadyAtTop = el.scrollTop === 0
const alreadyAtBottom = el.scrollTop + el.clientHeight === el.scrollHeight
const dir = e.shiftKey || e.deltaX ? 'x' : 'y'
const delta = dir === 'y' ? e.deltaY : e.deltaX || e.deltaY

let alreadyAtStart: boolean
let alreadyAtEnd: boolean
if (dir === 'y') {
alreadyAtStart = el.scrollTop === 0
alreadyAtEnd = el.scrollTop + el.clientHeight === el.scrollHeight
} else {
alreadyAtStart = el.scrollLeft === 0
alreadyAtEnd = el.scrollLeft + el.clientWidth === el.scrollWidth
}

const scrollingUp = delta < 0
const scrollingDown = delta > 0

if (!alreadyAtTop && scrollingUp) return true
if (!alreadyAtBottom && scrollingDown) return true
if ((alreadyAtTop || alreadyAtBottom)) {
return this.shouldScroll(el.parentNode as Element, delta)
if (!alreadyAtStart && scrollingUp) return true
if (!alreadyAtEnd && scrollingDown) return true
if ((alreadyAtStart || alreadyAtEnd)) {
return this.shouldScroll(el.parentNode as Element, e)
}

return false
Expand All @@ -185,14 +197,13 @@ export default Vue.extend<Vue & Toggleable & Stackable & options>().extend({
},
checkPath (e: WheelEvent) {
const path = composedPath(e)
const delta = e.deltaY

if (e.type === 'keydown' && path[0] === document.body) {
const dialog = this.$refs.dialog
// getSelection returns null in firefox in some edge cases, can be ignored
const selected = window.getSelection()!.anchorNode as Element
if (dialog && this.hasScrollbar(dialog) && this.isInside(selected, dialog)) {
return !this.shouldScroll(dialog, delta)
return !this.shouldScroll(dialog, e)
}
return true
}
Expand All @@ -204,7 +215,7 @@ export default Vue.extend<Vue & Toggleable & Stackable & options>().extend({
if (el === document.documentElement) return true
if (el === this.$refs.content) return true

if (this.hasScrollbar(el as Element)) return !this.shouldScroll(el as Element, delta)
if (this.hasScrollbar(el as Element)) return !this.shouldScroll(el as Element, e)
}

return true
Expand Down

0 comments on commit bc82074

Please sign in to comment.