Skip to content

[Toolkit][Shadcn] Add radio-group, collapsible, typography and toggle-group recipes - #3464

Merged
Kocal merged 5 commits into
symfony:3.xfrom
Amoifr:feat/toolkit-shadcn-radio-group
Apr 18, 2026
Merged

Kocal merged 5 commits into
symfony:3.xfrom
Amoifr:feat/toolkit-shadcn-radio-group

Conversation

@Amoifr

@Amoifr Amoifr commented Apr 14, 2026 •

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

Hi 👋

This PR adds four recipes from the unchecked list in #3233:

  • radio-group — form control mirroring the Checkbox pattern (native <input type=radio> + accent-primary), with a RadioGroup:Item sub-component.
  • collapsible — native <details> / <summary> based, no JS.
  • typography — H1–H4, P, Blockquote, List, InlineCode sub-components.
  • toggle-group — container for Toggle items, with variant / size propagated to items through outer-context variables (_toggle_group_variant / _toggle_group_size).

Each recipe has a Usage.html.twig and a Demo.html.twig example and passing snapshot tests.

I initially planned to send these as separate PRs and asked for a sanity check on #3233 — happy to split them back up if that is easier to review. Each recipe is a single commit so rebasing into 4 PRs is straightforward.

Note on sub-component context propagation

While working on radio-group, I noticed that variables set in a parent component ({% set _radio_group_name = ... %}) do not propagate to self-closing children, because <twig:RadioGroup:Item .../> compiles to a component() function call that does not carry outer context. It works fine for non-self-closing children (e.g. <twig:ToggleGroup:Item>...</twig:ToggleGroup:Item>, which uses the {% component %} tag — this pattern is used in toggle-group to inherit variant/size).

For radio-group, Item is always self-closing, so I kept name as an explicit prop on each Item. Curious if you would prefer a different pattern here (e.g. outerScope, forcing a block body, a helper).

Thanks a lot for the Toolkit work! 🙏

@Amoifr
Amoifr requested a review from Kocal as a code owner April 14, 2026 14:24
@carsonbot carsonbot added Feature New Feature Toolkit Status: Needs Review Needs to be reviewed labels Apr 14, 2026
@Amoifr Amoifr changed the title [Toolkit][Shadcn] Add radio-group recipe [Toolkit][Shadcn] Add radio-group, collapsible, typography and toggle-group recipes Apr 14, 2026
@Kocal

Kocal commented Apr 14, 2026

Copy link
Copy Markdown
Member

Hi, Symfony UX 3.0 has been released, and the 2.x branch is no longer maintained.

Could you please retarget this PR to the 3.x branch instead? That way we can review and merge it in the currently supported version.

Thanks!

Status: Needs Work

@carsonbot carsonbot added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Apr 14, 2026
@Amoifr
Amoifr force-pushed the feat/toolkit-shadcn-radio-group branch from 998f101 to b36173a Compare April 15, 2026 05:26
@carsonbot carsonbot added Status: Needs Review Needs to be reviewed and removed Status: Needs Work Additional work is needed labels Apr 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📊 Packages dist files size difference

Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.
Please review the changes and make sure they are expected.

FileBefore (Size / Gzip)After (Size / Gzip)
LazyImage
controller.d.ts 395 B / 257 B Removed
controller.js 904 B / 457 B Removed
Map
abstract_map_controller.d.ts 7.6 kB / 1.49 kB 7.29 kB-4% 📉 / 1.46 kB-2% 📉
abstract_map_controller.js 4.92 kB / 1.4 kB 4.65 kB-5% 📉 / 1.26 kB-10% 📉
Map (Bridge Google)
map_controller.d.ts 10.56 kB / 1.92 kB 10.26 kB-3% 📉 / 1.9 kB-1% 📉
map_controller.js 12.9 kB / 3.19 kB 11.25 kB-13% 📉 / 2.84 kB-11% 📉
Map (Bridge Leaflet)
map_controller.d.ts 9.92 kB / 1.84 kB 9.61 kB-3% 📉 / 1.81 kB-2% 📉
map_controller.js 12.45 kB / 3.36 kB 11.38 kB-9% 📉 / 3.17 kB-6% 📉
Svelte
components.d.ts 200 B / 150 B Removed
components.js 46 B / 69 B Removed
loader.d.ts 435 B / 217 B Removed
loader.js 553 B / 313 B Removed
register_controller.d.ts 384 B / 235 B Removed
register_controller.js 531 B / 303 B Removed
render_controller.d.ts 629 B / 353 B Removed
render_controller.js 1.05 kB / 493 B Removed
Swup
controller.d.ts 1012 B / 360 B Removed
controller.js 1.71 kB / 653 B Removed
TogglePassword
controller.d.ts 896 B / 355 B Removed
controller.js 2.64 kB / 1.07 kB Removed
style.min.css 312 B / 218 B Removed
Typed
controller.d.ts 1.9 kB / 501 B Removed
controller.js 1.8 kB / 638 B Removed

@Kocal
Kocal changed the base branch from 2.x to 3.x April 15, 2026 05:44
@Kocal

Kocal commented Apr 15, 2026

Copy link
Copy Markdown
Member

I just changed your base branch, can you also open a PR on https://github.com/symfony/ux.symfony.com, so I can visually see your work?

Thanks!

@Kocal Kocal added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Apr 15, 2026
@Amoifr

Amoifr commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

Sorry about this — rebased onto 3.x and moved the CHANGELOG entries into the 3.0.0 section. I'd already been reminded about this on a previous PR and still wasn't careful enough on this batch. Thanks for the patience! 🙏

@Amoifr

Amoifr commented Apr 15, 2026 •

Copy link
Copy Markdown
Contributor Author

@Kocal
Done! Companion PR on the website: symfony/ux.symfony.com#54 — it adds the matching docs stubs for all 15 new recipes across #3464, #3466, #3467, #3468 and #3469. Thanks! 🙏

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component does not perform like the Shadcn one, and the example code is wrong too:

Enregistrement.de.l.ecran.2026-04-15.a.19.23.58.mov

Please ensure the behavior is identical, and do not hesitate to write some JS if necessary, thanks 🙏🏻

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ensure to re-use the same (and all) examples from https://ui.shadcn.com/docs/components/radix/radio-group#examples 🙏🏻

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example is not correctly rendered:
Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same than Collapsible, but the component must be visually identical than the Shadcn component. Other examples must be added too:

Enregistrement.de.l.ecran.2026-04-15.a.19.31.13.mov

Thanks!

@Amoifr
Amoifr force-pushed the feat/toolkit-shadcn-radio-group branch from b36173a to 3d53e95 Compare April 16, 2026 09:28
@carsonbot carsonbot added Status: Needs Review Needs to be reviewed and removed Status: Needs Work Additional work is needed labels Apr 16, 2026
@Amoifr

Amoifr commented Apr 16, 2026

Copy link
Copy Markdown
Contributor Author

Hey @Kocal! Thanks for the thorough review — I've reworked all four components to match the Shadcn reference as closely as possible. Here's a summary of the changes:

Collapsible

  • Replaced <details>/<summary> with a <div>-based implementation using a Stimulus controller (CSS Grid animation, ARIA attributes, data-state)
  • Adopted the asChild pattern: Collapsible:Trigger now exposes collapsible_trigger_attrs (same pattern as AlertDialog:Trigger), so any element (typically a Button) can act as the trigger
  • Added all examples from the Shadcn docs: Demo (Order #4189), Basic (Product details), Settings Panel, File Tree (nested collapsibles), RTL (Arabic)

Radio Group

  • Replaced the native <input type="radio"> appearance with a custom styled radio using hidden input + visual spans (same pattern as Switch), with proper checked:bg-primary + inner dot indicator
  • Added all examples: Description, Choice Card, Fieldset, Disabled, Invalid, RTL (Arabic)

Typography

  • Rewrote the Demo with the complete Shadcn specimen ("The Joke Tax Chronicles"), including table, links, and proper heading spacing (mt-10 for H2, mt-8 for H3)
  • Added all individual examples: H1–H4, Paragraph, Blockquote, Table, List, Inline Code, Lead, Large, Small, Muted

Toggle Group

  • Added a Stimulus controller (toggle_group_controller.js) for type="single" mutual exclusion support
  • Fixed initial pressed state by passing data-toggle-pressed-value to the toggle controller
  • Used logical properties (rounded-s-lg/rounded-e-lg) for RTL support
  • Added all examples: Outline, Sizes, Vertical, Spacing, Disabled, Font Weight Selector (with dynamic label update), RTL (Arabic + Hebrew)

General

If this looks good to you, I'll continue with my 4 other PRs (currently in draft) for the remaining components and should be able to address any further feedback quickly. 🚀

@Kocal
Kocal force-pushed the feat/toolkit-shadcn-radio-group branch 2 times, most recently from dfe402d to 051113f Compare April 18, 2026 13:02
@Kocal
Kocal force-pushed the feat/toolkit-shadcn-radio-group branch from 051113f to debc869 Compare April 18, 2026 13:08
@Kocal
Kocal force-pushed the feat/toolkit-shadcn-radio-group branch from debc869 to 57f8a1d Compare April 18, 2026 13:13
@carsonbot carsonbot added Status: Reviewed Has been reviewed by a maintainer and removed Status: Needs Review Needs to be reviewed labels Apr 18, 2026
@Kocal
Kocal merged commit c5b635b into symfony:3.x Apr 18, 2026
28 checks passed
@Kocal

Kocal commented Apr 18, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution @Amoifr!

One quick note for your open PRs on Toolkit (and future ones): could you please keep it to one PR per recipe? I review PRs manually, and honestly it wasn't very fun to go through such a large batch of files and changes all at once.
Smaller, focused PRs will make the review process much smoother.

Also, please make sure to manually double-check that the visual rendering and the UX match what's provided by the original shadcn/ui components.

Thanks!

Kocal added a commit to symfony/ux.symfony.com that referenced this pull request Apr 19, 2026
This PR was merged into the main branch.

Discussion
----------

[Toolkit][Shadcn] Add docs page for collapsible

| Q              | A
| -------------- | ---
| Issues         | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License        | MIT

<!--
Replace this notice by a description of your feature/bugfix.
-->

Companion PR to symfony/ux#3464. Adds the Toolkit/Shadcn docs page for the `collapsible` recipe.

Also wires the Stimulus `Collapsible` controller in `assets/toolkit-shadcn.js` and `importmap.php` so the interactive demo on the docs page actually works (addition originally contributed by `@Kocal` on the previous #54).

Split out from the original #54 so each component can be reviewed/merged independently alongside its upstream recipe.

Commits
-------

2dee4b6 [Toolkit][Shadcn] Add docs page for collapsible
Kocal added a commit to symfony/ux.symfony.com that referenced this pull request Apr 19, 2026
This PR was merged into the main branch.

Discussion
----------

[Toolkit][Shadcn] Add docs page for radio-group

| Q              | A
| -------------- | ---
| Issues         | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License        | MIT

<!--
Replace this notice by a description of your feature/bugfix.
-->

Companion PR to symfony/ux#3464. Adds the Toolkit/Shadcn docs page for the `radio-group` recipe.

Split out from the original #54 so each component can be reviewed/merged independently alongside its upstream recipe.

Commits
-------

c83f0dd [Toolkit][Shadcn] Add docs page for radio-group
Kocal added a commit to symfony/ux.symfony.com that referenced this pull request Apr 19, 2026
This PR was merged into the main branch.

Discussion
----------

[Toolkit][Shadcn] Add docs page for toggle-group

| Q              | A
| -------------- | ---
| Issues         | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License        | MIT

<!--
Replace this notice by a description of your feature/bugfix.
-->

Companion PR to symfony/ux#3464. Adds the Toolkit/Shadcn docs page for the `toggle-group` recipe.

Split out from the original #54 so each component can be reviewed/merged independently alongside its upstream recipe.

Commits
-------

4291b1b [Toolkit][Shadcn] Add docs page for toggle-group
Kocal added a commit to symfony/ux.symfony.com that referenced this pull request Apr 19, 2026
This PR was merged into the main branch.

Discussion
----------

[Toolkit][Shadcn] Add docs page for typography

| Q              | A
| -------------- | ---
| Issues         | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License        | MIT

<!--
Replace this notice by a description of your feature/bugfix.
-->
Companion PR to symfony/ux#3464. Adds the Toolkit/Shadcn docs page for the `typography` recipe.

Split out from the original #54 so each component can be reviewed/merged independently alongside its upstream recipe.

Commits
-------

fad07ab [Toolkit][Shadcn] Add docs page for typography
Kocal added a commit that referenced this pull request Apr 19, 2026
…mples with shadcn reference (Amoifr)

This PR was squashed before being merged into the 3.x branch.

Discussion
----------

[Toolkit][Shadcn] Align collapsible File Tree and RTL examples with shadcn reference

| Q              | A
| -------------- | ---
| Bug fix?       | yes
| New feature?   | no
| Deprecations?  | no
| Documentation? | no
| Issues         | Part of #3233
| License        | MIT

Aligns the `collapsible` examples with the shadcn reference:

- **File Tree** (`apps/v4/examples/radix/collapsible-file-tree.tsx`):
  - Adds a nested `ui/` folder inside `components/` with 6 files (button, card, dialog, input, select, table)
  - Adds `login-form.tsx`, `register-form.tsx` as siblings of `ui/` in `components/`
  - Enriches `lib/` with `cn.ts`, `api.ts`
  - Replaces `use-toast.ts` with `use-media-query.ts`, `use-debounce.ts`, `use-local-storage.ts` in `hooks/`
  - Adds `api.d.ts` to `types/`
  - Adds `logo.svg`, `images` to `public/`
- **RTL** (`apps/v4/examples/radix/collapsible-rtl.tsx`):
  - Shadcn uses a shared `language-selector` component (React state + `<Select>`) to swap between English / Arabic / Hebrew. We don't have an equivalent in the Twig toolkit, so instead the example now stacks three independent `Collapsible`s — one per language with its own `dir` — which shows the same intent (RTL + LTR side-by-side) without introducing new JS infrastructure.

Follow-up to #3464.

Snapshots regenerated.

Commits
-------

6258c70 [Toolkit][Shadcn] Align collapsible File Tree and RTL examples with shadcn reference
Kocal added a commit that referenced this pull request Apr 21, 2026
…ypography recipe (Amoifr)

This PR was merged into the 3.x branch.

Discussion
----------

[Toolkit][Shadcn] Add Arabic and Hebrew RTL examples to typography recipe

| Q              | A
| -------------- | ---
| Bug fix?       | yes
| New feature?   | no
| Deprecations?  | no
| Documentation? | no
| Issues         | Part of #3233
| License        | MIT

Adds RTL examples to the `typography` recipe, aligning with the shadcn reference (`apps/v4/examples/radix/typography-rtl.tsx`):

- `Arabic.html.twig` — Arabic version of the existing Demo
- `Hebrew.html.twig` — Hebrew version of the existing Demo

Both wrap the content in `dir="rtl"` and use logical Tailwind utilities (`border-s-2`, `ps-6`, `text-start`) so the layout flips correctly.

Shadcn's upstream handles all three languages (en/ar/he) via a shared `language-selector` React component with `useState` + `<Select>`. Since the Twig toolkit has no equivalent, the example is split into two files instead (the English version is already shipped as `Demo.html.twig`).

Follow-up to #3464.

Snapshots regenerated.

Commits
-------

3a5c3bf [Toolkit][Shadcn] Add Arabic and Hebrew RTL examples to typography recipe
Kocal added a commit that referenced this pull request Apr 22, 2026
… reference (Amoifr)

This PR was merged into the 3.x branch.

Discussion
----------

[Toolkit][Shadcn] Align toggle-group examples with shadcn reference

| Q              | A
| -------------- | ---
| Bug fix?       | yes
| New feature?   | no
| Deprecations?  | no
| Documentation? | no
| Issues         | Part of #3233
| License        | MIT

Aligns the `toggle-group` examples with the shadcn reference:

- **Sizes** (`apps/v4/examples/radix/toggle-group-sizes.tsx`) — both groups now use `type="single"` (shadcn uses single, ours defaulted to multiple so all items could be pressed at once).
- **Spacing** (`apps/v4/examples/radix/toggle-group-spacing.tsx`) — same fix: `type="single"`.
- **RTL** (`apps/v4/examples/radix/toggle-group-rtl.tsx`) — adds the Hebrew version stacked below the Arabic one. Shadcn's reference switches languages via the shared `language-selector` component (React state + `<Select>`); the Twig toolkit has no equivalent, so the example stacks both variants like the `collapsible` RTL example does.

Follow-up to #3464.

Snapshots regenerated.

Commits
-------

244967d [Toolkit][Shadcn] Align toggle-group examples with shadcn reference
Kocal added a commit that referenced this pull request Apr 30, 2026
… (Kocal)

This PR was squashed before being merged into the 3.x branch.

Discussion
----------

[Toolkit] Add skill for Toolkit recipe development/review

| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations?  | no <!-- if yes, also update UPGRADE-*.md and src/**/CHANGELOG.md -->
| Documentation? | no <!-- required for new features, or documentation updates -->
| Issues         | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License        | MIT

cc `@Amoifr` `@DcgRG` `@zairigimad` `@ker0x` `@seb`-jean `@CODEheures` since you have _recently_ contributed on UX Toolkit.

I didn't have the change to try it yet, and I don't know if you all use LLMs, but any suggestion welcome :)

Generated with the following prompt (and [caveman](https://github.com/JuliusBrussee/caveman/)):
```
Génère un skill pour UX Toolkit, basé sur :
- le code des Kits existants `@src`/Toolkit/kits/
- le `@src`/Toolkit/CONTRIBUTING.md
- les commentaires de reviews dans les PR :
  - #3464
  - #3488
  - #3490
  - #3485

Il aura pour but de faciliter et normaliser la génération de code, et faciliter la code review. Identifie les différents patterns (twig doc, variable `<component>_trigger_attrs` pour Trigger/Close.html.twig, etc...)
```

Thanks!

Commits
-------

c4e04e1 [Toolkit] Add skill for Toolkit recipe development/review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New Feature Status: Reviewed Has been reviewed by a maintainer Toolkit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants