Skip to content

Commit 5d7e7df

Browse files
authored
feat(ui5-multi-input): initial implementation (#1942)
1 parent f69ffa5 commit 5d7e7df

24 files changed

+1163
-104
lines changed

packages/main/bundle.esm.js

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import Dialog from "./dist/Dialog.js";
4747
import FileUploader from "./dist/FileUploader.js";
4848
import Icon from "./dist/Icon.js";
4949
import Input from "./dist/Input.js";
50+
import MultiInput from "./dist/MultiInput.js";
5051
import Label from "./dist/Label.js";
5152
import Link from "./dist/Link.js";
5253
import Popover from "./dist/Popover.js";

packages/main/src/DatePicker.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,8 @@ class DatePicker extends UI5Element {
475475
return this.shadowRoot.querySelector("ui5-input");
476476
}
477477

478-
_handleInputChange() {
479-
let nextValue = this._getInput().getInputValue();
478+
async _handleInputChange() {
479+
let nextValue = await this._getInput().getInputValue();
480480
const emptyValue = nextValue === "";
481481
const isValid = emptyValue || this._checkValueValidity(nextValue);
482482

@@ -494,8 +494,8 @@ class DatePicker extends UI5Element {
494494
this.fireEvent("value-changed", { value: nextValue, valid: isValid });
495495
}
496496

497-
_handleInputLiveChange() {
498-
const nextValue = this._getInput().getInputValue();
497+
async _handleInputLiveChange() {
498+
const nextValue = await this._getInput().getInputValue();
499499
const emptyValue = nextValue === "";
500500
const isValid = emptyValue || this._checkValueValidity(nextValue);
501501

packages/main/src/DateRangePicker.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,10 @@ class DateRangePicker extends DatePicker {
249249
return this.placeholder !== undefined ? this.placeholder : this._displayFormat.concat(" ", this.delimiter, " ", this._displayFormat);
250250
}
251251

252-
_handleInputChange() {
253-
const nextValue = this._getInput().getInputValue(),
254-
emptyValue = nextValue === "",
255-
isValid = emptyValue || this._checkValueValidity(nextValue);
252+
async _handleInputChange() {
253+
const nextValue = await this._getInput().getInputValue();
254+
const emptyValue = nextValue === "";
255+
const isValid = emptyValue || this._checkValueValidity(nextValue);
256256

257257
if (isValid) {
258258
this._setValue(nextValue);

packages/main/src/Input.hbs

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
@keydown="{{_onkeydown}}"
3030
@keyup="{{_onkeyup}}"
3131
@click={{_click}}
32+
@focusin={{innerFocusIn}}
3233
data-sap-no-tab-ref
3334
data-sap-focus-ref
3435
step="{{step}}"
@@ -39,6 +40,8 @@
3940
</div>
4041
{{/if}}
4142

43+
{{> postContent }}
44+
4245
{{#if showSuggestions}}
4346
<span id="{{_id}}-suggestionsText" class="ui5-hidden-text">{{suggestionsText}}</span>
4447
<span id="{{_id}}-selectionText" class="ui5-hidden-text" aria-live="polite" role="status"></span>
@@ -58,4 +61,5 @@
5861
</div>
5962

6063

61-
{{#*inline "preContent"}}{{/inline}}
64+
{{#*inline "preContent"}}{{/inline}}
65+
{{#*inline "postContent"}}{{/inline}}

packages/main/src/Input.js

+28-34
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ class Input extends UI5Element {
547547
}
548548
}
549549

550-
onAfterRendering() {
550+
async onAfterRendering() {
551551
if (!this.firstRendering && !isPhone() && this.Suggestions) {
552552
const shouldOpenSuggestions = this.shouldOpenSuggestions();
553553

@@ -562,7 +562,8 @@ class Input extends UI5Element {
562562

563563
if (!isPhone() && shouldOpenSuggestions) {
564564
// Set initial focus to the native input
565-
this.inputDomRef && this.inputDomRef.focus();
565+
566+
(await this.getInputDOMRef()).focus();
566567
}
567568
}
568569

@@ -648,9 +649,7 @@ class Input extends UI5Element {
648649
return;
649650
}
650651

651-
if (this.popover) {
652-
this.popover.close();
653-
}
652+
this.closePopover();
654653

655654
this.previousValue = "";
656655
this.focused = false; // invalidating property
@@ -677,8 +676,9 @@ class Input extends UI5Element {
677676
}
678677

679678
async _handleInput(event) {
680-
await this.getInputDOMRef();
681-
if (event.target === this.inputDomRef) {
679+
const inputDomRef = await this.getInputDOMRef();
680+
681+
if (event.target === inputDomRef) {
682682
// stop the native event, as the semantic "input" would be fired.
683683
event.stopImmediatePropagation();
684684
}
@@ -687,7 +687,7 @@ class Input extends UI5Element {
687687
- value of the host and the internal input should be differnt in case of actual input
688688
- input is called when a key is pressed => keyup should not be called yet
689689
*/
690-
const skipFiring = (this.inputDomRef.value === this.value) && isIE() && !this._keyDown && !!this.placeholder;
690+
const skipFiring = (inputDomRef.value === this.value) && isIE() && !this._keyDown && !!this.placeholder;
691691

692692
!skipFiring && this.fireEventByAction(this.ACTION_USER_INPUT);
693693

@@ -709,8 +709,7 @@ class Input extends UI5Element {
709709
async _afterOpenPopover() {
710710
// Set initial focus to the native input
711711
if (isPhone()) {
712-
await this.getInputDOMRef();
713-
this.inputDomRef.focus();
712+
(await this.getInputDOMRef()).focus();
714713
}
715714
}
716715

@@ -741,18 +740,18 @@ class Input extends UI5Element {
741740
}
742741

743742
async openPopover() {
744-
this.popover = await this._getPopover();
745-
if (this.popover) {
743+
const popover = await this._getPopover();
744+
745+
if (popover) {
746746
this._isPopoverOpen = true;
747-
this.popover.openBy(this);
747+
popover.openBy(this);
748748
}
749749
}
750750

751-
closePopover() {
752-
if (this.isOpen()) {
753-
this._isPopoverOpen = false;
754-
this.popover && this.popover.close();
755-
}
751+
async closePopover() {
752+
const popover = await this._getPopover();
753+
754+
popover && popover.close();
756755
}
757756

758757
async _getPopover() {
@@ -791,14 +790,15 @@ class Input extends UI5Element {
791790
? this.valueBeforeItemSelection !== itemText : this.value !== itemText;
792791

793792
this.hasSuggestionItemSelected = true;
794-
this.fireEvent(this.EVENT_SUGGESTION_ITEM_SELECT, { item });
795793

796794
if (fireInput) {
797795
this.value = itemText;
798796
this.valueBeforeItemSelection = itemText;
799797
this.fireEvent(this.EVENT_INPUT);
800798
this.fireEvent(this.EVENT_CHANGE);
801799
}
800+
801+
this.fireEvent(this.EVENT_SUGGESTION_ITEM_SELECT, { item });
802802
}
803803

804804
previewSuggestion(item) {
@@ -839,7 +839,7 @@ class Input extends UI5Element {
839839
return;
840840
}
841841

842-
const inputValue = this.getInputValue();
842+
const inputValue = await this.getInputValue();
843843
const isSubmit = action === this.ACTION_ENTER;
844844
const isUserInput = action === this.ACTION_USER_INPUT;
845845

@@ -875,28 +875,22 @@ class Input extends UI5Element {
875875
}
876876
}
877877

878-
getInputValue() {
879-
const inputDOM = this.getDomRef();
880-
if (inputDOM) {
881-
return this.inputDomRef.value;
878+
async getInputValue() {
879+
const domRef = this.getDomRef();
880+
881+
if (domRef) {
882+
return (await this.getInputDOMRef()).value;
882883
}
883884
return "";
884885
}
885886

886887
async getInputDOMRef() {
887-
let inputDomRef;
888-
889-
if (isPhone() && this.Suggestions) {
888+
if (isPhone() && this.Suggestions && this.suggestionItems.length) {
890889
await this.Suggestions._respPopover();
891-
inputDomRef = this.Suggestions && this.Suggestions.responsivePopover.querySelector(".ui5-input-inner-phone");
892-
}
893-
894-
if (!inputDomRef) {
895-
inputDomRef = this.getDomRef().querySelector(`#${this.getInputId()}`);
890+
return this.Suggestions && this.Suggestions.responsivePopover.querySelector(".ui5-input-inner-phone");
896891
}
897892

898-
this.inputDomRef = inputDomRef;
899-
return this.inputDomRef;
893+
return this.getDomRef().querySelector(`input`);
900894
}
901895

902896
getLabelableElementId() {

packages/main/src/MultiComboBox.hbs

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
{{#each items}}
2222
{{#if this.selected}}
2323
<ui5-token
24-
?readonly="{{../readonly}}"
25-
class="ui5-multi-combobox-token"
26-
data-ui5-id="{{this._id}}"
27-
part="token-{{@index}}"
24+
?readonly="{{../readonly}}"
25+
class="ui5-multi-combobox-token"
26+
data-ui5-id="{{this._id}}"
27+
part="token-{{@index}}"
28+
text="{{this.text}}"
2829
>
29-
{{this.text}}
3030
</ui5-token>
3131
{{/if}}
3232
{{/each}}

packages/main/src/MultiComboBox.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ class MultiComboBox extends UI5Element {
410410

411411
tokenizer.tokens.forEach(token => { token.selected = false; });
412412

413-
this._tokenizer.contentDom.scrollLeft = 0;
413+
this._tokenizer.scrollToStart();
414414

415415
if (tokensCount === 0 && this._deleting) {
416416
setTimeout(() => {

packages/main/src/MultiInput.hbs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{{>include "./Input.hbs"}}
2+
3+
{{#*inline "preContent"}}
4+
<ui5-tokenizer
5+
class="ui5-multi-input-tokenizer"
6+
.morePopoverOpener={{this}}
7+
.popoverMinWidth={{_inputWidth}}
8+
?expanded="{{expandedTokenizer}}"
9+
show-more
10+
@show-more-items-press={{showMorePress}}
11+
@token-delete={{tokenDelete}}
12+
@focusout="{{_tokenizerFocusOut}}"
13+
>
14+
<slot name="tokens"></slot>
15+
</ui5-tokenizer>
16+
{{/inline}}
17+
18+
19+
{{#*inline "postContent"}}
20+
{{#if showValueHelpIcon}}
21+
<ui5-icon
22+
@click={{valueHelpPress}}
23+
@mousedown={{valueHelpMouseDown}}
24+
@mouseup={{valueHelpMouseUp}}
25+
input-icon
26+
name="value-help"
27+
></ui5-icon>
28+
{{/if}}
29+
{{/inline}}

0 commit comments

Comments
 (0)