From d81db390e86199658f28a0f44acdfd7d911f7747 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Wed, 3 Jun 2026 17:04:36 +0300 Subject: [PATCH 1/9] feat(ui5-dialog): focus goes on entire dialog for drag and resize operations JIRA: BGSOFUIRODOPI-3659 --- packages/main/src/Dialog.ts | 79 +++++++++++++++++-- packages/main/src/DialogTemplate.tsx | 42 ++++++---- .../main/src/i18n/messagebundle.properties | 25 ++++++ packages/main/src/themes/Dialog.css | 31 ++++++-- .../src/themes/base/Dialog-parameters.css | 2 + 5 files changed, 151 insertions(+), 28 deletions(-) diff --git a/packages/main/src/Dialog.ts b/packages/main/src/Dialog.ts index 89bd2b46ca4b..1f4e901dc82e 100644 --- a/packages/main/src/Dialog.ts +++ b/packages/main/src/Dialog.ts @@ -18,10 +18,17 @@ import "@ui5/webcomponents-icons/dist/sys-enter-2.js"; import "@ui5/webcomponents-icons/dist/information.js"; import { - DIALOG_HEADER_ARIA_ROLE_DESCRIPTION, DIALOG_HEADER_ARIA_DESCRIBEDBY_RESIZABLE, DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE, DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE, + DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE, + DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE, + DIALOG_ARIA_DESCRIBEDBY_RESIZABLE, + DIALOG_RESIZE_HANDLE_TOOLTIP, + DIALOG_DRAG_AND_RESIZE_HANDLE_ARIA_LABEL, + DIALOG_DRAG_HANDLE_ARIA_LABEL, + DIALOG_RESIZE_HANDLE_ARIA_LABEL, + DIALOG_HANDLE_ARIA_ROLEDESCRIPTION, } from "./generated/i18n/i18n-defaults.js"; // Template @@ -252,12 +259,33 @@ class Dialog extends Popup { return ariaLabelledById; } - get ariaRoleDescriptionHeaderText() { - return (this.resizable || this.draggable) ? Dialog.i18nBundle.getText(DIALOG_HEADER_ARIA_ROLE_DESCRIPTION) : undefined; + get effectiveAriaDescribedBy() { + return this._movable ? `${this._id}-dialog-descr` : undefined; } - get effectiveAriaDescribedBy() { - return (this.resizable || this.draggable) ? `${this._id}-descr` : undefined; + get ariaDescribedByIds() { + return [ + this.ariaDescriptionTextId, + this.effectiveAriaDescribedBy, + ].filter(Boolean).join(" "); + } + + get dialogAriaDescribedByText() { + if (!this._movable) { + return ""; + } + + if (this.resizable && this.draggable) { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE); + } + if (this.draggable) { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE); + } + if (this.resizable) { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_RESIZABLE); + } + + return ""; } get ariaDescribedByHeaderTextResizable() { @@ -284,13 +312,47 @@ class Dialog extends Popup { } get _headerTabIndex() { + return undefined; + } + + get _dragResizeHandleTabIndex() { return this._movable ? 0 : undefined; } + get _dragResizeHandleAriaLabel() { + if (!this._movable) { + return ""; + } + + if (this.resizable && this.draggable) { + return Dialog.i18nBundle.getText(DIALOG_DRAG_AND_RESIZE_HANDLE_ARIA_LABEL); + } + if (this.draggable) { + return Dialog.i18nBundle.getText(DIALOG_DRAG_HANDLE_ARIA_LABEL); + } + if (this.resizable) { + return Dialog.i18nBundle.getText(DIALOG_RESIZE_HANDLE_ARIA_LABEL); + } + + return ""; + } + + get _dragResizeHandleAriaRoleDescription() { + return this._movable ? Dialog.i18nBundle.getText(DIALOG_HANDLE_ARIA_ROLEDESCRIPTION) : undefined; + } + + get _dragResizeHandleAriaDescribedBy() { + return this._movable ? `${this._id}-descr` : undefined; + } + get _showResizeHandle() { return this.resizable && this.onDesktop; } + get _resizeHandleTooltip() { + return this._showResizeHandle ? Dialog.i18nBundle.getText(DIALOG_RESIZE_HANDLE_TOOLTIP) : undefined; + } + get _minHeight() { let minHeight = Number.parseInt(window.getComputedStyle(this.contentDOM).minHeight); @@ -470,7 +532,12 @@ class Dialog extends Popup { } _onDragOrResizeKeyDown(e: KeyboardEvent) { - if (!this._movable || !Dialog._isHeader(e.target as HTMLElement)) { + if (!this._movable) { + return; + } + + const target = e.target as HTMLElement; + if (!target || target.id !== `${this._id}-dragResizeHandler`) { return; } diff --git a/packages/main/src/DialogTemplate.tsx b/packages/main/src/DialogTemplate.tsx index 31bdd6f54300..2fa65078cdd8 100644 --- a/packages/main/src/DialogTemplate.tsx +++ b/packages/main/src/DialogTemplate.tsx @@ -18,11 +18,6 @@ function beforeContent(this: Dialog) {
{this.headerText} } - - {this.resizable ? - this.draggable ? - - : - - : - this.draggable && - - }
} @@ -62,9 +47,36 @@ function afterContent(this: Dialog) {
} + {this._movable && + <> + + {this.resizable ? + this.draggable ? + + : + + : + this.draggable && + + } + {this.dialogAriaDescribedByText && + + } + + } ); } diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index b43e02c4c878..f86c9b043522 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -840,6 +840,31 @@ DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE=Use Arrow keys to move #XACT: ARIA announcement for describedby attribute of draggable and resizable Dialog header DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE=Use Arrow keys to move, Shift+Arrow keys to resize + +#XACT: ARIA announcement for describedby attribute informing users how to reach drag and resize handle +DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE=Tab to the end of dialog to reach drag and resize handle. + +#XACT: ARIA announcement for describedby attribute informing users how to reach drag handle +DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE=Tab to the end of dialog to reach drag handle. + +#XACT: ARIA announcement for describedby attribute informing users how to reach resize handle +DIALOG_ARIA_DESCRIBEDBY_RESIZABLE=Tab to the end of dialog to reach resize handle. + +#XACT: Tooltip for the resize handle icon in the Dialog +DIALOG_RESIZE_HANDLE_TOOLTIP=Drag handle to resize (Shift+Arrow) + +#XACT: ARIA label for drag and resize handle +DIALOG_DRAG_AND_RESIZE_HANDLE_ARIA_LABEL=Drag and resize dialog + +#XACT: ARIA label for drag handle +DIALOG_DRAG_HANDLE_ARIA_LABEL=Drag dialog + +#XACT: ARIA label for resize handle +DIALOG_RESIZE_HANDLE_ARIA_LABEL=Resize dialog + +#XACT: ARIA role description for drag/resize handle +DIALOG_HANDLE_ARIA_ROLEDESCRIPTION=Handle + #XFLD: A colon to separate the "label" from an input. In some languages there might be a different symbol used for such a colon LABEL_COLON=: diff --git a/packages/main/src/themes/Dialog.css b/packages/main/src/themes/Dialog.css index a99dfbbcb206..72defd5111fa 100644 --- a/packages/main/src/themes/Dialog.css +++ b/packages/main/src/themes/Dialog.css @@ -102,17 +102,34 @@ outline: none; } -:host([desktop]) .ui5-popup-header-root:focus:after, -.ui5-popup-header-root:focus-visible:after { +.ui5-popup-drag-resize-handler { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.ui5-popup-drag-resize-handler:focus { + outline: none; +} + +.ui5-popup-root:has(.ui5-popup-drag-resize-handler:focus)::before { content: ''; position: absolute; - left: var(--_ui5_dialog_header_focus_left_offset); - bottom: var(--_ui5_dialog_header_focus_bottom_offset); - right: var(--_ui5_dialog_header_focus_right_offset); - top: var(--_ui5_dialog_header_focus_top_offset); + inset: var(--_ui5_dialog_focus_outline_offset); border: var(--sapContent_FocusWidth) var(--sapContent_FocusStyle) var(--sapContent_FocusColor); - border-radius: var(--_ui5_dialog_header_border_radius) var(--_ui5_dialog_header_border_radius) 0 0; + border-radius: var(--sapElement_BorderCornerRadius); pointer-events: none; + z-index: 5; +} + +:host([resizable]) .ui5-popup-root:has(.ui5-popup-drag-resize-handler:focus)::before { + border-end-end-radius: var(--_ui5_dialog_resizable_bottom_right_radius); } :host([stretch]) .ui5-popup-content { diff --git a/packages/main/src/themes/base/Dialog-parameters.css b/packages/main/src/themes/base/Dialog-parameters.css index c001a627e2db..7ce95a6c2f9e 100644 --- a/packages/main/src/themes/base/Dialog-parameters.css +++ b/packages/main/src/themes/base/Dialog-parameters.css @@ -5,4 +5,6 @@ --_ui5_dialog_header_focus_right_offset: 2px; --_ui5_dialog_header_border_radius: 0px; --_ui5_dialog_header_state_line_height: 0.0625rem; + --_ui5_dialog_focus_outline_offset: 0.0625rem; + --_ui5_dialog_resizable_bottom_right_radius: 1.75rem; } From 1ee962cc908f91f7acc2da77cc537993029a9fe6 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Thu, 4 Jun 2026 15:52:45 +0300 Subject: [PATCH 2/9] fix: cypress tests update --- packages/main/cypress/specs/Dialog.cy.tsx | 57 ++++++++++++----------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index 686ad9cef953..3674bd78ca28 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -580,11 +580,11 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Move dialog up using keyboard - cy.get("#header-slot").realClick(); + // Act - Focus the drag/resize handle and move dialog up using keyboard + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#header-slot").focused().realPress("{uparrow}"); - cy.get("#header-slot").focused().realPress("{uparrow}"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{uparrow}"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{uparrow}"); // Assert - Top position changes, left remains the same @@ -599,10 +599,10 @@ describe("Dialog general interaction", () => { }) // Act - Move dialog left using keyboard - cy.get("#header-slot").realClick(); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#header-slot").focused().realPress("{leftarrow}"); - cy.get("#header-slot").focused().realPress("{leftarrow}"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{leftarrow}"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{leftarrow}"); // Assert - Left position changes, top remains the same cy.get("#draggable-dialog") @@ -776,8 +776,8 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Resize height using keyboard - cy.get("#resizable-dialog").shadow().find(".ui5-popup-resize-handle").click(); + // Act - Focus the drag/resize handle and resize height using keyboard + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); cy.get("#resizable-dialog").realPress(["Shift", "ArrowDown"]); // Assert - Height changes, width and position remain the same @@ -790,8 +790,8 @@ describe("Dialog general interaction", () => { expect(heightAfterResizeHeight).not.to.equal(initialHeight); expect(leftAfterResizeHeight).to.equal(initialLeft); - // Act - Resize width using keyboard - cy.get("#resizable-dialog").shadow().find(".ui5-popup-resize-handle").click(); + // Act - Focus the drag/resize handle and resize width using keyboard + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); cy.get("#resizable-dialog").realPress(["Shift", "ArrowRight"]); // Assert - Width changes, height and position remain the same @@ -1078,30 +1078,33 @@ describe("Acc", () => { cy.get("#draggable-dialog").invoke("attr", "open", true); cy.get("#draggable-dialog").ui5DialogOpened(); - // Assert aria-labelledby and aria attributes + // Assert aria-label on the dialog root cy.get("#draggable-dialog") .shadow() .find(".ui5-popup-root") .should("have.attr", "aria-label", "Draggable"); + // Assert aria-describedby is on the drag/resize handle, not the header cy.get("#draggable-dialog") .shadow() - .find(".ui5-popup-header-root") + .find(".ui5-popup-drag-resize-handler") .should("have.attr", "aria-describedby"); + // Assert hidden text contains keyboard instructions cy.get("#draggable-dialog") .shadow() .find(".ui5-hidden-text") .should("exist") .then(hiddenText => { - const valueOfTheHiddenText = hiddenText.text(); + const valueOfTheHiddenText = hiddenText.first().text(); cy.wrap(valueOfTheHiddenText).should("equal", "Use Arrow keys to move"); }); + // Assert aria-roledescription on the drag/resize handle cy.get("#draggable-dialog") .shadow() - .find(".ui5-popup-header-root") - .should("have.attr", "aria-roledescription", "Interactive Header"); + .find(".ui5-popup-drag-resize-handler") + .should("have.attr", "aria-roledescription", "Handle"); }); it("tests aria-describedby for default header", () => { @@ -1119,10 +1122,10 @@ describe("Acc", () => { cy.get("#resizable-dialog").invoke("attr", "open", true); cy.get("#resizable-dialog").ui5DialogOpened(); - // Assert aria-describedby and aria-roledescription attributes + // Assert aria-describedby is on the drag/resize handle cy.get("#resizable-dialog") .shadow() - .find(".ui5-popup-header-root") + .find(".ui5-popup-drag-resize-handler") .should("have.attr", "aria-describedby") .then($el => { cy.get("#resizable-dialog") @@ -1130,15 +1133,16 @@ describe("Acc", () => { .find(".ui5-hidden-text") .should("exist") .then(hiddenText => { - const valueOfTheHiddenText = hiddenText.text(); + const valueOfTheHiddenText = hiddenText.first().text(); cy.wrap(valueOfTheHiddenText).should("equal", "Use Shift+Arrow keys to resize"); }); }); + // Assert aria-roledescription on the drag/resize handle cy.get("#resizable-dialog") .shadow() - .find(".ui5-popup-header-root") - .should("have.attr", "aria-roledescription", "Interactive Header"); + .find(".ui5-popup-drag-resize-handler") + .should("have.attr", "aria-roledescription", "Handle"); }); @@ -1157,10 +1161,10 @@ describe("Acc", () => { cy.get("#resizable-dialog-custom-header").invoke("attr", "open", true); cy.get("#resizable-dialog-custom-header").ui5DialogOpened(); - // Assert aria-describedby and aria-roledescription attributes + // Assert aria-describedby is on the drag/resize handle cy.get("#resizable-dialog-custom-header") .shadow() - .find(".ui5-popup-header-root") + .find(".ui5-popup-drag-resize-handler") .should("have.attr", "aria-describedby") .then($el => { cy.get("#resizable-dialog-custom-header") @@ -1168,15 +1172,16 @@ describe("Acc", () => { .find(".ui5-hidden-text") .should("exist") .then(hiddenText => { - const valueOfTheHiddenText = hiddenText.text(); + const valueOfTheHiddenText = hiddenText.first().text(); cy.wrap(valueOfTheHiddenText).should("equal", "Use Shift+Arrow keys to resize"); }); }); + // Assert aria-roledescription on the drag/resize handle cy.get("#resizable-dialog-custom-header") .shadow() - .find(".ui5-popup-header-root") - .should("have.attr", "aria-roledescription", "Interactive Header"); + .find(".ui5-popup-drag-resize-handler") + .should("have.attr", "aria-roledescription", "Handle"); }); it("tests accessibleName-ref", () => { From c3dff78d2f8d5804771729260e47d453f5a0e440 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Fri, 5 Jun 2026 12:27:43 +0300 Subject: [PATCH 3/9] fix: cypress tests --- packages/main/cypress/specs/Dialog.cy.tsx | 26 ++++++++++------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index 3674bd78ca28..a1022e4b243b 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -580,11 +580,10 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Focus the drag/resize handle and move dialog up using keyboard - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{uparrow}"); - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{uparrow}"); + // Act - Tab to the drag/resize handle and move dialog up + cy.realPress("Tab"); + cy.realPress("{uparrow}"); + cy.realPress("{uparrow}"); // Assert - Top position changes, left remains the same @@ -599,10 +598,8 @@ describe("Dialog general interaction", () => { }) // Act - Move dialog left using keyboard - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{leftarrow}"); - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focused().realPress("{leftarrow}"); + cy.realPress("{leftarrow}"); + cy.realPress("{leftarrow}"); // Assert - Left position changes, top remains the same cy.get("#draggable-dialog") @@ -776,9 +773,9 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Focus the drag/resize handle and resize height using keyboard - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#resizable-dialog").realPress(["Shift", "ArrowDown"]); + // Act - Tab to the drag/resize handle and resize height + cy.realPress("Tab"); + cy.realPress(["Shift", "ArrowDown"]); // Assert - Height changes, width and position remain the same cy.get("#resizable-dialog").then(dialogAfterResizeHeight => { @@ -790,9 +787,8 @@ describe("Dialog general interaction", () => { expect(heightAfterResizeHeight).not.to.equal(initialHeight); expect(leftAfterResizeHeight).to.equal(initialLeft); - // Act - Focus the drag/resize handle and resize width using keyboard - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#resizable-dialog").realPress(["Shift", "ArrowRight"]); + // Act - Resize width using keyboard + cy.realPress(["Shift", "ArrowRight"]); // Assert - Width changes, height and position remain the same cy.get("#resizable-dialog").then(dialogAfterResizeWidth => { From 7d7894f7fe7b440a86e4dc7fbdcb1df0a322ed04 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Tue, 9 Jun 2026 15:28:33 +0300 Subject: [PATCH 4/9] fix: correct merge --- packages/main/src/DialogTemplate.tsx | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/main/src/DialogTemplate.tsx b/packages/main/src/DialogTemplate.tsx index af896f1f6fbc..ab5e1f32b6f3 100644 --- a/packages/main/src/DialogTemplate.tsx +++ b/packages/main/src/DialogTemplate.tsx @@ -19,10 +19,6 @@ function beforeContent(this: Dialog) { id="ui5-popup-header" role="region" aria-label={this._headerAriaLabel} - aria-describedby={this.effectiveAriaDescribedBy} - aria-roledescription={this.ariaRoleDescriptionHeaderText} - tabIndex={this._headerTabIndex} - onKeyDown={this._onDragOrResizeKeyDown} onMouseDown={this._onDragMouseDown} part="header" // state={this.state} @@ -35,16 +31,6 @@ function beforeContent(this: Dialog) { : {this.headerText} } - - {this.resizable ? - this.draggable ? - - : - - : - this.draggable && - - } } ); From fa3e44c238fa4067eef9a06f35a9d97c1a1ea7c6 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Wed, 10 Jun 2026 14:14:18 +0300 Subject: [PATCH 5/9] chore: address review comments --- packages/main/cypress/specs/Dialog.cy.tsx | 8 ++--- packages/main/src/Dialog.ts | 32 +++++++++---------- packages/main/src/DialogTemplate.tsx | 6 ++-- .../main/src/i18n/messagebundle.properties | 21 ++++++------ .../src/themes/base/Dialog-parameters.css | 5 --- .../themes/sap_horizon/Dialog-parameters.css | 8 ----- .../sap_horizon_dark/Dialog-parameters.css | 8 ----- 7 files changed, 32 insertions(+), 56 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index 701517022ae1..024c46e13948 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -580,8 +580,8 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Tab to the drag/resize handle and move dialog up - cy.realPress("Tab"); + // Act - Focus drag/resize handle and move dialog up + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); cy.realPress("{uparrow}"); cy.realPress("{uparrow}"); @@ -773,8 +773,8 @@ describe("Dialog general interaction", () => { const initialTop = parseInt(dialog.css("top")); const initialLeft = parseInt(dialog.css("left")); - // Act - Tab to the drag/resize handle and resize height - cy.realPress("Tab"); + // Act - Focus drag/resize handle and resize height + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); cy.realPress(["Shift", "ArrowDown"]); // Assert - Height changes, width and position remain the same diff --git a/packages/main/src/Dialog.ts b/packages/main/src/Dialog.ts index a21304d254af..702dbd55e70f 100644 --- a/packages/main/src/Dialog.ts +++ b/packages/main/src/Dialog.ts @@ -18,12 +18,12 @@ import "@ui5/webcomponents-icons/dist/sys-enter-2.js"; import "@ui5/webcomponents-icons/dist/information.js"; import { - DIALOG_HEADER_ARIA_DESCRIBEDBY_RESIZABLE, - DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE, - DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE, - DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE, - DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE, DIALOG_ARIA_DESCRIBEDBY_RESIZABLE, + DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE, + DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE, + DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE_RESIZABLE, + DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE, + DIALOG_ARIA_DESCRIBEDBY_REACH_RESIZABLE, DIALOG_RESIZE_HANDLE_TOOLTIP, DIALOG_DRAG_AND_RESIZE_HANDLE_ARIA_LABEL, DIALOG_DRAG_HANDLE_ARIA_LABEL, @@ -88,14 +88,14 @@ const ICON_PER_STATE: Record = { * ### Keyboard Handling * * #### Basic Navigation - * When the `ui5-dialog` has the `draggable` property set to `true` and the header is focused, the user can move the dialog + * When the `ui5-dialog` has the `draggable` property set to `true`, the user can move the dialog * with the following keyboard shortcuts: * * - [Up] or [Down] arrow keys - Move the dialog up/down. * - [Left] or [Right] arrow keys - Move the dialog left/right. * * #### Resizing - * When the `ui5-dialog` has the `resizable` property set to `true` and the header is focused, the user can change the size of the dialog + * When the `ui5-dialog` has the `resizable` property set to `true`, the user can change the size of the dialog * with the following keyboard shortcuts: * * - [Shift] + [Up] or [Down] - Decrease/Increase the height of the dialog. @@ -279,28 +279,28 @@ class Dialog extends Popup { } if (this.resizable && this.draggable) { - return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE); + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE_RESIZABLE); } if (this.draggable) { - return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE); + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE); } if (this.resizable) { - return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_RESIZABLE); + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_REACH_RESIZABLE); } return ""; } - get ariaDescribedByHeaderTextResizable() { - return Dialog.i18nBundle.getText(DIALOG_HEADER_ARIA_DESCRIBEDBY_RESIZABLE); + get ariaDescribedByTextResizable() { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_RESIZABLE); } - get ariaDescribedByHeaderTextDraggable() { - return Dialog.i18nBundle.getText(DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE); + get ariaDescribedByTextDraggable() { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE); } - get ariaDescribedByHeaderTextDraggableAndResizable() { - return Dialog.i18nBundle.getText(DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE); + get ariaDescribedByTextDraggableAndResizable() { + return Dialog.i18nBundle.getText(DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE); } /** diff --git a/packages/main/src/DialogTemplate.tsx b/packages/main/src/DialogTemplate.tsx index ab5e1f32b6f3..f3763d1c2350 100644 --- a/packages/main/src/DialogTemplate.tsx +++ b/packages/main/src/DialogTemplate.tsx @@ -71,12 +71,12 @@ function afterContent(this: Dialog) { > {this.resizable ? this.draggable ? - + : - + : this.draggable && - + } {this.dialogAriaDescribedByText && diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 0c0e019aa0c3..6176393b46c1 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -832,26 +832,23 @@ MENU_ITEM_END_CONTENT_ACCESSIBLE_NAME=Additional Actions #XACT: ARIA information for the Menu Item loading state MENU_ITEM_LOADING=Loading -#XACT: ARIA announcement for roldesecription attribute of Dialog header -DIALOG_HEADER_ARIA_ROLE_DESCRIPTION=Interactive Header +#XACT: ARIA announcement for describedby attribute of resizable Dialog +DIALOG_ARIA_DESCRIBEDBY_RESIZABLE=Use Shift+Arrow keys to resize -#XACT: ARIA announcement for describedby attribute of resizable Dialog header -DIALOG_HEADER_ARIA_DESCRIBEDBY_RESIZABLE=Use Shift+Arrow keys to resize +#XACT: ARIA announcement for describedby attribute of draggable Dialog +DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE=Use Arrow keys to move -#XACT: ARIA announcement for describedby attribute of draggable Dialog header -DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE=Use Arrow keys to move - -#XACT: ARIA announcement for describedby attribute of draggable and resizable Dialog header -DIALOG_HEADER_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE=Use Arrow keys to move, Shift+Arrow keys to resize +#XACT: ARIA announcement for describedby attribute of draggable and resizable Dialog +DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE=Use Arrow keys to move, Shift+Arrow keys to resize #XACT: ARIA announcement for describedby attribute informing users how to reach drag and resize handle -DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE_RESIZABLE=Tab to the end of dialog to reach drag and resize handle. +DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE_RESIZABLE=Tab to the end of dialog to reach drag and resize handle. #XACT: ARIA announcement for describedby attribute informing users how to reach drag handle -DIALOG_ARIA_DESCRIBEDBY_DRAGGABLE=Tab to the end of dialog to reach drag handle. +DIALOG_ARIA_DESCRIBEDBY_REACH_DRAGGABLE=Tab to the end of dialog to reach drag handle. #XACT: ARIA announcement for describedby attribute informing users how to reach resize handle -DIALOG_ARIA_DESCRIBEDBY_RESIZABLE=Tab to the end of dialog to reach resize handle. +DIALOG_ARIA_DESCRIBEDBY_REACH_RESIZABLE=Tab to the end of dialog to reach resize handle. #XACT: Tooltip for the resize handle icon in the Dialog DIALOG_RESIZE_HANDLE_TOOLTIP=Drag handle to resize (Shift+Arrow) diff --git a/packages/main/src/themes/base/Dialog-parameters.css b/packages/main/src/themes/base/Dialog-parameters.css index 7ce95a6c2f9e..1fe83302ddfc 100644 --- a/packages/main/src/themes/base/Dialog-parameters.css +++ b/packages/main/src/themes/base/Dialog-parameters.css @@ -1,9 +1,4 @@ :host { - --_ui5_dialog_header_focus_bottom_offset: 3px; - --_ui5_dialog_header_focus_top_offset: 2px; - --_ui5_dialog_header_focus_left_offset: 2px; - --_ui5_dialog_header_focus_right_offset: 2px; - --_ui5_dialog_header_border_radius: 0px; --_ui5_dialog_header_state_line_height: 0.0625rem; --_ui5_dialog_focus_outline_offset: 0.0625rem; --_ui5_dialog_resizable_bottom_right_radius: 1.75rem; diff --git a/packages/main/src/themes/sap_horizon/Dialog-parameters.css b/packages/main/src/themes/sap_horizon/Dialog-parameters.css index 460e8d806f59..e2dca7790d2f 100644 --- a/packages/main/src/themes/sap_horizon/Dialog-parameters.css +++ b/packages/main/src/themes/sap_horizon/Dialog-parameters.css @@ -1,9 +1 @@ @import "../base/Dialog-parameters.css"; - -:host { - --_ui5_dialog_header_focus_bottom_offset: 2px; - --_ui5_dialog_header_focus_top_offset: 1px; - --_ui5_dialog_header_focus_left_offset: 1px; - --_ui5_dialog_header_focus_right_offset: 1px; - --_ui5_dialog_header_border_radius: var(--sapElement_BorderCornerRadius); -} \ No newline at end of file diff --git a/packages/main/src/themes/sap_horizon_dark/Dialog-parameters.css b/packages/main/src/themes/sap_horizon_dark/Dialog-parameters.css index 460e8d806f59..e2dca7790d2f 100644 --- a/packages/main/src/themes/sap_horizon_dark/Dialog-parameters.css +++ b/packages/main/src/themes/sap_horizon_dark/Dialog-parameters.css @@ -1,9 +1 @@ @import "../base/Dialog-parameters.css"; - -:host { - --_ui5_dialog_header_focus_bottom_offset: 2px; - --_ui5_dialog_header_focus_top_offset: 1px; - --_ui5_dialog_header_focus_left_offset: 1px; - --_ui5_dialog_header_focus_right_offset: 1px; - --_ui5_dialog_header_border_radius: var(--sapElement_BorderCornerRadius); -} \ No newline at end of file From 7f1fed6e4738d1b3e4fc5c4e6ecf8854701b1dad Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Wed, 10 Jun 2026 16:14:43 +0300 Subject: [PATCH 6/9] fix: cypress test --- packages/main/cypress/specs/Dialog.cy.tsx | 170 ++++++++++++---------- 1 file changed, 90 insertions(+), 80 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index 024c46e13948..e088be0c782e 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -575,56 +575,56 @@ describe("Dialog general interaction", () => { cy.get("#draggable-dialog").ui5DialogOpened(); // Capture initial position - cy.get("#draggable-dialog") - .then(dialog => { - const initialTop = parseInt(dialog.css("top")); - const initialLeft = parseInt(dialog.css("left")); - - // Act - Focus drag/resize handle and move dialog up - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.realPress("{uparrow}"); - cy.realPress("{uparrow}"); - - // Assert - Top position changes, left remains the same - - cy.get("#draggable-dialog").then(dialog => { - const leftAfterUp = parseInt(dialog.css("left")); - const topAfterUp = parseInt(dialog.css("top")); - cy.get("#draggable-dialog").should(() => { - expect(topAfterUp).not.to.equal(initialTop); - }) - cy.get("#draggable-dialog").should(() => { - expect(leftAfterUp).to.equal(initialLeft); - }) - - // Act - Move dialog left using keyboard - cy.realPress("{leftarrow}"); - cy.realPress("{leftarrow}"); - - // Assert - Left position changes, top remains the same - cy.get("#draggable-dialog") - .should(dialogAfterLeft => { - const topAfterLeft = parseInt(dialogAfterLeft.css("top")); - const leftAfterLeft = parseInt(dialogAfterLeft.css("left")); - expect(topAfterLeft).to.equal(topAfterUp); - expect(leftAfterLeft).not.to.equal(leftAfterUp); - }); - }); + cy.get("#draggable-dialog").then(dialog => { + cy.wrap({ + initialTop: parseInt(dialog.css("top")), + initialLeft: parseInt(dialog.css("left")) + }).as("initialPos"); + }); + + // Act - Focus drag/resize handle and move dialog up + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); + cy.realPress("{uparrow}"); + cy.realPress("{uparrow}"); + + // Assert - Top position changes, left remains the same + cy.get("@initialPos").then((initialPos: any) => { + cy.get("#draggable-dialog").then(dialog => { + const leftAfterUp = parseInt(dialog.css("left")); + const topAfterUp = parseInt(dialog.css("top")); + expect(topAfterUp).not.to.equal(initialPos.initialTop); + expect(leftAfterUp).to.equal(initialPos.initialLeft); + cy.wrap({ topAfterUp, leftAfterUp }).as("posAfterUp"); + }); + }); - // Close dialog - cy.get("#draggable-dialog").invoke("attr", "open", false); + // Act - Move dialog left using keyboard + cy.realPress("{leftarrow}"); + cy.realPress("{leftarrow}"); + + // Assert - Left position changes, top remains the same + cy.get("@posAfterUp").then((posAfterUp: any) => { + cy.get("#draggable-dialog").should(dialogAfterLeft => { + const topAfterLeft = parseInt(dialogAfterLeft.css("top")); + const leftAfterLeft = parseInt(dialogAfterLeft.css("left")); + expect(topAfterLeft).to.equal(posAfterUp.topAfterUp); + expect(leftAfterLeft).not.to.equal(posAfterUp.leftAfterUp); + }); + }); - // Reopen dialog - cy.get("#draggable-dialog").invoke("attr", "open", true); + // Close dialog + cy.get("#draggable-dialog").invoke("attr", "open", false); - // Assert - Position resets to initial - cy.get("#draggable-dialog") - .should(dialogAfterReopen => { - const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); + // Reopen dialog + cy.get("#draggable-dialog").invoke("attr", "open", true); - expect(leftAfterReopen).to.equal(initialLeft); - }); + // Assert - Position resets to initial + cy.get("@initialPos").then((initialPos: any) => { + cy.get("#draggable-dialog").should(dialogAfterReopen => { + const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); + expect(leftAfterReopen).to.equal(initialPos.initialLeft); }); + }); }); it("resizable - mouse support", () => { @@ -768,55 +768,65 @@ describe("Dialog general interaction", () => { // Capture initial dimensions cy.get("#resizable-dialog").then(dialog => { - const initialWidth = parseInt(dialog.css("width")); - const initialHeight = parseInt(dialog.css("height")); - const initialTop = parseInt(dialog.css("top")); - const initialLeft = parseInt(dialog.css("left")); + cy.wrap({ + initialWidth: parseInt(dialog.css("width")), + initialHeight: parseInt(dialog.css("height")), + initialTop: parseInt(dialog.css("top")), + initialLeft: parseInt(dialog.css("left")) + }).as("initialDimensions"); + }); - // Act - Focus drag/resize handle and resize height - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.realPress(["Shift", "ArrowDown"]); + // Act - Focus drag/resize handle and resize height + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); + cy.realPress(["Shift", "ArrowDown"]); - // Assert - Height changes, width and position remain the same + // Assert - Height changes, width and position remain the same + cy.get("@initialDimensions").then((initial: any) => { cy.get("#resizable-dialog").then(dialogAfterResizeHeight => { const widthAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("width")); const heightAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("height")); const leftAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("left")); - expect(widthAfterResizeHeight).to.equal(initialWidth); - expect(heightAfterResizeHeight).not.to.equal(initialHeight); - expect(leftAfterResizeHeight).to.equal(initialLeft); + expect(widthAfterResizeHeight).to.equal(initial.initialWidth); + expect(heightAfterResizeHeight).not.to.equal(initial.initialHeight); + expect(leftAfterResizeHeight).to.equal(initial.initialLeft); - // Act - Resize width using keyboard - cy.realPress(["Shift", "ArrowRight"]); + cy.wrap({ widthAfterResizeHeight, heightAfterResizeHeight, leftAfterResizeHeight }).as("dimensionsAfterHeight"); + }); + }); - // Assert - Width changes, height and position remain the same - cy.get("#resizable-dialog").then(dialogAfterResizeWidth => { - const widthAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("width")); - const heightAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("height")); - const leftAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("left")); + // Act - Resize width using keyboard + cy.realPress(["Shift", "ArrowRight"]); - expect(widthAfterResizeWidth).not.to.equal(widthAfterResizeHeight); - expect(heightAfterResizeWidth).to.equal(heightAfterResizeHeight); - expect(leftAfterResizeWidth).to.equal(leftAfterResizeHeight); + // Assert - Width changes, height and position remain the same + cy.get("@dimensionsAfterHeight").then((afterHeight: any) => { + cy.get("#resizable-dialog").then(dialogAfterResizeWidth => { + const widthAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("width")); + const heightAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("height")); + const leftAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("left")); - // Close dialog - cy.get("#resizable-dialog").invoke("attr", "open", false); + expect(widthAfterResizeWidth).not.to.equal(afterHeight.widthAfterResizeHeight); + expect(heightAfterResizeWidth).to.equal(afterHeight.heightAfterResizeHeight); + expect(leftAfterResizeWidth).to.equal(afterHeight.leftAfterResizeHeight); + }); + }); - // Reopen dialog - cy.get("#resizable-dialog").invoke("attr", "open", true); + // Close dialog + cy.get("#resizable-dialog").invoke("attr", "open", false); - // Assert - Dimensions reset to initial - cy.get("#resizable-dialog").then(dialogAfterReopen => { - const widthAfterReopen = parseInt(dialogAfterReopen.css("width")); - const heightAfterReopen = parseInt(dialogAfterReopen.css("height")); - const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); + // Reopen dialog + cy.get("#resizable-dialog").invoke("attr", "open", true); - expect(widthAfterReopen).to.equal(initialWidth); - expect(heightAfterReopen).to.equal(initialHeight); - expect(leftAfterReopen).to.equal(initialLeft); - }); - }); + // Assert - Dimensions reset to initial + cy.get("@initialDimensions").then((initial: any) => { + cy.get("#resizable-dialog").then(dialogAfterReopen => { + const widthAfterReopen = parseInt(dialogAfterReopen.css("width")); + const heightAfterReopen = parseInt(dialogAfterReopen.css("height")); + const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); + + expect(widthAfterReopen).to.equal(initial.initialWidth); + expect(heightAfterReopen).to.equal(initial.initialHeight); + expect(leftAfterReopen).to.equal(initial.initialLeft); }); }); }); From 16c06c0c5a63862bfad4575f4293c82cfadc7c25 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Wed, 10 Jun 2026 16:53:23 +0300 Subject: [PATCH 7/9] fix: test assertion --- packages/main/cypress/specs/Dialog.cy.tsx | 172 +++++++++++----------- 1 file changed, 82 insertions(+), 90 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index e088be0c782e..cb9a80065b33 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -575,56 +575,57 @@ describe("Dialog general interaction", () => { cy.get("#draggable-dialog").ui5DialogOpened(); // Capture initial position - cy.get("#draggable-dialog").then(dialog => { - cy.wrap({ - initialTop: parseInt(dialog.css("top")), - initialLeft: parseInt(dialog.css("left")) - }).as("initialPos"); - }); - - // Act - Focus drag/resize handle and move dialog up - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.realPress("{uparrow}"); - cy.realPress("{uparrow}"); - - // Assert - Top position changes, left remains the same - cy.get("@initialPos").then((initialPos: any) => { - cy.get("#draggable-dialog").then(dialog => { - const leftAfterUp = parseInt(dialog.css("left")); - const topAfterUp = parseInt(dialog.css("top")); - expect(topAfterUp).not.to.equal(initialPos.initialTop); - expect(leftAfterUp).to.equal(initialPos.initialLeft); - cy.wrap({ topAfterUp, leftAfterUp }).as("posAfterUp"); - }); - }); + cy.get("#draggable-dialog") + .then(dialog => { + const initialTop = parseInt(dialog.css("top")); + const initialLeft = parseInt(dialog.css("left")); + + // Act - Focus the drag/resize handle and move dialog up + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").should("be.focused"); + cy.realPress("{uparrow}"); + cy.realPress("{uparrow}"); + + // Assert - Top position changes, left remains the same + + cy.get("#draggable-dialog").then(dialog => { + const leftAfterUp = parseInt(dialog.css("left")); + const topAfterUp = parseInt(dialog.css("top")); + cy.get("#draggable-dialog").should(() => { + expect(topAfterUp).not.to.equal(initialTop); + }) + cy.get("#draggable-dialog").should(() => { + expect(leftAfterUp).to.equal(initialLeft); + }) + + // Act - Move dialog left using keyboard + cy.realPress("{leftarrow}"); + cy.realPress("{leftarrow}"); + + // Assert - Left position changes, top remains the same + cy.get("#draggable-dialog") + .should(dialogAfterLeft => { + const topAfterLeft = parseInt(dialogAfterLeft.css("top")); + const leftAfterLeft = parseInt(dialogAfterLeft.css("left")); + expect(topAfterLeft).to.equal(topAfterUp); + expect(leftAfterLeft).not.to.equal(leftAfterUp); + }); + }); - // Act - Move dialog left using keyboard - cy.realPress("{leftarrow}"); - cy.realPress("{leftarrow}"); - - // Assert - Left position changes, top remains the same - cy.get("@posAfterUp").then((posAfterUp: any) => { - cy.get("#draggable-dialog").should(dialogAfterLeft => { - const topAfterLeft = parseInt(dialogAfterLeft.css("top")); - const leftAfterLeft = parseInt(dialogAfterLeft.css("left")); - expect(topAfterLeft).to.equal(posAfterUp.topAfterUp); - expect(leftAfterLeft).not.to.equal(posAfterUp.leftAfterUp); - }); - }); + // Close dialog + cy.get("#draggable-dialog").invoke("attr", "open", false); - // Close dialog - cy.get("#draggable-dialog").invoke("attr", "open", false); + // Reopen dialog + cy.get("#draggable-dialog").invoke("attr", "open", true); - // Reopen dialog - cy.get("#draggable-dialog").invoke("attr", "open", true); + // Assert - Position resets to initial + cy.get("#draggable-dialog") + .should(dialogAfterReopen => { + const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); - // Assert - Position resets to initial - cy.get("@initialPos").then((initialPos: any) => { - cy.get("#draggable-dialog").should(dialogAfterReopen => { - const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); - expect(leftAfterReopen).to.equal(initialPos.initialLeft); + expect(leftAfterReopen).to.equal(initialLeft); + }); }); - }); }); it("resizable - mouse support", () => { @@ -768,65 +769,56 @@ describe("Dialog general interaction", () => { // Capture initial dimensions cy.get("#resizable-dialog").then(dialog => { - cy.wrap({ - initialWidth: parseInt(dialog.css("width")), - initialHeight: parseInt(dialog.css("height")), - initialTop: parseInt(dialog.css("top")), - initialLeft: parseInt(dialog.css("left")) - }).as("initialDimensions"); - }); + const initialWidth = parseInt(dialog.css("width")); + const initialHeight = parseInt(dialog.css("height")); + const initialTop = parseInt(dialog.css("top")); + const initialLeft = parseInt(dialog.css("left")); - // Act - Focus drag/resize handle and resize height - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.realPress(["Shift", "ArrowDown"]); + // Act - Focus the drag/resize handle and resize height + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").should("be.focused"); + cy.realPress(["Shift", "ArrowDown"]); - // Assert - Height changes, width and position remain the same - cy.get("@initialDimensions").then((initial: any) => { + // Assert - Height changes, width and position remain the same cy.get("#resizable-dialog").then(dialogAfterResizeHeight => { const widthAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("width")); const heightAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("height")); const leftAfterResizeHeight = parseInt(dialogAfterResizeHeight.css("left")); - expect(widthAfterResizeHeight).to.equal(initial.initialWidth); - expect(heightAfterResizeHeight).not.to.equal(initial.initialHeight); - expect(leftAfterResizeHeight).to.equal(initial.initialLeft); - - cy.wrap({ widthAfterResizeHeight, heightAfterResizeHeight, leftAfterResizeHeight }).as("dimensionsAfterHeight"); - }); - }); + expect(widthAfterResizeHeight).to.equal(initialWidth); + expect(heightAfterResizeHeight).not.to.equal(initialHeight); + expect(leftAfterResizeHeight).to.equal(initialLeft); - // Act - Resize width using keyboard - cy.realPress(["Shift", "ArrowRight"]); + // Act - Resize width using keyboard + cy.realPress(["Shift", "ArrowRight"]); - // Assert - Width changes, height and position remain the same - cy.get("@dimensionsAfterHeight").then((afterHeight: any) => { - cy.get("#resizable-dialog").then(dialogAfterResizeWidth => { - const widthAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("width")); - const heightAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("height")); - const leftAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("left")); + // Assert - Width changes, height and position remain the same + cy.get("#resizable-dialog").then(dialogAfterResizeWidth => { + const widthAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("width")); + const heightAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("height")); + const leftAfterResizeWidth = parseInt(dialogAfterResizeWidth.css("left")); - expect(widthAfterResizeWidth).not.to.equal(afterHeight.widthAfterResizeHeight); - expect(heightAfterResizeWidth).to.equal(afterHeight.heightAfterResizeHeight); - expect(leftAfterResizeWidth).to.equal(afterHeight.leftAfterResizeHeight); - }); - }); + expect(widthAfterResizeWidth).not.to.equal(widthAfterResizeHeight); + expect(heightAfterResizeWidth).to.equal(heightAfterResizeHeight); + expect(leftAfterResizeWidth).to.equal(leftAfterResizeHeight); - // Close dialog - cy.get("#resizable-dialog").invoke("attr", "open", false); + // Close dialog + cy.get("#resizable-dialog").invoke("attr", "open", false); - // Reopen dialog - cy.get("#resizable-dialog").invoke("attr", "open", true); + // Reopen dialog + cy.get("#resizable-dialog").invoke("attr", "open", true); - // Assert - Dimensions reset to initial - cy.get("@initialDimensions").then((initial: any) => { - cy.get("#resizable-dialog").then(dialogAfterReopen => { - const widthAfterReopen = parseInt(dialogAfterReopen.css("width")); - const heightAfterReopen = parseInt(dialogAfterReopen.css("height")); - const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); + // Assert - Dimensions reset to initial + cy.get("#resizable-dialog").then(dialogAfterReopen => { + const widthAfterReopen = parseInt(dialogAfterReopen.css("width")); + const heightAfterReopen = parseInt(dialogAfterReopen.css("height")); + const leftAfterReopen = parseInt(dialogAfterReopen.css("left")); - expect(widthAfterReopen).to.equal(initial.initialWidth); - expect(heightAfterReopen).to.equal(initial.initialHeight); - expect(leftAfterReopen).to.equal(initial.initialLeft); + expect(widthAfterReopen).to.equal(initialWidth); + expect(heightAfterReopen).to.equal(initialHeight); + expect(leftAfterReopen).to.equal(initialLeft); + }); + }); }); }); }); From 7c8de6a95245a969e64e480c90dfd1612f69b441 Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Thu, 11 Jun 2026 11:07:53 +0300 Subject: [PATCH 8/9] fix: test assertion --- packages/main/cypress/specs/Dialog.cy.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index cb9a80065b33..267a1ec61032 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -581,8 +581,10 @@ describe("Dialog general interaction", () => { const initialLeft = parseInt(dialog.css("left")); // Act - Focus the drag/resize handle and move dialog up - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler").should("be.focused"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler") + .focus() + .should("be.focused"); + cy.realPress("{uparrow}"); cy.realPress("{uparrow}"); @@ -775,8 +777,10 @@ describe("Dialog general interaction", () => { const initialLeft = parseInt(dialog.css("left")); // Act - Focus the drag/resize handle and resize height - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").focus(); - cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler").should("be.focused"); + cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler") + .focus() + .should("be.focused"); + cy.realPress(["Shift", "ArrowDown"]); // Assert - Height changes, width and position remain the same From 151e5cb0ffe807e8dfc68b5a541c1b363c84e97b Mon Sep 17 00:00:00 2001 From: Siyana Todorova Date: Mon, 15 Jun 2026 16:48:59 +0300 Subject: [PATCH 9/9] fix: address review comments --- packages/main/cypress/specs/Dialog.cy.tsx | 2 +- packages/main/src/Dialog.ts | 4 ---- packages/main/src/DialogTemplate.tsx | 2 +- packages/main/src/themes/Dialog.css | 12 ------------ 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/packages/main/cypress/specs/Dialog.cy.tsx b/packages/main/cypress/specs/Dialog.cy.tsx index 267a1ec61032..ea218a940f41 100644 --- a/packages/main/cypress/specs/Dialog.cy.tsx +++ b/packages/main/cypress/specs/Dialog.cy.tsx @@ -777,7 +777,7 @@ describe("Dialog general interaction", () => { const initialLeft = parseInt(dialog.css("left")); // Act - Focus the drag/resize handle and resize height - cy.get("#draggable-dialog").shadow().find(".ui5-popup-drag-resize-handler") + cy.get("#resizable-dialog").shadow().find(".ui5-popup-drag-resize-handler") .focus() .should("be.focused"); diff --git a/packages/main/src/Dialog.ts b/packages/main/src/Dialog.ts index 702dbd55e70f..435de4aaa553 100644 --- a/packages/main/src/Dialog.ts +++ b/packages/main/src/Dialog.ts @@ -314,10 +314,6 @@ class Dialog extends Popup { return !this.stretch && this.onDesktop && (this.draggable || this.resizable); } - get _headerTabIndex() { - return undefined; - } - get _dragResizeHandleTabIndex() { return this._movable ? 0 : undefined; } diff --git a/packages/main/src/DialogTemplate.tsx b/packages/main/src/DialogTemplate.tsx index f3763d1c2350..4abfddd66fc2 100644 --- a/packages/main/src/DialogTemplate.tsx +++ b/packages/main/src/DialogTemplate.tsx @@ -61,7 +61,7 @@ function afterContent(this: Dialog) { <>