@vaadin/component-base
Advanced tools
Comparing version 24.4.0-alpha12 to 24.4.0-alpha13
{ | ||
"name": "@vaadin/component-base", | ||
"version": "24.4.0-alpha12", | ||
"version": "24.4.0-alpha13", | ||
"publishConfig": { | ||
@@ -45,3 +45,3 @@ "access": "public" | ||
}, | ||
"gitHead": "811e8327e02a8ecdca0bb5d6528856e70d429d0c" | ||
"gitHead": "97246b0703cd04a4b0ea5dcd49e2581d45cf6367" | ||
} |
@@ -12,3 +12,3 @@ /** | ||
get() { | ||
return '24.4.0-alpha12'; | ||
return '24.4.0-alpha13'; | ||
}, | ||
@@ -15,0 +15,0 @@ }); |
@@ -58,2 +58,9 @@ /** | ||
this.scrollTarget.addEventListener('virtualizer-element-focused', (e) => this.__onElementFocused(e)); | ||
this.elementsContainer.addEventListener('focusin', (e) => { | ||
this.scrollTarget.dispatchEvent( | ||
new CustomEvent('virtualizer-element-focused', { detail: { element: this.__getFocusedElement() } }), | ||
); | ||
}); | ||
if (this.reorderElements) { | ||
@@ -429,2 +436,71 @@ // Reordering the physical elements cancels the user's grab of the scroll bar handle on Safari. | ||
/** @private */ | ||
__getFocusedElement(visibleElements = this.__getVisibleElements()) { | ||
return visibleElements.find( | ||
(element) => | ||
element.contains(this.elementsContainer.getRootNode().activeElement) || | ||
element.contains(this.scrollTarget.getRootNode().activeElement), | ||
); | ||
} | ||
/** @private */ | ||
__nextFocusableSiblingMissing(focusedElement, visibleElements) { | ||
return ( | ||
// Check if focused element is the last visible DOM element | ||
visibleElements.indexOf(focusedElement) === visibleElements.length - 1 && | ||
// ...while there are more items available | ||
this.size > focusedElement.__virtualIndex + 1 | ||
); | ||
} | ||
/** @private */ | ||
__previousFocusableSiblingMissing(focusedElement, visibleElements) { | ||
return ( | ||
// Check if focused element is the first visible DOM element | ||
visibleElements.indexOf(focusedElement) === 0 && | ||
// ...while there are preceding items available | ||
focusedElement.__virtualIndex > 0 | ||
); | ||
} | ||
/** @private */ | ||
__onElementFocused(e) { | ||
if (!this.reorderElements) { | ||
return; | ||
} | ||
const focusedElement = e.detail.element; | ||
if (!focusedElement) { | ||
return; | ||
} | ||
// User has tabbed to or within a virtualizer element. | ||
// Check if a next or previous focusable sibling is missing while it should be there (so the user can continue tabbing). | ||
// The focusable sibling might be missing due to the elements not yet being in the correct DOM order. | ||
// First try flushing (which also flushes any active __scrollReorderDebouncer). | ||
const visibleElements = this.__getVisibleElements(); | ||
if ( | ||
this.__previousFocusableSiblingMissing(focusedElement, visibleElements) || | ||
this.__nextFocusableSiblingMissing(focusedElement, visibleElements) | ||
) { | ||
this.flush(); | ||
} | ||
// If the focusable sibling is still missing (because the focused element is at the edge of the viewport and | ||
// the virtual scrolling logic hasn't had the need to recycle elements), scroll the virtualizer just enough to | ||
// have the focusable sibling inside the visible viewport to force the virtualizer to recycle. | ||
const reorderedVisibleElements = this.__getVisibleElements(); | ||
if (this.__nextFocusableSiblingMissing(focusedElement, reorderedVisibleElements)) { | ||
this._scrollTop += | ||
Math.ceil(focusedElement.getBoundingClientRect().bottom) - | ||
Math.floor(this.scrollTarget.getBoundingClientRect().bottom - 1); | ||
this.flush(); | ||
} else if (this.__previousFocusableSiblingMissing(focusedElement, reorderedVisibleElements)) { | ||
this._scrollTop -= | ||
Math.ceil(this.scrollTarget.getBoundingClientRect().top + 1) - | ||
Math.floor(focusedElement.getBoundingClientRect().top); | ||
this.flush(); | ||
} | ||
} | ||
_scrollHandler() { | ||
@@ -667,9 +743,3 @@ // The scroll target is hidden. | ||
const visibleElements = this.__getVisibleElements(); | ||
const elementWithFocus = visibleElements.find( | ||
(element) => | ||
element.contains(this.elementsContainer.getRootNode().activeElement) || | ||
element.contains(this.scrollTarget.getRootNode().activeElement), | ||
); | ||
const targetElement = elementWithFocus || visibleElements[0]; | ||
const targetElement = this.__getFocusedElement(visibleElements) || visibleElements[0]; | ||
if (!targetElement) { | ||
@@ -676,0 +746,0 @@ // All elements are hidden, don't reorder |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
212461
6311