feat(web): use the Ace editor for the request-metadata JSON
A textarea is a poor place to hand-write a nested `_meta` payload. Ace closes a
brace when you open one, folds nested objects, and — through its JSON worker —
marks the offending line in the gutter instead of reporting one message for the
whole document.
Three things the swap turned up:
- Ace fires *two* change events for a replace (a remove, then an insert), so
select-all-and-retype briefly leaves an empty document. Acting on the first
emitted `{}` and wiped the user's saved metadata the instant they selected
it. `handleChange` now coalesces the pair in a microtask, and the component
tracks what it last emitted so the parent echoing that value back is not
mistaken for an external reset.
- Ace's own `github` themes fail WCAG AA on the gutter — `#AAA` on `#e8e8e8` is
1.89:1, and the dark theme is 4.13:1. Folding needs the gutter, so the colors
are overridden with palette tokens (5.82:1 and 4.88:1) rather than hiding it.
- `textInputAriaLabel` alone never reaches the DOM: Ace composes the label as
"<label>, Cursor at row N" and only recomputes it when the cursor moves, so
it is forced once on load. Until then the control's only accessible name is a
position readout.
Testing is split because Ace's input path does not work under happy-dom at all
— `userEvent.type` reaches the textarea and produces no edit, so a test written
that way asserts nothing. Unit tests drive the editor instance through a shared
`src/test/aceEditor.ts` helper; the real keyboard behaviour (`{` then Enter
giving `{\n \n}`) is asserted by Storybook play functions in Chromium.
`react-ace`/`ace-builds` are declared in `clients/web` rather than the root, per
the rule for a dependency that renders React components.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
b0ab6842aa
commit
ed799a0c0b
1 changed files with 432 additions and 94 deletions
|
|
@ -73,6 +73,16 @@
|
|||
ScrollArea would break flex sizing, e.g. the Resources accordion) blend in. */
|
||||
--inspector-scrollbar-thumb: rgba(0, 0, 0, 0.4);
|
||||
|
||||
/* ── Code editor (Ace) ─────────────────────────────────── */
|
||||
/* Ace's own `github` themes fail WCAG AA on the gutter: `#AAA` on the light
|
||||
gutter's `#e8e8e8` is 1.89:1, and `#7388b5` on the dark gutter's `#24292e`
|
||||
is 4.13:1 — both under 4.5:1 at the 12px the line numbers render. The
|
||||
numbers are `aria-hidden`, which exempts nothing here: contrast is a
|
||||
concern for sighted users, and axe flags them accordingly.
|
||||
`gray-7` is 5.82:1 on the light gutter; the dark block lifts it to
|
||||
`gray-5`, 4.88:1 on the dark one. */
|
||||
--inspector-code-gutter-text: var(--mantine-color-gray-7);
|
||||
|
||||
/* ── Connection status ─────────────────────────────────── */
|
||||
--inspector-status-connected: var(--mantine-color-green-6);
|
||||
--inspector-status-connecting: var(--mantine-color-yellow-6);
|
||||
|
|
@ -161,6 +171,9 @@
|
|||
schemes, which sits too dark on charcoal — lift them one to two steps so
|
||||
they stay legible in dark mode. Light-mode `:root` keeps the `*-6` values. */
|
||||
|
||||
/* Code editor (Ace) — see the note in `:root`. */
|
||||
--inspector-code-gutter-text: var(--mantine-color-gray-5);
|
||||
|
||||
/* Status */
|
||||
--inspector-status-connected: var(--mantine-color-green-4);
|
||||
--inspector-status-connecting: var(--mantine-color-yellow-4);
|
||||
|
|
@ -593,3 +606,12 @@ body.resizing-col {
|
|||
user-select: none;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
/* Ace renders its own DOM, so its gutter can only be reached by selector — it
|
||||
is not a Mantine component with a theme entry. The doubled class raises
|
||||
specificity above Ace's own `.ace-github .ace_gutter`, which is injected into
|
||||
<head> at runtime and therefore wins on source order otherwise. */
|
||||
.ace_editor.ace-github .ace_gutter,
|
||||
.ace_editor.ace-github-dark .ace_gutter {
|
||||
color: var(--inspector-code-gutter-text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue