@aqua-ds/web-components
Version:
AquaDS Web Components
209 lines (205 loc) • 12.2 kB
JavaScript
import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
import { P as PopoverWidths } from './PopoverWidths.js';
const virtualScrollListCss = ".virtual-scroll-list.sc-virtual-scroll-list{width:100%;-webkit-transition:none !important;transition:none !important}.virtual-scroll-list.sc-virtual-scroll-list *.sc-virtual-scroll-list{-webkit-transition:none !important;transition:none !important}.sc-virtual-list.sc-virtual-scroll-list,.ag-body-horizontal-scroll-viewport.sc-virtual-scroll-list,.ag-body-vertical-scroll-viewport.sc-virtual-scroll-list{position:relative;overflow:auto}.sc-virtual-list.sc-virtual-scroll-list::-webkit-scrollbar-track,.ag-body-horizontal-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar-track,.ag-body-vertical-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar-track{background-color:var(--color-paper-lighter);border-radius:10px}.sc-virtual-list.sc-virtual-scroll-list::-webkit-scrollbar,.ag-body-horizontal-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar,.ag-body-vertical-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar{width:14px;height:14px;background-color:var(--color-paper-lighter)}.sc-virtual-list.sc-virtual-scroll-list::-webkit-scrollbar-thumb,.ag-body-horizontal-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar-thumb,.ag-body-vertical-scroll-viewport.sc-virtual-scroll-list::-webkit-scrollbar-thumb{background-color:var(--color-paper-base);border-radius:10px;border:3px var(--color-paper-lighter) solid}.sc-virtual-list--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-track,.ag-body-horizontal-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-track,.ag-body-vertical-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-track{border-radius:10px}.sc-virtual-list--wo-color.sc-virtual-scroll-list::-webkit-scrollbar,.ag-body-horizontal-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar,.ag-body-vertical-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar{width:14px;height:14px}.sc-virtual-list--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-thumb,.ag-body-horizontal-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-thumb,.ag-body-vertical-scroll-viewport--wo-color.sc-virtual-scroll-list::-webkit-scrollbar-thumb{border-radius:10px}.sc-virtual-scroll-list-h{overflow:scroll}.sc-virtual-scroll-list-h .scroller.sc-virtual-scroll-list{display:inline-block}.sc-virtual-scroll-list-h .item-container.sc-virtual-scroll-list{position:relative;display:inline-block}.sc-virtual-scroll-list-h .item-container.sc-virtual-scroll-list .item.sc-virtual-scroll-list{position:absolute}.aq-virtual-list__header.sc-virtual-scroll-list{border-bottom:1px solid var(--color-paper-light);padding-bottom:var(--spacing-size-short);position:relative;z-index:5}.aq-virtual-list__content.sc-virtual-scroll-list{max-height:360px;overflow-y:auto}.aq-virtual-list__footer.sc-virtual-scroll-list{padding-top:var(--spacing-size-short);border-top:1px solid var(--color-paper-light);position:relative;z-index:5}.virtual-item.sc-virtual-scroll-list{position:absolute;width:-webkit-fill-available;display:inline-block;visibility:visible;-webkit-transition:none !important;transition:none !important}.virtual-item.sc-virtual-scroll-list *.sc-virtual-scroll-list{-webkit-transition:none !important;transition:none !important}";
const VirtualScrollList = /*@__PURE__*/ proxyCustomElement(class VirtualScrollList extends HTMLElement {
constructor(registerHost) {
super();
if (registerHost !== false) {
this.__registerHost();
}
this.items = [];
this.estimatedItemHeight = 30;
this.maxRenderCount = 20;
this.width = PopoverWidths.DEFAULT;
this.showAllItems = false;
this.flagSelector = false;
this.scrollTop = 0;
this.viewportHeight = 300;
this.currentVisibleItems = [];
this.minimunWidth = 0;
this.widthPopover = 0;
this.cachedMultiItemWidth = 0;
this.keyVirtualScrollList = 0;
this.heightDefault = 32;
this.visibleItmesDefault = 11;
this.widthVirtual = 0;
this.handleScroll = (ev) => {
const target = ev.target;
const maxScroll = target.scrollHeight - target.clientHeight - 5;
if (target.scrollTop > maxScroll) {
target.scrollTop = maxScroll;
}
this.scrollTop = target?.scrollTop;
};
this.countOptions = item => {
let count = 0;
if (item.options) {
count += item.options.length;
item.options.forEach(option => {
count += this.countOptions(option);
});
}
return count;
};
this.calculateHeight = (items) => {
let totalHeight = 0;
for (const item of items) {
totalHeight += item.isDivider ? 0 : this.estimatedItemHeight;
if (item.options && Array.isArray(item.options)) {
totalHeight += this.calculateHeight(item.options);
}
}
return this.showAllItems ? totalHeight : totalHeight + 10;
};
}
connectedCallback() {
this.hostEl.addEventListener('scroll', this.handleScroll);
}
disconnectedCallback() {
this.hostEl.removeEventListener('scroll', this.handleScroll);
}
componentDidLoad() {
this.scrollContainer = this.hostEl.querySelector('.sc-virtual-list');
if (this.scrollContainer) {
this.scrollContainer.addEventListener('scroll', this.handleScroll);
}
}
componentDidRender() {
const newWidth = Number(this.getWidth());
const newScrollTop = this.scrollContainer?.scrollTop || 0;
requestAnimationFrame(() => {
if (this.widthVirtual !== newWidth) {
this.widthVirtual = newWidth;
}
if (this.scrollTop !== newScrollTop) {
this.scrollTop = newScrollTop;
}
});
}
getVisibleItems() {
const { scrollTop, estimatedItemHeight, items } = this;
const startIndex = Math.floor(scrollTop / estimatedItemHeight);
const endIndex = Math.min(items.length, startIndex + this.maxRenderCount);
const visibleItems = items.slice(startIndex, this.showAllItems ? items.length : endIndex);
return visibleItems;
}
getWidth() {
if (this.width && this.width == 'full') {
const popover = this.hostEl.closest('aq-popover');
const autocomplete = popover?.querySelector('aq-autocomplete') || popover?.closest('aq-autocomplete') || this.hostEl.closest('aq-autocomplete');
if (autocomplete) {
const width = autocomplete?.getBoundingClientRect()?.width;
const widthPopover = width ? width : 300;
this.widthPopover = widthPopover;
return widthPopover;
}
}
if (this.width && this.width == 'auto') {
const container = this.hostEl.querySelector('.sc-virtual-list');
const children = Array.from(container?.children || []);
const widthVirtualList = [];
let widthVirtual = 0;
children.forEach(child => {
const aqFlag = child.querySelector('aq-flag');
const aqAutocompleteItem = child.querySelector('aq-autocomplete-item');
if (aqFlag) {
const aqFlagRect = aqFlag.getBoundingClientRect();
widthVirtualList.push(aqFlagRect.width + 20);
}
if (aqAutocompleteItem) {
const aqAutocompleteItemRect = aqAutocompleteItem?.children[0]?.children[0]?.getBoundingClientRect();
const aqAutocompleteItems = child.querySelectorAll('aq-autocomplete-item');
if (aqAutocompleteItems.length > 1) {
if (this.cachedMultiItemWidth === 0) {
let totalWidth = 0;
aqAutocompleteItems.forEach(item => {
totalWidth = Math.max(totalWidth, item.getBoundingClientRect().width);
});
this.cachedMultiItemWidth = totalWidth;
}
widthVirtualList.push(this.cachedMultiItemWidth);
}
else {
widthVirtualList.push(aqAutocompleteItemRect.width + 30);
}
}
widthVirtual = Math.max(...widthVirtualList);
});
return widthVirtual;
}
else {
return this.width;
}
}
getPositions(visibleItems) {
let space = 0;
let totalOptions = 0;
const scrolledStartIndex = Math.floor(this.scrollTop / this.estimatedItemHeight);
return visibleItems.map((item, i) => {
if (visibleItems[i - 1]?.isDivider) {
space++;
}
if (visibleItems[i - 1]) {
totalOptions += this.countOptions(visibleItems[i - 1]);
}
const index = i + scrolledStartIndex;
const top = (index - space + totalOptions) * this.estimatedItemHeight;
return { item, top };
});
}
render() {
const visibleItems = this.getVisibleItems();
const widthVirtual = Number(this.getWidth());
let height = this.viewportHeight;
if (visibleItems.length < this.visibleItmesDefault) {
height = this.calculateHeight(this.items);
}
const widthVirtualList = this.widthPopover == 0 ? (Number(widthVirtual) < 40 ? 40 : widthVirtual) : this.widthPopover;
const withFinaly = this.flagSelector ? Number(widthVirtualList) + 15 : Number(widthVirtualList) + 20;
const positionedItems = this.getPositions(visibleItems);
if (visibleItems.length === 1) {
height = this.heightDefault;
}
return (h(Host, { key: '6e024d31b0b8c721647de191275975c90aac9891' }, h("div", { key: 'bf28c4d4dbf6fff84cda68df10a011f01950807c', style: { width: `${withFinaly}px` } }, h("slot", { key: '673903f5859b835116389910ff5acf1a2267be49', name: "header" }), h("div", { key: 'd5c148105c16a52ed612da532f7db60c50d7eff7', class: "sc-virtual-list", style: { height: `${height}px` } }, positionedItems.map(({ item, top }, i) => {
const isDivider = item.isDivider;
return (h("div", { key: item.id || i, class: "virtual-item", style: {
top: `${top}px`,
height: isDivider ? '0px' : `${this.estimatedItemHeight}px`,
} }, this.renderItem(item)));
}), h("div", { key: 'b2720c4e88d065d854f752fae3998712a98f3c32', style: { height: '20px' } })))));
}
get hostEl() { return this; }
static get style() { return virtualScrollListCss; }
}, [262, "virtual-scroll-list", {
"items": [16],
"renderItem": [16, "render-item"],
"estimatedItemHeight": [2, "estimated-item-height"],
"maxRenderCount": [2, "max-render-count"],
"width": [8],
"showAllItems": [4, "show-all-items"],
"flagSelector": [4, "flag-selector"],
"scrollTop": [32],
"viewportHeight": [32],
"currentVisibleItems": [32],
"minimunWidth": [32],
"widthPopover": [32],
"cachedMultiItemWidth": [32],
"keyVirtualScrollList": [32],
"heightDefault": [32],
"visibleItmesDefault": [32],
"widthVirtual": [32]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["virtual-scroll-list"];
components.forEach(tagName => { switch (tagName) {
case "virtual-scroll-list":
if (!customElements.get(tagName)) {
customElements.define(tagName, VirtualScrollList);
}
break;
} });
}
export { VirtualScrollList as V, defineCustomElement as d };