From b66f53e7317e800807679bafc93f1b67c7ee7b43 Mon Sep 17 00:00:00 2001 From: Ivaylo Plashkov Date: Mon, 28 Sep 2020 15:26:51 +0300 Subject: [PATCH 1/2] feat(ui5-multicombobox): Implement valueStateMessage --- packages/main/src/MultiComboBox.hbs | 3 +- packages/main/src/MultiComboBox.js | 150 +++++++++++++++++++- packages/main/src/MultiComboBoxPopover.hbs | 105 ++++++++++---- packages/main/test/pages/MultiComboBox.html | 14 ++ 4 files changed, 233 insertions(+), 39 deletions(-) diff --git a/packages/main/src/MultiComboBox.hbs b/packages/main/src/MultiComboBox.hbs index d1f820b0e399..ed875e7ea43d 100644 --- a/packages/main/src/MultiComboBox.hbs +++ b/packages/main/src/MultiComboBox.hbs @@ -63,7 +63,8 @@ input-icon slot="icon" tabindex="-1" - @click={{togglePopover}} + @click="{{togglePopover}}" + @mousedown="{{_onIconMousedown}}" ?pressed="{{open}}" dir="{{effectiveDir}}" accessible-name="{{_iconAccessibleNameText}}" diff --git a/packages/main/src/MultiComboBox.js b/packages/main/src/MultiComboBox.js index c61cc9193053..f820e9e217c9 100644 --- a/packages/main/src/MultiComboBox.js +++ b/packages/main/src/MultiComboBox.js @@ -1,5 +1,6 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import { isShow, @@ -9,6 +10,7 @@ import { isLeft, isRight, } from "@ui5/webcomponents-base/dist/Keys.js"; +import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js"; import { isIE, isPhone } from "@ui5/webcomponents-base/dist/Device.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; @@ -41,6 +43,7 @@ import MultiComboBoxPopoverTemplate from "./generated/templates/MultiComboBoxPop // Styles import styles from "./generated/themes/MultiComboBox.css.js"; import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js"; +import ValueStateMessageCss from "./generated/themes/ValueStateMessage.css.js"; /** * @public @@ -82,6 +85,22 @@ const metadata = { type: HTMLElement, }, + /** + * Defines the value state message that will be displayed as pop up under the ui5-multicombobox. + *

+ * + * Note: If not specified, a default text (in the respective language) will be displayed. + *
+ * Note: The valueStateMessage would be displayed, + * when the ui5-select is in Information, Warning or Error value state. + * @type {HTMLElement[]} + * @since 1.0.0-rc.9 + * @slot + * @public + */ + valueStateMessage: { + type: HTMLElement, + }, }, properties: /** @lends sap.ui.webcomponents.main.MultiComboBox.prototype */ { /** @@ -205,6 +224,22 @@ const metadata = { _rootFocused: { type: Boolean, }, + + _iconPressed: { + type: Boolean, + noAttribute: true, + }, + + _inputWidth: { + type: Integer, + noAttribute: true, + }, + + _listWidth: { + type: Integer, + defaultValue: 0, + noAttribute: true, + }, }, events: /** @lends sap.ui.webcomponents.main.MultiComboBox.prototype */ { /** @@ -319,7 +354,7 @@ class MultiComboBox extends UI5Element { } static get staticAreaStyles() { - return ResponsivePopoverCommonCss; + return [ResponsivePopoverCommonCss, ValueStateMessageCss]; } static get dependencies() { @@ -344,6 +379,19 @@ class MultiComboBox extends UI5Element { this._deleting = false; this._validationTimeout = null; this.i18nBundle = getI18nBundle("@ui5/webcomponents"); + this._handleResizeBound = this._handleResize.bind(this); + } + + onEnterDOM() { + ResizeHandler.register(this, this._handleResizeBound); + } + + onExitDOM() { + ResizeHandler.deregister(this, this._handleResizeBound); + } + + _handleResize() { + this._inputWidth = this.offsetWidth; } _inputChange() { @@ -605,6 +653,7 @@ class MultiComboBox extends UI5Element { this.blur(); } + this._iconPressed = false; this.filterSelected = false; } @@ -622,14 +671,51 @@ class MultiComboBox extends UI5Element { async onAfterRendering() { await this._getRespPopover(); + await this._getList(); + + this.toggle(this.shouldDisplayOnlyValueStateMessage); + this.storeResponsivePopoverWidth(); } - get valueStateTextMappings() { - return { - "Success": this.i18nBundle.getText(VALUE_STATE_SUCCESS), - "Error": this.i18nBundle.getText(VALUE_STATE_ERROR), - "Warning": this.i18nBundle.getText(VALUE_STATE_WARNING), - }; + get _isPhone() { + return isPhone(); + } + + _onIconMousedown() { + this._iconPressed = true; + } + + storeResponsivePopoverWidth() { + if (this.open && !this._listWidth) { + this._listWidth = this.list.offsetWidth; + } + } + + toggle(isToggled) { + if (isToggled && !this.open) { + this.openPopover(); + } else { + this.closePopover(); + } + } + + async openPopover() { + const popover = await this._getPopover(); + + if (popover) { + popover.openBy(this); + } + } + + async closePopover() { + const popover = await this._getPopover(); + + popover && popover.close(); + } + + async _getPopover() { + const staticAreaItem = await this.getStaticAreaItemDomRef(); + return staticAreaItem.querySelector("[ui5-popover]"); } get _tokenizer() { @@ -674,6 +760,10 @@ class MultiComboBox extends UI5Element { return this.valueState !== ValueState.None; } + get hasValueStateMessage() { + return this.hasValueState && this.valueState !== ValueState.Success; + } + get valueStateText() { return this.valueStateTextMappings[this.valueState]; } @@ -682,6 +772,26 @@ class MultiComboBox extends UI5Element { return this.hasValueState ? `${this._id}-valueStateDesc` : undefined; } + get valueStateMessageText() { + return this.getSlottedNodes("valueStateMessage").map(el => el.cloneNode(true)); + } + + get shouldDisplayDefaultValueStateMessage() { + return !this.valueStateMessage.length && this.hasValueStateMessage; + } + + get shouldDisplayOnlyValueStateMessage() { + return this._rootFocused && this.hasValueStateMessage && !this._iconPressed; + } + + get valueStateTextMappings() { + return { + "Success": this.i18nBundle.getText(VALUE_STATE_SUCCESS), + "Error": this.i18nBundle.getText(VALUE_STATE_ERROR), + "Warning": this.i18nBundle.getText(VALUE_STATE_WARNING), + }; + } + get _innerInput() { if (isPhone()) { if (this.allItemsPopover.opened) { @@ -704,6 +814,32 @@ class MultiComboBox extends UI5Element { return this._rootFocused || this.open; } + get classes() { + return { + popoverValueState: { + "ui5-valuestatemessage-root": true, + "ui5-valuestatemessage--success": this.valueState === ValueState.Success, + "ui5-valuestatemessage--error": this.valueState === ValueState.Error, + "ui5-valuestatemessage--warning": this.valueState === ValueState.Warning, + "ui5-valuestatemessage--information": this.valueState === ValueState.Information, + }, + }; + } + + get styles() { + return { + popoverValueStateMessage: { + "width": `${this._listWidth}px`, + "min-height": "2.5rem", + "padding": "0.5625rem 1rem", + "display": this._listWidth === 0 ? "none" : "inline-block", + }, + popoverHeader: { + "width": `${this._inputWidth}px`, + }, + }; + } + static async onDefine() { await fetchI18nBundle("@ui5/webcomponents"); } diff --git a/packages/main/src/MultiComboBoxPopover.hbs b/packages/main/src/MultiComboBoxPopover.hbs index 163bffe74944..2d8765a8a4bc 100644 --- a/packages/main/src/MultiComboBoxPopover.hbs +++ b/packages/main/src/MultiComboBoxPopover.hbs @@ -4,24 +4,24 @@ class="ui5-multi-combobox-all-items-responsive-popover" no-arrow _disable-initial-focus - content-only-on-desktop @ui5-selection-change={{_listSelectionChange}} @ui5-after-close={{_toggle}} @ui5-after-open={{_toggle}} > -
-
- {{_headerTitleText}} - - -
-
-
+
+ {{_headerTitleText}} + + +
+
+
+ /> +
+
- + {{#if hasValueStateMessage}} +
+ {{> valueStateMessage}} +
+ {{/if}} +
-
+ {{/if}} + + {{#unless _isPhone}} + {{#if hasValueStateMessage}} +
+ {{> valueStateMessage}} +
+ {{/if}} + {{/unless}} {{#each _filteredItems}} @@ -57,10 +72,38 @@ {{/each}} - + {{#if _isPhone}} + + {{/if}} + +{{#if hasValueStateMessage}} + +
+ {{> valueStateMessage}} +
+
+{{/if}} + +{{#*inline "valueStateMessage"}} + {{#if shouldDisplayDefaultValueStateMessage}} + {{valueStateText}} + {{else}} + {{#each valueStateMessageText}} + {{this}} + {{/each}} + {{/if}} +{{/inline}} diff --git a/packages/main/test/pages/MultiComboBox.html b/packages/main/test/pages/MultiComboBox.html index 753c6f108d1a..0ea17ee3b0b9 100644 --- a/packages/main/test/pages/MultiComboBox.html +++ b/packages/main/test/pages/MultiComboBox.html @@ -140,6 +140,20 @@ +
+ value state information + +
+ + + + + +
Information message. This is a Link. Extra long text used as an information message. Extra long text used as an information message - 2. Extra long text used as an information message - 3.
+
+
+
value state warning From 77fd20db44dfc0c7632d8b279a53a6e56cea0b03 Mon Sep 17 00:00:00 2001 From: Ivaylo Plashkov Date: Tue, 29 Sep 2020 09:44:19 +0300 Subject: [PATCH 2/2] translate OK button --- packages/main/src/MultiComboBox.js | 5 +++++ packages/main/src/MultiComboBoxPopover.hbs | 2 +- packages/main/src/i18n/messagebundle.properties | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/main/src/MultiComboBox.js b/packages/main/src/MultiComboBox.js index f820e9e217c9..47c9432f9c1b 100644 --- a/packages/main/src/MultiComboBox.js +++ b/packages/main/src/MultiComboBox.js @@ -34,6 +34,7 @@ import { TOKENIZER_ARIA_CONTAIN_SEVERAL_TOKENS, INPUT_SUGGESTIONS_TITLE, ICON_ACCESSIBLE_NAME, + MULTICOMBOBOX_DIALOG_OK_BUTTON, } from "./generated/i18n/i18n-defaults.js"; // Templates @@ -810,6 +811,10 @@ class MultiComboBox extends UI5Element { return this.i18nBundle.getText(ICON_ACCESSIBLE_NAME); } + get _dialogOkButton() { + return this.i18nBundle.getText(MULTICOMBOBOX_DIALOG_OK_BUTTON); + } + get _tokenizerExpanded() { return this._rootFocused || this.open; } diff --git a/packages/main/src/MultiComboBoxPopover.hbs b/packages/main/src/MultiComboBoxPopover.hbs index 2d8765a8a4bc..3a410f6fc266 100644 --- a/packages/main/src/MultiComboBoxPopover.hbs +++ b/packages/main/src/MultiComboBoxPopover.hbs @@ -77,7 +77,7 @@ OK + >{{_dialogOkButton}}
{{/if}} diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 0d50cb80a420..3048d55b9b7c 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -268,6 +268,9 @@ ARIA_LABEL_LIST_ITEM_CHECKBOX = Multiple Selection mode. #XTOL: Tooltip of messgae strip close button MESSAGE_STRIP_CLOSE_BUTTON=Message Strip Close +#XFLD: MultiComboBox dialog button +MULTICOMBOBOX_DIALOG_OK_BUTTON=OK + #XFLD: Token number indicator which is used to show more tokens in Tokenizers inside MultiInput and MultiComboBox MULTIINPUT_SHOW_MORE_TOKENS={0} More