Skip to content

Commit 3597902

Browse files
authored
fix(ui5-shellbar): fix overlapping of the search box over icons (#2155)
Now, when there is not enough space for the search field it is expanded to full width within the ui5-shellbar and the search filed does not overlap any other elements in the ui5-shellbar any more. FIXES: #2044
1 parent 7ae9253 commit 3597902

File tree

5 files changed

+122
-68
lines changed

5 files changed

+122
-68
lines changed

packages/fiori/src/ShellBar.hbs

+20-10
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,30 @@
7474
{{/if}}
7575
</div>
7676

77-
<div id="{{_id}}-searchfield-wrapper"
78-
class="ui5-shellbar-search-field"
79-
style="{{styles.searchField}}"
80-
>
81-
{{#if searchField.length}}
82-
<slot name="searchField"></slot>
83-
{{/if}}
84-
</div>
85-
8677
<div class="ui5-shellbar-overflow-container ui5-shellbar-overflow-container-right">
87-
8878
<div class="ui5-shellbar-overflow-container-right-child">
8979

9080
{{#if hasSearchField}}
81+
{{#if _fullWidthSearch}}
82+
<div class="ui5-shellbar-search-full-width-wrapper" style="{{styles.searchField}}">
83+
<div class="ui5-shellbar-search-full-field">
84+
<slot name="searchField"></slot>
85+
</div>
86+
<ui5-button
87+
@click={{_handleCancelButtonPress}}
88+
class="ui5-shellbar-button"
89+
>
90+
Cancel
91+
</ui5-button>
92+
</div>
93+
{{/if}}
94+
95+
<div class="ui5-shellbar-search-field" style="{{styles.searchField}}">
96+
{{#unless _fullWidthSearch}}
97+
<slot name="searchField"></slot>
98+
{{/unless}}
99+
</div>
100+
91101
<ui5-button
92102
id="{{this._id}}-item-1"
93103
class="{{classes.items.search}} ui5-shellbar-button ui5-shellbar-search-button"

packages/fiori/src/ShellBar.js

+53-38
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
SHELLBAR_LOGO,
2121
SHELLBAR_COPILOT,
2222
SHELLBAR_NOTIFICATIONS,
23+
SHELLBAR_CANCEL,
2324
SHELLBAR_PROFILE,
2425
SHELLBAR_PRODUCTS,
2526
SHELLBAR_SEARCH,
@@ -144,10 +145,6 @@ const metadata = {
144145
type: Object,
145146
},
146147

147-
_searchField: {
148-
type: Object,
149-
},
150-
151148
_header: {
152149
type: Object,
153150
},
@@ -164,6 +161,10 @@ const metadata = {
164161
type: Boolean,
165162
noAttribute: true,
166163
},
164+
_fullWidthSearch: {
165+
type: Boolean,
166+
noAttribute: true,
167+
},
167168
},
168169
managedSlots: true,
169170
slots: /** @lends sap.ui.webcomponents.fiori.ShellBar.prototype */ {
@@ -376,7 +377,7 @@ class ShellBar extends UI5Element {
376377

377378
static get FIORI_3_BREAKPOINTS() {
378379
return [
379-
559,
380+
599,
380381
1023,
381382
1439,
382383
1919,
@@ -386,7 +387,7 @@ class ShellBar extends UI5Element {
386387

387388
static get FIORI_3_BREAKPOINTS_MAP() {
388389
return {
389-
"559": "S",
390+
"599": "S",
390391
"1023": "M",
391392
"1439": "L",
392393
"1919": "XL",
@@ -429,10 +430,6 @@ class ShellBar extends UI5Element {
429430
},
430431
};
431432

432-
this._searchField = {
433-
left: 0,
434-
};
435-
436433
this._handleResize = async event => {
437434
await this._getResponsivePopover();
438435
this.overflowPopover.close();
@@ -527,15 +524,19 @@ class ShellBar extends UI5Element {
527524
const isHidden = (info.classes.indexOf("ui5-shellbar-hidden-button") !== -1);
528525
const isSet = info.classes.indexOf("ui5-shellbar-invisible-button") === -1;
529526
const isOverflowIcon = info.classes.indexOf("ui5-shellbar-overflow-button") !== -1;
527+
const isImageIcon = info.classes.indexOf("ui5-shellbar-image-button") !== -1;
528+
const shouldStayOnScreen = isOverflowIcon || (isImageIcon && this.hasProfile);
530529

531-
return isHidden && isSet && !isOverflowIcon;
530+
return isHidden && isSet && !shouldStayOnScreen;
532531
});
533532

534533
this._observeMenuItems();
535534
}
536535

537536
onAfterRendering() {
538537
this._overflowActions();
538+
539+
this._fullWidthSearch = this._showFullWidthSearch;
539540
}
540541

541542
/**
@@ -582,10 +583,16 @@ class ShellBar extends UI5Element {
582583

583584
_handleActionsOverflow() {
584585
const rightContainerRect = this.shadowRoot.querySelector(".ui5-shellbar-overflow-container-right").getBoundingClientRect();
585-
const icons = this.shadowRoot.querySelectorAll(".ui5-shellbar-button:not(.ui5-shellbar-overflow-button):not(.ui5-shellbar-invisible-button)");
586+
let overflowSelector = ".ui5-shellbar-button:not(.ui5-shellbar-overflow-button):not(.ui5-shellbar-invisible-button)";
587+
588+
if (this.showSearchField) {
589+
overflowSelector += ",.ui5-shellbar-search-field";
590+
}
591+
592+
const elementsToOverflow = this.shadowRoot.querySelectorAll(overflowSelector);
586593
const isRTL = this.effectiveDir === "rtl";
587594

588-
let overflowCount = [].filter.call(icons, icon => {
595+
let overflowCount = [].filter.call(elementsToOverflow, icon => {
589596
const iconRect = icon.getBoundingClientRect();
590597

591598
if (isRTL) {
@@ -597,7 +604,7 @@ class ShellBar extends UI5Element {
597604

598605
overflowCount = overflowCount.length;
599606

600-
const items = this._getAllItems(!!overflowCount);
607+
const items = this._getAllItems(!!overflowCount).filter(item => item.show);
601608

602609
const itemsByPriority = items.sort((item1, item2) => {
603610
if (item1.priority > item2.priority) {
@@ -653,26 +660,7 @@ class ShellBar extends UI5Element {
653660
return;
654661
}
655662

656-
const searchField = this.shadowRoot.querySelector(`#${this._id}-searchfield-wrapper`);
657-
const triggeredByOverflow = event.target.tagName.toLowerCase() === "ui5-li";
658-
const overflowButton = this.shadowRoot.querySelector(".ui5-shellbar-overflow-button");
659-
const overflowButtonRect = overflowButton.getBoundingClientRect();
660-
const isRTL = this.effectiveDir === "rtl";
661-
let right = "";
662-
663-
if (isRTL) {
664-
right = `${(triggeredByOverflow ? overflowButton.offsetLeft : event.target.offsetLeft) + overflowButtonRect.width}px`;
665-
} else {
666-
right = `calc(100% - ${triggeredByOverflow ? overflowButton.offsetLeft : event.target.offsetLeft}px)`;
667-
}
668-
669-
this._searchField = Object.assign({}, this._searchField, {
670-
"right": right,
671-
});
672-
673-
674-
const inputSlot = searchField.children[0];
675-
const input = inputSlot && inputSlot.assignedNodes()[0];
663+
const input = this.searchField[0];
676664

677665
// update the state immediately
678666
if (input) {
@@ -719,6 +707,10 @@ class ShellBar extends UI5Element {
719707
});
720708
}
721709

710+
_handleCancelButtonPress() {
711+
this.showSearchField = false;
712+
}
713+
722714
_handleProductSwitchPress(event) {
723715
const buttonRef = this.shadowRoot.querySelector(".ui5-shellbar-button-product-switch");
724716

@@ -744,6 +736,7 @@ class ShellBar extends UI5Element {
744736
style: `order: ${this.searchField.length ? 1 : -10}`,
745737
id: `${this._id}-item-${1}`,
746738
press: this._handleSearchIconPress.bind(this),
739+
show: !!this.searchField.length,
747740
},
748741
...this.items.map((item, index) => {
749742
return {
@@ -893,10 +886,6 @@ class ShellBar extends UI5Element {
893886

894887
get styles() {
895888
return {
896-
searchField: {
897-
[this.effectiveDir === "rtl" ? "left" : "right"]: this._searchField.right,
898-
"top": `${parseInt(this._searchField.top)}px`,
899-
},
900889
items: {
901890
notification: {
902891
"order": this.isIconHidden("bell") ? "-1" : "3",
@@ -911,9 +900,24 @@ class ShellBar extends UI5Element {
911900
"order": this.isIconHidden("grid") ? "-1" : "6",
912901
},
913902
},
903+
searchField: {
904+
"display": this.correctSearchFieldStyles,
905+
},
914906
};
915907
}
916908

909+
get correctSearchFieldStyles() {
910+
if (this.showSearchField) {
911+
if (this._fullWidthSearch) {
912+
return "flex";
913+
}
914+
915+
return "block";
916+
}
917+
918+
return "none";
919+
}
920+
917921
get customItemsInfo() {
918922
return this._itemsInfo.filter(itemInfo => !!itemInfo.custom);
919923
}
@@ -982,6 +986,17 @@ class ShellBar extends UI5Element {
982986
return this.i18nBundle.getText(SHELLBAR_NOTIFICATIONS, this.notificationCount);
983987
}
984988

989+
get _cancelBtnText() {
990+
return this.i18nBundle.getText(SHELLBAR_CANCEL);
991+
}
992+
993+
get _showFullWidthSearch() {
994+
const size = this._handleBarBreakpoints();
995+
const searchBtnHidden = !!this.shadowRoot.querySelector(".ui5-shellbar-search-button.ui5-shellbar-hidden-button");
996+
997+
return ((size === "S") || searchBtnHidden);
998+
}
999+
9851000
get _profileText() {
9861001
return this.i18nBundle.getText(SHELLBAR_PROFILE);
9871002
}

packages/fiori/src/i18n/messagebundle.properties

+4-1
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,11 @@ SHELLBAR_SEARCH = Search
114114
#XACT: ARIA announcement for the more button
115115
SHELLBAR_OVERFLOW = More
116116

117+
#XACT: ARIA announcement for the cancel button
118+
SHELLBAR_CANCEL = Cancel
119+
117120
#XACT: ARIA announcement for roledescription attribute of Wizard navigation header
118121
WIZARD_NAV_ARIA_ROLE_DESCRIPTION = Wizard
119122

120123
#XACT: WizardProgressNavigator predefined text for step
121-
WIZARD_NAV_STEP_DEFAULT_HEADING=Step
124+
WIZARD_NAV_STEP_DEFAULT_HEADING=Step

packages/fiori/src/themes/ShellBar.css

+40-13
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,19 @@ slot[name="profile"] {
170170
padding: 0.25rem 1rem;
171171
}
172172

173+
:host([breakpoint-size="S"]) .ui5-shellbar-search-full-width-wrapper {
174+
padding: 0.25rem 1rem;
175+
}
176+
173177
:host([breakpoint-size="S"]) ::slotted([ui5-button][slot="startButton"]) {
174178
margin-right: 0;
175179
}
176180

177-
:host([breakpoint-size="S"]) .ui5-shellbar-search-field {
178-
width: 200px;
181+
:host([breakpoint-size="M"]) .ui5-shellbar-root {
182+
padding: 0.25rem 2rem;
179183
}
180184

181-
:host([breakpoint-size="M"]) .ui5-shellbar-root {
185+
:host([breakpoint-size="M"]) .ui5-shellbar-search-full-width-wrapper {
182186
padding: 0.25rem 2rem;
183187
}
184188

@@ -263,10 +267,13 @@ slot[name="profile"] {
263267
overflow: hidden;
264268
box-sizing: border-box;
265269
white-space: nowrap;
266-
margin-left: 8rem;
267270
flex: 1;
268271
}
269272

273+
:host(:not([show-search-field])) .ui5-shellbar-overflow-container-right {
274+
margin-left: 8rem;
275+
}
276+
270277
.ui5-shellbar-overflow-container-right .ui5-shellbar-overflow-container-right-child {
271278
display: flex;
272279
float: right;
@@ -307,11 +314,6 @@ slot[name="profile"] {
307314
cursor: pointer;
308315
}
309316

310-
:host(:not([show-search-field])) .ui5-shellbar-search-field {
311-
display: none;
312-
}
313-
314-
315317
:host([breakpoint-size="L"]) .ui5-shellbar-with-searchfield .ui5-shellbar-overflow-container-right {
316318
margin-left: 1rem;
317319
}
@@ -358,18 +360,39 @@ slot[name="profile"] {
358360
}
359361

360362
.ui5-shellbar-search-field {
361-
z-index: 101;
362-
position: absolute;
363363
width: 240px;
364-
top: 0.25rem;
364+
min-width: 240px;
365+
margin-left: 0.5rem;
366+
}
367+
368+
.ui5-shellbar-search-full-width-wrapper .ui5-shellbar-search-full-field {
365369
height: 2.25rem;
370+
width: 100%;
371+
}
372+
373+
.ui5-shellbar-search-full-width-wrapper {
374+
position: absolute;
375+
top: 0;
376+
left: 0;
377+
background: var(--sapShellColor);
378+
height: 100%;
379+
width: 100%;
380+
z-index: 100;
381+
display: flex;
382+
align-items: center;
383+
box-sizing: border-box;
384+
}
385+
386+
.ui5-shellbar-search-full-width-wrapper .ui5-shellbar-button {
387+
width: auto;
366388
}
367389

368390
::slotted([ui5-input]) {
369391
background-color: var(--sapShellColor);
370392
border: 1px solid var(--sapShell_InteractiveBorderColor);
371393
color: var(--sapShell_TextColor);
372394
height: 100%;
395+
width: 100%;
373396
}
374397

375398
::slotted([ui5-input][focused]) {
@@ -451,11 +474,15 @@ slot[name="profile"] {
451474
margin-left: 0;
452475
}
453476

454-
[dir="rtl"] .ui5-shellbar-overflow-container-right {
477+
:host(:not([show-search-field])) [dir="rtl"] .ui5-shellbar-overflow-container-right {
455478
margin-right: 8rem;
456479
margin-left: 0;
457480
}
458481

482+
[dir="rtl"] .ui5-shellbar-overflow-container-right {
483+
margin-left: 0;
484+
}
485+
459486
[dir="rtl"] .ui5-shellbar-overflow-container-right .ui5-shellbar-overflow-container-right-child {
460487
float: left;
461488
}

0 commit comments

Comments
 (0)