Skip to content

Commit c67fe0a

Browse files
authored
fix(ui5-multi-combobox): overflow tokens correctly when not enough space (#714)
FIXES: #712
1 parent b610aeb commit c67fe0a

11 files changed

+61
-56
lines changed

packages/main/src/Tokenizer.hbs

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
<div style="display: inline-block"></div>
55
</div>
66
{{#each tokens}}
7-
<div class="ui5-tokenizer--token--wrapper">
8-
<slot name="{{this._individualSlot}}"></slot>
9-
</div>
7+
<slot name="{{this._individualSlot}}"></slot>
108
{{/each}}
119
</div>
1210

packages/main/src/Tokenizer.js

+40-48
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ const metadata = {
2424
properties: /** @lends sap.ui.webcomponents.main.Tokenizer.prototype */ {
2525
showMore: { type: Boolean },
2626
disabled: { type: Boolean },
27-
28-
_nMoreText: { type: String, noAttribute: true },
29-
_hiddenTokens: { type: Object, multiple: true },
27+
_nMoreText: { type: String },
3028
},
3129
events: /** @lends sap.ui.webcomponents.main.Tokenizer.prototype */ {
3230
tokenDelete: {
@@ -75,13 +73,18 @@ class Tokenizer extends UI5Element {
7573
return styles;
7674
}
7775

76+
_handleResize() {
77+
/*
78+
* Overflow happens with a pure CSS, but we
79+
* have to update the "n more" label when tokenizer is resized
80+
*/
81+
this._invalidate();
82+
}
83+
7884
constructor() {
7985
super();
8086

81-
this._itemsCount = 0;
82-
this._lastIndex = 0;
83-
this._lastTokenCount = 0;
84-
this._recalculateLayouting = false;
87+
this._tokensCount = 0;
8588
this._resizeHandler = this._handleResize.bind(this);
8689
this._itemNav = new ItemNavigation(this);
8790

@@ -101,20 +104,12 @@ class Tokenizer extends UI5Element {
101104
onBeforeRendering() {
102105
this._itemNav.init();
103106

104-
if (this._lastTokenCount !== this.tokens.length) {
105-
this._recalculateLayouting = true;
106-
}
107-
108-
this._lastTokenCount = this.tokens.length;
109-
this._nMoreText = this.resourceBundle.getText(MULTIINPUT_SHOW_MORE_TOKENS, [this._hiddenTokens.length]);
107+
setTimeout(() => {
108+
// wait for the layouting and update the text
109+
this._nMoreText = this.resourceBundle.getText(MULTIINPUT_SHOW_MORE_TOKENS, [this.overflownTokensCount]);
110+
}, 0);
110111
}
111112

112-
onAfterRendering() {
113-
if (this._recalculateLayouting) {
114-
this._handleResize();
115-
this._recalculateLayouting = false;
116-
}
117-
}
118113

119114
onEnterDOM() {
120115
ResizeHandler.register(this.shadowRoot.querySelector(".ui5-tokenizer--content"), this._resizeHandler);
@@ -128,37 +123,19 @@ class Tokenizer extends UI5Element {
128123
this.fireEvent("showMoreItemsPress");
129124
}
130125

131-
_handleResize() {
132-
const overflowTokens = this._getTokens(true);
133-
134-
if (!overflowTokens.length) {
135-
this._hiddenTokens = [];
136-
}
137-
138-
this._hiddenTokens = overflowTokens;
126+
_getTokens() {
127+
return this.tokens;
139128
}
140129

141-
_getTokens(overflow) {
142-
const firstToken = this.shadowRoot.querySelector(".ui5-tokenizer-token-placeholder");
143-
144-
if (!firstToken) {
145-
return [];
146-
}
147-
148-
const firstTokenTop = firstToken.getBoundingClientRect().top;
149-
const tokens = [];
150-
151-
if (firstToken && this.tokens.length) {
152-
this.tokens.forEach(token => {
153-
const tokenTop = token.getBoundingClientRect().top;
154-
const tokenOverflows = overflow && tokenTop > firstTokenTop;
155-
const tokenVisible = !overflow && tokenTop <= firstTokenTop;
156-
157-
(tokenVisible || tokenOverflows) && tokens.push(token);
158-
});
130+
onAfterRendering() {
131+
/*
132+
We schedule an invalidation as we have the tokens count
133+
changed and we need them rendered for the nmore count
134+
*/
135+
if (this._tokensCount !== this.tokens.length) {
136+
this._invalidate();
137+
this._tokensCount = this.tokens.length;
159138
}
160-
161-
return tokens;
162139
}
163140

164141
_tokenDelete(event) {
@@ -193,7 +170,22 @@ class Tokenizer extends UI5Element {
193170
}
194171

195172
get showNMore() {
196-
return this.showMore && this._hiddenTokens.length;
173+
return this.showMore && this.overflownTokensCount;
174+
}
175+
176+
get overflownTokensCount() {
177+
const placeholderToken = this.shadowRoot.querySelector(".ui5-tokenizer-token-placeholder");
178+
179+
if (!placeholderToken) {
180+
return;
181+
}
182+
183+
const placeholderTokenRect = placeholderToken.getBoundingClientRect();
184+
const tokens = this.tokens.filter(token => {
185+
return placeholderTokenRect.top < token.getBoundingClientRect().top;
186+
});
187+
188+
return tokens.length;
197189
}
198190

199191
get classes() {

packages/main/src/themes/MultiComboBox.css

+6-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
height: 100%;
1313
}
1414

15+
.ui5-multi-combobox-token {
16+
margin-top: var(--_ui5-multi_combobox_token_margin_top);
17+
}
18+
1519
.ui5-multi-combobox-icon {
1620
color: var(--sapUiContentIconColor);
1721
cursor: pointer;
@@ -32,12 +36,9 @@
3236
background: var(--sapUiButtonLiteHoverBackground);
3337
}
3438

35-
.ui5-multi-combobox-token {
36-
height: 80%;
37-
}
38-
3939
:host([data-ui5-compact-size]) .ui5-multi-combobox-token {
4040
height: 100%;
41+
margin-top: 0;
4142
}
4243

4344
.ui5-multi-combobox-tokenizer {
@@ -57,4 +58,5 @@ ui5-multi-combobox:not([hidden]) {
5758

5859
ui5-multi-combobox[data-ui5-compact-size] .ui5-multi-combobox-token {
5960
height: 100%;
61+
margin-top: 0;
6062
}

packages/main/src/themes/Tokenizer.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
.ui5-tokenizer-token-placeholder {
5454
display: inline-block;
55-
height: 1px;
55+
height: 100%;
5656
width: 1px;
5757
margin-top: auto;
5858
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:root {
2+
--_ui5-multi_combobox_token_margin_top: 3px;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "../base/MultiComboBox-parameters.css";

packages/main/src/themes/sap_belize/parameters-bundle.css

+1
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@
2828
@import "./ToggleButton-parameters.css";
2929
@import "./YearPicker-parameters.css";
3030
@import "./Token-parameters.css";
31+
@import "./MultiComboBox-parameters.css";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "../base/MultiComboBox-parameters.css";

packages/main/src/themes/sap_belize_hcb/parameters-bundle.css

+1
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
@import "./ToggleButton-parameters.css";
2828
@import "./YearPicker-parameters.css";
2929
@import "./Token-parameters.css";
30+
@import "./MultiComboBox-parameters.css";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import "../base/MultiComboBox-parameters.css";
2+
3+
:root {
4+
--_ui5-multi_combobox_token_margin_top: 1px;
5+
}

packages/main/src/themes/sap_fiori_3/parameters-bundle.css

+1
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
@import "./CalendarHeader-parameters.css";
2828
@import "./Table-parameters.css";
2929
@import "./Token-parameters.css";
30+
@import "./MultiComboBox-parameters.css";

0 commit comments

Comments
 (0)