Repository navigation
Keep RTE toolbar dropdowns from being clipped - #6280
Conversation
🟡 Waiting for changesLast updated: 2026-10-02 23:24 UTC |
7e32704 to
37c8abc
Compare
rtibblesbot
left a comment
There was a problem hiding this comment.
PR #6280: the format trigger label wraps for headings, and focus on the selected format option is invisible. Swapping both menus for KDropdownMenu does fix the clipping.
The head moved to 37c8abca0 after this review ran; those commits are unreviewed.
CI passing.
- Blocking: label wrap (
FormatDropdown.vue:8), invisible focus on selected option (FormatDropdown.vue:23). - Suggestions: off-screen menu on short viewports, RTL alignment, Home/End, screen-reader name, value-based selection, global class name, paste-select test, KDS
menu-itemrole.
Manual QA:
- Clipping is gone at the top and bottom of the panel.
- All five formats apply and save.
- The paste flows work from the chevron, the main button and More.
- Click-outside dismisses the menu without minimising the editor.
- Escape returns focus.
- The QA server then hit a Redis
MISCONFerror. Later scenarios ran on a standaloneTipTapEditorharness. - Not checked: cursor-tracking of the format label across blocks, undo/redo, and two RTEs on one card.
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran a phased review pipeline over the pull request diff:
- Classified the diff to select review passes (core, frontend, backend) and whether manual QA was required
- Core review pass checked correctness, design, architecture, testing, completeness, and DRY/SRP/Rule-of-Three principles
- Specialized frontend/backend review passes applied framework-specific lenses where those files changed
- For UI changes: manual QA and an accessibility audit against a live dev server, when available
- Checked CI status and linked issue acceptance criteria
- Synthesized one review from those passes and chose the verdict from the findings, CI status, and QA evidence
| :tabindex="index === focusedIndex ? 0 : -1" | ||
| @click="handleOptionClick(option)" | ||
| @keydown="handleItemKeydown($event, index, option)" | ||
| <KDropdownMenu |
There was a problem hiding this comment.
suggestion: Both menus now fail axe's aria-roles/aria-required-children checks. KDS 5.9.0 UiMenuOption renders the invalid role="menu-item". The removed menus used role="menuitem". Can a KDS issue be filed and linked here?
There was a problem hiding this comment.
Yes, could you open an issue in KDS for this?
There was a problem hiding this comment.
Already covered by learningequality/kolibri-design-system#1333, which includes the invalid role="menu-item".
| @click="handleOptionClick(option)" | ||
| @keydown="handleItemKeydown($event, index, option)" | ||
| <KDropdownMenu | ||
| :options="menuOptions" |
There was a problem hiding this comment.
nitpick: The paste menu stays open when its chevron overflows out of the toolbar.
- Repro: open the menu at 1200px, then narrow to 500px.
- The menu stays visible, 25px past the viewport, with
aria-expanded="true". - The overflowed chevron is hidden with
visibility: hidden, which the body-portaled menu doesn't inherit. - Close the menu when the chevron overflows.
There was a problem hiding this comment.
Could you open an issue on KDS to expose the closePopover method so that we can call it when it is squashed into the more button?
There was a problem hiding this comment.
Still waiting on the KDS issue to be filed for this.
There was a problem hiding this comment.
…r clipped The format and paste menus rendered inside the editor, so any ancestor that hides its overflow, such as the QTI question card, cut them off. KDropdownMenu renders them on document.body and flips them when there is no room, the way the toolbar's More menu already does. Format options keep previewing the editor's typography, and the hand-written keyboard, focus and outside-click handling is replaced by KDropdownMenu's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… own state With KDropdownMenu managing the menus, useDropdowns held only unrelated leftovers. The paste actions join the other toolbar action lists in useToolbarActions, and the format at the cursor is tracked by FormatDropdown, its only user, so the toolbar and paste dropdown no longer each listen to the editor for it. Drops the unused clipboardOptions and the redundant selectFormat. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
37c8abc to
51bf1ea
Compare
rtibblesbot
left a comment
There was a problem hiding this comment.
PR #6280: 3 of 13 prior findings still need action; the other 10 are resolved or acknowledged.
CI passes. Manual QA did not run.
Still open:
FormatDropdown.vue:6— screen readers don't announce the current format. This is pre-existing onunstable. Please file the issue the maintainer asked for.PasteDropdown.vue:35— menus fail axearia-roles/aria-required-children. Please file the requested KDS issue.PasteDropdown.vue:36— the paste menu stays open when overflowed. Please file the requested KDS issue to exposeclosePopover.
New:
- One suggestion on the format test (inline).
Prior-finding status
ACKNOWLEDGED — FormatDropdown.vue:8 — "Header 1/2/3" wraps onto two lines
ACKNOWLEDGED — FormatDropdown.vue:23 — Keyboard focus on selected option invisible
ACKNOWLEDGED — FormatDropdown.vue:16 — 322px menu can run off-screen
ACKNOWLEDGED — FormatDropdown.vue:14 — RTL menu overflows editor border (kolibri-design-system#1344)
ACKNOWLEDGED — FormatDropdown.vue:15 — Home/End close the menu (kolibri-design-system#1345)
UNADDRESSED — FormatDropdown.vue:6 — Screen-reader users can't hear the current format
RESOLVED — FormatDropdown.vue — Selection matched by translated label
RESOLVED — TipTapEditor.vue — Unscoped .format-option heading styles
RESOLVED — PasteDropdown.vue:38 — No test selects a paste menu option
UNADDRESSED — PasteDropdown.vue:35 — Menus fail axe aria-roles checks
UNADDRESSED — PasteDropdown.vue:36 — Paste menu stays open when overflowed
ACKNOWLEDGED — PasteDropdown.vue:169 — Labels take KDS 13.125px font size
RESOLVED — EditorToolbar.spec.js:451 — Menu-outside-toolbar assertion (praise)
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
|
|
||
| await user.click(within(screen.getByRole('menu')).getByText(formatHeader1$())); | ||
|
|
||
| expect(editor.commands).toContainEqual(['toggleHeading', { level: 1 }]); |
There was a problem hiding this comment.
suggestion: This test asserts the recorded command chain, not the resulting document.
- An equivalent rewrite such as
setHeadingwould break it with no behavior change. renderWithClipboard(:353) already renders a real editor.- Please start from
'<p>a</p>', pick "Header 1", and assertgetHTML()is'<h1>a</h1>'. - The chain-recording Proxy can then be deleted.
Superseded by my review of 51bf1ea: no blocking findings remain.
rtibbles
left a comment
There was a problem hiding this comment.
Code changes make sense, and local behaviour checks out. The only issues I could see are pre-existing and not introduced in this PR - or are underlying issues in KDS.
Will wait on filing of follow up issues before approving for merge.
rtibbles
left a comment
There was a problem hiding this comment.
All follow up issues filed, manual QA showed no other concerns to me. Ready to merge.
|
Quick check on rtibblesbot's review of this PR: react 👍 helpful · 😕 mixed · 👎 not helpful. Reply with anything specific. |
Summary
KDropdownMenu, like the toolbar's More menu. It renders the menu ondocument.bodyand flips it above the trigger when there's no room below.constrainToScrollParentis off, so the menu flips against the viewport instead of being pushed inside the question card, which would make it cover its own trigger..format-option.KDropdownMenu's. Trigger ArrowUp/ArrowDown and in-menu Home/End are no longer supported, matching the More menu.useDropdowns. Paste actions move touseToolbarActions, and format tracking moves intoFormatDropdown, its only consumer.References
None.
Reviewer guidance
AI usage
I used Claude Code to investigate the clipping, compare approaches, and implement and test the change. I reviewed the code, steered the approach toward
KDropdownMenu, and verified the menus in the browser.🤖 Generated with Claude Code