Skip to content

Commit 600685c

Browse files
committed
CVA: Allow array for base, variants and compound
1 parent 2ddc47b commit 600685c

File tree

3 files changed

+83
-8
lines changed

3 files changed

+83
-8
lines changed

src/TwigComponent/src/CVA.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ final class CVA
2626
{
2727
/**
2828
* @var string|list<string|null>|null
29-
* @var array<string, array<string, string>>|null the array should have the following format [variantCategory => [variantName => classes]]
29+
* @var array<string, array<string, string|list<string|null>>|null the array should have the following format [variantCategory => [variantName => classes]]
3030
* ex: ['colors' => ['primary' => 'bleu-8000', 'danger' => 'red-800 text-bold'], 'size' => [...]]
31-
* @var array<array<string, string[]>>|null the array should have the following format ['variantsCategory' => ['variantName', 'variantName'], 'class' => 'text-red-500']
31+
* @var array<array<string, string|array<string>>> the array should have the following format ['variantsCategory' => ['variantName', 'variantName'], 'class' => 'text-red-500']
3232
* @var array<string, string>|null
3333
*/
3434
public function __construct(
@@ -57,7 +57,11 @@ public function resolve(array $recipes): string
5757
continue;
5858
}
5959

60-
$classes .= ' '.$this->variants[$recipeName][$recipeValue];
60+
if (\is_string($this->variants[$recipeName][$recipeValue])) {
61+
$classes .= ' '.$this->variants[$recipeName][$recipeValue];
62+
} else {
63+
$classes .= ' '.implode(' ', $this->variants[$recipeName][$recipeValue]);
64+
}
6165
}
6266

6367
if (null !== $this->compoundVariants) {
@@ -80,11 +84,19 @@ public function resolve(array $recipes): string
8084
}
8185

8286
if ($isCompound) {
83-
if (!isset($compound['class']) || !\is_string($compound['class'])) {
87+
if (!isset($compound['class'])) {
8488
throw new \LogicException('A compound recipe matched but no classes are registered for this match');
8589
}
8690

87-
$classes .= ' '.$compound['class'];
91+
if (!\is_string($compound['class']) && !\is_array($compound['class'])) {
92+
throw new \LogicException('The class of a compound recipe should be a string or an array of string');
93+
}
94+
95+
if (\is_string($compound['class'])) {
96+
$classes .= ' '.$compound['class'];
97+
} else {
98+
$classes .= ' '.implode(' ', $compound['class']);
99+
}
88100
}
89101
}
90102
}

src/TwigComponent/src/Twig/ComponentExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ public function finishEmbeddedComponentRender(): void
8888

8989
/**
9090
* @param array{
91-
* base: string|string[]|null,
92-
* variants: array<string, array<string, string>>,
93-
* compoundVariants: array<array<string, string>>,
91+
* base: string|list<string|null>|null,
92+
* variants: array<string, array<string, string|array<string>>>,
93+
* compoundVariants: array<array<string, string|array<string>>>,
9494
* defaultVariants: array<string, string>
9595
* } $cva
9696
*

src/TwigComponent/tests/Unit/CVATest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@ public static function recipeProvider(): iterable
8888
'text-primary text-sm',
8989
];
9090

91+
yield 'base array' => [
92+
[
93+
'base' => ['font-semibold', 'border', 'rounded'],
94+
'variants' => [
95+
'colors' => [
96+
'primary' => 'text-primary',
97+
'secondary' => 'text-secondary',
98+
],
99+
'sizes' => [
100+
'sm' => 'text-sm',
101+
'md' => 'text-md',
102+
'lg' => 'text-lg',
103+
],
104+
]],
105+
['colors' => 'primary', 'sizes' => 'sm'],
106+
'font-semibold border rounded text-primary text-sm',
107+
];
108+
91109
yield 'no recipes match' => [
92110
[
93111
'base' => 'font-semibold border rounded',
@@ -126,6 +144,25 @@ public static function recipeProvider(): iterable
126144
'font-semibold border rounded text-primary text-sm',
127145
];
128146

147+
yield 'simple variants as array' => [
148+
[
149+
'base' => 'font-semibold border rounded',
150+
'variants' => [
151+
'colors' => [
152+
'primary' => ['text-primary', 'uppercase'],
153+
'secondary' => ['text-secondary', 'uppercase'],
154+
],
155+
'sizes' => [
156+
'sm' => 'text-sm',
157+
'md' => 'text-md',
158+
'lg' => 'text-lg',
159+
],
160+
],
161+
],
162+
['colors' => 'primary', 'sizes' => 'sm'],
163+
'font-semibold border rounded text-primary uppercase text-sm',
164+
];
165+
129166
yield 'simple variants with custom' => [
130167
[
131168
'base' => 'font-semibold border rounded',
@@ -171,6 +208,32 @@ public static function recipeProvider(): iterable
171208
'font-semibold border rounded text-primary text-sm text-red-500',
172209
];
173210

211+
yield 'compound variants as array' => [
212+
[
213+
'base' => 'font-semibold border rounded',
214+
'variants' => [
215+
'colors' => [
216+
'primary' => 'text-primary',
217+
'secondary' => 'text-secondary',
218+
],
219+
'sizes' => [
220+
'sm' => 'text-sm',
221+
'md' => 'text-md',
222+
'lg' => 'text-lg',
223+
],
224+
],
225+
'compounds' => [
226+
[
227+
'colors' => ['primary'],
228+
'sizes' => ['sm'],
229+
'class' => ['text-red-500', 'bold'],
230+
],
231+
],
232+
],
233+
['colors' => 'primary', 'sizes' => 'sm'],
234+
'font-semibold border rounded text-primary text-sm text-red-500 bold',
235+
];
236+
174237
yield 'multiple compound variants' => [
175238
[
176239
'base' => 'font-semibold border rounded',

0 commit comments

Comments
 (0)