perf(json-editor): unify admin JSON editing experience (#6421)

* perf(json-editor): improve JSON editing experience

- integrate Yace for syntax highlighting, history, indentation, auto-closing, and smart line breaks.
- add copy support, cursor location feedback, and synchronized content and line-number scrolling.
- extract JSON editor utilities and cover key interactions with unit tests.

* perf(system-settings): improve JSON configuration editing

- replace raw JSON textareas with the shared editor for highlighting, validation, copy, and formatting.
- preserve field-specific examples and make placeholders visible through the transparent editor layer.
- remove duplicate formatting controls while keeping existing form validation and save behavior.

* perf(json-editor): standardize JSON inputs across admin settings

- replace pure JSON textareas with the shared editor across system settings and channel workflows.
- preserve form focus, validation, placeholders, and visual or JSON editing modes.
- add happy-dom component coverage for form bindings, controlled updates, and formatting.

* fix(json-code-editor): address accessibility review findings

- Drop the unconditional aria-label that overrode every field's
  label-derived accessible name; add an optional ariaLabel prop and
  set it at call sites without an associated label
- Associate standalone Labels via htmlFor/id in channel-affinity views
- Hide the highlight mirror and line-number layers from the
  accessibility tree (aria-hidden)
- Give the line-number gutter an opaque background so horizontally
  scrolled code no longer slides under it
- Degrade to no scroll sync instead of destroying the editor when the
  line-number layer is not found
This commit is contained in:
QuentinHsu
2026-07-25 19:10:28 +08:00
committed by GitHub
parent 18b0b7631a
commit eb4a1bd193
28 changed files with 1089 additions and 419 deletions
+43
View File
@@ -45,6 +45,49 @@ For commercial licensing, please contact support@quantumnous.com
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
.json-code-editor-textarea {
overflow: auto !important;
scrollbar-gutter: stable;
}
.json-code-editor-textarea::placeholder {
color: var(--muted-foreground);
opacity: 1;
-webkit-text-fill-color: var(--muted-foreground);
}
.json-code-editor-textarea,
.json-code-editor-highlight,
.json-code-editor-lines {
overflow-wrap: normal !important;
white-space: pre !important;
}
.json-code-editor-lines {
background: var(--background);
z-index: 1;
}
.json-code-editor-highlight .yace-tok--str {
color: var(--chart-5);
}
.json-code-editor-highlight .yace-tok--num {
color: var(--chart-4);
}
.json-code-editor-highlight .yace-tok--kw {
color: var(--chart-1);
}
.json-code-editor-highlight .yace-tok--punc {
color: var(--muted-foreground);
}
.json-code-editor-highlight .yace-tok--com {
color: var(--muted-foreground);
}
}
@layer base {