diff --git a/src/Toolkit/kits/shadcn/templates/components/Alert.meta.json b/src/Toolkit/kits/shadcn/templates/components/Alert.meta.json
new file mode 100644
index 00000000000..9e08e59b32e
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Alert.meta.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "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"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Alert/Description.meta.json b/src/Toolkit/kits/shadcn/templates/components/Alert/Description.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Alert/Description.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Alert/Title.meta.json b/src/Toolkit/kits/shadcn/templates/components/Alert/Title.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Alert/Title.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/AspectRatio.meta.json b/src/Toolkit/kits/shadcn/templates/components/AspectRatio.meta.json
new file mode 100644
index 00000000000..3c7c094fde0
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/AspectRatio.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "twig/extra-bundle"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Avatar.meta.json b/src/Toolkit/kits/shadcn/templates/components/Avatar.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Avatar.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Avatar/Image.meta.json b/src/Toolkit/kits/shadcn/templates/components/Avatar/Image.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Avatar/Image.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Avatar/Text.meta.json b/src/Toolkit/kits/shadcn/templates/components/Avatar/Text.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Avatar/Text.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Badge.meta.json b/src/Toolkit/kits/shadcn/templates/components/Badge.meta.json
new file mode 100644
index 00000000000..9e08e59b32e
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Badge.meta.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "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"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb.meta.json
new file mode 100644
index 00000000000..079eea5bb20
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb.meta.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": []
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Ellipsis.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Ellipsis.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Ellipsis.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Item.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Item.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Item.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Link.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Link.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Link.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/List.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/List.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/List.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Page.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Page.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Page.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.html.twig b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.html.twig
index 2e11b3871f5..d06cb0c2a3a 100644
--- a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.html.twig
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.html.twig
@@ -5,6 +5,6 @@
aria-hidden="true"
>
{%- block content -%}
-
+
{%- endblock %}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.meta.json b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.meta.json
new file mode 100644
index 00000000000..19987b2a1b8
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Breadcrumb/Separator.meta.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "symfony/ux-icons"
+ },
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Button.meta.json b/src/Toolkit/kits/shadcn/templates/components/Button.meta.json
new file mode 100644
index 00000000000..9e08e59b32e
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Button.meta.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "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"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card/Content.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card/Content.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card/Content.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card/Description.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card/Description.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card/Description.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card/Footer.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card/Footer.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card/Footer.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card/Header.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card/Header.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card/Header.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Card/Title.meta.json b/src/Toolkit/kits/shadcn/templates/components/Card/Title.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Card/Title.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Checkbox.meta.json b/src/Toolkit/kits/shadcn/templates/components/Checkbox.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Checkbox.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Input.meta.json b/src/Toolkit/kits/shadcn/templates/components/Input.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Input.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Label.meta.json b/src/Toolkit/kits/shadcn/templates/components/Label.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Label.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Content.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Content.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Content.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.html.twig b/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.html.twig
index b79f11d0fac..417c0baa941 100644
--- a/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.html.twig
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.html.twig
@@ -3,6 +3,6 @@
class="{{ 'flex h-9 w-9 items-center justify-center ' ~ attributes.render('class')|tailwind_merge }}"
{{ attributes.without('class') }}
>
-
+
More pages
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.meta.json
new file mode 100644
index 00000000000..19987b2a1b8
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Ellipsis.meta.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "symfony/ux-icons"
+ },
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Item.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Item.meta.json
new file mode 100644
index 00000000000..d39de6e07e6
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Item.meta.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": []
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Link.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Link.meta.json
new file mode 100644
index 00000000000..d39de6e07e6
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Link.meta.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": []
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.html.twig b/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.html.twig
index cd09ce5b044..53bf8ade927 100644
--- a/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.html.twig
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.html.twig
@@ -5,5 +5,5 @@
{{ ...attributes.without('class') }}
>
Next
-
+
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.meta.json
new file mode 100644
index 00000000000..19987b2a1b8
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Next.meta.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "symfony/ux-icons"
+ },
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.html.twig b/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.html.twig
index 1d09bd7739c..e2f693c8701 100644
--- a/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.html.twig
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.html.twig
@@ -4,6 +4,6 @@
class="{{ 'gap-1 pl-2.5 ' ~ attributes.render('class')|tailwind_merge }}"
{{ ...attributes.without('class') }}
>
-
+
Previous
diff --git a/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.meta.json b/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.meta.json
new file mode 100644
index 00000000000..19987b2a1b8
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Pagination/Previous.meta.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "symfony/ux-icons"
+ },
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Progress.meta.json b/src/Toolkit/kits/shadcn/templates/components/Progress.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Progress.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Select.meta.json b/src/Toolkit/kits/shadcn/templates/components/Select.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Select.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Separator.meta.json b/src/Toolkit/kits/shadcn/templates/components/Separator.meta.json
new file mode 100644
index 00000000000..9e08e59b32e
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Separator.meta.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "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"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Skeleton.meta.json b/src/Toolkit/kits/shadcn/templates/components/Skeleton.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Skeleton.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Switch.meta.json b/src/Toolkit/kits/shadcn/templates/components/Switch.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Switch.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Body.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Body.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Body.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Caption.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Caption.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Caption.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Cell.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Cell.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Cell.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Footer.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Footer.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Footer.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Head.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Head.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Head.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Header.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Header.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Header.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Table/Row.meta.json b/src/Toolkit/kits/shadcn/templates/components/Table/Row.meta.json
new file mode 100644
index 00000000000..99e25114927
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Table/Row.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/kits/shadcn/templates/components/Textarea.meta.json b/src/Toolkit/kits/shadcn/templates/components/Textarea.meta.json
new file mode 100644
index 00000000000..d50410b06b3
--- /dev/null
+++ b/src/Toolkit/kits/shadcn/templates/components/Textarea.meta.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "../../../../schemas/component.json",
+ "dependencies": [
+ {
+ "type": "php",
+ "package": "tales-from-a-dev/twig-tailwind-extra"
+ }
+ ]
+}
diff --git a/src/Toolkit/schemas/component.json b/src/Toolkit/schemas/component.json
new file mode 100644
index 00000000000..85749807f22
--- /dev/null
+++ b/src/Toolkit/schemas/component.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Component Meta Schema",
+ "type": "object",
+ "required": ["dependencies"],
+ "properties": {
+ "dependencies": {
+ "type": "array",
+ "description": "List of dependencies required by the component",
+ "items": {
+ "oneOf": [
+ {
+ "type": "object",
+ "required": ["type", "package"],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["php"],
+ "description": "PHP package dependency"
+ },
+ "package": {
+ "type": "string",
+ "description": "Package name and optional version constraint"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/Toolkit/src/Asset/Component.php b/src/Toolkit/src/Asset/Component.php
index 09dacbdf7d9..8e6ee0868af 100644
--- a/src/Toolkit/src/Asset/Component.php
+++ b/src/Toolkit/src/Asset/Component.php
@@ -16,6 +16,7 @@
use Symfony\UX\Toolkit\Dependency\DependencyInterface;
use Symfony\UX\Toolkit\Dependency\PhpPackageDependency;
use Symfony\UX\Toolkit\Dependency\StimulusControllerDependency;
+use Symfony\UX\Toolkit\File\ComponentMeta;
use Symfony\UX\Toolkit\File\Doc;
use Symfony\UX\Toolkit\File\File;
@@ -34,6 +35,7 @@ public function __construct(
public readonly string $name,
public readonly array $files,
public ?Doc $doc = null,
+ public ?ComponentMeta $meta = null,
private array $dependencies = [],
) {
Assert::componentName($name);
@@ -41,6 +43,10 @@ public function __construct(
if ([] === $files) {
throw new \InvalidArgumentException(\sprintf('The component "%s" must have at least one file.', $name));
}
+
+ foreach ($this->meta?->dependencies ?? [] as $dependency) {
+ $this->addDependency($dependency);
+ }
}
public function addDependency(DependencyInterface $dependency): void
@@ -75,4 +81,15 @@ public function getDependencies(): array
{
return $this->dependencies;
}
+
+ public function hasDependency(DependencyInterface $dependency): bool
+ {
+ foreach ($this->dependencies as $existingDependency) {
+ if ($existingDependency->isEquivalentTo($dependency)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/Toolkit/src/Command/CreateKitCommand.php b/src/Toolkit/src/Command/CreateKitCommand.php
index 42f86014240..1ab720be848 100644
--- a/src/Toolkit/src/Command/CreateKitCommand.php
+++ b/src/Toolkit/src/Command/CreateKitCommand.php
@@ -101,7 +101,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
TWIG
);
- $this->filesystem->dumpFile('docs/components/Button.md', <<filesystem->dumpFile('docs/components/Button.md', <<Secondary
```
-TWIG
+MARKDOWN
);
+ $this->filesystem->dumpFile('docs/components/Button.meta.json', json_encode([
+ '$schema' => '../vendor/symfony/ux-toolkit/schemas/component.schema.json',
+ 'dependencies' => (object) [],
+ ], \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
$io->success('Your kit has been scaffolded, enjoy!');
diff --git a/src/Toolkit/src/Dependency/ComponentDependency.php b/src/Toolkit/src/Dependency/ComponentDependency.php
index 7811c3ae34c..d5eb860b3a0 100644
--- a/src/Toolkit/src/Dependency/ComponentDependency.php
+++ b/src/Toolkit/src/Dependency/ComponentDependency.php
@@ -31,6 +31,15 @@ public function __construct(
Assert::componentName($this->name);
}
+ public function isEquivalentTo(DependencyInterface $dependency): bool
+ {
+ if (!$dependency instanceof self) {
+ return false;
+ }
+
+ return $this->name === $dependency->name;
+ }
+
public function __toString(): string
{
return $this->name;
diff --git a/src/Toolkit/src/Dependency/DependencyInterface.php b/src/Toolkit/src/Dependency/DependencyInterface.php
index 60957d99ce7..c4089c4b5cd 100644
--- a/src/Toolkit/src/Dependency/DependencyInterface.php
+++ b/src/Toolkit/src/Dependency/DependencyInterface.php
@@ -20,4 +20,5 @@
*/
interface DependencyInterface extends \Stringable
{
+ public function isEquivalentTo(self $dependency): bool;
}
diff --git a/src/Toolkit/src/Dependency/PhpPackageDependency.php b/src/Toolkit/src/Dependency/PhpPackageDependency.php
index fed6e153540..ab365d1886c 100644
--- a/src/Toolkit/src/Dependency/PhpPackageDependency.php
+++ b/src/Toolkit/src/Dependency/PhpPackageDependency.php
@@ -32,6 +32,15 @@ public function __construct(
Assert::phpPackageName($name);
}
+ public function isEquivalentTo(DependencyInterface $dependency): bool
+ {
+ if (!$dependency instanceof self) {
+ return false;
+ }
+
+ return $this->name === $dependency->name;
+ }
+
public function isHigherThan(self $dependency): bool
{
if (null === $this->constraintVersion || null === $dependency->constraintVersion) {
diff --git a/src/Toolkit/src/Dependency/StimulusControllerDependency.php b/src/Toolkit/src/Dependency/StimulusControllerDependency.php
index f1319b18033..6fd8733c1ec 100644
--- a/src/Toolkit/src/Dependency/StimulusControllerDependency.php
+++ b/src/Toolkit/src/Dependency/StimulusControllerDependency.php
@@ -31,6 +31,15 @@ public function __construct(
Assert::stimulusControllerName($this->name);
}
+ public function isEquivalentTo(DependencyInterface $dependency): bool
+ {
+ if (!$dependency instanceof self) {
+ return false;
+ }
+
+ return $this->name === $dependency->name;
+ }
+
public function __toString(): string
{
return $this->name;
diff --git a/src/Toolkit/src/File/ComponentMeta.php b/src/Toolkit/src/File/ComponentMeta.php
new file mode 100644
index 00000000000..f57b62240e5
--- /dev/null
+++ b/src/Toolkit/src/File/ComponentMeta.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Toolkit\File;
+
+use Symfony\UX\Toolkit\Dependency\DependencyInterface;
+use Symfony\UX\Toolkit\Dependency\PhpPackageDependency;
+use Symfony\UX\Toolkit\Dependency\Version;
+
+/**
+ * @author Hugo Alliaume
+ *
+ * @internal
+ */
+final class ComponentMeta
+{
+ public static function fromJson(string $json): self
+ {
+ $data = json_decode($json, true, flags: JSON_THROW_ON_ERROR);
+ unset($data['$schema']);
+
+ $dependencies = [];
+ foreach ($data['dependencies'] ?? [] as $i => $dependency) {
+ if (!isset($dependency['type'])) {
+ throw new \InvalidArgumentException(sprintf('The dependency type is missing for dependency #%d, add "type" key.', $i));
+ }
+
+ if ('php' === $dependency['type']) {
+ $package = $dependency['package'] ?? throw new \InvalidArgumentException(sprintf('The package name is missing for dependency #%d.', $i));
+ if (str_contains($package, ':')) {
+ [$name, $version] = explode(':', $package, 2);
+ $dependencies[] = new PhpPackageDependency($name, new Version($version));
+ } else {
+ $dependencies[] = new PhpPackageDependency($package);
+ }
+ } else {
+ throw new \InvalidArgumentException(\sprintf('The dependency type "%s" is not supported.', $dependency['type']));
+ }
+ }
+ unset($data['dependencies']);
+
+ if ([] !== $unused = array_keys($data)) {
+ throw new \InvalidArgumentException(\sprintf('The following key(s) are not supported: "%s".', implode('", "', $unused)));
+ }
+
+ return new self(
+ $dependencies
+ );
+ }
+
+ /**
+ * @param list $dependencies
+ */
+ private function __construct(
+ public readonly array $dependencies
+ ) {
+ }
+}
diff --git a/src/Toolkit/src/Kit/KitSynchronizer.php b/src/Toolkit/src/Kit/KitSynchronizer.php
index e5907ae2618..9160b3a1333 100644
--- a/src/Toolkit/src/Kit/KitSynchronizer.php
+++ b/src/Toolkit/src/Kit/KitSynchronizer.php
@@ -19,7 +19,7 @@
use Symfony\UX\Toolkit\Dependency\ComponentDependency;
use Symfony\UX\Toolkit\Dependency\PhpPackageDependency;
use Symfony\UX\Toolkit\Dependency\StimulusControllerDependency;
-use Symfony\UX\Toolkit\Dependency\Version;
+use Symfony\UX\Toolkit\File\ComponentMeta;
use Symfony\UX\Toolkit\File\Doc;
use Symfony\UX\Toolkit\File\File;
use Symfony\UX\Toolkit\File\FileType;
@@ -41,6 +41,11 @@ final class KitSynchronizer
*/
private const RE_STIMULUS_CONTROLLER_REFERENCES = '/data-controller=(["\'])(?P.+?)\1/';
+ private const UX_COMPONENTS_PACKAGES = [
+ 'ux:icon' => 'symfony/ux-icons',
+ 'ux:map' => 'symfony/ux-map',
+ ];
+
public function __construct(
private readonly Filesystem $filesystem,
) {
@@ -68,6 +73,17 @@ private function synchronizeComponents(Kit $kit): void
$relativePathNameToKit = $file->getRelativePathname();
$relativePathName = str_replace($componentsPath.\DIRECTORY_SEPARATOR, '', $relativePathNameToKit);
$componentName = $this->extractComponentName($relativePathName);
+
+ $meta = null;
+ if ($this->filesystem->exists($metaJsonFile = Path::join($file->getPath(), str_replace('.html.twig', '.meta.json', $file->getBasename())))) {
+ $metaJson = file_get_contents($metaJsonFile) ?: throw new \RuntimeException(sprintf('Unable to get contents from file "%s".', $metaJsonFile));
+ try {
+ $meta = ComponentMeta::fromJson($metaJson);
+ } catch (\Throwable $e) {
+ throw new \RuntimeException(sprintf('Unable to parse component "%s" meta from JSON file "%s".', $componentName, $metaJsonFile), previous: $e);
+ }
+ }
+
$component = new Component(
name: $componentName,
files: [new File(
@@ -75,6 +91,7 @@ private function synchronizeComponents(Kit $kit): void
relativePathNameToKit: $relativePathNameToKit,
relativePathName: $relativePathName,
)],
+ meta: $meta,
);
$kit->addComponent($component);
@@ -108,26 +125,17 @@ private function resolveComponentDependencies(Kit $kit, Component $component): v
$fileContent = file_get_contents($filePath);
if (FileType::Twig === $file->type) {
- if (str_contains($fileContent, 'html_cva')) {
- $component->addDependency(new PhpPackageDependency('twig/extra-bundle'));
- $component->addDependency(new PhpPackageDependency('twig/html-extra', new Version('3.12.0')));
- }
-
- if (str_contains($fileContent, 'tailwind_merge')) {
- $component->addDependency(new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'));
- }
-
if (str_contains($fileContent, 'name) {
continue;
}
- if ('ux:icon' === strtolower($componentReferenceName)) {
- $component->addDependency(new PhpPackageDependency('symfony/ux-icons'));
- } elseif ('ux:map' === strtolower($componentReferenceName)) {
- $component->addDependency(new PhpPackageDependency('symfony/ux-map'));
- } elseif (null === $componentReference = $kit->getComponent($componentReferenceName)) {
+ if (null !== $package = self::UX_COMPONENTS_PACKAGES[strtolower($componentReferenceName)] ?? null) {
+ if (!$component->hasDependency(new PhpPackageDependency($package))) {
+ throw new \RuntimeException(\sprintf('Component "%s" uses "%s" UX Twig component, but the composer package "%s" is not listed as a dependency in meta file.', $component->name, $componentReferenceName, $package));
+ }
+ } else if (null === $componentReference = $kit->getComponent($componentReferenceName)) {
throw new \RuntimeException(\sprintf('Component "%s" not found in component "%s" (file "%s")', $componentReferenceName, $component->name, $file->relativePathNameToKit));
} else {
$component->addDependency(new ComponentDependency($componentReference->name));
diff --git a/src/Toolkit/tests/Command/DebugKitCommandTest.php b/src/Toolkit/tests/Command/DebugKitCommandTest.php
index e3f9d61e181..1774009f44d 100644
--- a/src/Toolkit/tests/Command/DebugKitCommandTest.php
+++ b/src/Toolkit/tests/Command/DebugKitCommandTest.php
@@ -32,9 +32,9 @@ public function testShouldBeAbleToDebug(): void
->assertOutputContains(<<<'EOF'
+--------------+----------------------- Component: "Avatar" --------------------------------------+
| File(s) | templates/components/Avatar.html.twig (Twig) |
-| Dependencies | Avatar:Image |
+| Dependencies | tales-from-a-dev/twig-tailwind-extra |
+| | Avatar:Image |
| | Avatar:Text |
-| | tales-from-a-dev/twig-tailwind-extra |
+--------------+----------------------------------------------------------------------------------+
EOF
);
diff --git a/src/Toolkit/tests/Kit/KitFactoryTest.php b/src/Toolkit/tests/Kit/KitFactoryTest.php
index 59272656d14..937e7221100 100644
--- a/src/Toolkit/tests/Kit/KitFactoryTest.php
+++ b/src/Toolkit/tests/Kit/KitFactoryTest.php
@@ -56,6 +56,7 @@ public function testCanCreateShadKit(): void
$this->assertNotNull($table);
$this->assertNotEmpty($table->files);
$this->assertEquals([
+ new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'),
new ComponentDependency('Table:Body'),
new ComponentDependency('Table:Caption'),
new ComponentDependency('Table:Cell'),
@@ -63,7 +64,6 @@ public function testCanCreateShadKit(): void
new ComponentDependency('Table:Head'),
new ComponentDependency('Table:Header'),
new ComponentDependency('Table:Row'),
- new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'),
], $table->getDependencies());
$this->assertNotNull($table->doc);
$this->assertStringContainsString(<<<'EOF'
diff --git a/src/Toolkit/tests/Kit/KitSynchronizerTest.php b/src/Toolkit/tests/Kit/KitSynchronizerTest.php
index 3b16710fd06..05829ea1133 100644
--- a/src/Toolkit/tests/Kit/KitSynchronizerTest.php
+++ b/src/Toolkit/tests/Kit/KitSynchronizerTest.php
@@ -42,11 +42,12 @@ public function testCanResolveDependencies(): void
$this->assertEquals([
new PhpPackageDependency('twig/extra-bundle'),
- new PhpPackageDependency('twig/html-extra', new Version('3.12.0')),
+ new PhpPackageDependency('twig/html-extra', new Version('^3.12.0')),
new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'),
], $kit->getComponent('Button')->getDependencies());
$this->assertEquals([
+ new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'),
new ComponentDependency('Table:Body'),
new ComponentDependency('Table:Caption'),
new ComponentDependency('Table:Cell'),
@@ -54,7 +55,6 @@ public function testCanResolveDependencies(): void
new ComponentDependency('Table:Head'),
new ComponentDependency('Table:Header'),
new ComponentDependency('Table:Row'),
- new PhpPackageDependency('tales-from-a-dev/twig-tailwind-extra'),
], $kit->getComponent('Table')->getDependencies());
}