Skip to content

Commit 5831f68

Browse files
web-padawanclaude
andauthored
refactor: simplify multi-select-combo-box updating chips logic (#11295)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a35b92d commit 5831f68

File tree

1 file changed

+70
-53
lines changed

1 file changed

+70
-53
lines changed

packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-mixin.js

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,11 @@ export const MultiSelectComboBoxMixin = (superClass) =>
872872
return chip;
873873
}
874874

875+
/** @private */
876+
__getWrapperWidth() {
877+
return this._inputField.$.wrapper.clientWidth;
878+
}
879+
875880
/** @private */
876881
__getOverflowWidth() {
877882
const chip = this._overflow;
@@ -905,82 +910,94 @@ export const MultiSelectComboBoxMixin = (superClass) =>
905910
chip.remove();
906911
});
907912

908-
const items = [...this.selectedItems];
913+
if (this.selectedItems.length === 0) {
914+
this._overflowItems = [];
915+
return;
916+
}
917+
918+
// When auto expanding vertically, create all chips without overflow
919+
if (this.autoExpandVertically) {
920+
this.selectedItems.forEach((item) => {
921+
this.appendChild(this.__createChip(item));
922+
});
923+
this._overflowItems = [];
924+
return;
925+
}
909926

910-
// Detect available remaining width for chips
911-
const totalWidth = this._inputField.$.wrapper.clientWidth;
912927
const inputWidth = parseInt(getComputedStyle(this.inputElement).flexBasis);
913928

914-
let remainingWidth = totalWidth - inputWidth;
929+
if (this.autoExpandHorizontally) {
930+
this._overflowItems = this.__updateChipsHorizontalExpand(this.selectedItems, inputWidth);
931+
} else {
932+
this._overflowItems = this.__updateChipsDefault(this.selectedItems, inputWidth);
933+
}
934+
}
915935

916-
if (items.length > 1) {
917-
remainingWidth -= this.__getOverflowWidth();
936+
/** @private */
937+
__updateChipsHorizontalExpand(items, inputWidth) {
938+
// Add all chips to make the field fully expand
939+
const chips = items.map((item) => {
940+
const chip = this.__createChip(item);
941+
this.appendChild(chip);
942+
return chip;
943+
});
944+
945+
if (this.__getWrapperWidth() - this.$.chips.clientWidth >= inputWidth) {
946+
return [];
918947
}
919948

920-
const chipMinWidth = parseInt(getComputedStyle(this).getPropertyValue('--_chip-min-width'));
949+
// Remove chips from the end until there is enough width for the input element to fit,
950+
// keeping at least one chip visible
951+
const overflowWidth = this.__getOverflowWidth();
952+
let visibleCount = chips.length;
921953

922-
if (this.autoExpandHorizontally) {
923-
const chips = [];
924-
925-
// First, add all chips to make the field fully expand
926-
for (let i = items.length - 1, refNode = null; i >= 0; i--) {
927-
const chip = this.__createChip(items[i]);
928-
this.insertBefore(chip, refNode);
929-
refNode = chip;
930-
chips.unshift(chip);
954+
while (visibleCount > 1) {
955+
visibleCount -= 1;
956+
chips[visibleCount].remove();
957+
958+
if (this.__getWrapperWidth() - this.$.chips.clientWidth >= inputWidth + overflowWidth) {
959+
break;
931960
}
961+
}
932962

933-
const overflowItems = [];
934-
const availableWidth = this._inputField.$.wrapper.clientWidth - this.$.chips.clientWidth;
935-
936-
// When auto expanding vertically, no need to measure width
937-
if (!this.autoExpandVertically && availableWidth < inputWidth) {
938-
// Always show at least last item as a chip
939-
while (chips.length > 1) {
940-
const lastChip = chips.pop();
941-
lastChip.remove();
942-
overflowItems.unshift(items.pop());
943-
944-
// Remove chips until there is enough width for the input element to fit
945-
const neededWidth = overflowItems.length > 0 ? inputWidth + this.__getOverflowWidth() : inputWidth;
946-
if (this._inputField.$.wrapper.clientWidth - this.$.chips.clientWidth >= neededWidth) {
947-
break;
948-
}
949-
}
963+
if (visibleCount === 1) {
964+
const chipMinWidth = parseInt(getComputedStyle(this).getPropertyValue('--_chip-min-width'));
965+
const remainingWidth = this.__getWrapperWidth() - inputWidth - overflowWidth;
966+
chips[0].style.maxWidth = `${Math.max(chipMinWidth, remainingWidth)}px`;
967+
}
950968

951-
if (chips.length === 1) {
952-
chips[0].style.maxWidth = `${Math.max(chipMinWidth, remainingWidth)}px`;
953-
}
954-
}
969+
return items.slice(visibleCount);
970+
}
955971

956-
this._overflowItems = overflowItems;
957-
return;
972+
/** @private */
973+
__updateChipsDefault(items, inputWidth) {
974+
let remainingWidth = this.__getWrapperWidth() - inputWidth;
975+
976+
if (items.length > 1) {
977+
remainingWidth -= this.__getOverflowWidth();
958978
}
959979

960-
// Add chips until remaining width is exceeded
980+
const chipMinWidth = parseInt(getComputedStyle(this).getPropertyValue('--_chip-min-width'));
981+
982+
// Add chips from the end until remaining width is exceeded
961983
for (let i = items.length - 1, refNode = null; i >= 0; i--) {
962984
const chip = this.__createChip(items[i]);
963985
this.insertBefore(chip, refNode);
964986

965-
// When auto expanding vertically, no need to measure remaining width
966-
if (!this.autoExpandVertically) {
967-
if (this.$.chips.clientWidth > remainingWidth) {
968-
// If there is no more space for chips, or if there is at least one
969-
// chip already shown, collapse all remaining chips to the overflow
970-
if (remainingWidth < chipMinWidth || refNode !== null) {
971-
chip.remove();
972-
break;
973-
}
987+
if (this.$.chips.clientWidth > remainingWidth) {
988+
// If there is no more space for chips, or if there is at least one
989+
// chip already shown, collapse all remaining chips to the overflow
990+
if (remainingWidth < chipMinWidth || refNode !== null) {
991+
chip.remove();
992+
return items.slice(0, i + 1);
974993
}
975-
976-
chip.style.maxWidth = `${remainingWidth}px`;
977994
}
978995

979-
items.pop();
996+
chip.style.maxWidth = `${remainingWidth}px`;
980997
refNode = chip;
981998
}
982999

983-
this._overflowItems = items;
1000+
return [];
9841001
}
9851002

9861003
/** @private */

0 commit comments

Comments
 (0)