@vaadin/component-base
Advanced tools
Comparing version 24.4.0-dev.b3e1d14600 to 24.4.0-rc1
{ | ||
"name": "@vaadin/component-base", | ||
"version": "24.4.0-dev.b3e1d14600", | ||
"version": "24.4.0-rc1", | ||
"publishConfig": { | ||
@@ -45,3 +45,3 @@ "access": "public" | ||
}, | ||
"gitHead": "502d4f5b03f770a83d270d98078cde230254dd0e" | ||
"gitHead": "a81e3b927d44c56613fa4e1307494a2acc81005f" | ||
} |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -20,2 +20,9 @@ */ | ||
/** | ||
* The number of items. | ||
* | ||
* @type {number} | ||
*/ | ||
size = 0; | ||
/** | ||
* The number of items to display per page. | ||
@@ -56,10 +63,2 @@ * | ||
/** | ||
* The number of items. | ||
* | ||
* @type {number} | ||
* @private | ||
*/ | ||
__size = 0; | ||
/** | ||
* The total number of items, including items from expanded sub-caches. | ||
@@ -143,42 +142,2 @@ * | ||
/** | ||
* The number of items. | ||
* | ||
* @type {number} | ||
* @private | ||
*/ | ||
get size() { | ||
return this.__size; | ||
} | ||
/** | ||
* Sets the number of items. | ||
* | ||
* @type {number} | ||
* @private | ||
*/ | ||
set size(size) { | ||
const oldSize = this.__size; | ||
if (oldSize === size) { | ||
return; | ||
} | ||
this.__size = size; | ||
if (this.context.placeholder !== undefined) { | ||
this.items.length = size; | ||
for (let i = 0; i < size; i++) { | ||
// eslint-disable-next-line logical-assignment-operators | ||
this.items[i] = this.items[i] || this.context.placeholder; | ||
} | ||
} | ||
Object.keys(this.pendingRequests).forEach((page) => { | ||
const startIndex = parseInt(page) * this.pageSize; | ||
if (startIndex >= this.size) { | ||
delete this.pendingRequests[page]; | ||
} | ||
}); | ||
} | ||
/** | ||
* Recalculates the flattened size for the cache and its descendant caches recursively. | ||
@@ -207,6 +166,3 @@ */ | ||
items.forEach((item, i) => { | ||
const itemIndex = startIndex + i; | ||
if (itemIndex < this.size) { | ||
this.items[itemIndex] = item; | ||
} | ||
this.items[startIndex + i] = item; | ||
}); | ||
@@ -213,0 +169,0 @@ } |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -68,17 +68,3 @@ */ | ||
/** | ||
* Indicates whether any data has been loaded since the last cache clear. | ||
* | ||
* @type {boolean} | ||
*/ | ||
hasData = false; | ||
/** | ||
* A placeholder item that is used to indicate that the item is not loaded yet. | ||
* | ||
* @type {undefined | object} | ||
*/ | ||
placeholder; | ||
constructor(host, { size, pageSize, isExpanded, getItemId, placeholder, dataProvider, dataProviderParams }) { | ||
constructor(host, { size, pageSize, isExpanded, getItemId, dataProvider, dataProviderParams }) { | ||
super(); | ||
@@ -89,3 +75,2 @@ this.host = host; | ||
this.isExpanded = isExpanded; | ||
this.placeholder = placeholder; | ||
this.dataProvider = dataProvider; | ||
@@ -107,3 +92,2 @@ this.dataProviderParams = dataProviderParams; | ||
isExpanded: this.isExpanded, | ||
placeholder: this.placeholder, | ||
// The controller instance is needed to ensure deprecated cache methods work. | ||
@@ -155,3 +139,2 @@ __controller: this, | ||
this.rootCache = this.__createRootCache(this.rootCache.size); | ||
this.hasData = false; | ||
} | ||
@@ -211,3 +194,3 @@ | ||
if (this.__isPlaceholder(item)) { | ||
if (!item) { | ||
this.__loadCachePage(cache, page); | ||
@@ -227,3 +210,3 @@ } | ||
if (!this.__isPlaceholder(item) && this.isExpanded(item) && !cache.getSubCache(index)) { | ||
if (item && this.isExpanded(item) && !cache.getSubCache(index)) { | ||
const subCache = cache.createSubCache(index); | ||
@@ -277,4 +260,2 @@ this.__loadCachePage(subCache, 0); | ||
this.hasData = true; | ||
this.dispatchEvent(new CustomEvent('page-received')); | ||
@@ -293,7 +274,2 @@ | ||
} | ||
/** @private */ | ||
__isPlaceholder(item) { | ||
return item === this.placeholder; | ||
} | ||
} |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -12,3 +12,3 @@ */ | ||
get() { | ||
return '24.4.0-alpha1'; | ||
return '24.4.0-rc1'; | ||
}, | ||
@@ -15,0 +15,0 @@ }); |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -72,3 +72,3 @@ */ | ||
// Add new classes based on the overlayClass | ||
const classesToAdd = typeof overlayClass === 'string' ? overlayClass.split(' ') : []; | ||
const classesToAdd = typeof overlayClass === 'string' ? overlayClass.split(' ').filter(Boolean) : []; | ||
if (classesToAdd.length > 0) { | ||
@@ -75,0 +75,0 @@ classList.add(...classesToAdd); |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -96,2 +96,5 @@ */ | ||
// Set the key for this property | ||
this.getOrCreateMap('__propKeys').set(name, key); | ||
if (options.sync) { | ||
@@ -236,2 +239,22 @@ result = { | ||
/** | ||
* Set several properties at once and perform synchronous update. | ||
* @protected | ||
*/ | ||
setProperties(props) { | ||
Object.entries(props).forEach(([name, value]) => { | ||
// Use private key and not setter to not trigger | ||
// update for properties marked as `sync: true`. | ||
const key = this.constructor.__propKeys.get(name); | ||
const oldValue = this[key]; | ||
this[key] = value; | ||
this.requestUpdate(name, oldValue); | ||
}); | ||
// Perform sync update | ||
if (this.hasUpdated) { | ||
this.performUpdate(); | ||
} | ||
} | ||
/** @protected */ | ||
@@ -238,0 +261,0 @@ _createMethodObserver(observer) { |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2022 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2022 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2022 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2022 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2022 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2022 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2022 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2022 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -5,0 +5,0 @@ */ |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -8,5 +8,9 @@ */ | ||
/** | ||
* Check if two paths can be resolved as URLs | ||
* with the same origin and pathname. | ||
* Checks if two paths match based on their origin, pathname, and query parameters. | ||
* | ||
* The function matches an actual URL against an expected URL to see if they share | ||
* the same base origin (like https://example.com), the same path (like /path/to/page), | ||
* and if the actual URL contains at least all the query parameters with the same values | ||
* from the expected URL. | ||
*/ | ||
export declare function matchPaths(path1: string, path2: string): boolean; | ||
export declare function matchPaths(actual: string, expected: string): boolean; |
/** | ||
* @license | ||
* Copyright (c) 2023 Vaadin Ltd. | ||
* Copyright (c) 2023 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -8,13 +8,35 @@ */ | ||
/** | ||
* Check if two paths can be resolved as URLs | ||
* with the same origin and pathname. | ||
* Checks if one set of URL parameters contains all the parameters | ||
* with the same values from another set. | ||
* | ||
* @param {string} path1 | ||
* @param {string} path2 | ||
* @param {URLSearchParams} actual | ||
* @param {URLSearchParams} expected | ||
*/ | ||
export function matchPaths(path1, path2) { | ||
function containsQueryParams(actual, expected) { | ||
return [...expected.entries()].every(([key, value]) => { | ||
return actual.getAll(key).includes(value); | ||
}); | ||
} | ||
/** | ||
* Checks if two paths match based on their origin, pathname, and query parameters. | ||
* | ||
* The function matches an actual URL against an expected URL to see if they share | ||
* the same base origin (like https://example.com), the same path (like /path/to/page), | ||
* and if the actual URL contains at least all the query parameters with the same values | ||
* from the expected URL. | ||
* | ||
* @param {string} actual The actual URL to match. | ||
* @param {string} expected The expected URL to match. | ||
*/ | ||
export function matchPaths(actual, expected) { | ||
const base = document.baseURI; | ||
const url1 = new URL(path1, base); | ||
const url2 = new URL(path2, base); | ||
return url1.origin === url2.origin && url1.pathname === url2.pathname; | ||
const actualUrl = new URL(actual, base); | ||
const expectedUrl = new URL(expected, base); | ||
return ( | ||
actualUrl.origin === expectedUrl.origin && | ||
actualUrl.pathname === expectedUrl.pathname && | ||
containsQueryParams(actualUrl.searchParams, expectedUrl.searchParams) | ||
); | ||
} |
/** | ||
* @license | ||
* Copyright (c) 2021 - 2023 Vaadin Ltd. | ||
* Copyright (c) 2021 - 2024 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
@@ -8,3 +8,3 @@ */ | ||
// https://github.com/vaadin/eslint-config-vaadin/issues/33 | ||
import { animationFrame, timeOut } from './async.js'; | ||
import { animationFrame, microTask, timeOut } from './async.js'; | ||
import { isSafari } from './browser-utils.js'; | ||
@@ -59,2 +59,9 @@ import { Debouncer, flush } from './debounce.js'; | ||
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) { | ||
@@ -87,2 +94,6 @@ // Reordering the physical elements cancels the user's grab of the scroll bar handle on Safari. | ||
get _maxVirtualIndexOffset() { | ||
return this.size - this._virtualCount; | ||
} | ||
__hasPlaceholders() { | ||
@@ -112,3 +123,3 @@ return this.__getVisibleElements().some((el) => el.__virtualizerPlaceholder); | ||
targetVirtualIndex = this._virtualCount - (this.size - index); | ||
this._vidxOffset = this.size - this._virtualCount; | ||
this._vidxOffset = this._maxVirtualIndexOffset; | ||
} else if (targetVirtualIndex < visibleElementCount) { | ||
@@ -143,3 +154,2 @@ if (index < OFFSET_ADJUST_MIN_THRESHOLD) { | ||
flush() { | ||
const startPhysicalCount = this._physicalCount; | ||
// The scroll target is hidden. | ||
@@ -162,7 +172,2 @@ if (this.scrollTarget.offsetHeight === 0) { | ||
} | ||
if (this._physicalCount !== startPhysicalCount) { | ||
// Flushing again until physical count stabilizes fixes https://github.com/vaadin/flow-components/issues/5595#issuecomment-1770278913 | ||
this.flush(); | ||
} | ||
} | ||
@@ -236,2 +241,3 @@ | ||
el.style.paddingTop = ''; | ||
el.style.opacity = ''; | ||
el.__virtualizerPlaceholder = false; | ||
@@ -261,2 +267,3 @@ } | ||
el.style.paddingTop = `${this.__placeholderHeight}px`; | ||
el.style.opacity = '0'; | ||
el.__virtualizerPlaceholder = true; | ||
@@ -308,20 +315,37 @@ | ||
// Prevent element update while the scroll position is being restored | ||
this.__preventElementUpdates = true; | ||
// Record the scroll position before changing the size | ||
let fvi; // First visible index | ||
let fviOffsetBefore; // Scroll offset of the first visible index | ||
if (size > 0) { | ||
fvi = this.adjustedFirstVisibleIndex; | ||
fviOffsetBefore = this.__getIndexScrollOffset(fvi); | ||
} | ||
// Change the size | ||
this.__size = size; | ||
if (!this._physicalItems) { | ||
// Not initialized yet | ||
this._itemsChanged({ | ||
path: 'items', | ||
}); | ||
this.__preventElementUpdates = true; | ||
flush(); | ||
this.__preventElementUpdates = false; | ||
} else { | ||
// Already initialized, just update _virtualCount | ||
this._updateScrollerSize(); | ||
this._virtualCount = this.items.length; | ||
this._render(); | ||
this._itemsChanged({ | ||
path: 'items', | ||
}); | ||
flush(); | ||
// Try to restore the scroll position if the new size is larger than 0 | ||
if (size > 0) { | ||
fvi = Math.min(fvi, size - 1); | ||
// Note, calling scrollToIndex also updates the virtual index offset, | ||
// causing the virtualizer to add more items when size is increased, | ||
// and remove exceeding items when size is decreased. | ||
this.scrollToIndex(fvi); | ||
const fviOffsetAfter = this.__getIndexScrollOffset(fvi); | ||
if (fviOffsetBefore !== undefined && fviOffsetAfter !== undefined) { | ||
this._scrollTop += fviOffsetBefore - fviOffsetAfter; | ||
} | ||
} | ||
this.__preventElementUpdates = false; | ||
// When reducing size while invisible, iron-list does not update items, so | ||
@@ -338,6 +362,8 @@ // their hidden state is not updated and their __lastUpdatedIndex is not | ||
// Schedule and flush a resize handler. This will cause a | ||
// re-render for the elements. | ||
// Schedule and flush a resize handler | ||
this._resizeHandler(); | ||
flush(); | ||
// Schedule an update to ensure item positions are correct after subsequent size changes | ||
// Fix for https://github.com/vaadin/flow-components/issues/6269 | ||
this._debounce('_update', this._update, microTask); | ||
} | ||
@@ -438,2 +464,71 @@ | ||
/** @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() { | ||
@@ -676,9 +771,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) { | ||
@@ -718,2 +807,4 @@ // All elements are hidden, don't reorder | ||
_adjustVirtualIndexOffset(delta) { | ||
const maxOffset = this._maxVirtualIndexOffset; | ||
if (this._virtualCount >= this.size) { | ||
@@ -725,5 +816,4 @@ this._vidxOffset = 0; | ||
// Process a large scroll position change | ||
const scale = this._scrollTop / (this.scrollTarget.scrollHeight - this.scrollTarget.offsetHeight); | ||
const offset = scale * this.size; | ||
this._vidxOffset = Math.round(offset - scale * this._virtualCount); | ||
const scale = this._scrollTop / (this.scrollTarget.scrollHeight - this.scrollTarget.clientHeight); | ||
this._vidxOffset = Math.round(scale * maxOffset); | ||
} else { | ||
@@ -747,3 +837,2 @@ // Make sure user can always swipe/wheel scroll to the start and end | ||
// Near end | ||
const maxOffset = this.size - this._virtualCount; | ||
if (this._scrollTop >= this._maxScrollTop && this._maxScrollTop > 0) { | ||
@@ -750,0 +839,0 @@ this._vidxOffset = maxOffset; |
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
214286
6348