From 4133a4249327d7ee1e06eb460b6989efa7daf434 Mon Sep 17 00:00:00 2001 From: Nayden Naydenov <31909318+nnaydenow@users.noreply.github.com> Date: Wed, 5 Aug 2020 12:18:22 +0300 Subject: [PATCH] =?UTF-8?q?feat(ui5-select):=20Impl=D0=B5ment=20value=20st?= =?UTF-8?q?ate=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now, ValueStateMessages are supported in ui5-select when ValueState is set to "Warning", Error or "Information" #1086 --- packages/main/src/Select.js | 109 +++++++++++++++++- packages/main/src/SelectPopover.hbs | 41 +++++++ packages/main/src/themes/SelectPopover.css | 9 ++ packages/main/test/samples/Select.sample.html | 14 ++- 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 packages/main/src/themes/SelectPopover.css diff --git a/packages/main/src/Select.js b/packages/main/src/Select.js index c0dcdeaa22ae..f4de6132693d 100644 --- a/packages/main/src/Select.js +++ b/packages/main/src/Select.js @@ -10,9 +10,11 @@ import { isTabNext, isTabPrevious, } from "@ui5/webcomponents-base/dist/Keys.js"; +import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js"; +import { isPhone } from "@ui5/webcomponents-base/dist/Device.js"; import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import "@ui5/webcomponents-icons/dist/icons/decline.js"; import { @@ -25,6 +27,7 @@ import { import Option from "./Option.js"; import Label from "./Label.js"; import ResponsivePopover from "./ResponsivePopover.js"; +import Popover from "./Popover.js"; import List from "./List.js"; import StandardListItem from "./StandardListItem.js"; import Icon from "./Icon.js"; @@ -36,6 +39,8 @@ import SelectPopoverTemplate from "./generated/templates/SelectPopoverTemplate.l // Styles import selectCss from "./generated/themes/Select.css.js"; import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js"; +import ValueStateMessageCss from "./generated/themes/ValueStateMessage.css.js"; +import SelectPopoverCss from "./generated/themes/SelectPopover.css.js"; /** * @public @@ -64,6 +69,23 @@ const metadata = { type: HTMLElement, listenFor: { include: ["*"] }, }, + + /** + * Defines the value state message that will be displayed as pop up under the ui5-select. + *

+ * + * 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.Select.prototype */ { @@ -139,6 +161,12 @@ const metadata = { type: Boolean, }, + _listWidth: { + type: Integer, + defaultValue: 0, + noAttribute: true, + }, + /** * @private */ @@ -211,7 +239,7 @@ class Select extends UI5Element { } static get staticAreaStyles() { - return ResponsivePopoverCommonCss; + return [ResponsivePopoverCommonCss, ValueStateMessageCss, SelectPopoverCss]; } constructor() { @@ -230,6 +258,14 @@ class Select extends UI5Element { this._enableFormSupport(); } + onAfterRendering() { + this.toggleValueStatePopover(this.shouldOpenValueStateMessagePopover); + + if (this._isPickerOpen && !this._listWidth) { + this._listWidth = this.responsivePopover.offsetWidth; + } + } + _onfocusin() { this.focused = true; } @@ -441,6 +477,7 @@ class Select extends UI5Element { _afterClose() { this._iconPressed = false; + this._listWidth = 0; if (this._escapePressed) { this._select(this._selectedIndexBeforeOpen); @@ -504,11 +541,81 @@ class Select extends UI5Element { && this.responsivePopover.opened ? "-1" : "0"; } + 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 { + popoverHeader: { + "width": `${this.offsetWidth}px`, + }, + responsivePopoverHeader: { + "display": this.options.length && this._listWidth === 0 ? "none" : "inline-block", + "width": `${this.options.length ? this._listWidth : this.offsetWidth}px`, + }, + }; + } + + get valueStateMessageText() { + return this.getSlottedNodes("valueStateMessage").map(el => el.cloneNode(true)); + } + + get shouldDisplayDefaultValueStateMessage() { + return !this.valueStateMessage.length && this.hasValueStateText; + } + + get hasValueStateText() { + return this.hasValueState && this.valueState !== ValueState.Success; + } + + get shouldOpenValueStateMessagePopover() { + return this.focused && this.hasValueStateText && !this._iconPressed + && !this._isPickerOpen && !this._isPhone; + } + + get _isPhone() { + return isPhone(); + } + + async openValueStatePopover() { + this.popover = await this._getPopover(); + if (this.popover) { + this.popover.openBy(this); + } + } + + closeValueStatePopover() { + this.popover && this.popover.close(); + } + + toggleValueStatePopover(open) { + if (open) { + this.openValueStatePopover(); + } else { + this.closeValueStatePopover(); + } + } + + async _getPopover() { + const staticAreaItem = await this.getStaticAreaItemDomRef(); + return staticAreaItem.querySelector("ui5-popover"); + } + static async onDefine() { await Promise.all([ Option.define(), Label.define(), ResponsivePopover.define(), + Popover.define(), List.define(), StandardListItem.define(), Icon.define(), diff --git a/packages/main/src/SelectPopover.hbs b/packages/main/src/SelectPopover.hbs index 07745b803d61..56c65fe3084a 100644 --- a/packages/main/src/SelectPopover.hbs +++ b/packages/main/src/SelectPopover.hbs @@ -21,8 +21,23 @@ > + {{#if _isPhone}} + {{#if hasValueStateText}} +
+ {{> valueStateMessage}} +
+ {{/if}} + {{/if}} + {{#unless _isPhone}} + {{#if hasValueStateText}} +
+ {{> valueStateMessage}} +
+ {{/if}} + {{/unless}} + {{#each _syncedOptions}} @@ -32,3 +47,29 @@ {{/if}} + +{{#if shouldOpenValueStateMessagePopover}} + +
+ {{> valueStateMessage}} +
+
+{{/if}} + +{{#*inline "valueStateMessage"}} + {{#if shouldDisplayDefaultValueStateMessage}} + {{valueStateText}} + {{else}} + {{#each valueStateMessageText}} + {{this}} + {{/each}} + {{/if}} +{{/inline}} \ No newline at end of file diff --git a/packages/main/src/themes/SelectPopover.css b/packages/main/src/themes/SelectPopover.css new file mode 100644 index 000000000000..15b9f8fab8dc --- /dev/null +++ b/packages/main/src/themes/SelectPopover.css @@ -0,0 +1,9 @@ +.ui5-select-value-state-popover-padding { + padding: 0.5625rem 1rem; +} + +.ui5-select-value-state-dialog-header.row { + padding: 0.5625rem 1rem; + height: auto; + display: inline-block; +} \ No newline at end of file diff --git a/packages/main/test/samples/Select.sample.html b/packages/main/test/samples/Select.sample.html index d41fe73228e7..e40833231338 100644 --- a/packages/main/test/samples/Select.sample.html +++ b/packages/main/test/samples/Select.sample.html @@ -52,7 +52,7 @@

Basic Select

-

Select with Value State

+

Select with Value State and Value State Message

Apple @@ -63,16 +63,22 @@

Select with Value State

Orange Pumpkin Carrot +
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.
+
Information message 2. 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.
Strawberry Tomato Red Chili Pepper +
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.
+
Information message 2. 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.
Blueberry Grape Plum +
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.
+
Information message 2. 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.

@@ -85,16 +91,22 @@ <h3>Select with Value State</h3>
 	<ui5-option icon="meal">Orange</ui5-option>
 	<ui5-option icon="meal" selected>Pumpkin</ui5-option>
 	<ui5-option icon="meal">Carrot</ui5-option>
+	<div slot="valueStateMessage">Information message. This is a <a href="#">Link</a>. 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.</div>
+	<div slot="valueStateMessage">Information message 2. This is a <a href="#">Link</a>. 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.</div>
 </ui5-select>
 <ui5-select value-state="Error" class="select">
 	<ui5-option icon="meal">Strawberry</ui5-option>
 	<ui5-option icon="meal">Tomato</ui5-option>
 	<ui5-option icon="meal" selected>Red Chili Pepper</ui5-option>
+	<div slot="valueStateMessage">Information message. This is a <a href="#">Link</a>. 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.</div>
+	<div slot="valueStateMessage">Information message 2. This is a <a href="#">Link</a>. 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.</div>
 </ui5-select>
 <ui5-select value-state="Information" class="select">
 	<ui5-option icon="meal">Blueberry</ui5-option>
 	<ui5-option icon="meal">Grape</ui5-option>
 	<ui5-option icon="meal" selected>Plum</ui5-option>
+	<div slot="valueStateMessage">Information message. This is a <a href="#">Link</a>. 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.</div>
+<div slot="valueStateMessage">Information message 2. This is a <a href="#">Link</a>. 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.</div>
 </ui5-select>