@@ -9,12 +9,60 @@ const elementInViewport = (el: HTMLElement) => {
99}
1010
1111export const getScrollableParent = ( element : HTMLElement | null ) : HTMLElement | null => {
12+ const allowsVerticalScroll = ( el : HTMLElement ) : boolean => {
13+ const computedStyle = window . getComputedStyle ( el )
14+
15+ if ( [ 'scroll' , 'overlay' ] . includes ( computedStyle . overflowY ) ) {
16+ return true
17+ }
18+
19+ if ( computedStyle . overflowY !== 'auto' ) {
20+ return false
21+ }
22+
23+ if ( [ 'visible' , 'clip' ] . includes ( computedStyle . overflowX ) ) {
24+ return true
25+ }
26+
27+ return hasDimensionConstraint ( computedStyle . maxHeight , el . style . height )
28+ }
29+
30+ const allowsHorizontalScroll = ( el : HTMLElement ) : boolean => {
31+ const computedStyle = window . getComputedStyle ( el )
32+
33+ if ( [ 'scroll' , 'overlay' ] . includes ( computedStyle . overflowX ) ) {
34+ return true
35+ }
36+
37+ if ( computedStyle . overflowX !== 'auto' ) {
38+ return false
39+ }
40+
41+ if ( [ 'visible' , 'clip' ] . includes ( computedStyle . overflowY ) ) {
42+ return true
43+ }
44+
45+ return hasDimensionConstraint ( computedStyle . maxWidth , el . style . width )
46+ }
47+
48+ const hasDimensionConstraint = ( computedMaxDimension : string , inlineStyleDimension : string ) : boolean => {
49+ if ( computedMaxDimension && computedMaxDimension !== 'none' && computedMaxDimension !== '0px' ) {
50+ return true
51+ }
52+
53+ if ( inlineStyleDimension && inlineStyleDimension !== 'auto' && inlineStyleDimension !== '0' ) {
54+ return true
55+ }
56+
57+ return false
58+ }
59+
1260 let parent = element ?. parentElement
1361
1462 while ( parent ) {
15- const overflowY = window . getComputedStyle ( parent ) . overflowY
63+ const allowsScroll = allowsVerticalScroll ( parent ) || allowsHorizontalScroll ( parent )
1664
17- if ( overflowY === 'auto' || overflowY === 'scroll' ) {
65+ if ( window . getComputedStyle ( parent ) . display !== 'contents' && allowsScroll ) {
1866 return parent
1967 }
2068
0 commit comments