Skip to content

[Toolkit] Rework kits architecture, change term for "recipe" #2986

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Toolkit/bin/ux-toolkit-kit-debug
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use Symfony\Contracts\Service\ServiceProviderInterface;
use Symfony\UX\Toolkit\Command\DebugKitCommand;
use Symfony\UX\Toolkit\Kit\KitSynchronizer;
use Symfony\UX\Toolkit\Kit\KitFactory;
use Symfony\UX\Toolkit\Recipe\RecipeSynchronizer;
use Symfony\UX\Toolkit\Registry\GitHubRegistry;
use Symfony\UX\Toolkit\Registry\LocalRegistry;
use Symfony\UX\Toolkit\Registry\RegistryFactory;
Expand All @@ -46,7 +47,8 @@ if (!class_exists(Application::class)) {
}

$filesystem = new Filesystem();
$kitFactory = new KitFactory($filesystem, new KitSynchronizer($filesystem));
$kitSynchronizer = new KitSynchronizer($filesystem, new RecipeSynchronizer($filesystem));
$kitFactory = new KitFactory($filesystem, $kitSynchronizer);

(new Application())->add($command = new DebugKitCommand($kitFactory))
->getApplication()
Expand Down
15 changes: 13 additions & 2 deletions src/Toolkit/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\UX\Toolkit\Command\CreateKitCommand;
use Symfony\UX\Toolkit\Command\DebugKitCommand;
use Symfony\UX\Toolkit\Command\InstallComponentCommand;
use Symfony\UX\Toolkit\Command\InstallCommand;
use Symfony\UX\Toolkit\Kit\KitContextRunner;
use Symfony\UX\Toolkit\Kit\KitFactory;
use Symfony\UX\Toolkit\Kit\KitSynchronizer;
use Symfony\UX\Toolkit\Recipe\RecipeSynchronizer;
use Symfony\UX\Toolkit\Registry\GitHubRegistry;
use Symfony\UX\Toolkit\Registry\LocalRegistry;
use Symfony\UX\Toolkit\Registry\RegistryFactory;
Expand All @@ -34,7 +36,13 @@
])
->tag('console.command')

->set('.ux_toolkit.command.install', InstallComponentCommand::class)
->set('.ux_toolkit.command.create_kit', CreateKitCommand::class)
->args([
service('filesystem'),
])
->tag('console.command')

->set('.ux_toolkit.command.install', InstallCommand::class)
->args([
service('.ux_toolkit.registry.registry_factory'),
service('filesystem'),
Expand Down Expand Up @@ -75,6 +83,7 @@
->set('.ux_toolkit.kit.kit_synchronizer', KitSynchronizer::class)
->args([
service('filesystem'),
service('.ux_toolkit.recipe.recipe_synchronizer'),
])

->set('ux_toolkit.kit.kit_context_runner', KitContextRunner::class)
Expand All @@ -83,5 +92,7 @@
service('twig'),
service('ux.twig_component.component_factory'),
])

->set('.ux_toolkit.recipe.recipe_synchronizer', RecipeSynchronizer::class)
;
};
94 changes: 63 additions & 31 deletions src/Toolkit/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,24 @@ to change, or even change drastically.
Symfony UX Toolkit provides a set of ready-to-use kits for Symfony applications.
It is part of `the Symfony UX initiative`_.

Kits are a nice way to begin a new Symfony application, by providing a set
of `Twig components`_ (based on Tailwind CSS, but fully customizable depending
on your needs).
Kits are a nice way to begin a new Symfony application, they contains
recipes to install nicely-crafter `Twig components`_ (already stylized,
but fully customizable depending on your needs) and more.

Please note that the **UX Toolkit is not a library of UI components**,
but **a tool to help you build your own UI components**.
It uses the same approach than the popular `Shadcn UI`_,
and a similar approach than `Tailwind Plus`_.

After installing the UX Toolkit, you can start pulling the components you need
from `UX Toolkit Kits`_, and use them in your project.
They become **your own components**, and **you can customize them as you want**.
After installing the UX Toolkit, you can start installing the recipes you need
from `UX Toolkit Kits`_ and use them in your project.
Files created by the recipes become part of your project, and
you can customize them as you want.

Additionally, some `Twig components`_ use ``html_cva`` and ``tailwind_merge``,
you can either remove them from your project or install ``twig/html-extra``
and ``tales-from-a-dev/twig-tailwind-extra`` to use them.

Also, we do not force you to use Tailwind CSS at all. You can use whatever
CSS framework you want, but you will need to adapt the UI components to it.

Installation
------------

Expand All @@ -37,27 +35,25 @@ Install the UX Toolkit using Composer and Symfony Flex:
# The UX Toolkit is a development dependency:
$ composer require --dev symfony/ux-toolkit

# If you want to keep `html_cva` and `tailwind_merge` in your Twig components:
$ composer require twig/extra-bundle twig/html-extra:^3.12.0 tales-from-a-dev/twig-tailwind-extra

Usage
-----

You may find a list of components in the `UX Components page`_, with the installation instructions for each of them.
You may find a list of available kits in the `UX Toolkit Kits`_ page, with the installation instructions for each of them.

For example, if you want to install a `Button` component, you will find the following instruction:

.. code-block:: terminal

$ php bin/console ux:toolkit:install-component Button --kit=<kitName>
$ php bin/console ux:install Button --kit=<kitName>
Copy link
Member Author

Choose a reason for hiding this comment

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

The command ux:toolkit:install-component has been renamed to ux:install, cc @smnandre


It will create the ``templates/components/Button.html.twig`` file, and you will be able to use the `Button` component like this:
It will create the ``templates/components/Button.html.twig`` file in your project,
and you will be able to use the `Button` component like this:

.. code-block:: html+twig

<twig:Button>Click me</twig:Button>

Create your own kit
Create your own Kit
-------------------

You have the ability to create and share your own kit with the community,
Expand Down Expand Up @@ -96,19 +92,55 @@ After creating your kit, the repository should have the following structure:
.. code-block:: text

.
├── docs
│ └── components
│ └── Button.twig
├── manifest.json
└── templates
└── components
└── Button.html.twig

A kit is composed of:

- A ``manifest.json`` file, that describes the kit (name, license, homepage, authors, ...),
- A ``templates/components`` directory, that contains the Twig components,
- A ``docs/components`` directory, optional, that contains the documentation for each "root" Twig component.
├── Button
│   ├── manifest.json
│   └── templates
│   └── components
│   └── Button.html.twig
└── manifest.json


A kit is described by a ``manifest.json`` file at the root directory, which contains the metadata of the kit:

.. code-block:: json

{
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-v1.json",
"name": "My UX Toolkit Kit",
"description": "A custom kit for Symfony UX Toolkit.",
"homepage": "https://github/com/User/MyUxToolkitKit",
"license": "MIT"
}

Then, a kit can contain one or more recipes. Each recipe is a directory
with a ``manifest.json`` file and some files to be copied into the project.

The ``manifest.json`` file of a recipe contains the metadata of the recipe:

.. code-block:: json

{
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json",
"name": "Button",
"description": "A clickable element that triggers actions or events, supporting various styles and states.",
"copy-files": {
"templates/": "templates/"
},
"dependencies": {
{
"type": "php",
"package": "twig/extra-bundle"
},
{
"type": "php",
"package": "twig/html-extra:^3.12.0"
},
{
"type": "php",
"package": "tales-from-a-dev/twig-tailwind-extra"
}
}
}

Using your kit
~~~~~~~~~~~~~~
Expand All @@ -117,10 +149,10 @@ Once your kit is published on GitHub, you can use it by specifying the ``--kit``

.. code-block:: terminal

$ php bin/console ux:toolkit:install-component Button --kit=github.com/my-username/my-ux-toolkit-kit
$ php bin/console ux:install Button --kit=github.com/my-username/my-ux-toolkit-kit

# or for a specific version
$ php bin/console ux:toolkit:install-component Button --kit=github.com/my-username/my-ux-toolkit-kit:1.0.0
$ php bin/console ux:install Button --kit=github.com/my-username/my-ux-toolkit-kit:1.0.0

Backward Compatibility promise
------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Alert
# Examples

A notification component that displays important messages with an icon, title, and description.
## Default

```twig {"preview":true}
<twig:Alert class="max-w-lg">
Expand All @@ -12,29 +12,7 @@ A notification component that displays important messages with an icon, title, a
</twig:Alert>
```

## Installation

<!-- Placeholder: Installation -->

## Usage

<!-- Placeholder: Usage -->

## Examples

### Default

```twig {"preview":true}
<twig:Alert class="max-w-lg">
<twig:ux:icon name="tabler:terminal" class="h-4 w-4" />
<twig:Alert:Title>Heads up!</twig:Alert:Title>
<twig:Alert:Description>
You can add components to your app using the cli.
</twig:Alert:Description>
</twig:Alert>
```

### Destructive
## Destructive

```twig {"preview":true}
<twig:Alert variant="destructive" class="max-w-lg">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"$schema": "../../../../schemas/component.json",
"$schema": "../../../schema-kit-recipe-v1.json",
"type": "component",
"name": "Alert",
"description": "A notification component that displays important messages with an icon, title, and description.",
"copy-files": {
"templates/": "templates/"
},
"dependencies": [
{
"type": "php",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AspectRatio
# Examples

A container that maintains a specific width-to-height ratio for its content.
## Default

```twig {"preview":true,"height":"400px"}
<twig:AspectRatio ratio="1 / 1" class="max-w-[300px]">
Expand All @@ -12,17 +12,7 @@ A container that maintains a specific width-to-height ratio for its content.
</twig:AspectRatio>
```

## Installation

<!-- Placeholder: Installation -->

## Usage

<!-- Placeholder: Usage -->

## Examples

### With a 1 / 1 aspect ratio
## With a 1 / 1 aspect ratio

```twig {"preview":true,"height":"400px"}
<twig:AspectRatio ratio="1 / 1" class="max-w-[350px]">
Expand All @@ -34,7 +24,7 @@ A container that maintains a specific width-to-height ratio for its content.
</twig:AspectRatio>
```

### With a 16 / 9 aspect ratio
## With a 16 / 9 aspect ratio

```twig {"preview":true,"height":"400px"}
<twig:AspectRatio ratio="16 / 9" class="max-w-[350px]">
Expand Down
15 changes: 15 additions & 0 deletions src/Toolkit/kits/shadcn/AspectRatio/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "../../../schema-kit-recipe-v1.json",
"type": "component",
"name": "AspectRatio",
"description": "A container that maintains a specific width-to-height ratio for its content.",
"copy-files": {
"templates/": "templates/"
},
"dependencies": [
{
"type": "php",
"package": "twig/extra-bundle"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
# Avatar
# Examples

A circular element that displays a user's profile image or initials as a fallback.
## Avatar with Image

```twig {"preview":true}
<twig:Avatar>
<twig:Avatar:Image src="https://github.com/symfony.png" alt="@symfony" />
</twig:Avatar>
```

## Installation

<!-- Placeholder: Installation -->

## Usage

<!-- Placeholder: Usage -->

## Examples

### Avatar with Image

```twig {"preview":true}
<twig:Avatar>
<twig:Avatar:Image src="https://github.com/symfony.png" alt="@symfony" />
</twig:Avatar>
```

### Avatar with Text
## Avatar with Text

```twig {"preview":true}
<div class="flex gap-1">
Expand All @@ -39,7 +21,7 @@ A circular element that displays a user's profile image or initials as a fallbac
</div>
```

### Avatar Group
## Avatar Group

```twig {"preview":true}
<div class="flex -space-x-2">
Expand Down
15 changes: 15 additions & 0 deletions src/Toolkit/kits/shadcn/Avatar/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "../../../schema-kit-recipe-v1.json",
"type": "component",
"name": "Avatar",
"description": "A circular element that displays a user's profile image or initials as a fallback.",
"copy-files": {
"templates/": "templates/"
},
"dependencies": [
{
"type": "php",
"package": "tales-from-a-dev/twig-tailwind-extra"
}
]
}
Loading
Loading