Skip to content

Commit 4133a42

Browse files
authored
feat(ui5-select): Implеment value state message
Now, ValueStateMessages are supported in ui5-select when ValueState is set to "Warning", Error or "Information" #1086
1 parent a640f84 commit 4133a42

File tree

4 files changed

+171
-2
lines changed

4 files changed

+171
-2
lines changed

packages/main/src/Select.js

+108-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import {
1010
isTabNext,
1111
isTabPrevious,
1212
} from "@ui5/webcomponents-base/dist/Keys.js";
13+
import Integer from "@ui5/webcomponents-base/dist/types/Integer.js";
1314
import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js";
1415
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
1516
import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js";
17+
import { isPhone } from "@ui5/webcomponents-base/dist/Device.js";
1618
import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
1719
import "@ui5/webcomponents-icons/dist/icons/decline.js";
1820
import {
@@ -25,6 +27,7 @@ import {
2527
import Option from "./Option.js";
2628
import Label from "./Label.js";
2729
import ResponsivePopover from "./ResponsivePopover.js";
30+
import Popover from "./Popover.js";
2831
import List from "./List.js";
2932
import StandardListItem from "./StandardListItem.js";
3033
import Icon from "./Icon.js";
@@ -36,6 +39,8 @@ import SelectPopoverTemplate from "./generated/templates/SelectPopoverTemplate.l
3639
// Styles
3740
import selectCss from "./generated/themes/Select.css.js";
3841
import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js";
42+
import ValueStateMessageCss from "./generated/themes/ValueStateMessage.css.js";
43+
import SelectPopoverCss from "./generated/themes/SelectPopover.css.js";
3944

4045
/**
4146
* @public
@@ -64,6 +69,23 @@ const metadata = {
6469
type: HTMLElement,
6570
listenFor: { include: ["*"] },
6671
},
72+
73+
/**
74+
* Defines the value state message that will be displayed as pop up under the <code>ui5-select</code>.
75+
* <br><br>
76+
*
77+
* <b>Note:</b> If not specified, a default text (in the respective language) will be displayed.
78+
* <br>
79+
* <b>Note:</b> The <code>valueStateMessage</code> would be displayed,
80+
* when the <code>ui5-select</code> is in <code>Information</code>, <code>Warning</code> or <code>Error</code> value state.
81+
* @type {HTMLElement[]}
82+
* @since 1.0.0-rc.9
83+
* @slot
84+
* @public
85+
*/
86+
valueStateMessage: {
87+
type: HTMLElement,
88+
},
6789
},
6890
properties: /** @lends sap.ui.webcomponents.main.Select.prototype */ {
6991

@@ -139,6 +161,12 @@ const metadata = {
139161
type: Boolean,
140162
},
141163

164+
_listWidth: {
165+
type: Integer,
166+
defaultValue: 0,
167+
noAttribute: true,
168+
},
169+
142170
/**
143171
* @private
144172
*/
@@ -211,7 +239,7 @@ class Select extends UI5Element {
211239
}
212240

213241
static get staticAreaStyles() {
214-
return ResponsivePopoverCommonCss;
242+
return [ResponsivePopoverCommonCss, ValueStateMessageCss, SelectPopoverCss];
215243
}
216244

217245
constructor() {
@@ -230,6 +258,14 @@ class Select extends UI5Element {
230258
this._enableFormSupport();
231259
}
232260

261+
onAfterRendering() {
262+
this.toggleValueStatePopover(this.shouldOpenValueStateMessagePopover);
263+
264+
if (this._isPickerOpen && !this._listWidth) {
265+
this._listWidth = this.responsivePopover.offsetWidth;
266+
}
267+
}
268+
233269
_onfocusin() {
234270
this.focused = true;
235271
}
@@ -441,6 +477,7 @@ class Select extends UI5Element {
441477

442478
_afterClose() {
443479
this._iconPressed = false;
480+
this._listWidth = 0;
444481

445482
if (this._escapePressed) {
446483
this._select(this._selectedIndexBeforeOpen);
@@ -504,11 +541,81 @@ class Select extends UI5Element {
504541
&& this.responsivePopover.opened ? "-1" : "0";
505542
}
506543

544+
get classes() {
545+
return {
546+
popoverValueState: {
547+
"ui5-valuestatemessage-root": true,
548+
"ui5-valuestatemessage--success": this.valueState === ValueState.Success,
549+
"ui5-valuestatemessage--error": this.valueState === ValueState.Error,
550+
"ui5-valuestatemessage--warning": this.valueState === ValueState.Warning,
551+
"ui5-valuestatemessage--information": this.valueState === ValueState.Information,
552+
},
553+
};
554+
}
555+
556+
get styles() {
557+
return {
558+
popoverHeader: {
559+
"width": `${this.offsetWidth}px`,
560+
},
561+
responsivePopoverHeader: {
562+
"display": this.options.length && this._listWidth === 0 ? "none" : "inline-block",
563+
"width": `${this.options.length ? this._listWidth : this.offsetWidth}px`,
564+
},
565+
};
566+
}
567+
568+
get valueStateMessageText() {
569+
return this.getSlottedNodes("valueStateMessage").map(el => el.cloneNode(true));
570+
}
571+
572+
get shouldDisplayDefaultValueStateMessage() {
573+
return !this.valueStateMessage.length && this.hasValueStateText;
574+
}
575+
576+
get hasValueStateText() {
577+
return this.hasValueState && this.valueState !== ValueState.Success;
578+
}
579+
580+
get shouldOpenValueStateMessagePopover() {
581+
return this.focused && this.hasValueStateText && !this._iconPressed
582+
&& !this._isPickerOpen && !this._isPhone;
583+
}
584+
585+
get _isPhone() {
586+
return isPhone();
587+
}
588+
589+
async openValueStatePopover() {
590+
this.popover = await this._getPopover();
591+
if (this.popover) {
592+
this.popover.openBy(this);
593+
}
594+
}
595+
596+
closeValueStatePopover() {
597+
this.popover && this.popover.close();
598+
}
599+
600+
toggleValueStatePopover(open) {
601+
if (open) {
602+
this.openValueStatePopover();
603+
} else {
604+
this.closeValueStatePopover();
605+
}
606+
}
607+
608+
async _getPopover() {
609+
const staticAreaItem = await this.getStaticAreaItemDomRef();
610+
return staticAreaItem.querySelector("ui5-popover");
611+
}
612+
507613
static async onDefine() {
508614
await Promise.all([
509615
Option.define(),
510616
Label.define(),
511617
ResponsivePopover.define(),
618+
Popover.define(),
512619
List.define(),
513620
StandardListItem.define(),
514621
Icon.define(),

packages/main/src/SelectPopover.hbs

+41
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@
2121
>
2222
</ui5-button>
2323
</div>
24+
{{#if _isPhone}}
25+
{{#if hasValueStateText}}
26+
<div class="{{classes.popoverValueState}} row ui5-select-value-state-dialog-header">
27+
{{> valueStateMessage}}
28+
</div>
29+
{{/if}}
30+
{{/if}}
2431
</div>
2532

33+
{{#unless _isPhone}}
34+
{{#if hasValueStateText}}
35+
<div class="{{classes.popoverValueState}} ui5-select-value-state-popover-padding" style="{{styles.responsivePopoverHeader}}">
36+
{{> valueStateMessage}}
37+
</div>
38+
{{/if}}
39+
{{/unless}}
40+
2641
<ui5-list mode="SingleSelectAuto" separators="None" @keydown="{{_handlePickerKeydown}}" @ui5-selection-change="{{_handleSelectionChange}}" @ui5-item-press="{{_handleItemPress}}">
2742
{{#each _syncedOptions}}
2843
<ui5-li ?selected="{{this.selected}}" icon="{{this.icon}}" id="{{this.id}}-li">
@@ -32,3 +47,29 @@
3247
</ui5-list>
3348
</ui5-responsive-popover>
3449
{{/if}}
50+
51+
{{#if shouldOpenValueStateMessagePopover}}
52+
<ui5-popover
53+
skip-registry-update
54+
_disable-initial-focus
55+
prevent-focus-restore
56+
no-padding
57+
no-arrow
58+
class="ui5-valuestatemessage-popover"
59+
placement-type="Bottom"
60+
>
61+
<div slot="header" class="ui5-responsive-popover-header {{classes.popoverValueState}}" style="{{styles.popoverHeader}}">
62+
{{> valueStateMessage}}
63+
</div>
64+
</ui5-popover>
65+
{{/if}}
66+
67+
{{#*inline "valueStateMessage"}}
68+
{{#if shouldDisplayDefaultValueStateMessage}}
69+
{{valueStateText}}
70+
{{else}}
71+
{{#each valueStateMessageText}}
72+
{{this}}
73+
{{/each}}
74+
{{/if}}
75+
{{/inline}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.ui5-select-value-state-popover-padding {
2+
padding: 0.5625rem 1rem;
3+
}
4+
5+
.ui5-select-value-state-dialog-header.row {
6+
padding: 0.5625rem 1rem;
7+
height: auto;
8+
display: inline-block;
9+
}

packages/main/test/samples/Select.sample.html

+13-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ <h3>Basic Select</h3>
5252
</section>
5353

5454
<section>
55-
<h3>Select with Value State</h3>
55+
<h3>Select with Value State and Value State Message</h3>
5656
<div class="snippet">
5757
<ui5-select value-state="Success" class="select">
5858
<ui5-option icon="meal" selected>Apple</ui5-option>
@@ -63,16 +63,22 @@ <h3>Select with Value State</h3>
6363
<ui5-option icon="meal">Orange</ui5-option>
6464
<ui5-option icon="meal" selected>Pumpkin</ui5-option>
6565
<ui5-option icon="meal">Carrot</ui5-option>
66+
<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>
67+
<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>
6668
</ui5-select>
6769
<ui5-select value-state="Error" class="select">
6870
<ui5-option icon="meal">Strawberry</ui5-option>
6971
<ui5-option icon="meal">Tomato</ui5-option>
7072
<ui5-option icon="meal" selected>Red Chili Pepper</ui5-option>
73+
<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>
74+
<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>
7175
</ui5-select>
7276
<ui5-select value-state="Information" class="select">
7377
<ui5-option icon="meal">Blueberry</ui5-option>
7478
<ui5-option icon="meal">Grape</ui5-option>
7579
<ui5-option icon="meal" selected>Plum</ui5-option>
80+
<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>
81+
<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>
7682
</ui5-select>
7783
</div>
7884
<pre class="prettyprint lang-html"><xmp>
@@ -85,16 +91,22 @@ <h3>Select with Value State</h3>
8591
<ui5-option icon="meal">Orange</ui5-option>
8692
<ui5-option icon="meal" selected>Pumpkin</ui5-option>
8793
<ui5-option icon="meal">Carrot</ui5-option>
94+
<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>
95+
<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>
8896
</ui5-select>
8997
<ui5-select value-state="Error" class="select">
9098
<ui5-option icon="meal">Strawberry</ui5-option>
9199
<ui5-option icon="meal">Tomato</ui5-option>
92100
<ui5-option icon="meal" selected>Red Chili Pepper</ui5-option>
101+
<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>
102+
<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>
93103
</ui5-select>
94104
<ui5-select value-state="Information" class="select">
95105
<ui5-option icon="meal">Blueberry</ui5-option>
96106
<ui5-option icon="meal">Grape</ui5-option>
97107
<ui5-option icon="meal" selected>Plum</ui5-option>
108+
<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>
109+
<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>
98110
</ui5-select>
99111
</xmp></pre>
100112
</section>

0 commit comments

Comments
 (0)