Skip to content

Commit cfee250

Browse files
author
Brijesh Bittu
committed
Add variants page
1 parent 9f9e1be commit cfee250

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed
+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# Variants
2+
3+
<Subtitle>Learn how to create variants for your components using Pigment CSS.</Subtitle>
4+
<Meta
5+
name="description"
6+
content="Learn how to create variants for your components using Pigment CSS."
7+
/>
8+
9+
## Variants
10+
11+
Inspired by Stitches, Pigment CSS has first class support for variants. You can create variants for your components by using the `variants` key in the JS object syntax.
12+
13+
> [!IMPORTANT]
14+
> The `variants` feature is available only when authoring styles in the JS object syntax.
15+
16+
Lets look at an example to understand how to create variants for a component.
17+
18+
```tsx title="App.js"
19+
const StyledHeading = styled('h1')({
20+
fontFamily: 'var(--font-family-sans)',
21+
variants: {
22+
level: {
23+
one: {
24+
fontSize: '2rem',
25+
},
26+
two: {
27+
fontSize: '1.5rem',
28+
},
29+
three: {
30+
fontSize: '1rem',
31+
},
32+
},
33+
},
34+
});
35+
36+
const TAGS {
37+
one: 'h1',
38+
two: 'h2',
39+
three: 'h3',
40+
};
41+
42+
function Heading({
43+
level,
44+
children,
45+
}: {
46+
level: 'one' | 'two' | 'three';
47+
children: React.ReactNode;
48+
}) {
49+
const Tag = TAGS[level];
50+
return <StyledHeading as={Tag} level={level}>{children}</StyledHeading>;
51+
}
52+
```
53+
54+
The above example will generate the following css -
55+
56+
```css
57+
@layer pigment.base {
58+
.heading {
59+
font-family: var(--font-family-sans);
60+
}
61+
}
62+
63+
@layer pigment.variants {
64+
.heading-level-one {
65+
font-size: 2rem;
66+
}
67+
68+
.heading-level-two {
69+
font-size: 1.5rem;
70+
}
71+
72+
.heading-level-three {
73+
font-size: 1rem;
74+
}
75+
}
76+
```
77+
78+
and will conditionally apply the appropriate css classes based on the `level` prop at runtime, ie, when `level` is `three`, the rendered `h3` element will have its class set as `heading heading-level-three`.
79+
80+
> [!NOTE]
81+
> Both the base styles and the variant styles are wrapped in a `@layer pigment.base` and `@layer pigment.variants` respectively. Learn more about the layer's precedence in the [composition](/guides/composition#layers) page.
82+
83+
The same logic applies when using `css()` function, except in that case, you pass the variant values as an object like so -
84+
85+
```tsx title="App.js"
86+
import { css } from '@pigment-css/react-new';
87+
88+
const styles = css({
89+
fontFamily: 'var(--font-family-sans)',
90+
variants: {
91+
level: {
92+
one: {
93+
fontSize: '2rem',
94+
},
95+
two: {
96+
fontSize: '1.5rem',
97+
},
98+
three: {
99+
fontSize: '1rem',
100+
},
101+
},
102+
},
103+
});
104+
const baseClass = styles().className; // heading
105+
const headingThreeClass = styles({ level: 'three' }).className; // heading heading-level-three
106+
```
107+
108+
## Compound Variants
109+
110+
You can combine multiple variants together to apply styles when multiple variants' values match a certain condition by using the `compoundVariants` key in the JS object syntax.
111+
112+
```tsx title="App.js"
113+
const StyledHeading = styled('h1')({
114+
fontFamily: 'var(--font-family-sans)',
115+
variants: {
116+
level: {
117+
one: {
118+
fontSize: '2rem',
119+
},
120+
two: {
121+
fontSize: '1.5rem',
122+
},
123+
three: {
124+
fontSize: '1rem',
125+
},
126+
},
127+
color: {
128+
error: {
129+
color: 'red',
130+
},
131+
success: {
132+
color: 'green',
133+
},
134+
},
135+
},
136+
compoundVariants: [
137+
{
138+
level: 'three',
139+
color: 'error',
140+
css: {
141+
fontSize: '1.5rem',
142+
},
143+
},
144+
],
145+
});
146+
```
147+
148+
The above example will generate the following css -
149+
150+
```css
151+
@layer pigment.base {
152+
.heading {
153+
font-family: var(--font-family-sans);
154+
}
155+
}
156+
157+
@layer pigment.variants {
158+
.heading-level-one {
159+
font-size: 2rem;
160+
}
161+
162+
.heading-level-two {
163+
font-size: 1.5rem;
164+
}
165+
166+
.heading-level-three {
167+
font-size: 1rem;
168+
}
169+
170+
.heading-color-error {
171+
color: red;
172+
}
173+
174+
.heading-color-success {
175+
color: green;
176+
}
177+
}
178+
179+
@layer pigment.compoundvariants {
180+
.heading-cv-1 {
181+
font-size: 1.5rem;
182+
}
183+
}
184+
```
185+
186+
Based on what props you pass to the component, the appropriate css classes will be applied.
187+
188+
```tsx title="App.js"
189+
// classes: heading heading-level-three heading-color-success
190+
<Heading level="three" color="success">
191+
Hello World
192+
</Heading>
193+
194+
// classes: heading heading-level-three heading-color-error heading-cv-1
195+
<Heading level="three" color="error">
196+
Hello World
197+
</Heading>
198+
```
199+
200+
## Default Variants
201+
202+
You can set the default variants for a component by using the `defaultVariants` key in the JS object syntax.
203+
204+
```tsx title="App.js"
205+
const StyledHeading = styled('h1')({
206+
fontFamily: 'var(--font-family-sans)',
207+
variants: {
208+
level: {
209+
one: {
210+
fontSize: '2rem',
211+
},
212+
two: {
213+
fontSize: '1.5rem',
214+
},
215+
three: {
216+
fontSize: '1rem',
217+
},
218+
},
219+
color: {
220+
default: {
221+
color: 'blue',
222+
},
223+
error: {
224+
color: 'red',
225+
},
226+
success: {
227+
color: 'green',
228+
},
229+
},
230+
},
231+
defaultVariants: {
232+
level: 'three',
233+
color: 'default',
234+
},
235+
});
236+
```
237+
238+
For the above example, when rendering the `Heading` component without any props, the default variants will be applied.
239+
240+
```tsx title="App.js"
241+
// classes: heading heading-level-three heading-color-default
242+
<Heading>Title</Heading>
243+
244+
// or
245+
246+
// classes: heading heading-level-two heading-color-default
247+
<Heading level="two">Title</Heading>
248+
```

0 commit comments

Comments
 (0)