@@ -167,8 +167,53 @@ class Utils {
167167 return true
168168 }
169169
170+ /**
171+ * detects if an element is inside a Shadow DOM
172+ */
173+ static isInShadowDOM ( el ) {
174+ if ( ! el || ! el . getRootNode ) {
175+ return false
176+ }
177+
178+ const rootNode = el . getRootNode ( )
179+
180+ // check if root node is a ShadowRoot
181+ return rootNode && rootNode !== document && Utils . is ( 'ShadowRoot' , rootNode )
182+ }
183+
184+ /**
185+ * gets the shadow root host element
186+ */
187+ static getShadowRootHost ( el ) {
188+ if ( ! Utils . isInShadowDOM ( el ) ) {
189+ return null
190+ }
191+
192+ const rootNode = el . getRootNode ( )
193+ return rootNode . host || null
194+ }
195+
170196 static getDimensions ( el ) {
171- const computedStyle = getComputedStyle ( el , null )
197+ if ( ! el ) return [ 0 , 0 ]
198+
199+ // check if in shadow DOM
200+ const rootNode = el . getRootNode && el . getRootNode ( )
201+ const inShadowDOM = rootNode && rootNode !== document
202+
203+ if ( inShadowDOM && rootNode . host ) {
204+ // in shadow DOM: use host container dimensions
205+ const hostRect = rootNode . host . getBoundingClientRect ( )
206+ return [ hostRect . width , hostRect . height ]
207+ }
208+
209+ // regular DOM
210+ let computedStyle
211+ try {
212+ computedStyle = getComputedStyle ( el , null )
213+ } catch ( e ) {
214+ // fallback to clientWidth/Height
215+ return [ el . clientWidth || 0 , el . clientHeight || 0 ]
216+ }
172217
173218 let elementHeight = el . clientHeight
174219 let elementWidth = el . clientWidth
@@ -183,6 +228,19 @@ class Utils {
183228 }
184229
185230 static getBoundingClientRect ( element ) {
231+ if ( ! element ) {
232+ return {
233+ top : 0 ,
234+ right : 0 ,
235+ bottom : 0 ,
236+ left : 0 ,
237+ width : 0 ,
238+ height : 0 ,
239+ x : 0 ,
240+ y : 0 ,
241+ }
242+ }
243+
186244 const rect = element . getBoundingClientRect ( )
187245 return {
188246 top : rect . top ,
0 commit comments