Skip to content

Commit

Permalink
feat(ui5-select): Implеment value state message
Browse files Browse the repository at this point in the history
Now, ValueStateMessages are supported in ui5-select when ValueState is set to "Warning", Error or "Information"

#1086
  • Loading branch information
nnaydenow authored Aug 5, 2020
1 parent a640f84 commit 4133a42
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 2 deletions.
109 changes: 108 additions & 1 deletion packages/main/src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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";
Expand All @@ -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
Expand Down Expand Up @@ -64,6 +69,23 @@ const metadata = {
type: HTMLElement,
listenFor: { include: ["*"] },
},

/**
* Defines the value state message that will be displayed as pop up under the <code>ui5-select</code>.
* <br><br>
*
* <b>Note:</b> If not specified, a default text (in the respective language) will be displayed.
* <br>
* <b>Note:</b> The <code>valueStateMessage</code> would be displayed,
* when the <code>ui5-select</code> is in <code>Information</code>, <code>Warning</code> or <code>Error</code> value state.
* @type {HTMLElement[]}
* @since 1.0.0-rc.9
* @slot
* @public
*/
valueStateMessage: {
type: HTMLElement,
},
},
properties: /** @lends sap.ui.webcomponents.main.Select.prototype */ {

Expand Down Expand Up @@ -139,6 +161,12 @@ const metadata = {
type: Boolean,
},

_listWidth: {
type: Integer,
defaultValue: 0,
noAttribute: true,
},

/**
* @private
*/
Expand Down Expand Up @@ -211,7 +239,7 @@ class Select extends UI5Element {
}

static get staticAreaStyles() {
return ResponsivePopoverCommonCss;
return [ResponsivePopoverCommonCss, ValueStateMessageCss, SelectPopoverCss];
}

constructor() {
Expand All @@ -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;
}
Expand Down Expand Up @@ -441,6 +477,7 @@ class Select extends UI5Element {

_afterClose() {
this._iconPressed = false;
this._listWidth = 0;

if (this._escapePressed) {
this._select(this._selectedIndexBeforeOpen);
Expand Down Expand Up @@ -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(),
Expand Down
41 changes: 41 additions & 0 deletions packages/main/src/SelectPopover.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,23 @@
>
</ui5-button>
</div>
{{#if _isPhone}}
{{#if hasValueStateText}}
<div class="{{classes.popoverValueState}} row ui5-select-value-state-dialog-header">
{{> valueStateMessage}}
</div>
{{/if}}
{{/if}}
</div>

{{#unless _isPhone}}
{{#if hasValueStateText}}
<div class="{{classes.popoverValueState}} ui5-select-value-state-popover-padding" style="{{styles.responsivePopoverHeader}}">
{{> valueStateMessage}}
</div>
{{/if}}
{{/unless}}

<ui5-list mode="SingleSelectAuto" separators="None" @keydown="{{_handlePickerKeydown}}" @ui5-selection-change="{{_handleSelectionChange}}" @ui5-item-press="{{_handleItemPress}}">
{{#each _syncedOptions}}
<ui5-li ?selected="{{this.selected}}" icon="{{this.icon}}" id="{{this.id}}-li">
Expand All @@ -32,3 +47,29 @@
</ui5-list>
</ui5-responsive-popover>
{{/if}}

{{#if shouldOpenValueStateMessagePopover}}
<ui5-popover
skip-registry-update
_disable-initial-focus
prevent-focus-restore
no-padding
no-arrow
class="ui5-valuestatemessage-popover"
placement-type="Bottom"
>
<div slot="header" class="ui5-responsive-popover-header {{classes.popoverValueState}}" style="{{styles.popoverHeader}}">
{{> valueStateMessage}}
</div>
</ui5-popover>
{{/if}}

{{#*inline "valueStateMessage"}}
{{#if shouldDisplayDefaultValueStateMessage}}
{{valueStateText}}
{{else}}
{{#each valueStateMessageText}}
{{this}}
{{/each}}
{{/if}}
{{/inline}}
9 changes: 9 additions & 0 deletions packages/main/src/themes/SelectPopover.css
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 13 additions & 1 deletion packages/main/test/samples/Select.sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h3>Basic Select</h3>
</section>

<section>
<h3>Select with Value State</h3>
<h3>Select with Value State and Value State Message</h3>
<div class="snippet">
<ui5-select value-state="Success" class="select">
<ui5-option icon="meal" selected>Apple</ui5-option>
Expand All @@ -63,16 +63,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>
</div>
<pre class="prettyprint lang-html"><xmp>
Expand All @@ -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>
</xmp></pre>
</section>
Expand Down

0 comments on commit 4133a42

Please sign in to comment.