Skip to content

feat(ui): syntax highlighting in the code editor - #24

Merged
suradet-ps merged 7 commits into
mainfrom
feat/editor-highlight
Aug 15, 2026
Merged

feat(ui): syntax highlighting in the code editor#24
suradet-ps merged 7 commits into
mainfrom
feat/editor-highlight

Conversation

@suradet-ps

Copy link
Copy Markdown
Owner

What

Adds live syntax highlighting to the code input(s) in the sidebar — the textarea is now overlaid on a <pre> rendered from the same syntect token stream that drives the canvas export, so what you type matches what you export.

Branch note: stacked on feat/sidebar-redesign (#23). Once #23 merges, GitHub retargets this PR to main automatically.

How it works

  • highlighter::highlight_to_html() renders tokens as inline-HTML <span>s (color + weight/style/underline from the theme)
  • CodeEditor component (new editor.rs): transparent-text textarea over a pointer-events: none <pre>; both layers share identical font metrics and wrapping; the <pre> scrolls in lockstep with the textarea
  • The editor wrapper takes the theme palette as background and the theme foreground as caret color — the input box mirrors the export card (Dracula input = dark editor box, GitHub Light = white box)
  • Works for both the main and split panels (split uses its own theme/language)
  • Tab still inserts 4 spaces; text is HTML-escaped; highlight errors degrade to an escaped message

Verified in headless Chrome (CDP probe)

  • 18 spans rendered; fn pink under Dracula; wrapper bg rgb(40,42,54), caret rgb(248,248,242)
  • Textarea/pre identical metrics: width 299px, padding 12px, JetBrains Mono 12.5px, line-height 18.75px, pre-wrap/break-all
  • Scroll sync: textarea scrollTop 200 → pre 200; reset → 0

Commits

  1. feat(highlighter): render token streams as inline-HTML spanshighlight_to_html, token_to_html, escape_html + 8 new tests
  2. feat(app): add syntax-highlighted code editor overlayCodeEditor component, wired into both panels
  3. feat(ui): style the highlighted code editor overlaystyle.css
  4. docs: document the highlighted code editor overlay patterndocs/DESIGN.md

Verification

  • cargo check -p codeframe-app --target wasm32-unknown-unknown passes
  • cargo fmt --all --check passes
  • cargo clippy --workspace --all-targets -- -D warnings passes
  • cargo test --workspace passes (43 tests incl. 8 new)
  • trunk build --release succeeds
  • Headless-Chrome end-to-end probe passes (highlight, metrics, scroll sync)

Add highlight_to_html() (plus the token_to_html and escape_html
helpers) so the code editor can overlay syntax-colored text behind
a transparent-text textarea. Pure string building - no web-sys or
Leptos types, unit-tested on any host.
New CodeEditor component: a transparent-text textarea over a pre
layer whose innerHTML comes from highlighter::highlight_to_html.
Both panels (main + split) now mirror the selected syntax theme -
the editor background and caret use the theme palette, scroll syncs
between layers, and Tab still inserts spaces.
The editor wrapper carries the theme palette as background and the
caret uses the theme foreground, so the input mirrors the export.
The pre overlay and the transparent-text textarea share identical
font metrics and wrapping (pre-wrap, break-all) and the pre layer
scrolls in lockstep with the textarea.
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
codeshot Ready Ready Preview Aug 15, 2026 3:38am

The reactive prop:value binding rewrote the textarea on every input,
stomping the browser's caret during paste/undo. Set the value once at
creation and let the DOM own it - the signal now only follows input
events. Tab insertion also switches from manual UTF-16 byte slicing
(which panicked on multi-byte characters like the em dash in the
sample code) to the native setRangeText().
@suradet-ps
suradet-ps merged commit 82b6ff8 into main Aug 15, 2026
12 of 13 checks passed
@suradet-ps
suradet-ps deleted the feat/editor-highlight branch August 15, 2026 03:34
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.

1 participant