Skip to content

Commit 279f1d2

Browse files
committed
feat: added support for boolean definition into variants
1 parent 3fd61b0 commit 279f1d2

File tree

2 files changed

+104
-10
lines changed

2 files changed

+104
-10
lines changed

packages/jacaranda/src/index.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,82 @@ describe('sva', () => {
125125
display: 'flex',
126126
});
127127
});
128+
129+
it('should support boolean variants', () => {
130+
const { sva } = defineTokens({});
131+
const buttonStyles = sva({
132+
base: { display: 'flex' },
133+
variants: {
134+
disabled: {
135+
true: { opacity: 0.5 },
136+
false: { opacity: 1 }
137+
}
138+
},
139+
defaultVariants: {
140+
disabled: false
141+
}
142+
});
143+
144+
// Test with explicit true value
145+
expect(buttonStyles({ disabled: true })).toEqual({
146+
display: 'flex',
147+
opacity: 0.5
148+
});
149+
150+
// Test with explicit false value
151+
expect(buttonStyles({ disabled: false })).toEqual({
152+
display: 'flex',
153+
opacity: 1
154+
});
155+
156+
// Test with default value
157+
expect(buttonStyles()).toEqual({
158+
display: 'flex',
159+
opacity: 1
160+
});
161+
});
162+
163+
it('should support compound variants with boolean values', () => {
164+
const { sva } = defineTokens({});
165+
const buttonStyles = sva({
166+
base: { display: 'flex' },
167+
variants: {
168+
disabled: {
169+
true: { opacity: 0.5 },
170+
false: { opacity: 1 }
171+
},
172+
size: {
173+
sm: { padding: 4 },
174+
lg: { padding: 8 },
175+
}
176+
},
177+
compoundVariants: [
178+
{
179+
variants: { disabled: true, size: 'lg' },
180+
style: { fontStyle: 'italic' },
181+
},
182+
],
183+
defaultVariants: {
184+
disabled: false,
185+
size: 'sm'
186+
}
187+
});
188+
189+
// Test compound variant with boolean true
190+
expect(buttonStyles({ disabled: true, size: 'lg' })).toEqual({
191+
display: 'flex',
192+
opacity: 0.5,
193+
padding: 8,
194+
fontStyle: 'italic'
195+
});
196+
197+
// Test without triggering compound variant
198+
expect(buttonStyles({ disabled: true, size: 'sm' })).toEqual({
199+
display: 'flex',
200+
opacity: 0.5,
201+
padding: 4
202+
});
203+
});
128204
});
129205

130206
describe('defineTokens', () => {

packages/jacaranda/src/index.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ type VariantOptions<V> = {
6262

6363
type CompoundVariant<V> = {
6464
variants: Partial<{
65-
[P in keyof V]: keyof V[P];
65+
[P in keyof V]: keyof V[P] | boolean;
6666
}>;
6767
style: StyleObject;
6868
};
6969

7070
// DefaultVariants type
7171
type DefaultVariants<V> = Partial<{
72-
[P in keyof V]: keyof V[P];
72+
[P in keyof V]: keyof V[P] | boolean;
7373
}>;
7474

7575
// VariantStyleConfig type
@@ -97,7 +97,7 @@ export type VariantProps<Component extends (...args: any) => any> = Omit<
9797
* Creates a function that generates styles based on variants
9898
*/
9999
function styles<V extends VariantOptions<V>>(config: VariantStyleConfig<V>) {
100-
type VariantProps = { [P in keyof V]: keyof V[P] | (string & {}) };
100+
type VariantProps = { [P in keyof V]: keyof V[P] | boolean | (string & {}) };
101101
type DefaultProps = NonNullable<typeof config.defaultVariants>;
102102
type Props = OptionalIfHasDefault<VariantProps, DefaultProps>;
103103

@@ -117,12 +117,24 @@ function styles<V extends VariantOptions<V>>(config: VariantStyleConfig<V>) {
117117
for (const [propName, value] of Object.entries(mergedProps) as [keyof V, any][]) {
118118
const variantGroup = config.variants[propName];
119119
if (variantGroup) {
120-
const variantValue = value || config.defaultVariants?.[propName];
121-
if (variantValue && variantGroup[variantValue as keyof typeof variantGroup]) {
122-
styles = {
123-
...styles,
124-
...variantGroup[variantValue as keyof typeof variantGroup],
125-
};
120+
// Handle boolean variants
121+
if (typeof value === 'boolean') {
122+
const booleanValue = value ? 'true' : 'false';
123+
if (variantGroup[booleanValue as keyof typeof variantGroup]) {
124+
styles = {
125+
...styles,
126+
...variantGroup[booleanValue as keyof typeof variantGroup],
127+
};
128+
}
129+
} else {
130+
// Handle string/enum variants
131+
const variantValue = value || config.defaultVariants?.[propName];
132+
if (variantValue && variantGroup[variantValue as keyof typeof variantGroup]) {
133+
styles = {
134+
...styles,
135+
...variantGroup[variantValue as keyof typeof variantGroup],
136+
};
137+
}
126138
}
127139
}
128140
}
@@ -132,7 +144,13 @@ function styles<V extends VariantOptions<V>>(config: VariantStyleConfig<V>) {
132144
for (const compound of config.compoundVariants) {
133145
if (
134146
Object.entries(compound.variants).every(
135-
([propName, value]: [string, unknown]) => mergedProps[propName as keyof V] === value,
147+
([propName, value]: [string, unknown]) => {
148+
// Handle boolean values in compound variants
149+
if (typeof value === 'boolean') {
150+
return mergedProps[propName as keyof V] === value;
151+
}
152+
return mergedProps[propName as keyof V] === value;
153+
}
136154
)
137155
) {
138156
styles = {

0 commit comments

Comments
 (0)