Repository navigation
Free the lab editor's keyboard, keep code readable when the compiler fails, and localise presets - #14
Conversation
JSX trims each line of a text block and joins the lines with one space.
The Chinese copy is wrapped across source lines throughout the course, so
it rendered with spaces between Chinese characters and around full-width
punctuation: 1,572 of them in 36 files.
- 1,548 line breaks are joined by a script that walks the TypeScript
syntax tree and touches only JSX text and JSX attribute strings, never
code samples, template literals or comments. Breaks next to Latin
letters, digits, expressions, "——" or operators keep their space.
- 24 more spaces go: 20 after full-width punctuation, 3 between Chinese
text and a tag whose text is Chinese, and one {" "} between a
full-width mark and Chinese text.
- test/zh-copy-spacing.test.ts, the check DataData and AlgoAlgo use,
scans every TSX file and fails on any new stray space; CLAUDE.md states
the rule.
Apart from the one {" "}, the diff changes nothing but whitespace. The
text every edited file renders differs from master only by deleted
spaces, each next to Chinese text, so the English copy is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fails, localise presets - Tab no longer traps focus: Esc, then Tab or Shift+Tab, leaves the editor, and a hint shown while it is focused says so. Tab indents (every selected line when the selection spans lines), Shift+Tab outdents and never inserts spaces, and both go through insertText so the browser's undo history survives. - Loading and failure states are a banner above the editor instead of an overlay that blurred the code. The Playground link carries the current code (#src=), and while the compiler is not running the type bar and the status bar say so. - Diagnostics are tied to the source they were computed for: squiggles disappear the moment the code changes and come back with the new result, and the list is shown as stale meanwhile. - Screen readers hear one "N errors" summary from a status region instead of the whole list. The tabs follow the WAI-ARIA pattern (aria-controls, tabpanel, roving tabindex, arrow keys, Home and End), and the editor has a visible focus ring. - The ten presets with comments now come in both languages (TsLabPreset.code is Loc<string>), so a Chinese reader no longer gets English comments after a click. - The lab keeps the dark theme's accent inside its always-dark frame in the light theme, and the status note, timing and type-bar hints are raised above 6:1. - The editor uses 16px text on narrow screens, the spinner keeps turning slowly under reduced motion, an unset strict switch shows as on as the worker treats it, and useTsLab subscribes through useSyncExternalStore. - "About 11 MB" becomes "About 2 MB to download", the empty output message no longer implies that errors block emit, and the version badge's tooltip is bilingual. - Stop tracking public/tslab/typescript.js and libs.json (11.6 MB that nothing loads) and ignore everything in public/tslab except worker.js. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a563b75570
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| setMs(r.ms); | ||
| setChecking(false); | ||
| const n = r.diagnostics.filter((d) => d.severity === "error").length; | ||
| setLiveSummary(n > 0 ? L(TXT.errorCount(n)) : L(TXT.noErrors)); |
There was a problem hiding this comment.
Recompute the live summary after language changes
When a lab has already compiled and the reader switches between English and Chinese, this stores the translated summary in state, but the checking effect does not depend on lang or L. If the source is unchanged—or the learner has edited it, so language switching preserves it—the hidden role="status" continues exposing text such as “1 error” in the previous language. Store the error count instead and translate during render, or update the summary when the language changes.
Useful? React with 👍 / 👎.
| [text, lang], | ||
| ); | ||
|
|
||
| if (text === null) return <div className="tsl-diag-idle">{pending}</div>; |
There was a problem hiding this comment.
Stop showing a pending emit after compiler failure
When the worker fails before the user has opened an output tab, output.js and output.dts remain null, while the emit effect refuses to run unless ts.status === "ready". Opening Compiled JS or Declaration .d.ts therefore displays “checking…” indefinitely even though the failure banner and status bar say the compiler is not running. Handle the failed state separately instead of treating every null output as pending.
Useful? React with 👍 / 👎.
Branches from #9 (commit
2148ad8), so it can be merged before or after it, and independently of #10–#13.Summary
Fixes from the 2026-10-09 audit (
04-TSer-代码与体验.md), all in the compiler lab:.tsl-st-note): the status note, timing and type-bar hint were 3.4–3.6:1.public/tslab/typescript.jsandlibs.json(11.6 MB) were tracked and deployed, but nothing loads them.strictswitch showed as off, although the worker treats it as on.useTsLabsubscribed in an effect, which can miss an update.Changes
lib/tslab.tsxinsertText, so the browser's undo history is kept.aria-describedbysays so..tsl-bannerabove the editor; the code stays readable and selectable.…/play/#src=<encoded current code>, and the type bar and status bar say the compiler is not running.role="status"announces one summary ("1 error") only when it changes.aria-controls, atabpanel, a roving tabindex and Arrow/Home/End keys.TsLabPreset.codeisLoc<string>. An unsetstrictswitch is shown as on.lib/tslab-client.tsx:useTsLabusesuseSyncExternalStore, with a snapshot that changes reference on every publish.app/globals.css, section 14 (the lab) only:.tsl-bannerreplaces.tsl-overlay.--acc,--acc-ink,--acc-softand--acc-borderto the dark theme's values..tsl-ta:focus-visible,.tsl-keyhint,.tsl-srand.tsl-diags[data-stale].2s infinite !important.app/types,functions,structural,utility,type-magicpage.tsx: only the ten preset constants listed in A16 change. The English code is byte-for-byte the same, and the Chinese copy translates only the comments.public/tslab/typescript.jsandlibs.jsonare removed..gitignorenow ignores/public/tslab/*exceptworker.js.test/tslab-editor.test.tsx.Verification
npx tsc --noEmit --incremental false: clean.npm test: 7 files, 48 tests pass.npm run build: succeeds.next start:/types): Tab inserts 2 characters, and ⌘Z restores the original text. Shift+Tab at column 0 changes nothing. Esc then Tab moves focus out of the editor.qtyagain and the status region says "1 error".worker.jsblocked, the banner shows the failure and no overlay is rendered. The editor's centre hits the textarea, so the code is selectable. The Playground link is…/play/#src=%2F%2F%20Not%20one%20type…, and the type bar and status say the compiler is not running.typescriptlang.org/play/#src=…with a sample that has a Chinese comment loads exactly that code into the Playground editor./tsconfig, colours resolved on a canvas): selected tab 9.37:1, enabledstrictswitch 8.2:1, status note 6.33:1, type-bar hint 6.42:1./types,/functions,/structural,/utilityand/type-magicleaves no English comment.infinite 2s./tslab/typescript.jsand/tslab/libs.jsonreturn 404.🤖 Generated with Claude Code