Skip to content

[Toolkit][Shadcn] Add code-block recipe - #4100

Open
ker0x wants to merge 2 commits into
symfony:3.xfrom
ker0x:feat/toolkit-shadcn-code-block
Open

ker0x wants to merge 2 commits into
symfony:3.xfrom
ker0x:feat/toolkit-shadcn-code-block

Conversation

@ker0x

@ker0x ker0x commented Oct 15, 2026

Copy link
Copy Markdown
Contributor
Q A
Bug fix? no
New feature? yes
Deprecations? no
Documentation? yes
Issues Part of #3233
License MIT

Based on #4099 (trace recipe), which it uses in one example and updates.

The Shadcn kit had no code-block recipe, the component Shadcn uses to display code, terminal output, logs and diffs.

This adds it, ported from the Nova style: CodeBlock (with a destructive variant and an sm size), CodeBlock:Header, CodeBlock:Title, CodeBlock:Actions, CodeBlock:CopyButton, CodeBlock:Content, CodeBlock:Line (added, removed and highlighted variants) and CodeBlock:Footer. CodeBlock:Content takes a code string or a list of CodeBlock:Line, and supports wrap, lineNumbers and startLine. Line numbers and diff markers are generated content, left out of a copied selection, and blank lines survive the copy. The content is always dir="ltr", and the header follows the page direction.

A code-block Stimulus controller replaces the React state of upstream: copy (check icon, "Copied" label and live region for 2 seconds), download, toggleWrap (syncs aria-pressed) and toggleExpanded (toggles data-expanded on the content the button controls, for Show More). The edges fade with the scroll-fade-* utilities of the shadcn package the kit already depends on.

Choices that differ from upstream:

  • The copy text is read from a data-code-block-text attribute rather than a Stimulus param, since Stimulus parses params as JSON and would turn a JSON snippet into an object.
  • scrollbar-thin is not a Tailwind utility, so [scrollbar-width:thin] is used.
  • Syntax highlighting is not ported: upstream does it with Shiki in a React hook. The Syntax Highlighting, Languages, Terminal Output, Streaming and Markdown sections are left out, and the examples that only used highlighting for looks show plain text.
  • The Typeset example is left out: it relies on the typeset stylesheet of the Shadcn docs site, shipped neither by the kit nor by the shadcn package.

The README carries the demo and every other example of the upstream documentation: Basic, Header, Actions, Floating Actions, Line Numbers, Start Line, Wrap, Highlighted Lines, Diff, Height, Show More, Max Height, Size, Destructive, Trace, Tabs, Message and RTL, plus an Accessibility section. A lucide:wrap-text icon fixture is added.

The trace README used <pre> elements styled like a code block, since the kit had none. They are replaced with CodeBlock, as upstream does.

Checks run:

  • ComponentsRenderingTest: snapshots of the 19 examples, and the full Toolkit PHPUnit suite (1408 tests) passes.
  • Playwright: 50 tests for the recipe (screenshots in light and dark mode, plus specs for copying, the reset after 2 seconds, a selection without line numbers, the wrap toggle, the download, Show More, the higher cap and the floating actions on focus), and the 42 tests of trace pass.
  • ux-toolkit-kit-lint --fail-on-warning, oxfmt and oxlint are clean.

ker0x added 2 commits October 15, 2026 01:08
| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | yes
| Deprecations?  | no
| Documentation? | yes
| Issues         | Part of symfony#3233
| License        | MIT

The Shadcn kit had no `trace` recipe, the building block Shadcn uses for reasoning, tool calls, sources and more.

This adds it, ported from the Nova style: `Trace`, `Trace:Line` (with a `status` of `running`, `error` or `pending`), `Trace:Icon`, `Trace:Title`, `Trace:Description`, `Trace:Collapsible`, `Trace:Collapsible:Trigger` and `Trace:Collapsible:Content`. Physical classes are switched to logical ones (`ms-*`, `border-s`, `text-start`) so the recipe works in RTL.

`Trace:Collapsible` reuses the controller of the `collapsible` recipe, declared as a dependency, the way `drawer` reuses `dialog`. The shimmer on a running title uses the `shimmer` utility of the `shadcn` package the kit already depends on.

Choices that differ from upstream:

- Rows open and close without the accordion animation, like `Collapsible`, since they share its controller.
- `Trace` styles the elements wrapping a `Trace:Line` one level deeper than upstream (`*:*:has-…`). `Dialog` and `Sheet` put a `<div>` around their trigger, so a line opening a dialog or a sheet would otherwise lose its focus ring and its layout.
- The examples that stream a fake AI SDK chat upstream (the demo, Reasoning and Tool) show the transcript in its finished state, without the Replay button.
- The kit has no CodeBlock recipe, so the examples use a `<pre>` with the same classes.

The README carries the demo and every example the upstream documentation shows: Trace Line, Status, Description, Collapsible, Open State, Link, Dialog, Sheet, Group, Sources, Chain of Thought, Commit, Whole Turn, Reasoning, Tool and RTL, plus an Accessibility section. Six Lucide icon fixtures the examples use are added.

Checks run:

- `ComponentsRenderingTest`: snapshots of the 17 examples, and the full Toolkit PHPUnit suite (1387 tests) passes.
- Playwright: 42 tests for the recipe (screenshots in light and dark mode, plus specs for opening on click, rows open on render, a toggle outside the trigger, closing, Enter and Space, nested rows and opening a dialog from a line).
- `ux-toolkit-kit-lint --fail-on-warning` and `oxfmt` are clean.
| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | yes
| Deprecations?  | no
| Documentation? | yes
| Issues         | Part of symfony#3233
| License        | MIT

Based on symfony#4099 (`trace` recipe), which it uses in one example and updates.

The Shadcn kit had no `code-block` recipe, the component Shadcn uses to display code, terminal output, logs and diffs.

This adds it, ported from the Nova style: `CodeBlock` (with a `destructive` variant and an `sm` size), `CodeBlock:Header`, `CodeBlock:Title`, `CodeBlock:Actions`, `CodeBlock:CopyButton`, `CodeBlock:Content`, `CodeBlock:Line` (`added`, `removed` and `highlighted` variants) and `CodeBlock:Footer`. `CodeBlock:Content` takes a `code` string or a list of `CodeBlock:Line`, and supports `wrap`, `lineNumbers` and `startLine`. Line numbers and diff markers are generated content, left out of a copied selection, and blank lines survive the copy. The content is always `dir="ltr"`, and the header follows the page direction.

A `code-block` Stimulus controller replaces the React state of upstream: `copy` (check icon, "Copied" label and live region for 2 seconds), `download`, `toggleWrap` (syncs `aria-pressed`) and `toggleExpanded` (toggles `data-expanded` on the content the button controls, for Show More). The edges fade with the `scroll-fade-*` utilities of the `shadcn` package the kit already depends on.

Choices that differ from upstream:

- The copy text is read from a `data-code-block-text` attribute rather than a Stimulus param, since Stimulus parses params as JSON and would turn a JSON snippet into an object.
- `scrollbar-thin` is not a Tailwind utility, so `[scrollbar-width:thin]` is used.
- Syntax highlighting is not ported: upstream does it with Shiki in a React hook. The Syntax Highlighting, Languages, Terminal Output, Streaming and Markdown sections are left out, and the examples that only used highlighting for looks show plain text.
- The Typeset example is left out: it relies on the `typeset` stylesheet of the Shadcn docs site, shipped neither by the kit nor by the `shadcn` package.

The README carries the demo and every other example of the upstream documentation: Basic, Header, Actions, Floating Actions, Line Numbers, Start Line, Wrap, Highlighted Lines, Diff, Height, Show More, Max Height, Size, Destructive, Trace, Tabs, Message and RTL, plus an Accessibility section. A `lucide:wrap-text` icon fixture is added.

The `trace` README used `<pre>` elements styled like a code block, since the kit had none. They are replaced with `CodeBlock`, as upstream does.

Checks run:

- `ComponentsRenderingTest`: snapshots of the 19 examples, and the full Toolkit PHPUnit suite (1408 tests) passes.
- Playwright: 50 tests for the recipe (screenshots in light and dark mode, plus specs for copying, the reset after 2 seconds, a selection without line numbers, the wrap toggle, the download, Show More, the higher cap and the floating actions on focus), and the 42 tests of `trace` pass.
- `ux-toolkit-kit-lint --fail-on-warning`, `oxfmt` and `oxlint` are clean.
@ker0x
ker0x requested a review from Kocal as a code owner October 15, 2026 07:34
@carsonbot carsonbot added Documentation Improvements or additions to documentation Feature New Feature Toolkit Status: Needs Review Needs to be reviewed labels Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation Feature New Feature Status: Needs Review Needs to be reviewed Toolkit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants