Skip to content

Commit 0545dc4

Browse files
committed
added debounce; added const width
1 parent 7227494 commit 0545dc4

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

src/bundle/Resources/public/ts/components/overflow_list.ts

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Base } from '../partials';
22
import { escapeHTML } from '@ids-core/helpers/escape';
33

4+
const RESIZE_TIMEOUT = 200;
5+
46
export class OverflowList extends Base {
7+
private _itemsNode: HTMLDivElement;
58
private _moreItemNode: HTMLDivElement;
69
private _numberOfItems = 0;
710
private _numberOfVisibleItems = 0;
@@ -10,37 +13,43 @@ export class OverflowList extends Base {
1013
itemMore: '',
1114
};
1215

16+
private _resizeTimeoutId: number | null = null;
1317
private _resizeObserver = new ResizeObserver(() => {
14-
this.resetState();
15-
this.rerender();
18+
if (this._resizeTimeoutId) {
19+
clearTimeout(this._resizeTimeoutId);
20+
}
21+
22+
this._resizeTimeoutId = window.setTimeout(() => {
23+
this.setItemsContainerWidth();
24+
this.resetState();
25+
this.rerender();
26+
}, RESIZE_TIMEOUT);
1627
});
1728

1829
constructor(container: HTMLDivElement) {
1930
super(container);
2031

21-
this._templates = {
22-
item: this.getTemplate('item'),
23-
itemMore: this.getTemplate('item_more'),
24-
};
25-
26-
this.removeTemplate('item');
27-
this.removeTemplate('item_more');
28-
29-
const moreItemNode = container.querySelector<HTMLDivElement>(':scope *:last-child');
32+
const itemsNode = container.querySelector<HTMLDivElement>('.ids-overflow-list__items');
33+
const moreItemNode = itemsNode?.querySelector<HTMLDivElement>(':scope *:last-child');
3034

31-
if (!moreItemNode) {
35+
if (!itemsNode || !moreItemNode) {
3236
throw new Error('OverflowList: OverflowList elements are missing in the container.');
3337
}
3438

39+
this._itemsNode = itemsNode;
3540
this._moreItemNode = moreItemNode;
41+
this._templates = {
42+
item: this.getTemplate('item'),
43+
itemMore: this.getTemplate('item_more'),
44+
};
3645

3746
this._numberOfItems = this.getItems(false, false).length;
3847
this._numberOfVisibleItems = this._numberOfItems;
3948
}
4049

4150
private getItems(getOnlyVisible = false, withOverflow = true): HTMLDivElement[] {
4251
const itemsSelector = `:scope > *${getOnlyVisible ? ':not([hidden])' : ''}`;
43-
const items = Array.from(this._container.querySelectorAll<HTMLDivElement>(itemsSelector));
52+
const items = Array.from(this._itemsNode.querySelectorAll<HTMLDivElement>(itemsSelector));
4453

4554
if (withOverflow) {
4655
return items;
@@ -59,12 +68,6 @@ export class OverflowList extends Base {
5968
return templateNode.innerHTML.trim();
6069
}
6170

62-
private removeTemplate(type: 'item' | 'item_more') {
63-
const templateNode = this._container.querySelector<HTMLTemplateElement>(`.ids-overflow-list__template[data-id="${type}"]`);
64-
65-
templateNode?.remove();
66-
}
67-
6871
private updateMoreItem() {
6972
const hiddenCount = this._numberOfItems - this._numberOfVisibleItems;
7073

@@ -92,7 +95,7 @@ export class OverflowList extends Base {
9295

9396
private recalculateVisibleItems() {
9497
const itemsNodes = this.getItems(true);
95-
const { right: listRightPosition } = this._container.getBoundingClientRect();
98+
const { right: listRightPosition } = this._itemsNode.getBoundingClientRect();
9699
const newNumberOfVisibleItems = itemsNodes.findIndex((itemNode) => {
97100
const { right: itemRightPosition } = itemNode.getBoundingClientRect();
98101

@@ -143,6 +146,7 @@ export class OverflowList extends Base {
143146
const filledItem = Object.entries(item).reduce((acc, [key, value]) => {
144147
const pattern = `{{ ${key} }}`;
145148
const escapedValue = escapeHTML(value);
149+
146150
return acc.replaceAll(pattern, escapedValue);
147151
}, this._templates.item);
148152
const container = document.createElement('div');
@@ -159,11 +163,17 @@ export class OverflowList extends Base {
159163

160164
fragment.append(this._moreItemNode);
161165

162-
this._container.innerHTML = '';
163-
this._container.appendChild(fragment);
166+
this._itemsNode.innerHTML = '';
167+
this._itemsNode.appendChild(fragment);
164168
this._numberOfItems = items.length;
165169
}
166170

171+
private setItemsContainerWidth() {
172+
const overflowListWidth = this._container.clientWidth;
173+
174+
this._itemsNode.style.width = `${overflowListWidth}px`;
175+
}
176+
167177
public setItems(items: Record<string, string>[]) {
168178
this.setItemsContainer(items);
169179
this.resetState();
@@ -175,6 +185,7 @@ export class OverflowList extends Base {
175185

176186
this.initResizeListener();
177187

188+
this.setItemsContainerWidth();
178189
this.rerender();
179190
}
180191
}

src/bundle/Resources/views/themes/standard/design_system/components/overflow_list.html.twig

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{% set overflow_list_classes = html_classes('ids-overflow-list', attributes.render('class') ?? '') %}
22

33
<div class="{{ overflow_list_classes }}">
4-
{% for item in items %}
5-
{{ block('item') }}
6-
{% endfor %}
7-
8-
{{ block('more_item') }}
4+
<div class="ids-overflow-list__items">
5+
{% for item in items %}
6+
{{ block('item') }}
7+
{% endfor %}
98

9+
{{ block('more_item') }}
10+
</div>
1011
<template class="ids-overflow-list__template" data-id="item">
1112
{% with { item: item_template_props } %}
1213
{{ block('item') }}

0 commit comments

Comments
 (0)