Skip to content

feat(demo): highlighted code blocks with labels, tabs and Copy - #31

Merged
alekswebnet merged 2 commits into
mainfrom
feat/demo-code-blocks
Oct 14, 2026
Merged

alekswebnet merged 2 commits into
mainfrom
feat/demo-code-blocks

Conversation

@alekswebnet

Copy link
Copy Markdown
Contributor

Closes #30.

The demo pages' code snippets now stand apart from the text. Each block is a dark panel in both themes, highlighted, with a label, tabs where there are alternatives, and a Copy button.

How

Authoring: a page writes <pre class="code" data-lang="sh|js|html|xml|text">.

  • data-title names a block by a file instead of a language, such as cmi5.xml on the cmi5 page.
  • Blocks inside <div class="code-tabs"> that each carry data-tab become tabs. The setup page's install command is now npm / pnpm / yarn.

Build: apps/demo/scripts/lib/code-blocks.mjs is a transformIndexHtml hook that runs after the site URL is filled in.

  • It highlights each block with Shiki 4.4.3 and wraps it in a <figure> with a head (label, tabs, Copy).
  • The policy is style-src 'self', and Shiki's themes write a style attribute on every token. So the theme is our own: its colours name roles (var(--tk-string)), and a transformer turns each into a class.
  • The roles are coloured in player-page.css: tag, attribute, string, keyword, function, constant, comment, punctuation.
  • Shiki is a dev dependency only; none of it reaches a visitor.

Page: apps/demo/demo/code-blocks.js (1.6 kB built) works the tabs and Copy.

  • Tabs follow the ARIA pattern: arrow keys, Home and End.
  • A tab is one choice for the whole site, remembered in localStorage.
  • Copy writes the visible panel to the clipboard. Where the clipboard is refused, it selects the code instead, and a status line reads the result to screen readers.

Style:

  • Light theme: an ink panel (#141a23).
  • Dark theme: a panel darker than the page, with a border.
  • Blocks are spaced apart, and the event logs keep their pale panel so output still looks different from code.

Pages: setup, embed, examples, normalize and cmi5. Every block is labelled, and the five pages load the script.

Testing

Run Result
tests/code-blocks.test.ts, Chromium 12/12
Same, Firefox / WebKit 11/11 each, Copy skipped (reading the clipboard back needs a permission only Chromium grants a test)
Demo suite, Chromium 51/51
pnpm build:demo, then preview:demo with the production headers, five pages no CSP violation; token colours applied; Copy put the yarn command on the clipboard
Built setup.html 8 blocks, no style attribute
Typecheck clean

The unit tests check every snippet on the five pages: after highlighting, each says exactly what the page wrote, which is what Copy hands over. They also check that no style attribute appears, the tab markup (ids, aria-controls, the first tab selected), file titles, and unknown languages. The browser test covers clicks, the arrow keys, End, the choice surviving a reload, and Copy.

I compared screenshots before and after on the setup page, in both themes, at desktop and phone widths, and checked every block on the other four pages.

Release

None: demo site only. Vercel deploys it on merge.

🤖 Generated with Claude Code

The demo pages' snippets used the page's pale surface colour in the prose's
ink, and consecutive ones touched, so they were hard to tell from the text.
A Vite plugin now highlights every <pre class="code" data-lang> with Shiki
when a page is served or built: a dark panel in both themes, a label naming
the language or file, tabs for alternatives (npm, pnpm, yarn), and a copy
button. The theme names roles that leave the output as classes, since the
site's style-src 'self' refuses the style attributes highlighters write;
only a 1.6 kB script for the tabs and Copy reaches the browser.

Closes #30.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

socket-security Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedshiki@​4.4.31001007794100

View full report

Comment thread apps/demo/scripts/lib/code-blocks.mjs Fixed
Comment thread apps/demo/tests/code-blocks.test.ts Fixed
…hout stripping tags

CodeQL flagged the tab group's pattern for backtracking (js/redos) and the
test's tag-stripping replace as incomplete sanitization. A group now runs to
the first </div>, which a block's escaped code cannot contain, and the test
reads the text between tags instead of removing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alekswebnet
alekswebnet merged commit 7fe89ec into main Oct 14, 2026
7 checks passed
@alekswebnet
alekswebnet deleted the feat/demo-code-blocks branch October 15, 2026 17:07
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.

Demo: code snippets are hard to tell from text

2 participants