@vaadin/multi-select-combo-box 25.4.0-alpha1 → 25.4.0-alpha3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/multi-select-combo-box",
3
- "version": "25.4.0-alpha1",
3
+ "version": "25.4.0-alpha3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,23 +37,23 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/a11y-base": "25.4.0-alpha1",
41
- "@vaadin/combo-box": "25.4.0-alpha1",
42
- "@vaadin/component-base": "25.4.0-alpha1",
43
- "@vaadin/field-base": "25.4.0-alpha1",
44
- "@vaadin/input-container": "25.4.0-alpha1",
45
- "@vaadin/item": "25.4.0-alpha1",
46
- "@vaadin/lit-renderer": "25.4.0-alpha1",
47
- "@vaadin/overlay": "25.4.0-alpha1",
48
- "@vaadin/vaadin-themable-mixin": "25.4.0-alpha1",
40
+ "@vaadin/a11y-base": "25.4.0-alpha3",
41
+ "@vaadin/combo-box": "25.4.0-alpha3",
42
+ "@vaadin/component-base": "25.4.0-alpha3",
43
+ "@vaadin/field-base": "25.4.0-alpha3",
44
+ "@vaadin/input-container": "25.4.0-alpha3",
45
+ "@vaadin/item": "25.4.0-alpha3",
46
+ "@vaadin/lit-renderer": "25.4.0-alpha3",
47
+ "@vaadin/overlay": "25.4.0-alpha3",
48
+ "@vaadin/vaadin-themable-mixin": "25.4.0-alpha3",
49
49
  "lit": "^3.0.0"
50
50
  },
51
51
  "devDependencies": {
52
- "@vaadin/aura": "25.4.0-alpha1",
53
- "@vaadin/chai-plugins": "25.4.0-alpha1",
54
- "@vaadin/test-runner-commands": "25.4.0-alpha1",
52
+ "@vaadin/aura": "25.4.0-alpha3",
53
+ "@vaadin/chai-plugins": "25.4.0-alpha3",
54
+ "@vaadin/test-runner-commands": "25.4.0-alpha3",
55
55
  "@vaadin/testing-helpers": "^2.0.0",
56
- "@vaadin/vaadin-lumo-styles": "25.4.0-alpha1",
56
+ "@vaadin/vaadin-lumo-styles": "25.4.0-alpha3",
57
57
  "sinon": "^22.0.0"
58
58
  },
59
59
  "customElements": "custom-elements.json",
@@ -61,5 +61,5 @@
61
61
  "web-types.json",
62
62
  "web-types.lit.json"
63
63
  ],
64
- "gitHead": "be38ec1866e96508f3f4591f95c949ef55903a34"
64
+ "gitHead": "db7e679c1a8af00840cc05ddcbefff68dfed1e45"
65
65
  }
@@ -12,6 +12,8 @@ export const multiSelectComboBoxStyles = [
12
12
  css`
13
13
  :host {
14
14
  max-width: 100%;
15
+ /* Content stays at the top, keep the default guide height */
16
+ --_field-input-height: var(--_field-input-default-height);
15
17
  --_input-min-width: var(--vaadin-multi-select-combo-box-input-min-width, 4rem);
16
18
  --_chip-min-width: var(--vaadin-multi-select-combo-box-chip-min-width, 48px);
17
19
  --_wrapper-gap: var(--vaadin-multi-select-combo-box-chips-gap, 2px);
@@ -35,13 +37,13 @@ export const multiSelectComboBoxStyles = [
35
37
  flex: 1 0 var(--_input-min-width);
36
38
  }
37
39
 
38
- ::slotted([slot='chip']),
39
- ::slotted([slot='overflow']) {
40
+ ::slotted([slot='chip']) {
40
41
  flex: 0 1 auto;
42
+ overflow: hidden;
41
43
  }
42
44
 
43
- ::slotted([slot='chip']) {
44
- overflow: hidden;
45
+ ::slotted([slot='overflow']) {
46
+ flex: none;
45
47
  }
46
48
 
47
49
  :host(:is([readonly], [disabled])) ::slotted(input) {
@@ -52,6 +52,10 @@ export const multiSelectComboBoxChipStyles = css`
52
52
  translate: 25%;
53
53
  }
54
54
 
55
+ :host(:dir(rtl)) [part='remove-button'] {
56
+ translate: -25%;
57
+ }
58
+
55
59
  [part='remove-button']::before {
56
60
  content: '';
57
61
  display: block;
@@ -62,11 +66,8 @@ export const multiSelectComboBoxChipStyles = css`
62
66
  }
63
67
 
64
68
  :host([disabled]) {
65
- cursor: var(--vaadin-disabled-cursor);
66
- }
67
-
68
- :host([disabled]) [part='label'] {
69
69
  --vaadin-chip-text-color: var(--vaadin-text-color-disabled);
70
+ cursor: var(--vaadin-disabled-cursor);
70
71
  }
71
72
 
72
73
  :host([hidden]),
@@ -90,11 +91,11 @@ export const multiSelectComboBoxChipStyles = css`
90
91
  }
91
92
 
92
93
  :host([slot='overflow'])::before {
93
- left: calc(-4px - var(--vaadin-chip-border-width, 1px));
94
+ inset-inline-start: calc(-4px - var(--vaadin-chip-border-width, 1px));
94
95
  }
95
96
 
96
97
  :host([slot='overflow'])::after {
97
- left: calc(-8px - var(--vaadin-chip-border-width, 1px));
98
+ inset-inline-start: calc(-8px - var(--vaadin-chip-border-width, 1px));
98
99
  }
99
100
 
100
101
  :host([count='2']) {
@@ -860,27 +860,49 @@ export const MultiSelectComboBoxMixin = (superClass) =>
860
860
  return chip;
861
861
  }
862
862
 
863
+ /**
864
+ * Returns the width of the element with its fraction, unlike `clientWidth`.
865
+ * The chips do not shrink below their `max-width`, so a rounding error moves the input out.
866
+ * @private
867
+ */
868
+ __getUsedWidth(element) {
869
+ return parseFloat(getComputedStyle(element).width);
870
+ }
871
+
863
872
  /** @private */
864
- __getWrapperWidth() {
865
- return this._inputField.$.wrapper.clientWidth;
873
+ __getWrapperGap() {
874
+ // The gap computes to `normal` when not set, which is 0 in a flex container
875
+ return parseFloat(getComputedStyle(this._inputField.$.wrapper).columnGap) || 0;
866
876
  }
867
877
 
868
878
  /** @private */
869
- __getOverflowWidth() {
879
+ __getWrapperWidth() {
880
+ // Exclude the gap between the chips and the input
881
+ return this.__getUsedWidth(this._inputField.$.wrapper) - this.__getWrapperGap();
882
+ }
883
+
884
+ /**
885
+ * Returns the width that the overflow chip with the given count takes,
886
+ * including its margins and the gap between it and the chips.
887
+ * @private
888
+ */
889
+ __getOverflowWidth(count) {
870
890
  const chip = this._overflow;
871
891
 
892
+ // The `_overflowItems` observer sets the final label and count afterwards
872
893
  chip.style.visibility = 'hidden';
873
894
  chip.removeAttribute('hidden');
895
+ chip.label = `${count}`;
896
+ chip.setAttribute('count', `${count}`);
874
897
 
875
- const count = chip.getAttribute('count');
898
+ // The chip uses `box-sizing: border-box`, so its width includes padding and border
899
+ const { marginInlineStart, marginInlineEnd } = getComputedStyle(chip);
900
+ const overflowWidth =
901
+ this.__getUsedWidth(chip) +
902
+ parseFloat(marginInlineStart) +
903
+ parseFloat(marginInlineEnd) +
904
+ this.__getWrapperGap();
876
905
 
877
- // Detect max possible width of the overflow chip
878
- // by measuring it with widest number (2 digits)
879
- chip.setAttribute('count', '99');
880
- const overflowStyle = getComputedStyle(chip);
881
- const overflowWidth = chip.clientWidth + parseInt(overflowStyle.marginInlineStart);
882
-
883
- chip.setAttribute('count', count);
884
906
  chip.setAttribute('hidden', '');
885
907
  chip.style.visibility = '';
886
908
 
@@ -912,7 +934,7 @@ export const MultiSelectComboBoxMixin = (superClass) =>
912
934
  return;
913
935
  }
914
936
 
915
- const inputWidth = parseInt(getComputedStyle(this.inputElement).flexBasis);
937
+ const inputWidth = parseFloat(getComputedStyle(this.inputElement).flexBasis);
916
938
 
917
939
  if (this.collapseChips) {
918
940
  this._overflowItems = this.__updateChipsCollapsed(this.selectedItems, inputWidth);
@@ -931,7 +953,7 @@ export const MultiSelectComboBoxMixin = (superClass) =>
931
953
  return chip;
932
954
  });
933
955
 
934
- const allChipsFit = this.__getWrapperWidth() - this.$.chips.clientWidth >= inputWidth;
956
+ const allChipsFit = this.__getWrapperWidth() - this.__getUsedWidth(this.$.chips) >= inputWidth;
935
957
  return { chips, allChipsFit };
936
958
  }
937
959
 
@@ -958,21 +980,28 @@ export const MultiSelectComboBoxMixin = (superClass) =>
958
980
 
959
981
  // Remove chips from the end until there is enough width for the input element to fit,
960
982
  // keeping at least one chip visible
961
- const overflowWidth = this.__getOverflowWidth();
983
+ const wrapperWidth = this.__getWrapperWidth();
984
+ // Start from the width for the largest count, and measure the exact count only
985
+ // when the chips would fit with the estimate, as the label width varies per count
986
+ let overflowWidth = this.__getOverflowWidth(items.length - 1);
962
987
  let visibleCount = chips.length;
963
988
 
964
989
  while (visibleCount > 1) {
965
990
  visibleCount -= 1;
966
991
  chips[visibleCount].remove();
967
992
 
968
- if (this.__getWrapperWidth() - this.$.chips.clientWidth >= inputWidth + overflowWidth) {
969
- break;
993
+ const chipsWidth = this.__getUsedWidth(this.$.chips);
994
+ if (wrapperWidth - chipsWidth >= inputWidth + overflowWidth) {
995
+ overflowWidth = this.__getOverflowWidth(items.length - visibleCount);
996
+ if (wrapperWidth - chipsWidth >= inputWidth + overflowWidth) {
997
+ break;
998
+ }
970
999
  }
971
1000
  }
972
1001
 
973
1002
  if (visibleCount === 1) {
974
1003
  const chipMinWidth = parseInt(getComputedStyle(this).getPropertyValue('--_chip-min-width'));
975
- const remainingWidth = this.__getWrapperWidth() - inputWidth - overflowWidth;
1004
+ const remainingWidth = wrapperWidth - inputWidth - overflowWidth;
976
1005
  chips[0].style.maxWidth = `${Math.max(chipMinWidth, remainingWidth)}px`;
977
1006
  }
978
1007
 
@@ -981,11 +1010,7 @@ export const MultiSelectComboBoxMixin = (superClass) =>
981
1010
 
982
1011
  /** @private */
983
1012
  __updateChipsDefault(items, inputWidth) {
984
- let remainingWidth = this.__getWrapperWidth() - inputWidth;
985
-
986
- if (items.length > 1) {
987
- remainingWidth -= this.__getOverflowWidth();
988
- }
1013
+ const availableWidth = this.__getWrapperWidth() - inputWidth;
989
1014
 
990
1015
  const chipMinWidth = parseInt(getComputedStyle(this).getPropertyValue('--_chip-min-width'));
991
1016
 
@@ -994,7 +1019,12 @@ export const MultiSelectComboBoxMixin = (superClass) =>
994
1019
  const chip = this.__createChip(items[i]);
995
1020
  this.insertBefore(chip, refNode);
996
1021
 
997
- if (this.$.chips.clientWidth > remainingWidth) {
1022
+ // Reserve space for the overflow chip with the count of the items that are not
1023
+ // added yet, measured with a chip rendered so that the spacing between them counts
1024
+ const remainingWidth =
1025
+ items.length > 1 ? availableWidth - this.__getOverflowWidth(Math.max(i, 1)) : availableWidth;
1026
+
1027
+ if (this.__getUsedWidth(this.$.chips) > remainingWidth) {
998
1028
  // If there is no more space for chips, or if there is at least one
999
1029
  // chip already shown, collapse all remaining chips to the overflow
1000
1030
  if (remainingWidth < chipMinWidth || refNode !== null) {
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/multi-select-combo-box",
4
- "version": "25.4.0-alpha1",
4
+ "version": "25.4.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/multi-select-combo-box",
4
- "version": "25.4.0-alpha1",
4
+ "version": "25.4.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {