Skip to content

Commit 2ee134c

Browse files
committed
Merge remote-tracking branch 'origin/main' into list-add-sticky-header
2 parents e345b56 + 878d8a3 commit 2ee134c

63 files changed

Lines changed: 1731 additions & 298 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
# [2.18.0-rc.0](https://github.com/UI5/webcomponents/compare/v2.17.0...v2.18.0-rc.0) (2025-12-11)
7+
8+
9+
### Bug Fixes
10+
11+
* **ui5-button:** fix end-icon margin ([#12777](https://github.com/UI5/webcomponents/issues/12777)) ([4a52be6](https://github.com/UI5/webcomponents/commit/4a52be6b82adfd4e8fe91616e995a3ead15c6919)), closes [#12710](https://github.com/UI5/webcomponents/issues/12710)
12+
* **ui5-button:** set "type" property in accessibilityInfo with correct value. ([#12759](https://github.com/UI5/webcomponents/issues/12759)) ([337d97b](https://github.com/UI5/webcomponents/commit/337d97b485bfd9c6ea2fc3fd294e2d1e93370ea8)), closes [#12750](https://github.com/UI5/webcomponents/issues/12750)
13+
* **ui5-date-time-picker:** correct initial focus on small screens ([#12752](https://github.com/UI5/webcomponents/issues/12752)) ([1884137](https://github.com/UI5/webcomponents/commit/1884137632a0563f3a4eae45011216c8eb3c5435))
14+
* **ui5-datetime-picker:** show header on mobile mode ([#12746](https://github.com/UI5/webcomponents/issues/12746)) ([7bdad89](https://github.com/UI5/webcomponents/commit/7bdad891f1196aebb4a227b7bee1f6135cf5ce2d)), closes [#12724](https://github.com/UI5/webcomponents/issues/12724)
15+
* **ui5-popover:** render block layers in the correct order ([#12659](https://github.com/UI5/webcomponents/issues/12659)) ([43e545a](https://github.com/UI5/webcomponents/commit/43e545a4a5e486f19fb52ae18fe7c162680cf56e))
16+
* **ui5-step-input:** prevent false validation error with valuePrecision ([#12778](https://github.com/UI5/webcomponents/issues/12778)) ([08f8e35](https://github.com/UI5/webcomponents/commit/08f8e353a3e2f0ede3aa8239e3ef89dce7c5e70e))
17+
* **ui5-time-picker:** show header on mobile ([#12768](https://github.com/UI5/webcomponents/issues/12768)) ([8447e0d](https://github.com/UI5/webcomponents/commit/8447e0d052a5a380ff2e9e49fd3537678dd60da7)), closes [#12695](https://github.com/UI5/webcomponents/issues/12695)
18+
19+
20+
### Features
21+
22+
* **ui5-li-custom:** enhance arrow key navigation ([#12700](https://github.com/UI5/webcomponents/issues/12700)) ([f672e13](https://github.com/UI5/webcomponents/commit/f672e130aff2db2bdea62ed05de52ebaeacc7ae8)), closes [#11987](https://github.com/UI5/webcomponents/issues/11987)
23+
* **ui5-link:** add default text slot ([#12781](https://github.com/UI5/webcomponents/issues/12781)) ([6bc4f0a](https://github.com/UI5/webcomponents/commit/6bc4f0a41de164f4aa504fff99719c361f953d80))
24+
25+
26+
27+
28+
629
# [2.17.0](https://github.com/UI5/webcomponents/compare/v2.17.0-rc.5...v2.17.0) (2025-12-05)
730

831

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"packages/create-package",
1515
"packages/compat"
1616
],
17-
"version": "2.17.0",
17+
"version": "2.18.0-rc.0",
1818
"command": {
1919
"publish": {
2020
"allowBranch": "*",

packages/ai/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
# [2.18.0-rc.0](https://github.com/UI5/webcomponents/compare/v2.17.0...v2.18.0-rc.0) (2025-12-11)
7+
8+
**Note:** Version bump only for package @ui5/webcomponents-ai
9+
10+
11+
12+
13+
614
# [2.17.0](https://github.com/UI5/webcomponents/compare/v2.17.0-rc.5...v2.17.0) (2025-12-05)
715

816
**Note:** Version bump only for package @ui5/webcomponents-ai

packages/ai/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ui5/webcomponents-ai",
3-
"version": "2.17.0",
3+
"version": "2.18.0-rc.0",
44
"description": "UI5 Web Components: webcomponents.ai",
55
"ui5": {
66
"webComponentsPackage": true
@@ -46,15 +46,15 @@
4646
"directory": "packages/ai"
4747
},
4848
"dependencies": {
49-
"@ui5/webcomponents": "2.17.0",
50-
"@ui5/webcomponents-base": "2.17.0",
51-
"@ui5/webcomponents-icons": "2.17.0",
52-
"@ui5/webcomponents-theming": "2.17.0"
49+
"@ui5/webcomponents": "2.18.0-rc.0",
50+
"@ui5/webcomponents-base": "2.18.0-rc.0",
51+
"@ui5/webcomponents-icons": "2.18.0-rc.0",
52+
"@ui5/webcomponents-theming": "2.18.0-rc.0"
5353
},
5454
"devDependencies": {
5555
"@custom-elements-manifest/analyzer": "^0.10.10",
5656
"@ui5/cypress-internal": "0.1.0",
57-
"@ui5/webcomponents-tools": "2.17.0",
57+
"@ui5/webcomponents-tools": "2.18.0-rc.0",
5858
"cypress": "^15.3.0",
5959
"vite": "5.4.21"
6060
}

packages/base/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
# [2.18.0-rc.0](https://github.com/UI5/webcomponents/compare/v2.17.0...v2.18.0-rc.0) (2025-12-11)
7+
8+
9+
### Bug Fixes
10+
11+
* **ui5-popover:** render block layers in the correct order ([#12659](https://github.com/UI5/webcomponents/issues/12659)) ([43e545a](https://github.com/UI5/webcomponents/commit/43e545a4a5e486f19fb52ae18fe7c162680cf56e))
12+
13+
14+
15+
16+
617
# [2.17.0](https://github.com/UI5/webcomponents/compare/v2.17.0-rc.5...v2.17.0) (2025-12-05)
718

819

packages/base/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ui5/webcomponents-base",
3-
"version": "2.17.0",
3+
"version": "2.18.0-rc.0",
44
"description": "UI5 Web Components: webcomponents.base",
55
"author": "SAP SE (https://www.sap.com)",
66
"license": "Apache-2.0",
@@ -64,7 +64,7 @@
6464
"@openui5/sap.ui.core": "1.120.17",
6565
"@sap-theming/theming-base-content": "11.29.3",
6666
"@ui5/cypress-internal": "0.1.0",
67-
"@ui5/webcomponents-tools": "2.17.0",
67+
"@ui5/webcomponents-tools": "2.18.0-rc.0",
6868
"clean-css": "^5.2.2",
6969
"cypress": "^15.3.0",
7070
"mocha": "^11.7.2",

packages/base/src/css/OpenUI5PopupStyles.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22
border: none;
33
overflow: visible;
44
margin: 0;
5+
}
6+
7+
.sapUiBLy[popover] {
8+
width: 100%;
9+
height: 100%;
510
}

packages/base/src/features/OpenUI5Support.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
removeOpenedPopup,
77
getTopmostPopup,
88
} from "./patchPopup.js";
9-
import type { OpenUI5Popup, OpenUI5PopupBasedControl, PopupInfo } from "./patchPopup.js";
9+
import type { OpenUI5PopupClass, OpenUI5DialogClass, PopupInfo } from "./patchPopup.js";
1010
import { registerFeature } from "../FeaturesRegistry.js";
1111
import { setTheme } from "../config/Theme.js";
1212
import type { CLDRData } from "../asset-registries/LocaleData.js";
@@ -110,7 +110,7 @@ class OpenUI5Support {
110110
"sap/ui/core/date/CalendarUtils",
111111
];
112112
}
113-
window.sap.ui.require(deps, (Popup: OpenUI5Popup, Dialog: OpenUI5PopupBasedControl, Patcher: OpenUI5Patcher) => {
113+
window.sap.ui.require(deps, (Popup: OpenUI5PopupClass, Dialog: OpenUI5DialogClass, Patcher: OpenUI5Patcher) => {
114114
patchPatcher(Patcher);
115115
patchPopup(Popup, Dialog);
116116
resolve();

packages/base/src/features/patchPopup.ts

Lines changed: 103 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,31 @@ type Control = {
88

99
// The lifecycle of Popup.js is open -> _opened -> close -> _closed, we're interested in the first (open) and last (_closed)
1010
type OpenUI5Popup = {
11-
prototype: {
12-
open: (...args: any[]) => void,
13-
_closed: (...args: any[]) => void,
14-
getOpenState: () => "CLOSED" | "CLOSING" | "OPEN" | "OPENING",
15-
getContent: () => Control | HTMLElement | null, // this is the OpenUI5 Element/Control instance that opens the Popup (usually sap.m.Popover/sap.m.Dialog)
16-
onFocusEvent: (...args: any[]) => void,
17-
}
11+
open: (...args: any[]) => void,
12+
_closed: (...args: any[]) => void,
13+
getOpenState: () => "CLOSED" | "CLOSING" | "OPEN" | "OPENING",
14+
getContent: () => Control | HTMLElement | null, // this is the OpenUI5 Element/Control instance that opens the Popup (usually sap.m.Popover/sap.m.Dialog)
15+
onFocusEvent: (...args: any[]) => void,
16+
getModal: () => boolean
1817
};
1918

20-
type OpenUI5PopupBasedControl = {
19+
type OpenUI5PopupClass = {
20+
prototype: OpenUI5Popup
21+
};
22+
23+
type OpenUI5DialogClass = {
2124
prototype: {
2225
onsapescape: (...args: any[]) => void,
2326
oPopup: OpenUI5Popup,
2427
}
2528
};
2629

2730
type PopupInfo = {
28-
type: "OpenUI5" | "WebComponent";
31+
type: "WebComponent";
2932
instance: object;
33+
} | {
34+
type: "OpenUI5";
35+
instance: OpenUI5Popup;
3036
};
3137

3238
// contains all OpenUI5 and Web Component popups that are currently opened
@@ -38,12 +44,20 @@ const addOpenedPopup = (popupInfo: PopupInfo) => {
3844

3945
const removeOpenedPopup = (popup: object) => {
4046
const index = AllOpenedPopupsRegistry.openedRegistry.findIndex(el => el.instance === popup);
47+
48+
if (index === AllOpenedPopupsRegistry.openedRegistry.length - 1) {
49+
fixTopmostOpenUI5Popup();
50+
}
51+
4152
if (index > -1) {
4253
AllOpenedPopupsRegistry.openedRegistry.splice(index, 1);
4354
}
4455
};
4556

4657
const getTopmostPopup = () => {
58+
if (AllOpenedPopupsRegistry.openedRegistry.length === 0) {
59+
return null;
60+
}
4761
return AllOpenedPopupsRegistry.openedRegistry[AllOpenedPopupsRegistry.openedRegistry.length - 1].instance;
4862
};
4963

@@ -68,16 +82,83 @@ const hasWebComponentPopupAbove = (popup: object) => {
6882
return false;
6983
};
7084

71-
const openNativePopover = (domRef: HTMLElement) => {
85+
const getPopupContentElement = (popup: OpenUI5Popup): HTMLElement | null => {
86+
const content = popup.getContent();
87+
return content instanceof HTMLElement ? content : content?.getDomRef() || null;
88+
};
89+
90+
const openNativePopoverForOpenUI5 = (popup: OpenUI5Popup) => {
91+
const openingInitiated = ["OPENING", "OPEN"].includes(popup.getOpenState());
92+
if (!openingInitiated || !isNativePopoverOpen()) {
93+
return;
94+
}
95+
96+
const domRef = getPopupContentElement(popup);
97+
98+
if (!domRef) {
99+
return;
100+
}
101+
102+
const openUI5BlockLayer = document.getElementById("sap-ui-blocklayer-popup");
103+
104+
if (popup.getModal() && openUI5BlockLayer) {
105+
openUI5BlockLayer.setAttribute("popover", "manual");
106+
openUI5BlockLayer.hidePopover();
107+
openUI5BlockLayer.showPopover();
108+
}
109+
72110
domRef.setAttribute("popover", "manual");
73111
domRef.showPopover();
74112
};
75113

76-
const closeNativePopover = (domRef: HTMLElement) => {
114+
const closeNativePopoverForOpenUI5 = (popup: OpenUI5Popup) => {
115+
const domRef = getPopupContentElement(popup);
116+
117+
if (!domRef) {
118+
return;
119+
}
120+
77121
if (domRef.hasAttribute("popover")) {
78122
domRef.hidePopover();
79123
domRef.removeAttribute("popover");
80124
}
125+
126+
if (getTopmostPopup() !== popup) {
127+
return;
128+
}
129+
130+
// The OpenUI5 block layer is only one for all modal OpenUI5 popups,
131+
// and it is displayed above all opened pupups - OpenUI5 and Web Components,
132+
// as a result, we need to hide this block layer.
133+
// If the underlying popup is a Web Component - it is displayed like a native popover, and we don't need to do anything
134+
// If the underlying popup is an OpenUI5 popup, it will be fixed in fixTopmostOpenUI5Popup method.
135+
if (popup.getModal()) {
136+
const openUI5BlockLayer = document.getElementById("sap-ui-blocklayer-popup");
137+
if (openUI5BlockLayer && openUI5BlockLayer.hasAttribute("popover")) {
138+
openUI5BlockLayer.hidePopover();
139+
}
140+
}
141+
};
142+
143+
const fixTopmostOpenUI5Popup = () => {
144+
if (!isNativePopoverOpen()) {
145+
return;
146+
}
147+
148+
const prevPopup = AllOpenedPopupsRegistry.openedRegistry[AllOpenedPopupsRegistry.openedRegistry.length - 2];
149+
if (!prevPopup
150+
|| prevPopup.type !== "OpenUI5"
151+
|| !prevPopup.instance.getModal()) {
152+
return;
153+
}
154+
155+
const content = getPopupContentElement(prevPopup.instance);
156+
const openUI5BlockLayer = document.getElementById("sap-ui-blocklayer-popup");
157+
158+
content?.hidePopover();
159+
openUI5BlockLayer?.showPopover();
160+
161+
content?.showPopover();
81162
};
82163

83164
const isNativePopoverOpen = (root: Document | ShadowRoot = document): boolean => {
@@ -91,9 +172,9 @@ const isNativePopoverOpen = (root: Document | ShadowRoot = document): boolean =>
91172
});
92173
};
93174

94-
const patchPopupBasedControl = (PopupBasedControl: OpenUI5PopupBasedControl) => {
95-
const origOnsapescape = PopupBasedControl.prototype.onsapescape;
96-
PopupBasedControl.prototype.onsapescape = function onsapescape(...args: any[]) {
175+
const patchDialog = (Dialog: OpenUI5DialogClass) => {
176+
const origOnsapescape = Dialog.prototype.onsapescape;
177+
Dialog.prototype.onsapescape = function onsapescape(...args: any[]) {
97178
if (hasWebComponentPopupAbove(this.oPopup)) {
98179
return;
99180
}
@@ -102,21 +183,11 @@ const patchPopupBasedControl = (PopupBasedControl: OpenUI5PopupBasedControl) =>
102183
};
103184
};
104185

105-
const patchOpen = (Popup: OpenUI5Popup) => {
186+
const patchOpen = (Popup: OpenUI5PopupClass) => {
106187
const origOpen = Popup.prototype.open;
107188
Popup.prototype.open = function open(...args: any[]) {
108189
origOpen.apply(this, args); // call open first to initiate opening
109-
const topLayerAlreadyInUse = isNativePopoverOpen();
110-
const openingInitiated = ["OPENING", "OPEN"].includes(this.getOpenState());
111-
if (openingInitiated && topLayerAlreadyInUse) {
112-
const element = this.getContent();
113-
if (element) {
114-
const domRef = element instanceof HTMLElement ? element : element?.getDomRef();
115-
if (domRef) {
116-
openNativePopover(domRef);
117-
}
118-
}
119-
}
190+
openNativePopoverForOpenUI5(this);
120191

121192
addOpenedPopup({
122193
type: "OpenUI5",
@@ -125,21 +196,16 @@ const patchOpen = (Popup: OpenUI5Popup) => {
125196
};
126197
};
127198

128-
const patchClosed = (Popup: OpenUI5Popup) => {
199+
const patchClosed = (Popup: OpenUI5PopupClass) => {
129200
const _origClosed = Popup.prototype._closed;
130201
Popup.prototype._closed = function _closed(...args: any[]) {
131-
const element = this.getContent();
132-
const domRef = element instanceof HTMLElement ? element : element?.getDomRef();
202+
closeNativePopoverForOpenUI5(this);
133203
_origClosed.apply(this, args); // only then call _close
134-
if (domRef) {
135-
closeNativePopover(domRef); // unset the popover attribute and close the native popover, but only if still in DOM
136-
}
137-
138204
removeOpenedPopup(this);
139205
};
140206
};
141207

142-
const patchFocusEvent = (Popup: OpenUI5Popup) => {
208+
const patchFocusEvent = (Popup: OpenUI5PopupClass) => {
143209
const origFocusEvent = Popup.prototype.onFocusEvent;
144210
Popup.prototype.onFocusEvent = function onFocusEvent(...args: any[]) {
145211
if (!hasWebComponentPopupAbove(this)) {
@@ -154,13 +220,13 @@ const createGlobalStyles = () => {
154220
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
155221
};
156222

157-
const patchPopup = (Popup: OpenUI5Popup, Dialog: OpenUI5PopupBasedControl) => {
223+
const patchPopup = (Popup: OpenUI5PopupClass, Dialog: OpenUI5DialogClass) => {
158224
insertOpenUI5PopupStyles();
159225
patchOpen(Popup); // Popup.prototype.open
160226
patchClosed(Popup); // Popup.prototype._closed
161227
createGlobalStyles(); // Ensures correct popover positioning by OpenUI5 (otherwise 0,0 is the center of the screen)
162228
patchFocusEvent(Popup);// Popup.prototype.onFocusEvent
163-
patchPopupBasedControl(Dialog); // Dialog.prototype.onsapescape
229+
patchDialog(Dialog); // Dialog.prototype.onsapescape
164230
};
165231

166232
export {
@@ -170,4 +236,4 @@ export {
170236
getTopmostPopup,
171237
};
172238

173-
export type { OpenUI5Popup, OpenUI5PopupBasedControl, PopupInfo };
239+
export type { OpenUI5PopupClass, OpenUI5DialogClass, PopupInfo };

packages/compat/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
# [2.18.0-rc.0](https://github.com/UI5/webcomponents/compare/v2.17.0...v2.18.0-rc.0) (2025-12-11)
7+
8+
**Note:** Version bump only for package @ui5/webcomponents-compat
9+
10+
11+
12+
13+
614
# [2.17.0](https://github.com/UI5/webcomponents/compare/v2.17.0-rc.5...v2.17.0) (2025-12-05)
715

816

0 commit comments

Comments
 (0)