This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Introduce CVA to html-extra
Hey! This PR introduces CVA to Twig. All of this has already been merged into SymfonyUX (https://github.com/symfony/ux/pull/1416), but `@kbond` suggested that this repo can be a better place for this feature.
Here is a description from the PR merged in to SymfonyUX:
------------------------------
This PR introduces a new concept CVA (Class Variance Authority), by adding a1 twig function, to help you manage your class in your component.
Let's take an example an Alert component. In your app, an alert can have a lot of different styles one for success, one for alert, one for warning, and different sizes, with icons or not... You need something that lets you completely change the style of your component without creating a new component, and without creating too much complexity in your template.
Here is the reason came CVA.
Your Alert component can now look like this:
```twig
{% props color = 'blue', size = 'md' %}
{% set alert = html_cva(
'alert rounded-lg',
{
color: {
blue: 'text-blue-800 bg-blue-50 dark:bg-gray-800 dark:text-blue-400',
red: 'text-red-800 bg-red-50 dark:bg-gray-800 dark:text-red-400',
green: 'text-green-800 bg-green-50 dark:bg-gray-800 dark:text-green-400',
yellow: 'text-yellow-800 bg-yellow-50 dark:bg-gray-800 dark:text-yellow-400',
},
size: {
sm: 'px-4 py-3 text-sm',
md: 'px-6 py-4 text-base',
lg: 'px-8 py-5 text-lg',
}
},
[{
color: ['red'],
size: ['lg'],
class: 'font-semibold'
}],
{
rounded: 'md'
}
}) %}
<div class="{{ cva.apply({color, size}, attribute.render('class'), 'flex p-4') }}">
...
</div>
```
So here you have a `cva` function that lets you define different variants of your component.
You can now use your component like this:
```twig
<twig:Alert color="red" size="md"/>
<twig:Alert color="green" size="sm"/>
<twig:Alert color="yellow" size="lg"/>
<twig:Alert color="red" size="md" class="dark:bg-gray-800"/>
```
And then you get the following result:
<img width="1269" alt="Capture d’écran 2024-01-24 à 00 52 33" src="https://github.com/symfony/ux/assets/32077734/6a5e25be-5b81-4ae7-8385-0fa5422d0396">
If you want to know more about the concept I implement here you can look at:
- CVA (js version): https://cva.style/docs
- tailwind merge: https://github.com/gehrisandro/tailwind-merge-php, https://github.com/dcastil/tailwind-merge
- this implementation by using tailwind-merge and cva is inspired a lot by: https://ui.shadcn.com/ (shadcn is the most starred library on github in 2023)
- a really good article that explains the philosophy behind https://manupa.dev/blog/anatomy-of-shadcn-ui
- this PR works great in a LASTstack: https://symfonycasts.com/screencast/last-stack/last-stack
Tell me what you think about it! Thanks for your time! Cheers 🧡
------------
Commits
-------
e3ac14e1 Introduce CVA to html-extra
* 3.x:
Add the notion of a Twig callable
Drop support for 8.0
Add more tests to the Lexer
Add a note about how to escape a string interpolation in a string
Bump version to 3.12
Implement the enum_cases function
Remove deprecation arg
Fix integration tests when a test has more than on data/expect section and deprecations
Bump version
Prepare the 3.11.0 release
Update CHANGELOG
This PR was merged into the 3.x branch.
Discussion
----------
Add a note about how to escape a string interpolation in a string
Commits
-------
38e47a3e Add a note about how to escape a string interpolation in a string
The implementation contains an optimized implementation of the function
for the common case of using a string literal as the argument. It will
validate the enum existence during compilation and compile the code to
use `MyEnum::cases()` directly.
This PR was merged into the 3.x branch.
Discussion
----------
Add support for package/version on deprecations
Commits
-------
0ce79df5 Use trigger_deprecation() instead of trigger_error() for deprecations
* 3.x:
Introduce ChainCache and ReadOnlyFilesystemCache
Add a note about how macros can override existing functions
Fix dumping callables on Node::__toString()
This PR was squashed before being merged into the 4.x branch.
Discussion
----------
Add support for recursive loops
Fixes#3416Fixes#4144
Commits
-------
481e7f0d Prevent infinite loops
fa1a217f Add another test
036c9943 Don't unset loop when it's not defined
1b9baa76 Remove usage of the internal _parent context variable in loops
c28f68f8 Add support for Escaper and Sandbox for Generator nodes
c1933323 Simplify implementation
8c5dd39b Use loop() to recurse instead of loop.recurse()
e95d6b2f Add support for recursive loops
This PR was merged into the 3.x branch.
Discussion
----------
Deprecate NameExpression internal methods
Deprecate two methods from `Twig\Node\Expression\NameExpression`:
* `isSimple()`: did not find any usage in Twig (or even Symfony) repositories
* `isSpecial()`: inlined for better performance ($name is available in the method)
Commits
-------
3531f959 Deprecate NameExpression internal methods
Deprecate two methods from NameExpression:
* isSimple(): did not find any usage in Twig (or even Symfony) repositories
* isSpecial(): inlined for better performance ($name is available in the method)