Conversation
Every recipe declared `type: "component"` and no code path depended on the distinction: the only consumers filtered `getRecipes()` to `RecipeType::Component`, but iterating all recipes is equivalent since a recipe without component templates contributes nothing to Twig component resolution. The `create-kit` scaffolder already omitted `type` from its generated manifest, so requiring it was also inconsistent. Drop the property from `RecipeManifest`, delete the `RecipeType` enum, remove `type` from the recipe schema and all kit manifests, and simplify `Kit::getRecipes()`/`getRecipe()` to no longer take a type filter.
There was a problem hiding this comment.
Pull request overview
Removes the unused type field from Symfony UX Toolkit recipe manifests, simplifying the internal recipe model and allowing future “non-component” (e.g. controller-only) recipes without forcing an artificial enum classification.
Changes:
- Remove
RecipeTypeand drop thetypeproperty fromRecipeManifest+ JSON parsing. - Simplify
Kit::getRecipes()/Kit::getRecipe()and updateKitContextRunnerto iterate all recipes. - Update recipe schema + kit recipe manifests (and tests) to no longer include/require
type.
Reviewed changes
Copilot reviewed 76 out of 76 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Toolkit/src/Recipe/RecipeType.php | Removes the unused enum that previously backed manifest type. |
| src/Toolkit/src/Recipe/RecipeManifest.php | Drops type from the manifest object and JSON parsing. |
| src/Toolkit/src/Kit/Kit.php | Simplifies recipe retrieval APIs by removing the type filter parameters. |
| src/Toolkit/src/Kit/KitContextRunner.php | Updates Twig/component resolution wiring to iterate all recipes. |
| src/Toolkit/schema-kit-recipe-v1.json | Removes type from the recipe manifest schema and keeps name required. |
| src/Toolkit/kits/shadcn/accordion/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/alert/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/alert-dialog/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/aspect-ratio/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/avatar/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/badge/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/breadcrumb/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/button/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/button-group/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/card/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/checkbox/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/collapsible/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/combobox/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/dialog/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/empty/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/field/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/hover-card/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/input/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/input-group/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/item/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/kbd/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/label/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/pagination/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/progress/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/radio-group/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/resizable/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/select/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/separator/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/skeleton/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/sonner/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/spinner/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/switch/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/table/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/tabs/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/textarea/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/toggle/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/toggle-group/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/tooltip/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/shadcn/typography/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/alert/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/avatar/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/badge/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/button/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/button-group/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/card/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/checkbox/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/dropdown/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/indicator/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/input/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/kbd/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/label/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/modal/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/pagination/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/radio/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/select/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/skeleton/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/spinner/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/table/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/tabs/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/textarea/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/flowbite-4/toggle/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/common/logout-link/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/kits/common/post-link/manifest.json | Removes the type property from the recipe manifest. |
| src/Toolkit/tests/Recipe/RecipeTest.php | Updates unit tests to construct manifests without type. |
| src/Toolkit/tests/Recipe/RecipeManifestTest.php | Updates JSON parsing tests to no longer require/validate type. |
| src/Toolkit/tests/Kit/Lint/Checker/DocCheckerTest.php | Updates fixtures for new manifest constructor shape. |
| src/Toolkit/tests/Kit/Lint/Checker/DocHeadingLevelCheckerTest.php | Updates fixtures for new manifest constructor shape. |
| src/Toolkit/tests/Kit/KitTest.php | Updates kit tests to no longer assert type-filtered behavior. |
| src/Toolkit/tests/Installer/PoolTest.php | Updates installer pool tests for new manifest constructor shape. |
| src/Toolkit/tests/Functional/ComponentsRenderingTest.php | Adjusts functional rendering to iterate all recipes. |
| src/Toolkit/CHANGELOG.md | Documents the manifest type removal in 3.4.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| foreach ($kit->getRecipes() as $recipe) { | ||
| $loaders[] = new FilesystemLoader($recipe->absolutePath); | ||
| } |
| foreach ($this->kit->getRecipes() as $recipe) { | ||
| foreach ($recipe->getFiles() as $file) { | ||
| if (str_ends_with($file->sourceRelativePathName, 'templates/components/'.str_replace(':', '/', $name).'.html.twig')) { | ||
| return $file->sourceRelativePathName; |
| foreach ($kit->getRecipes(RecipeType::Component) as $recipe) { | ||
| foreach ($kit->getRecipes() as $recipe) { | ||
| foreach ($recipe->getExamples() as $i => $example) { | ||
| yield \sprintf('Kit %s, component %s, example #%d', $kitName, $recipe->name, $i) => [$kitName, $recipe->name, $example['code']]; |
Kocal
left a comment
There was a problem hiding this comment.
I didn't had time to work on it, but the type was supposed to be component or block (#3246) , like https://ui.shadcn.com/blocks, https://flowbite.com/blocks/, https://getbootstrap.com/docs/5.3/examples/#custom-components, etc..
So 👎🏻 for me
|
See open PR #3596 |
|
So a recipe that's purely a stimulus recipe, should be "component"? |
|
Mmmh, let's say that big compound recipes are blocks, and others are components, yep! Note that ux.symfony.com consumes
Everything is ready for building blocks, I just didn't have time to continue to work on them. |

Every recipe manifest declared
"type": "component", and no code path actually depended on the value. The only consumers wereKit::getRecipes()/getRecipe(), whoseRecipeTypefilter was used in exactly one place —KitContextRunner, to select recipes when wiring Twig component resolution. Iterating all recipes there is equivalent: a recipe with no component templates contributes nothing to resolution and simply falls through. Theblockcase existed only in in-memory unit-test fixtures — no real recipe ever used it. And thecreate-kitscaffolder already omittedtypefrom the manifest it generates, so requiring the property was internally inconsistent.So the field carried no information that isn't already implicit in a recipe's files. This removes it:
RecipeTypeenum and drop thetypeproperty fromRecipeManifest.Kit::getRecipes()/getRecipe()to drop the type filter;KitContextRunnernow iterates all recipes.typefromschema-kit-recipe-v1.jsonand from all 63 kit manifests.This clears the way for controller-only recipes (e.g. a forthcoming
closeablerecipe in thecommonkit) that ship a Stimulus controller and no Twig component — a shape thecomponent/blockenum had no honest slot for.