Skip to content

Commit 3d7eda2

Browse files
committed
[Toolkit] Adds engine for parsing, downloading and manage components
1 parent a471878 commit 3d7eda2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2617
-0
lines changed

src/Toolkit/.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/.git* export-ignore
2+
/.symfony.bundle.yaml export-ignore
3+
/phpunit.xml.dist export-ignore
4+
/doc export-ignore
5+
/tests export-ignore
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Please do not submit any Pull Requests here. They will be closed.
2+
---
3+
4+
Please submit your PR here instead:
5+
https://github.com/symfony/ux
6+
7+
This repository is what we call a "subtree split": a read-only subset of that main repository.
8+
We're looking forward to your PR there!
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Close Pull Request
2+
3+
on:
4+
pull_request_target:
5+
types: [opened]
6+
7+
jobs:
8+
run:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: superbrothers/close-pull-request@v3
12+
with:
13+
comment: |
14+
Thanks for your Pull Request! We love contributions.
15+
16+
However, you should instead open your PR on the main repository:
17+
https://github.com/symfony/ux
18+
19+
This repository is what we call a "subtree split": a read-only subset of that main repository.
20+
We're looking forward to your PR there!

src/Toolkit/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
vendor
2+
composer.lock
3+
.phpunit.result.cache
4+
var
5+
tests/ui/output
6+
tests/ui/screens

src/Toolkit/.symfony.bundle.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
branches: ["2.x"]
2+
maintained_branches: ["2.x"]
3+
doc_dir: "doc"

src/Toolkit/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# CHANGELOG
2+
3+
## 2.23
4+
5+
- Component added

src/Toolkit/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2025-present Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

src/Toolkit/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.PHONY: build
2+
build:
3+
./bin/build-registry.php \
4+
--destination=registry/default \
5+
--licenses="MIT" \
6+
Symfony "https://www.symfony.com"

src/Toolkit/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Symfony UX Toolkit
2+
3+
**EXPERIMENTAL** This component is currently experimental and is
4+
likely to change, or even change drastically.
5+
6+
Symfony UX Toolkit provides a set of ready-to-use UI components for Symfony applications.
7+
8+
**This repository is a READ-ONLY sub-tree split**. See
9+
https://github.com/symfony/ux to create issues or submit pull requests.
10+
11+
## Resources
12+
13+
- [Documentation](https://symfony.com/bundles/ux-toolkit/current/index.html)
14+
- [Report issues](https://github.com/symfony/ux/issues) and
15+
[send Pull Requests](https://github.com/symfony/ux/pulls)
16+
in the [main Symfony UX repository](https://github.com/symfony/ux)

src/Toolkit/bin/build-registry.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the Symfony package.
6+
*
7+
* (c) Fabien Potencier <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
require_once __DIR__.'/../vendor/autoload.php';
14+
15+
$app = new Symfony\Component\Console\Application('Symfony UX Toolkit Builder', '0.1');
16+
$compiler = new Symfony\UX\Toolkit\Compiler\RegistryCompiler(new Symfony\Component\Filesystem\Filesystem());
17+
$app->add(new Symfony\UX\Toolkit\Command\BuildRegistryCommand($compiler));
18+
$app->setDefaultCommand('ux:toolkit:build-registry', true);
19+
$app->run();

src/Toolkit/composer.json

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"name": "symfony/ux-toolkit",
3+
"type": "symfony-bundle",
4+
"description": "Twig Toolkit for Symfony",
5+
"keywords": [
6+
"symfony-ux",
7+
"twig",
8+
"components"
9+
],
10+
"homepage": "https://symfony.com",
11+
"license": "MIT",
12+
"authors": [
13+
{
14+
"name": "Symfony Community",
15+
"homepage": "https://symfony.com/contributors"
16+
},
17+
{
18+
"name": "Hugo Alliaume",
19+
"email": "[email protected]"
20+
},
21+
{
22+
"name": "Jean-François Lépine",
23+
"email": "[email protected]"
24+
},
25+
{
26+
"name": "Simon André",
27+
"email": "[email protected]"
28+
}
29+
],
30+
"require": {
31+
"php": ">=8.3",
32+
"twig/extra-bundle": "^3.19|^4.0",
33+
"twig/html-extra": "^3.19",
34+
"twig/twig": "^2.12|^3.0",
35+
"symfony/console": "^7.2",
36+
"symfony/framework-bundle": "^6.4|^7.0",
37+
"symfony/twig-bundle": "^6.4|^7.0",
38+
"symfony/ux-twig-component": "^2.22",
39+
"symfony/filesystem": "^7.2"
40+
},
41+
"require-dev": {
42+
"symfony/finder": "6.4|^7.0",
43+
"tales-from-a-dev/twig-tailwind-extra": "^0.3.0",
44+
"zenstruck/console-test": "^1.7",
45+
"symfony/http-client": "6.4|^7.0",
46+
"symfony/stopwatch": "^7.2",
47+
"symfony/phpunit-bridge": "^6.4|^7.0"
48+
},
49+
"autoload": {
50+
"psr-4": {
51+
"Symfony\\UX\\Toolkit\\": "src"
52+
},
53+
"exclude-from-classmap": []
54+
},
55+
"autoload-dev": {
56+
"psr-4": {
57+
"Symfony\\UX\\Toolkit\\Tests\\": "tests/"
58+
}
59+
},
60+
"conflict": {
61+
"symfony/ux-twig-component": "<2.21"
62+
},
63+
"extra": {
64+
"thanks": {
65+
"name": "symfony/ux",
66+
"url": "https://github.com/symfony/ux"
67+
}
68+
}
69+
}

src/Toolkit/doc/index.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Symfony UX Toolkit
2+
==================
3+
4+
**EXPERIMENTAL** This component is currently experimental and is likely
5+
to change, or even change drastically.
6+
7+
Symfony UX Toolkit provides a set of ready-to-use UI components for Symfony applications.
8+
It is part of `the Symfony UX initiative`_.
9+
10+
Installation
11+
------------
12+
13+
TODO
14+
15+
Configuration
16+
-------------
17+
18+
TODO
19+
20+
Backward Compatibility promise
21+
------------------------------
22+
23+
This bundle aims at following the same Backward Compatibility promise as
24+
the Symfony framework:
25+
https://symfony.com/doc/current/contributing/code/bc.html
26+
27+
.. _`the Symfony UX initiative`: https://ux.symfony.com/
28+
#.. _`Twig Component`: https://symfony.com/bundles/ux-twig-component/current/index.html

src/Toolkit/phpunit.xml.dist

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
3+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
4+
backupGlobals="false"
5+
colors="true"
6+
bootstrap="tests/bootstrap.php"
7+
failOnRisky="true"
8+
failOnWarning="true"
9+
>
10+
<php>
11+
<ini name="display_errors" value="1"/>
12+
<ini name="error_reporting" value="-1"/>
13+
<server name="APP_ENV" value="test" force="true"/>
14+
<server name="SHELL_VERBOSITY" value="-1"/>
15+
<server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
16+
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5"/>
17+
<server name="SYMFONY_DEPRECATIONS_HELPER" value="max[total]=999999"/>
18+
<server name="KERNEL_CLASS" value="Symfony\UX\Toolkit\Tests\Fixtures\Kernel"/>
19+
</php>
20+
<testsuites>
21+
<testsuite name="UX Toolkit Test Suite">
22+
<directory>tests</directory>
23+
</testsuite>
24+
</testsuites>
25+
<listeners>
26+
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
27+
</listeners>
28+
<coverage>
29+
<include>
30+
<directory suffix=".php">src</directory>
31+
</include>
32+
</coverage>
33+
</phpunit>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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\Command;
13+
14+
use Symfony\Component\Console\Attribute\AsCommand;
15+
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Input\InputOption;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Component\Console\Style\SymfonyStyle;
21+
use Symfony\Component\Finder\Finder;
22+
use Symfony\UX\Toolkit\Compiler\RegistryCompiler;
23+
use Symfony\UX\Toolkit\Registry\Registry;
24+
use Symfony\UX\Toolkit\Registry\RegistryItemFactory;
25+
26+
/**
27+
* @author Jean-François Lépine
28+
* @author Hugo Alliaume <[email protected]>
29+
*
30+
* @internal
31+
*/
32+
#[AsCommand(
33+
name: 'ux:toolkit:build-registry',
34+
description: 'This command allows to distribute your components, and build the registry.'
35+
)]
36+
class BuildRegistryCommand extends Command
37+
{
38+
public function __construct(
39+
private readonly RegistryCompiler $compiler,
40+
) {
41+
parent::__construct();
42+
}
43+
44+
protected function configure(): void
45+
{
46+
$this
47+
->addOption(
48+
'template-directory',
49+
't',
50+
InputOption::VALUE_REQUIRED,
51+
'The directory where the templates are stored.',
52+
'templates'
53+
)
54+
->addOption(
55+
'destination',
56+
'r',
57+
InputOption::VALUE_REQUIRED,
58+
'The directory where the registry will be stored.',
59+
'registry'
60+
)
61+
->addArgument('name', InputArgument::OPTIONAL, 'The name of the component.', '')
62+
->addArgument('homepage', InputArgument::OPTIONAL, 'The homepage of the component.', 'https://...')
63+
->addOption(
64+
'authors',
65+
'',
66+
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
67+
'The authors of the component.',
68+
[]
69+
)
70+
->addOption(
71+
'licenses',
72+
'',
73+
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
74+
'The licenses of the component.',
75+
[]
76+
);
77+
}
78+
79+
protected function execute(InputInterface $input, OutputInterface $output): int
80+
{
81+
$io = new SymfonyStyle($input, $output);
82+
83+
$io->title('Building the registry...');
84+
85+
$registry = Registry::empty();
86+
$registry->setName($input->getArgument('name'));
87+
$registry->setHomepage($input->getArgument('homepage'));
88+
89+
foreach ($input->getOption('authors') as $author) {
90+
// author is a string like "name <email>"
91+
$email = null;
92+
if (preg_match('/^(.+) <(.+)>$/', $author, $matches)) {
93+
$author = ['name' => $matches[1], 'email' => $matches[2]];
94+
}
95+
$registry->addAuthor($author, $email);
96+
}
97+
98+
foreach ($input->getOption('licenses') as $license) {
99+
$registry->addLicense($license);
100+
}
101+
102+
$finderTemplates = Finder::create()
103+
->files()
104+
->in($input->getOption('template-directory'))
105+
->name('*.html.twig')
106+
->sortByName();
107+
108+
$table = [];
109+
foreach ($finderTemplates as $file) {
110+
$table[] = [$file->getRelativePathname()];
111+
$registry->add(RegistryItemFactory::fromTwigFile($file));
112+
}
113+
114+
$registryDir = $input->getOption('destination');
115+
$this->compiler->compile($registry, $registryDir);
116+
117+
$io->table(['Templates'], $table);
118+
119+
$io->success('The registry has been successfully built.');
120+
121+
return Command::SUCCESS;
122+
}
123+
}

0 commit comments

Comments
 (0)