Skip to content

Commit c02b7e2

Browse files
committed
defaultVariables and use an array to configure a cva
1 parent 511e135 commit c02b7e2

File tree

5 files changed

+159
-23
lines changed

5 files changed

+159
-23
lines changed

src/TwigComponent/src/CVA.php

+9
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function __construct(
3434
private ?string $base = null,
3535
private ?array $variants = null,
3636
private ?array $compoundVariants = null,
37+
private ?array $defaultVariants = null
3738
) {
3839
}
3940

@@ -83,6 +84,14 @@ public function resolve(array $recipes): string
8384
}
8485
}
8586

87+
if (null !== $this->defaultVariants) {
88+
foreach ($this->defaultVariants as $defaultVariantName => $defaultVariantValue) {
89+
if (!isset($recipes[$defaultVariantName])) {
90+
$classes .= ' '.$this->variants[$defaultVariantName][$defaultVariantValue];
91+
}
92+
}
93+
}
94+
8695
return trim($classes);
8796
}
8897
}

src/TwigComponent/src/Twig/ComponentExtension.php

+18-5
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,26 @@ public function finishEmbeddedComponentRender(): void
8787
}
8888

8989
/**
90-
* @param string $base some base class you want to have in every matching recipes
91-
* @param array $variants your recipes class
92-
* @param array|null $compoundVariants compounds allow you to add extra class when multiple variation are matching in the same time
90+
* @param array{
91+
* base: string,
92+
* variants: array<string, array<string, string>>,
93+
* compoundVariants: array<array<string, string>>,
94+
* defaultVariants: array<string, string>
95+
* } $cva
96+
*
97+
* base some base class you want to have in every matching recipes
98+
* variants your recipes class
99+
* compoundVariants compounds allow you to add extra class when multiple variation are matching in the same time
100+
* defaultVariants allow you to add a default class when no recipe is matching
93101
*/
94-
public function cva(string $base, array $variants, ?array $compoundVariants = []): CVA
102+
public function cva(array $cva): CVA
95103
{
96-
return new CVA($base, $variants, $compoundVariants);
104+
return new CVA(
105+
$cva['base'] ?? [],
106+
$cva['variants'] ?? [],
107+
$cva['compoundVariants'] ?? [],
108+
$cva['defaultVariants'] ?? []
109+
);
97110
}
98111

99112
private function throwRuntimeError(string $name, \Throwable $e): void
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
{% props color = 'blue', size = 'md' %}
22

3-
{% set alert = cva('alert', {
4-
color: {
5-
blue: 'alert-blue',
6-
red: 'alert-red',
7-
green: 'alert-green',
8-
yellow: 'alert-yellow',
3+
{% set alert = cva({
4+
base: 'alert',
5+
variants: {
6+
color: {
7+
blue: 'alert-blue',
8+
red: 'alert-red',
9+
green: 'alert-green',
10+
yellow: 'alert-yellow',
11+
},
12+
size: {
13+
sm: 'alert-sm',
14+
md: 'alert-md',
15+
lg: 'alert-lg',
16+
},
17+
rounded: {
18+
sm: 'rounded-sm',
19+
md: 'rounded-md',
20+
lg: 'rounded-lg',
21+
}
922
},
10-
size: {
11-
sm: 'alert-sm',
12-
md: 'alert-md',
13-
lg: 'alert-lg',
14-
}
15-
}, [
16-
{
23+
compoundVariants: [{
1724
color: ['red'],
1825
size: ['lg'],
1926
class: 'font-semibold'
27+
}],
28+
defaultVariants: {
29+
rounded: 'md'
2030
}
21-
]
22-
) %}
31+
}) %}
2332

24-
<div class="{{ alert.apply({color, size}, attributes.render('class'), 'rounded') }}">
33+
<div class="{{ alert.apply({color, size}, attributes.render('class'), 'flex p-4') }}">
2534
...
2635
</div>

src/TwigComponent/tests/Integration/ComponentExtensionTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ public function testComponentWithClassMerge(): void
260260
{
261261
$output = self::getContainer()->get(Environment::class)->render('class_merge.html.twig');
262262

263-
$this->assertStringContainsString('class="alert alert-red alert-lg font-semibold dark:bg-gray-600"', $output);
263+
$this->assertStringContainsString('class="alert alert-red alert-lg font-semibold rounded-md dark:bg-gray-600 flex p-4"', $output);
264264
}
265265

266266
private function renderComponent(string $name, array $data = []): string

src/TwigComponent/tests/Unit/CVATest.php

+106-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class CVATest extends TestCase
2424
*/
2525
public function testRecipes(array $recipe, array $recipes, string $expected): void
2626
{
27-
$recipeClass = new CVA($recipe['base'] ?? '', $recipe['variants'] ?? [], $recipe['compounds'] ?? []);
27+
$recipeClass = new CVA($recipe['base'] ?? '', $recipe['variants'] ?? [], $recipe['compounds'] ?? [], $recipe['defaultVariants'] ?? []);
2828

2929
$this->assertEquals($expected, $recipeClass->resolve($recipes));
3030
}
@@ -230,5 +230,110 @@ public static function recipeProvider(): iterable
230230
['colors' => 'primary', 'sizes' => 'sm'],
231231
'font-semibold border rounded text-primary text-sm',
232232
];
233+
yield 'default variables' => [
234+
[
235+
'base' => 'font-semibold border rounded',
236+
'variants' => [
237+
'colors' => [
238+
'primary' => 'text-primary',
239+
'secondary' => 'text-secondary',
240+
],
241+
'sizes' => [
242+
'sm' => 'text-sm',
243+
'md' => 'text-md',
244+
'lg' => 'text-lg',
245+
],
246+
'rounded' => [
247+
'sm' => 'rounded-sm',
248+
'md' => 'rounded-md',
249+
'lg' => 'rounded-lg',
250+
],
251+
],
252+
'compounds' => [
253+
[
254+
'colors' => ['danger', 'secondary'],
255+
'sizes' => ['sm'],
256+
'class' => 'text-red-500',
257+
],
258+
],
259+
'defaultVariants' => [
260+
'colors' => 'primary',
261+
'sizes' => 'sm',
262+
'rounded' => 'md',
263+
],
264+
],
265+
['colors' => 'primary', 'sizes' => 'sm'],
266+
'font-semibold border rounded text-primary text-sm rounded-md',
267+
];
268+
yield 'default variables all overwrite' => [
269+
[
270+
'base' => 'font-semibold border rounded',
271+
'variants' => [
272+
'colors' => [
273+
'primary' => 'text-primary',
274+
'secondary' => 'text-secondary',
275+
],
276+
'sizes' => [
277+
'sm' => 'text-sm',
278+
'md' => 'text-md',
279+
'lg' => 'text-lg',
280+
],
281+
'rounded' => [
282+
'sm' => 'rounded-sm',
283+
'md' => 'rounded-md',
284+
'lg' => 'rounded-lg',
285+
],
286+
],
287+
'compounds' => [
288+
[
289+
'colors' => ['danger', 'secondary'],
290+
'sizes' => ['sm'],
291+
'class' => 'text-red-500',
292+
],
293+
],
294+
'defaultVariants' => [
295+
'colors' => 'primary',
296+
'sizes' => 'sm',
297+
'rounded' => 'md',
298+
],
299+
],
300+
['colors' => 'primary', 'sizes' => 'sm', 'rounded' => 'lg'],
301+
'font-semibold border rounded text-primary text-sm rounded-lg',
302+
];
303+
yield 'default variables without matching variants' => [
304+
[
305+
'base' => 'font-semibold border rounded',
306+
'variants' => [
307+
'colors' => [
308+
'primary' => 'text-primary',
309+
'secondary' => 'text-secondary',
310+
],
311+
'sizes' => [
312+
'sm' => 'text-sm',
313+
'md' => 'text-md',
314+
'lg' => 'text-lg',
315+
],
316+
'rounded' => [
317+
'sm' => 'rounded-sm',
318+
'md' => 'rounded-md',
319+
'lg' => 'rounded-lg',
320+
],
321+
],
322+
'compounds' => [
323+
[
324+
'colors' => ['danger', 'secondary'],
325+
'sizes' => ['sm'],
326+
'class' => 'text-red-500',
327+
],
328+
],
329+
'defaultVariants' => [
330+
'colors' => 'primary',
331+
'sizes' => 'sm',
332+
'rounded' => 'md',
333+
],
334+
],
335+
[],
336+
'font-semibold border rounded text-primary text-sm rounded-md',
337+
];
233338
}
234339
}

0 commit comments

Comments
 (0)