diff --git a/src/Toolkit/kits/shadcn/AlertDialog/templates/components/AlertDialog/Trigger.html.twig b/src/Toolkit/kits/shadcn/AlertDialog/templates/components/AlertDialog/Trigger.html.twig
new file mode 100644
index 00000000000..a52777db61a
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/AlertDialog/templates/components/AlertDialog/Trigger.html.twig
@@ -0,0 +1,7 @@
+{%- set trigger_attrs = {
+ 'data-action': 'click->alert-dialog#open',
+ 'data-alert-dialog-target': 'trigger',
+ 'aria-haspopup': 'dialog',
+ 'aria-expanded': _alert_dialog_open ? 'true' : 'false',
+} -%}
+{%- block content %}{% endblock -%}
diff --git a/src/Toolkit/kits/shadcn/manifest.json b/src/Toolkit/kits/shadcn/manifest.json
index 03571bdbcc3..928f5511527 100644
--- a/src/Toolkit/kits/shadcn/manifest.json
+++ b/src/Toolkit/kits/shadcn/manifest.json
@@ -3,5 +3,5 @@
"name": "Shadcn UI",
"description": "Component based on the Shadcn UI library, one of the most popular design systems in JavaScript world.",
"license": "MIT",
- "homepage": "https://ux.symfony.com/components"
+ "homepage": "https://ux.symfony.com/toolkit/kits/shadcn"
}
diff --git a/src/Toolkit/src/Command/InstallCommand.php b/src/Toolkit/src/Command/InstallCommand.php
index 3400348a524..0467532e609 100644
--- a/src/Toolkit/src/Command/InstallCommand.php
+++ b/src/Toolkit/src/Command/InstallCommand.php
@@ -216,15 +216,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
*/
private function getAlternativeRecipes(Kit $kit, string $recipeName): array
{
- $alternative = [];
+ $alternativeRecipes = [];
foreach ($kit->getRecipes() as $recipe) {
$lev = levenshtein($recipeName, $recipe->manifest->name, 2, 5, 10);
if ($lev <= 8 || str_contains($recipe->manifest->name, $recipeName)) {
- $alternative[] = $recipe;
+ $alternativeRecipes[] = $recipe;
}
}
- return $alternative;
+ usort($alternativeRecipes, fn (Recipe $recipeA, Recipe $recipeB) => strcmp($recipeA->manifest->name, $recipeB->manifest->name));
+
+ return $alternativeRecipes;
}
}
diff --git a/src/Toolkit/src/Kit/KitContextRunner.php b/src/Toolkit/src/Kit/KitContextRunner.php
index 20813b2a270..e052380f221 100644
--- a/src/Toolkit/src/Kit/KitContextRunner.php
+++ b/src/Toolkit/src/Kit/KitContextRunner.php
@@ -24,6 +24,11 @@
*/
final class KitContextRunner
{
+ /**
+ * @var array
+ */
+ private static $componentTemplateFinders = [];
+
public function __construct(
private readonly \Twig\Environment $twig,
private readonly ComponentFactory $componentFactory,
@@ -39,51 +44,59 @@ public function __construct(
*/
public function runForKit(Kit $kit, callable $callback): mixed
{
- $resetServices = $this->contextualizeServicesForKit($kit);
+ $resetTwig = $this->contextualizeTwig($kit);
+ $resetComponentFactory = $this->contextualizeComponentFactory($kit);
try {
return $callback($kit);
} finally {
- $resetServices();
+ $resetTwig();
+ $resetComponentFactory();
}
}
/**
- * @return callable(): void Reset the services when called
+ * @return callable(): void
*/
- private function contextualizeServicesForKit(Kit $kit): callable
+ private function contextualizeTwig(Kit $kit): callable
{
- // Configure Twig
$initialTwigLoader = $this->twig->getLoader();
+
$loaders = [];
foreach ($kit->getRecipes(type: RecipeType::Component) as $recipe) {
$loaders[] = new FilesystemLoader($recipe->absolutePath);
}
- $this->twig->setLoader(new ChainLoader([...$loaders, $initialTwigLoader]));
+ $loaders[] = $initialTwigLoader;
+
+ $this->twig->setLoader(new ChainLoader($loaders));
- // Configure Twig Components
+ return fn () => $this->twig->setLoader($initialTwigLoader);
+ }
+
+ /**
+ * @return callable(): void
+ */
+ private function contextualizeComponentFactory(Kit $kit): callable
+ {
$reflComponentFactory = new \ReflectionClass($this->componentFactory);
- $reflComponentFactoryConfig = $reflComponentFactory->getProperty('config');
- $initialComponentFactoryConfig = $reflComponentFactoryConfig->getValue($this->componentFactory);
- $reflComponentFactoryConfig->setValue($this->componentFactory, []);
+ $reflConfig = $reflComponentFactory->getProperty('config');
+ $initialConfig = $reflConfig->getValue($this->componentFactory);
+ $reflConfig->setValue($this->componentFactory, []);
- $reflComponentFactoryComponentTemplateFinder = $reflComponentFactory->getProperty('componentTemplateFinder');
- $initialComponentFactoryComponentTemplateFinder = $reflComponentFactoryComponentTemplateFinder->getValue($this->componentFactory);
- $reflComponentFactoryComponentTemplateFinder->setValue($this->componentFactory, $this->createComponentTemplateFinder($kit));
+ $reflComponentTemplateFinder = $reflComponentFactory->getProperty('componentTemplateFinder');
+ $initialComponentTemplateFinder = $reflComponentTemplateFinder->getValue($this->componentFactory);
+ $reflComponentTemplateFinder->setValue($this->componentFactory, $this->createComponentTemplateFinder($kit));
- return function () use ($initialTwigLoader, $reflComponentFactoryConfig, $initialComponentFactoryConfig, $reflComponentFactoryComponentTemplateFinder, $initialComponentFactoryComponentTemplateFinder) {
- $this->twig->setLoader($initialTwigLoader);
- $reflComponentFactoryConfig->setValue($this->componentFactory, $initialComponentFactoryConfig);
- $reflComponentFactoryComponentTemplateFinder->setValue($this->componentFactory, $initialComponentFactoryComponentTemplateFinder);
+ return function () use ($reflConfig, $initialConfig, $reflComponentTemplateFinder, $initialComponentTemplateFinder): void {
+ $reflConfig->setValue($this->componentFactory, $initialConfig);
+ $reflComponentTemplateFinder->setValue($this->componentFactory, $initialComponentTemplateFinder);
};
}
private function createComponentTemplateFinder(Kit $kit): ComponentTemplateFinderInterface
{
- static $instances = [];
-
- return $instances[$kit->manifest->name] ?? new class($kit) implements ComponentTemplateFinderInterface {
+ return self::$componentTemplateFinders[$kit->manifest->name] ??= new class($kit) implements ComponentTemplateFinderInterface {
public function __construct(private readonly Kit $kit)
{
}
diff --git a/src/Toolkit/tests/Command/DebugKitCommandTest.php b/src/Toolkit/tests/Command/DebugKitCommandTest.php
index 78878d2a791..f5e65e3f25a 100644
--- a/src/Toolkit/tests/Command/DebugKitCommandTest.php
+++ b/src/Toolkit/tests/Command/DebugKitCommandTest.php
@@ -28,7 +28,7 @@ public function testShouldBeAbleToDebugShadcnKit()
->assertSuccessful()
// Kit details
->assertOutputContains('Name Shadcn')
- ->assertOutputContains('Homepage https://ux.symfony.com/components')
+ ->assertOutputContains('Homepage https://ux.symfony.com/toolkit/kits/shadcn')
->assertOutputContains('License MIT')
// Components details
->assertOutputContains(implode(\PHP_EOL, [
diff --git a/src/Toolkit/tests/Command/InstallCommandTest.php b/src/Toolkit/tests/Command/InstallCommandTest.php
index afecc0b77c6..5da5ee8e6bb 100644
--- a/src/Toolkit/tests/Command/InstallCommandTest.php
+++ b/src/Toolkit/tests/Command/InstallCommandTest.php
@@ -76,7 +76,7 @@ public function testShouldFailAndSuggestAlternativeRecipesWhenKitIsExplicit()
->execute()
->assertFaulty()
->assertOutputContains('[WARNING] The recipe "A" does not exist')
- ->assertOutputContains('Possible alternatives: "Alert", "AspectRatio", "Avatar"')
+ ->assertOutputContains('Possible alternatives: "Alert", "AlertDialog", "AspectRatio"')
;
}
diff --git a/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 1__1.html b/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 1__1.html
new file mode 100644
index 00000000000..8b2110a2a35
--- /dev/null
+++ b/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 1__1.html
@@ -0,0 +1,45 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 2__1.html b/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 2__1.html
new file mode 100644
index 00000000000..29d9d235f6d
--- /dev/null
+++ b/src/Toolkit/tests/Functional/__snapshots__/ComponentsRenderingTest__testComponentRendering with data set Kit shadcn, component AlertDialog, code 2__1.html
@@ -0,0 +1,45 @@
+
+