Skip to content

Prototype: rename, move and icon controls on the selected row (opt-in) - #261

Draft
dknauss wants to merge 21 commits into
mainfrom
proto/selected-row-controls
Draft

dknauss wants to merge 21 commits into
mainfrom
proto/selected-row-controls

Conversation

@dknauss

@dknauss dknauss commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Requested by Dan

Draft prototype, do not merge. Opt-in only: without ?maestro_rows=1 nothing changes. It should be rebased after the mobile keyboard/dialog polish lands and is tagged.

Playground demo

Launch the selected-row controls demo. Opens logged in as admin, in edit mode with the prototype enabled. Loads the current PR branch, including the rename-persistence and 44px touch-target fixes. Includes a long menu label for narrow-width testing.

Summary

Before: rename, move up/down and the icon picker live in the bottom toolbar. Selecting a row sends focus down to the toolbar's rename field (and on phones, raises the keyboard).

After (with ?maestro_rows=1): the selected row carries its own controls. A strip under it has Rename (pencil), Move up and Move down, and the row's own icon becomes a Change icon button. Rename edits the label in place: Enter, blur, or selecting another row commits to the original item; Escape cancels. IME composition owns its Enter/Escape keys until composition ends. The field follows live menu-width and viewport changes while preserving unsaved text, focus and text selection, including RTL and submenu rows. With a fine pointer the strip's fourth button is More (⋯), which opens a small menu with Visibility, Reset item and Add separator below (Dan's call, 2026-10-26: six buttons can't share one row at 160px). A selected separator gets Up, Down and Remove on its own row. On touch screens the three item actions stay in the toolbar, because four 44px buttons don't fit in 160px. Global controls stay in the toolbar.

How: one set of controls is re-parented into whichever <li> is selected (buildRowControls() / placeRowControls() in assets/maestro.js). They are children of the <li>, never of its <a>, so they can't navigate or nest interactive content. The toolbar's rename field, arrows and icon button are hidden only while a row owns them. ?maestro_rows=1 turns the mode on and stores it in that browser; ?maestro_rows=0 turns it off. Choices are written up in .planning/DESKTOP-UX-NEXT-PASS.md under "Prototype".

Try it: Playground, prototype branch. It lands in edit mode with the flag on, plus a plugin menu with a long name ("WooCommerce Marketing & Analytics Insights").

The concerns raised before the prototype

Concern What the prototype does
Folded menu Nothing to design for while editing. forceUnfold() already strips folded/auto-fold from 783px up, so at 783–960px edit mode shows the full-width menu (screenshot: tablet 860px).
44px touch targets With a coarse pointer the strip buttons are 44×44, and the strip drops its icon-column indent so all three fit in 160px. The selected icon is a real 44×44px button inside the row, with label space reserved; its hit area stays within the viewport in LTR and RTL. A fine pointer gets 32px (WCAG 2.5.8 needs 24).
Icon click vs drag vs navigation One rule: the first click on any row, icon included, only selects it. The icon becomes a button only on the selected row. It's a <button>, so the sortable's cancel won't start a drag from it, and since it's outside the <a> it can't navigate. The spec tests that clicking an unselected icon opens no picker.
F2 on Macs Enter on the row that's already selected is the main keyboard path. F2 works too, and so does the pencil.
Screen-reader focus Focus stays on the row after selection and the selection is announced ("Posts selected. Its editing buttons follow it in the menu."). Tab order is row, Change icon, Rename, Move up, Move down, then the submenu. Names include the item: "Rename Posts", "Change icon of Posts". After a move, focus goes back to the arrow you pressed; after Enter or Escape in rename, it goes back to the pencil. I ran no real VoiceOver or NVDA pass.
Help tour steps With the flag on, the rename, move and icon tips point at the row controls and their text says how to use them. The step count is unchanged (14 on desktop, 12 on a phone).
Phone UI inside #adminmenuwrap The controls are inside #adminmenu, so core never counts a tap on them as an outside click. The spec checks this and checks that the menu stays open.
Stored width Never widened to make room. The strip wraps instead.

Screenshots

160px, 240px, 320px, a submenu row, renaming, the icon picker, Arabic RTL (a real ar site, not a CSS flip), tablet 860px, phone portrait, phone RTL, phone landscape, the tour, and today's flag-off toolbar for comparison:

Row controls contact sheet

More menu and separators

More is a keyboard menu button: ArrowDown or Enter opens it, arrows/Home/End move, Escape returns to More, Tab and outside clicks close it. Its items call the same functions as the toolbar buttons, so Reset item is disabled when there's nothing to reset and Add separator follows the same rules. It opens over the page (to the left in RTL) and lifts above the button when the bottom toolbar is in the way. The tour swaps the three toolbar tips for one More tip (12 steps on desktop).

More menu and separator rows

Type of change

  • Feature (prototype, behind a flag)

Verification

  • Local wp-env: all 19 selected-row tests pass, including authentication, desktop/phone controls, IME Enter/Escape, live resizing in Arabic RTL, rename persistence when switching rows, and real 44px icon targets.
  • The four new IME/RTL regression cases failed before the fixes and pass after them. RTL coverage includes long labels, top-level and submenu rows, 160/240/320px widths, window resizing, focus, and selection preservation. IME coverage exercises isComposing, composition lifecycle events, and keyCode 229, then ordinary commit/cancel.
  • Six new regression cases failed before the latest fixes and pass afterwards: mouse and touch selection changes preserve top-level/submenu renames through reload; LTR/RTL icon targets are at least 44×44px, contained in the row and viewport, and tappable at all corners without blocking the label.
  • npm run test:js: all 142 tests pass; JavaScript syntax and diff whitespace checks pass.
  • phpcs on includes/class-assets.php.
  • The hosted blueprint was booted locally: it installs the branch zip and the strip appears.
  • Latest full CI run passes at commit 9208180: 219 Playwright tests passed, 28 skipped, no failures; both PHP integration suites and all other checks are green.

Notes

  • Still open (from the brief): whether Visibility, Reset item and the separator actions move onto the row or into an overflow, real screen-reader passes, and a real touch-device pass.
  • Things I noticed: the selected row's strip reads well on the default dark scheme. On lighter schemes it takes its colour from an ordinary menu label, which I haven't checked by eye. A very long label gets a field the width of the label column, which is cramped at 160px.

🤖 Generated with Claude Code

Opt-in with ?maestro_rows=1 (remembered per browser, ?maestro_rows=0 turns
it off). The selected menu row gets a strip with Rename, Move up and Move
down, and its own icon becomes a Change icon button. Rename edits the label
in place (pencil, Enter on the selected row, or F2). Visibility, Reset item,
separators and the global controls stay in the toolbar. Without the flag the
shipped toolbar flow is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dknauss dknauss self-assigned this Oct 24, 2026
@dknauss dknauss mentioned this pull request Oct 25, 2026
Keeps both new stylesheet blocks: the prototype's row controls and #265's
dialog standard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012tY8BSUE4tF9wo8m1hx4qW
@dknauss
dknauss marked this pull request as ready for review October 25, 2026 23:30
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T23:34:00.104358Z 9c7aa9f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c7aa9f681

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread assets/maestro.css
Comment on lines +1615 to +1619
.maestro-editing #adminmenu li.maestro-selected > a.menu-top {
box-sizing: border-box;
min-height: 44px;
}
.maestro-editing #adminmenu li.maestro-selected > a.menu-top .wp-menu-name {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate the selected-row layout rules behind the prototype class

On coarse-pointer devices, these rules also apply with ?maestro_rows=0 or when the prototype has never been enabled: the ordinary editor still assigns maestro-selected to the selected row. Consequently, selecting an item changes its label padding and potentially its height even in the shipped toolbar-only flow, causing labels to shift or wrap differently. Scope these selected-row layout overrides under .maestro-row-controls, which buildRowControls() already adds only when the prototype is enabled.

Useful? React with 👍 / 👎.

dknauss and others added 8 commits October 26, 2026 19:28
With a fine pointer the selected row's strip is now Rename, Up, Down and
More (⋯); More opens a small menu with Visibility, Reset item and Add
separator below, each running the same function as its toolbar twin. It is a
keyboard-operable menu button, opens toward the page (left in RTL), and
stays clear of the bottom toolbar. A selected separator gets Up, Down and
Remove on its own row. Touch screens keep the three item actions in the
toolbar, since four 44px buttons do not fit in 160px. The tour replaces the
three toolbar tips with one More tip.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A dialog opened from a menu row (Visibility from the row's More menu) had
no room above, so it opened below and ran under the fixed toolbar. Desktop
placement now treats the toolbar's top as the floor: above the anchor if it
fits, else below if it fits, else on the roomier side with its own scroll.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With rename, the arrows and the icon on the menu row, the phone toolbar
holds at most six 44px buttons, which fit one row from 320px up. #265's
two-row column layout stays for the shipped toolbar flow.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On a short visual viewport (360px or less) the in-place rename field now
scrolls to the middle of what is visible when it opens, and again as the
keyboard settles. The pinned-strip alternative is recorded as a backlog
fallback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Desktop dialogs now treat the admin bar as the ceiling as well as the
toolbar as the floor. One that fits neither above nor below its anchor
fills the space between them on the top layer, beside the anchor so the
selected row stays in view, and scrolls only if it is taller than all of it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The scroll-into-view fix felt bad on a real phone and also ran upright, so
it is gone. On coarse-pointer landscape screens 500px tall or less, rename
moves into a strip pinned to the bottom of the visual viewport, just above
the keyboard: the item's name, a full-width field and Done, with the same
commit and cancel rules as the in-place field. Upright phones, tablets and
desktops keep renaming in place.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Titles set their own direction, so an untranslated one stays LTR while
Close follows the page to the left; the title's logical padding then cleared
the wrong side and Close covered "Menu width" in Arabic. Titles now clear
Close on the page's side and align with the page.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dknauss and others added 4 commits October 26, 2026 21:46
Focusing the in-place rename field with preventScroll stopped iOS from
moving it above the keyboard and its floating bars on an upright iPhone.
Touch screens now focus it normally so the browser does that; mouse and
keyboard keep the menu still. The More menu also gets an accessible name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Opening the row rename field selected the whole name, and on a phone a tap
did not clear that selection, so the first keystroke wiped the old name.
Touch now places the caret at the end; keyboard and mouse still select the
name, as F2 does elsewhere.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Plain-language steps for outside testers: the Playground link, what is
different from the shipped toolbar, tasks to try on desktop, phones and the
keyboard, what feedback helps, and where to leave it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dknauss dknauss mentioned this pull request Oct 27, 2026
3 of 4 tasks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dknauss
dknauss marked this pull request as draft October 27, 2026 19:42
# Conflicts:
#	assets/maestro.css
dknauss added a commit to newlocalmedia/newlocalmedia.github.io that referenced this pull request Oct 27, 2026
A standalone page at /guides/maestro-prototype-testing/ for outside testers
of the Maestro selected-row controls prototype (dknauss/Maestro#261).
guides/** now triggers deploys and the site checks.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants