Skip to content

Commit 3dd1cce

Browse files
committed
iterate
1 parent bb8f27c commit 3dd1cce

File tree

6 files changed

+188
-36
lines changed

6 files changed

+188
-36
lines changed

src/Toolkit/config/services.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Symfony\UX\Toolkit\Command\CreateKitCommand;
1415
use Symfony\UX\Toolkit\Command\DebugKitCommand;
15-
use Symfony\UX\Toolkit\Command\InstallComponentCommand;
16+
use Symfony\UX\Toolkit\Command\InstallCommand;
1617
use Symfony\UX\Toolkit\Kit\KitContextRunner;
1718
use Symfony\UX\Toolkit\Kit\KitFactory;
1819
use Symfony\UX\Toolkit\Kit\KitSynchronizer;
@@ -35,7 +36,13 @@
3536
])
3637
->tag('console.command')
3738

38-
->set('.ux_toolkit.command.install', InstallComponentCommand::class)
39+
->set('.ux_toolkit.command.create_kit', CreateKitCommand::class)
40+
->args([
41+
service('filesystem'),
42+
])
43+
->tag('console.command')
44+
45+
->set('.ux_toolkit.command.install', InstallCommand::class)
3946
->args([
4047
service('.ux_toolkit.registry.registry_factory'),
4148
service('filesystem'),

src/Toolkit/doc/index.rst

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,24 @@ to change, or even change drastically.
77
Symfony UX Toolkit provides a set of ready-to-use kits for Symfony applications.
88
It is part of `the Symfony UX initiative`_.
99

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

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

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

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

27-
Also, we do not force you to use Tailwind CSS at all. You can use whatever
28-
CSS framework you want, but you will need to adapt the UI components to it.
29-
3028
Installation
3129
------------
3230

@@ -37,27 +35,25 @@ Install the UX Toolkit using Composer and Symfony Flex:
3735
# The UX Toolkit is a development dependency:
3836
$ composer require --dev symfony/ux-toolkit
3937
40-
# If you want to keep `html_cva` and `tailwind_merge` in your Twig components:
41-
$ composer require twig/extra-bundle twig/html-extra:^3.12.0 tales-from-a-dev/twig-tailwind-extra
42-
4338
Usage
4439
-----
4540

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

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

5045
.. code-block:: terminal
5146
5247
$ php bin/console ux:install Button --kit=<kitName>
5348
54-
It will create the ``templates/components/Button.html.twig`` file, and you will be able to use the `Button` component like this:
49+
It will create the ``templates/components/Button.html.twig`` file in your project,
50+
and you will be able to use the `Button` component like this:
5551

5652
.. code-block:: html+twig
5753

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

60-
Create your own kit
56+
Create your own Kit
6157
-------------------
6258

6359
You have the ability to create and share your own kit with the community,
@@ -96,20 +92,55 @@ After creating your kit, the repository should have the following structure:
9692
.. code-block:: text
9793
9894
.
99-
├── docs
100-
│ └── components
101-
│ └── Button.twig
102-
├── manifest.json
103-
└── templates
104-
└── components
105-
└── Button.html.twig
106-
107-
A kit is composed of:
108-
109-
- A ``manifest.json`` file, that describes the kit (name, description, dependencies, ...),
110-
- A ``templates/components`` directory, that contains the Twig components,
111-
- A ``assets`` directory, optional, that contains the assets (CSS, JS, Stimulus Controllers, ...) used by the components,
112-
- A ``examples`` directory, optional, that contains Twig code examples
95+
├── Button
96+
│   ├── manifest.json
97+
│   └── templates
98+
│   └── components
99+
│   └── Button.html.twig
100+
└── manifest.json
101+
102+
103+
A kit is described by a ``manifest.json`` file at the root directory, which contains the metadata of the kit:
104+
105+
.. code-block:: json
106+
107+
{
108+
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-v1.json",
109+
"name": "My UX Toolkit Kit",
110+
"description": "A custom kit for Symfony UX Toolkit.",
111+
"homepage": "https://github/com/User/MyUxToolkitKit",
112+
"license": "MIT"
113+
}
114+
115+
Then, a kit can contain one or more recipes. Each recipe is a directory
116+
with a ``manifest.json`` file and some files to be copied into the project.
117+
118+
The ``manifest.json`` file of a recipe contains the metadata of the recipe:
119+
120+
.. code-block:: json
121+
122+
{
123+
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json",
124+
"name": "Button",
125+
"description": "A clickable element that triggers actions or events, supporting various styles and states.",
126+
"copy-files": {
127+
"templates/": "templates/"
128+
},
129+
"dependencies": {
130+
{
131+
"type": "php",
132+
"package": "twig/extra-bundle"
133+
},
134+
{
135+
"type": "php",
136+
"package": "twig/html-extra:^3.12.0"
137+
},
138+
{
139+
"type": "php",
140+
"package": "tales-from-a-dev/twig-tailwind-extra"
141+
}
142+
}
143+
}
113144
114145
Using your kit
115146
~~~~~~~~~~~~~~

src/Toolkit/src/Command/CreateKitCommand.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
110110
'$schema' => '../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json',
111111
'name' => 'Button',
112112
'description' => 'A clickable element that triggers actions or events, supporting various styles and states.',
113-
'dependencies' => (object) [
113+
'copy-files' => [
114+
'templates/' => 'templates/',
115+
],
116+
'dependencies' => [
114117
['type' => 'php', 'package' => 'twig/extra-bundle'],
115118
['type' => 'php', 'package' => 'twig/html-extra:^3.12.0'],
116119
['type' => 'php', 'package' => 'tales-from-a-dev/twig-tailwind-extra'],
117120
],
118121
], \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
119122

120-
$io->success('Your kit has been scaffolded, happy crafting!');
123+
$io->success('Your kit has been created successfully, happy coding!');
121124

122125
return self::SUCCESS;
123126
}

src/Toolkit/src/Command/InstallComponentCommand.php renamed to src/Toolkit/src/Command/InstallCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
* @internal
3636
*/
3737
#[AsCommand(
38-
name: 'ux:install-component',
38+
name: 'ux:install',
3939
description: 'Install a new UX Toolkit recipe in your project',
4040
)]
41-
class InstallComponentCommand extends Command
41+
class InstallCommand extends Command
4242
{
4343
private SymfonyStyle $io;
4444

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\Toolkit\Tests\Command;
13+
14+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
15+
use Symfony\Component\Filesystem\Filesystem;
16+
use Zenstruck\Console\Test\InteractsWithConsole;
17+
18+
class CreateKitCommandTest extends KernelTestCase
19+
{
20+
use InteractsWithConsole;
21+
22+
private string $cwd;
23+
private Filesystem $filesystem;
24+
private string $tmpDir;
25+
26+
protected function setUp(): void
27+
{
28+
$this->cwd = getcwd();
29+
30+
$this->filesystem = new Filesystem();
31+
$this->tmpDir = $this->filesystem->tempnam(sys_get_temp_dir(), 'ux_toolkit_github_');
32+
$this->filesystem->remove($this->tmpDir);
33+
$this->filesystem->mkdir($this->tmpDir);
34+
35+
chdir($this->tmpDir);
36+
}
37+
38+
protected function tearDown(): void
39+
{
40+
chdir($this->cwd);
41+
$this->filesystem->remove($this->tmpDir);
42+
}
43+
44+
public function testShouldBeAbleToCreateAKit()
45+
{
46+
$this->bootKernel();
47+
$this->consoleCommand('ux:toolkit:create-kit')
48+
->addInput('MyKit')
49+
->addInput('http://example.com')
50+
->addInput('MIT')
51+
->execute()
52+
->assertSuccessful()
53+
->assertOutputContains('Your kit has been created successfully, happy coding!')
54+
;
55+
56+
$this->assertStringEqualsFile($this->tmpDir.'/manifest.json', <<<'JSON'
57+
{
58+
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-v1.json",
59+
"name": "MyKit",
60+
"description": "A custom kit for Symfony UX Toolkit.",
61+
"homepage": "http://example.com",
62+
"license": "MIT"
63+
}
64+
JSON
65+
);
66+
$this->assertStringEqualsFile($this->tmpDir.'/Button/manifest.json', <<<'JSON'
67+
{
68+
"$schema": "../vendor/symfony/ux-toolkit/schema-kit-recipe-v1.json",
69+
"name": "Button",
70+
"description": "A clickable element that triggers actions or events, supporting various styles and states.",
71+
"copy-files": {
72+
"templates/": "templates/"
73+
},
74+
"dependencies": [
75+
{
76+
"type": "php",
77+
"package": "twig/extra-bundle"
78+
},
79+
{
80+
"type": "php",
81+
"package": "twig/html-extra:^3.12.0"
82+
},
83+
{
84+
"type": "php",
85+
"package": "tales-from-a-dev/twig-tailwind-extra"
86+
}
87+
]
88+
}
89+
JSON
90+
);
91+
$this->assertStringEqualsFile($this->tmpDir.'/Button/templates/components/Button.html.twig', <<<'TWIG'
92+
{% props type = 'button', variant = 'default' %}
93+
{%- set style = html_cva(
94+
base: 'inline-flex items-center',
95+
variants: {
96+
variant: {
97+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
98+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
99+
},
100+
},
101+
) -%}
102+
103+
<button class="{{ style.apply({ variant }, attributes.render('class'))|tailwind_merge }}"
104+
{{ attributes }}
105+
>
106+
{%- block content %}{% endblock -%}
107+
</button>
108+
TWIG
109+
);
110+
}
111+
}

src/Toolkit/tests/Command/InstallComponentCommandTest.php renamed to src/Toolkit/tests/Command/InstallCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Symfony\Component\Filesystem\Filesystem;
1616
use Zenstruck\Console\Test\InteractsWithConsole;
1717

18-
class InstallComponentCommandTest extends KernelTestCase
18+
class InstallCommandTest extends KernelTestCase
1919
{
2020
use InteractsWithConsole;
2121

0 commit comments

Comments
 (0)