Implement keyboard navigation improvements in HtmlEditor#34309
Open
Raushen wants to merge 10 commits into
Open
Implement keyboard navigation improvements in HtmlEditor#34309Raushen wants to merge 10 commits into
Raushen wants to merge 10 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds “focus escape” keyboard navigation for HtmlEditor content (Ctrl+Shift+Up/Down), enabling users to move focus to the toolbar or to the nearest focusable element outside the editor. This is implemented via new shared focus utilities and is covered by new unit and TestCafe e2e tests.
Changes:
- Add focus traversal helpers (
getFirstFocusableElement,getNextFocusableElement,getPreviousFocusableElement) and centralize the “all focusables” selector inm_selectors. - Implement HtmlEditor Ctrl+Shift+Up/Down handling, including focusing the first toolbar item when appropriate.
- Update TestCafe HtmlEditor toolbar models and add/adjust e2e + unit tests for the new keyboard behavior.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/testcafe-models/toolbar/toolbarItem.ts | Adds a TestCafe model wrapper for toolbar items with an isFocused helper. |
| packages/testcafe-models/htmlEditor/rootToolbar.ts | Switches getItemByName to return a ToolbarItem model (used by updated tests). |
| packages/devextreme/js/__internal/ui/toolbar/toolbar.ts | Adds focusFirstItem() to programmatically focus the first focusable toolbar element. |
| packages/devextreme/js/__internal/ui/popover/popover.ts | Adjusts top-overlay comparison typing in the Escape key handler. |
| packages/devextreme/js/__internal/ui/html_editor/modules/m_toolbar.ts | Uses a Toolbar implementation that exposes focusFirstItem() and proxies it from the module. |
| packages/devextreme/js/__internal/ui/html_editor/html_editor.ts | Implements Ctrl+Shift+Up/Down focus escape from editor content and returns toolbar method results. |
| packages/devextreme/js/__internal/ui/html_editor/tests/focus_escape.test.ts | Adds unit tests for focus escape behavior. |
| packages/devextreme/js/__internal/ui/tests/mock/model/html_editor.ts | Adds a minimal HtmlEditor test model for dispatching keyboard events and querying key elements. |
| packages/devextreme/js/__internal/grids/new/grid_core/keyboard_navigation/const.ts | Re-exports the shared focusables selector from m_selectors. |
| packages/devextreme/js/__internal/core/utils/m_selectors.ts | Moves/exports ALL_FOCUSABLE_ELEMENTS_SELECTOR and adds isElementVisible as a named export. |
| packages/devextreme/js/__internal/core/utils/focus.ts | Introduces shared focus traversal utilities used by HtmlEditor/Toolbar. |
| packages/devextreme/js/__internal/core/utils/focus.test.ts | Adds unit tests for the new focus traversal utilities. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/keyboard.ts | Adds e2e coverage for HtmlEditor focus escape behavior. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/dialogs/aiDialog/common.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/dialogs/addImage/common.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/dialogs/addImage/addImageUrl.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/dialogs/addImage/addImageFromDevice.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/tests/editors/htmlEditor/common.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/tests/accessibility/htmlEditor.ts | Updates to click toolbar item .element after model return type change. |
| e2e/testcafe-devextreme/helpers/domUtils.ts | Adds helper to inject a focusable element after a target for navigation tests. |
pharret31
reviewed
Jul 15, 2026
|
|
||
| _keyDownHandler(e: ValueChangedEvent): void { | ||
| this._saveValueChangeEvent(e); | ||
| this._handleFocusEscape(e as unknown as KeyboardEvent); |
Contributor
There was a problem hiding this comment.
Can we somehow avoid such casting?
pharret31
reviewed
Jul 15, 2026
Raushen
commented
Jul 15, 2026
|
|
||
| const overlayStack = this._overlayStack(); | ||
| // @ts-ignore expected: types Overlay<OverlayProperties> and this have no overlap | ||
| // @ts-expect-error expected: types Overlay<OverlayProperties> and this have no overlap |
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

No description provided.