Skip to content

Commit 8447e0d

Browse files
fix(ui5-time-picker): show header on mobile (#12768)
fixes: #12695
1 parent 337d97b commit 8447e0d

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

packages/main/cypress/specs/TimePicker.mobile.cy.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ describe("TimePicker on phone - general interactions", () => {
125125
.ui5TimePickerGetClock("seconds")
126126
.should("have.prop", "valueNow", 13);
127127

128+
cy.get<TimePicker>("@timePicker")
129+
.shadow()
130+
.find("[ui5-responsive-popover]")
131+
.find("[ui5-time-selection-clocks]")
132+
.shadow()
133+
.find("[ui5-toggle-spin-button]")
134+
.first()
135+
.realClick()
136+
.should("be.focused");
137+
128138
cy.realType("092233");
129139

130140
cy.get<TimePicker>("@timePicker")

packages/main/src/TimePicker.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import {
6161
TIMEPICKER_PATTERN_MISSMATCH,
6262
TIMEPICKER_OPEN_ICON_TITLE_OPENED,
6363
TIMEPICKER_OPEN_ICON_TITLE,
64+
INPUT_SUGGESTIONS_TITLE,
6465
} from "./generated/i18n/i18n-defaults.js";
6566

6667
// Styles
@@ -834,6 +835,22 @@ class TimePicker extends UI5Element implements IFormInputElement {
834835
return this.valueStateMessage.length > 0 && !this.open && !this._isMobileDevice;
835836
}
836837

838+
get _headerTitleText() {
839+
return this.ariaLabelText || TimePicker.i18nBundle.getText(INPUT_SUGGESTIONS_TITLE);
840+
}
841+
842+
get showHeader() {
843+
return isPhone();
844+
}
845+
846+
/**
847+
* Defines whether the dialog on mobile should have header
848+
* @private
849+
*/
850+
get _shouldHideHeader() {
851+
return !this.showHeader && !this.hasValueStateText;
852+
}
853+
837854
/**
838855
* @protected
839856
*/

packages/main/src/TimePickerPopoverTemplate.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Icon from "./Icon.js";
55
import ResponsivePopover from "./ResponsivePopover.js";
66
import TimeSelectionClocks from "./TimeSelectionClocks.js";
77
import TimeSelectionInputs from "./TimeSelectionInputs.js";
8+
import decline from "@ui5/webcomponents-icons/dist/decline.js";
89
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
910
import error from "@ui5/webcomponents-icons/dist/error.js";
1011
import alert from "@ui5/webcomponents-icons/dist/alert.js";
@@ -22,7 +23,7 @@ export default function TimePickerPopoverTemplate(this: TimePicker) {
2223
opener={this}
2324
open={this.open}
2425
allowTargetOverlap={true}
25-
_hideHeader={!this.hasValueStateText}
26+
_hideHeader={this._shouldHideHeader}
2627
hideArrow={true}
2728
accessibleName={this.pickerAccessibleName}
2829
onClose={this.onResponsivePopoverAfterClose}
@@ -31,6 +32,8 @@ export default function TimePickerPopoverTemplate(this: TimePicker) {
3132
onWheel={this._handleWheel}
3233
onKeyDown={this._onkeydown}
3334
>
35+
{ !!this.showHeader && defaultHeader.call(this) }
36+
3437
{ this.shouldDisplayValueStateMessageInResponsivePopover && valueStateTextHeader.call(this) }
3538

3639
<TimeSelectionClocks
@@ -61,7 +64,7 @@ export default function TimePickerPopoverTemplate(this: TimePicker) {
6164
onWheel={this._handleWheel}
6265
onKeyDown={this._onkeydown}
6366
>
64-
{ this.hasValueStateText && valueStateTextHeader.call(this, { "width": "100%" }) }
67+
{ this.hasValueStateText && valueStateTextHeader.call(this) }
6568

6669
<div class="popover-content">
6770
<TimeSelectionInputs
@@ -83,20 +86,37 @@ export default function TimePickerPopoverTemplate(this: TimePicker) {
8386
);
8487
}
8588

89+
function defaultHeader(this: TimePicker) {
90+
return (
91+
<div slot="header" class="ui5-responsive-popover-header">
92+
<div class="row">
93+
<span>{this._headerTitleText}</span>
94+
<Button
95+
class="ui5-responsive-popover-close-btn"
96+
icon={decline}
97+
design="Transparent"
98+
onClick={this._togglePicker}
99+
>
100+
</Button>
101+
</div>
102+
</div>
103+
);
104+
}
105+
86106
function valueStateMessage(this: TimePicker) {
87107
return (
88108
this.shouldDisplayDefaultValueStateMessage ? this.valueStateDefaultText : <slot name="valueStateMessage"></slot>
89109
);
90110
}
91111

92-
function valueStateTextHeader(this: TimePicker, style?: Record<string, string>) {
112+
function valueStateTextHeader(this: TimePicker) {
93113
if (!this.hasValueStateText) {
94114
return;
95115
}
96116

97117
return (
98118
<div
99-
slot="header"
119+
slot={!this.showHeader ? "header" : undefined}
100120
class={{
101121
"ui5-popover-header": true,
102122
"ui5-valuestatemessage-header": true,
@@ -106,7 +126,6 @@ function valueStateTextHeader(this: TimePicker, style?: Record<string, string>)
106126
"ui5-valuestatemessage--warning": this.valueState === ValueState.Critical,
107127
"ui5-valuestatemessage--information": this.valueState === ValueState.Information,
108128
}}
109-
style={style}
110129
>
111130
<Icon class="ui5-input-value-state-message-icon" name={valueStateMessageInputIcon.call(this)}/>
112131
{ valueStateMessage.call(this) }

0 commit comments

Comments
 (0)