Spun out of the editConfirmRef discussion on #338 / #340. The ref-and-.click() mechanism for editorRef.confirm() is sound and stays; the genuine smell next to it is that the controls themselves aren't buttons.
Problem
The ✓ / ✗ controls in InputButtons (src/ButtonPanels.tsx) are <div onClick> elements — as is all clickable chrome in core (edit/copy/delete/add icons, the new-key row; there are no <button> elements anywhere in src/). Screen readers don't announce them as actionable, and they're not keyboard-activatable natively.
Scope
Start with the ✓ / ✗ pair (they're the commit path, highest value), then sweep EditButtons' icon controls. Use <button type="button"> with an appearance reset in src/style.css.
Things to decide / watch
- Tab semantics: the editor owns Tab (field-to-field navigation via
keyboardControls). Focusable buttons would inject themselves into that flow — likely want tabIndex={-1} so behaviour is unchanged while screen readers still get role=button semantics, unless full keyboard operability is the goal (bigger design).
editConfirmRef type changes RefObject<HTMLDivElement> → RefObject<HTMLButtonElement> (internal only — the type isn't exported).
- Consumer CSS breakage: anything targeting
.jer-confirm-buttons > div or descendant div selectors breaks — that includes our own tests (test/JsonEditor.test.tsx, test/customNode.test.tsx click .jer-confirm-buttons > div). The v2 window is the time to do this; needs a migration-guide line for the selector change.
aria-labels from the existing tooltip strings (TOOLTIP_* localisation keys) come nearly free.
- Bundle impact: negligible (element rename + a few attributes; small CSS reset).
🤖 Generated with Claude Code
Spun out of the
editConfirmRefdiscussion on #338 / #340. The ref-and-.click()mechanism foreditorRef.confirm()is sound and stays; the genuine smell next to it is that the controls themselves aren't buttons.Problem
The ✓ / ✗ controls in
InputButtons(src/ButtonPanels.tsx) are<div onClick>elements — as is all clickable chrome in core (edit/copy/delete/add icons, the new-key row; there are no<button>elements anywhere insrc/). Screen readers don't announce them as actionable, and they're not keyboard-activatable natively.Scope
Start with the ✓ / ✗ pair (they're the commit path, highest value), then sweep
EditButtons' icon controls. Use<button type="button">with an appearance reset insrc/style.css.Things to decide / watch
keyboardControls). Focusable buttons would inject themselves into that flow — likely wanttabIndex={-1}so behaviour is unchanged while screen readers still getrole=buttonsemantics, unless full keyboard operability is the goal (bigger design).editConfirmReftype changesRefObject<HTMLDivElement>→RefObject<HTMLButtonElement>(internal only — the type isn't exported)..jer-confirm-buttons > divor descendantdivselectors breaks — that includes our own tests (test/JsonEditor.test.tsx,test/customNode.test.tsxclick.jer-confirm-buttons > div). The v2 window is the time to do this; needs a migration-guide line for the selector change.aria-labels from the existing tooltip strings (TOOLTIP_*localisation keys) come nearly free.🤖 Generated with Claude Code