Repository navigation
WireframeEditor and WireframePlayground - #3
Merged
Merged
Conversation
- <WireframeEditor>: tsquare/editor in React. value/defaultValue, onChange, onProblems (after a 300 ms pause), autocomplete, lineNumbers, ariaLabel; a ref gets getText, setText, focus, goToLine. EditorCore is the shared part. - <WireframePlayground>: the editor and the viewer on one text, side by side (stacked under 640px via a container query, or layout="row"/"column"). While typing (until 400 ms without a change) the board redraws on the streaming throttle and problems wait; then they're underlined and counted in a note on the board. - The viewer calls tsquare's destroy() on unmount. - styles.css: the editor's colors from the --tsquare-* theme, the playground layout, --tsquare-editor-height and --tsquare-playground-height. - Docs: editor.md, playground.md; the overview table and styling.md. - Tests (20): editor text/ref/onChange, problems underlined after a pause and onProblems, controlled value and options, playground (board, problems held while typing then underlined and noted, layout, showProblems), viewer destroy on unmount; docs examples typecheck and props documented. - tsquare ^0.12.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
At 760px wide (a typical docs or app column) the editor got 303px while the example's lines needed 746px; most of each line was hidden behind sideways scrolling. Side by side now starts at 900px, and the two panes share the space evenly. Wrapping long lines (tsquare 0.12.1) comes next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Mount-time ref calls can fail silently, the persistence example can overwrite another sketch, and viewer-only bundles can retain the editor dependency.
3 open issues
What changed in this PR
Adds React editing components alongside the existing wireframe viewer, with live previews and delayed problem reporting.
Changes:
- Adds
WireframeEditorand responsiveWireframePlayground. - Adds themed styles and viewer cleanup on unmount.
- Updates tsquare, documentation, and component tests.
| File | Description |
|---|---|
| test/react.test.tsx | Tests editors, playground behavior, styles, and cleanup. |
| test/docs.test.ts | Checks new component prop documentation. |
| src/viewer.tsx | Destroys the viewer on unmount. |
| src/styles.css | Adds editor themes and playground layouts. |
| src/playground.tsx | Combines editing and live preview. |
| src/index.ts | Exports new components and types. |
| src/editor.tsx | Wraps the editor with diagnostics and ref methods. |
| README.md | Introduces editing components. |
| package.json | Updates tsquare to 0.12. |
| package-lock.json | Locks the updated dependency. |
| docs/styling.md | Documents editor and playground styling. |
| docs/README.md | Extends component selection guidance. |
| docs/playground.md | Documents playground usage and persistence. |
| docs/editor.md | Documents editor props and controls. |
| CHANGELOG.md | Records new features and cleanup. |
Review effort: Balanced
lineWrapping, default true, on WireframeEditor and WireframePlayground: long lines wrap instead of scrolling sideways, continuing 4 spaces past their indentation. tsquare ^0.12.1. Docs and CHANGELOG; a test for the default and for turning it off. Checked in Chrome: a 379px editor in a side-by-side playground wraps every line and doesn't scroll sideways. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ample - The editor and playground move to @tsquare-js/react/editor (a second esbuild entry with a shared chunk): the main entry never reaches tsquare/editor, so a Wireframe-only app bundles 489 KB gzipped instead of 617 KB (no CodeMirror). test/package.test.ts checks what each entry reaches, the shared chunk and "use client" on every file. - The editor is created in a layout effect declared before useImperativeHandle, so a callback ref or a parent's useLayoutEffect can focus it and read its text (before: no-op and ""). useEffect on the server. Test added (mutation-checked: it fails with the old useEffect). - docs/playground.md: the saved-sketch example keys its stateful part by id, so switching sketches can't save one's text under another's id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Part 2 of v0.2's plan, React side. Released as 0.3.0 after this.
Imported from
@tsquare-js/react/editor(review fix)The editor and playground are a second entry point, so the main one never loads
tsquare/editor(CodeMirror). Measured with esbuild: an app importing onlyWireframewent from 617 KB gzipped (CodeMirror included) to 489 KB; the playground is 617 KB.test/package.test.tschecks what each entry reaches, the shared chunk and"use client".Components
<WireframeEditor>(tsquare 0.12'stsquare/editor): highlighting, autocomplete (languageData()), problems underlined ~300 ms after typing stops (with the message on hover), Enter keeps indentation, a pasted model reply is trimmed to its code block. Props:value/defaultValue,onChange,onProblems,autocomplete,lineNumbers,ariaLabel,className,style. Aref(WireframeEditorHandle) getsgetText,setText,focus,goToLine. A newvaluereplaces the text unless it's the editor's own change coming back.<WireframePlayground>: editor + viewer on one text.layout"auto"(row ≥ 900px wide, column below, via a container query),"row"or"column". While typing (until 400 ms without a change) the board redraws on the 200 ms streaming throttle and problems wait; then the editor underlines them and the board gets "N problems · showing the last valid board" (dimmed). AlsoshowProblems,chips,zoomControls,autocomplete,lineNumbers,onProblems, and the sameref.destroy()on unmount (part 1's known leak).Narrow editors (added after review of a screenshot)
In a 760px playground the editor was 303px wide while the example's lines needed 746px: most of each line was hidden behind sideways scrolling.
layout="auto"stacks below 900px (was 640px), and side by side the editor and board share the width half and half (was 2:3).lineWrapping, tsquare 0.12.1's new editor option), each continuation 4 spaces past its line's indentation;lineWrapping={false}scrolls sideways instead.Styles
The editor's colors come from the
--tsquare-*theme (its highlighting keeps the editor's light/dark defaults unless--tsquare-syntax-*is set);.tsquare-editor20rem and.tsquare-playground36rem by default (--tsquare-editor-height,--tsquare-playground-height). All rules stay in:where().Docs
New
docs/editor.mdanddocs/playground.md(props tables, typing behavior, ref methods, saving the text, bundle size); the overview's "which component" table andstyling.mdcover them. The site picks the pages up from the package once it pins 0.3.0 (they're linked from the overview's table, so they join the nav and previous/next in order).Verification
npm test: 20 (was 15): editor (text, aria, ref.setText → onChange, unmount removes it; problems underlined only after a pause, onProblems with the list and[]on fix; controlled value; options), playground (board and 4 chips; nothing while typing, then note + underline + dim + onProblems;layout,showProblems={false}keeps underlines), viewer destroy on unmount; docs (examples typecheck, every prop of the two new components documented). Three consecutive runs green.butonshows nothing at once, then the underline, the note, the dimmed board andonProblems; autocomplete offersbutton; hovering the underline shows the message; at 375px it stacks;data-theme="dark"turns the editor and viewer dark; no console errors.AbortControllerandWindowglobals (the viewer's listeners, CodeMirror's measuring); browsers and Jest/Vitest's jsdom environments provide them.🤖 Generated with Claude Code