99/**
1010 * Core variant resolution engine, shared by all ClassVariance implementations.
1111 *
12- * The class using this trait must declare the following public readonly properties:
12+ * The class using this trait must declare the following public readable properties:
1313 * - array|string $base
1414 * - ClassMerger $merger
1515 * - array $variants
1616 * - array $compoundVariants
1717 * - array $defaultVariants
1818 *
19+ * @property-read array|string $base
20+ * @property-read ClassMerger $merger
21+ * @property-read array $variants
22+ * @property-read array $compoundVariants
23+ * @property-read array $defaultVariants
24+ *
1925 * @internal
2026 */
2127trait ResolvesVariants
2228{
29+ /** @param array<string, string|bool> $props */
2330 public function __invoke (array $ props = [], string $ slot = '' ): string
2431 {
2532 $ props = $ this ->applyDefaultVariants ($ props );
@@ -33,10 +40,16 @@ public function __invoke(array $props = [], string $slot = ''): string
3340 return $ this ->merger ->merge (...$ classes ->toArray ());
3441 }
3542
36- /** @param array<string, string|bool> $props */
43+ /**
44+ * @param array<string, string|bool> $props
45+ * @return array<string, string|bool>
46+ */
3747 private function applyDefaultVariants (array $ props ): array
3848 {
39- foreach ($ this ->defaultVariants as $ key => $ value ) {
49+ /** @var array<string, string|bool> $defaults */
50+ $ defaults = $ this ->defaultVariants ;
51+
52+ foreach ($ defaults as $ key => $ value ) {
4053 $ props [$ key ] ??= $ value ;
4154 }
4255
@@ -76,6 +89,7 @@ private function resolveSlot(string $slot): string
7689 */
7790 private function resolvePassthrough (array $ props , string $ slot ): ClassNames
7891 {
92+ /** @var string|array<array-key, mixed>|bool $value */
7993 $ value = $ props ['class ' ] ?? $ props ['className ' ] ?? '' ;
8094
8195 if (is_bool ($ value ) || $ value === '' ) {
@@ -98,8 +112,12 @@ private function resolveVariants(array $props, string $slot): ClassNames
98112 {
99113 $ classes = ClassNames::empty ();
100114
115+ /** @var array<string, array<string, string|array<string, mixed>>> $variants */
116+ $ variants = $ this ->variants ;
117+
101118 foreach ($ props as $ key => $ value ) {
102- $ entry = $ this ->variants [$ key ][$ value ] ?? null ;
119+ $ lookupKey = is_bool ($ value ) ? ($ value ? 'true ' : 'false ' ) : $ value ;
120+ $ entry = $ variants [$ key ][$ lookupKey ] ?? null ;
103121
104122 if ($ entry === null ) {
105123 continue ;
@@ -118,11 +136,15 @@ private function resolveCompoundVariants(array $props, string $slot): ClassNames
118136 {
119137 $ classes = ClassNames::empty ();
120138
121- foreach ($ this ->compoundVariants as $ compound ) {
139+ /** @var array<int, array<string, mixed>> $compoundVariants */
140+ $ compoundVariants = $ this ->compoundVariants ;
141+
142+ foreach ($ compoundVariants as $ compound ) {
122143 if (! $ this ->compoundMatches ($ props , $ compound )) {
123144 continue ;
124145 }
125146
147+ /** @var string|array<string, mixed>|bool $classValue */
126148 $ classValue = $ compound ['class ' ] ?? $ compound ['className ' ] ?? '' ;
127149 $ classes = $ classes ->concat (ClassNames::of ($ classValue , $ slot ));
128150 }
@@ -137,10 +159,12 @@ private function resolveCompoundVariants(array $props, string $slot): ClassNames
137159 private function compoundMatches (array $ props , array $ compound ): bool
138160 {
139161 foreach ($ compound as $ key => $ value ) {
140- if ($ key === 'class ' || $ key === 'className ' ) {
162+ if ($ key === 'class ' ) {
163+ continue ;
164+ }
165+ if ($ key === 'className ' ) {
141166 continue ;
142167 }
143-
144168 if (is_array ($ value )) {
145169 if (! isset ($ props [$ key ]) || ! in_array ($ props [$ key ], $ value , strict: true )) {
146170 return false ;
0 commit comments