Skip to content

Commit ddb3680

Browse files
authored
Adds support for GraphQL query variables and variant definition for the styleguide (#4)
* Adds support for variables and variant argument in GraphQL queries to extract different versions of the styles (theming) * Updates examples with new variant option * Updates README with examples and adds headings for better structure
1 parent be525ac commit ddb3680

8 files changed

+223
-84
lines changed

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ This also means that you can reuse the same query by using different alias:
278278
}
279279
```
280280

281+
#### Using fragments
282+
281283
Because _This is just GraphQL™_, you can also create fragments that can then be included in other queries:
282284

283285
```js
@@ -307,6 +309,8 @@ const otherH1Styles = gql`
307309

308310
This is a powerful pattern that avoids lots of repetitions and allows for a bigger separation of concerns.
309311

312+
#### Defining custom unit
313+
310314
You can also override the pre-defined unit directly in your query by using the argument `unit`:
311315

312316
```js
@@ -322,6 +326,39 @@ You can also override the pre-defined unit directly in your query by using the a
322326

323327
This will return `marginLeft: 24em, paddingTop: 32px`.
324328

329+
#### Using style variations (theming)
330+
331+
One of the big advantages of CSS-in-GQL™ is that you can use the power of variables to build custom queries. In `graphql-css` that means that we can easily define variants (think themes) for specific components.
332+
333+
```js
334+
const styles = {
335+
theme: {
336+
light: {
337+
button: {
338+
// button light styles
339+
},
340+
},
341+
dark: {
342+
button: {
343+
// button dark styles
344+
},
345+
},
346+
},
347+
};
348+
349+
const stateStyles = gql`
350+
{
351+
theme(variant: $variant) {
352+
button
353+
}
354+
}
355+
`;
356+
357+
// This can also be a stateful component that changes the variant according to state.
358+
// Please check the examples folder for a detailed example.
359+
const StyledComponent = gqlCSS(styles)(stateStyles, null, { variant: "light" });
360+
```
361+
325362
## Developing
326363

327364
You can use `yarn run dev` and `yarn run dev:server` to run the examples and test this library before using it in your project.

examples/App.jsx

+8-72
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,12 @@
11
import React from "react";
22
import styles from "./styleguide";
3-
import gqlCSS, { GqlCSS, GqlCSSProvider, withGqlCSS, WithGqlCSS } from "../lib";
3+
import gqlCSS, { GqlCSS, GqlCSSProvider, WithGqlCSS } from "../lib";
44
import gql from "graphql-tag";
55
import glamorous from "glamorous";
6-
7-
const h2Styles = gql`
8-
{
9-
typography {
10-
fontSize: scale {
11-
l
12-
}
13-
fontWeight: weight {
14-
bold
15-
}
16-
}
17-
marginLeft: spacing {
18-
xl
19-
}
20-
color: colors {
21-
green
22-
}
23-
}
24-
`;
25-
26-
const h1Styles = gql`
27-
fragment H1 on styles {
28-
typography {
29-
fontSize: scale {
30-
xl
31-
}
32-
fontWeight: weight {
33-
bold
34-
}
35-
}
36-
marginLeft: spacing {
37-
l
38-
}
39-
color: colors {
40-
red
41-
}
42-
}
43-
`;
44-
45-
const customH1Styles = gql`
46-
${h1Styles}
47-
{
48-
...H1
49-
marginLeft: spacing(unit: "em") {
50-
s
51-
}
52-
color: colors {
53-
blue
54-
}
55-
}
56-
`;
6+
import HOCStyledComponent from "./HOC";
7+
import SubscriberComponent from "./SubscriberComponent";
8+
import StatefulComponent from "./StatefulComponent";
9+
import { h2Styles } from "./styleQueries";
5710

5811
// Generates H2 glamorous component
5912
const H2 = gqlCSS(styles)(h2Styles, "h2");
@@ -64,39 +17,22 @@ const H2Comp = (props) => <h2 {...props} />
6417
// Extracts styles object
6518
const inlineStyles = gqlCSS(styles)(h2Styles, false);
6619

67-
// Simulates existing component that is enhanced by the HOC
68-
const ExistingComponent = ({ gqlStyles, ...rest }) => (
69-
<glamorous.Div css={gqlStyles} {...rest} />
70-
);
71-
72-
const HOCStyledComponent = withGqlCSS(styles, customH1Styles)(ExistingComponent);
73-
74-
75-
7620
const App = () => (
7721
<div>
7822
<H2>This is a styled text</H2>
7923
<GqlCSS styles={styles} query={h2Styles} component={H2Comp}>
8024
Using component
8125
</GqlCSS>
8226
<GqlCSSProvider styles={styles}>
83-
<div>
84-
<div>
85-
<span>
86-
<GqlCSS query={h2Styles}>Using provider</GqlCSS>
87-
</span>
88-
</div>
89-
</div>
90-
<GqlCSS query={h1Styles} css={{ marginTop: 30 }}>
91-
Also using provider
92-
</GqlCSS>
27+
<SubscriberComponent/>
9328
</GqlCSSProvider>
9429
<h2 style={inlineStyles}>Inline styles</h2>
9530
<HOCStyledComponent>HOC Styled Component</HOCStyledComponent>
9631
<WithGqlCSS styles={styles} query={h2Styles}>
9732
{({ gqlStyles }) => <div style={gqlStyles}>Render props component</div>}
9833
</WithGqlCSS>
34+
<StatefulComponent />
9935
</div>
10036
);
10137

102-
export default App;
38+
export default App;

examples/HOC.jsx

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from "react";
2+
import { withGqlCSS } from "../lib";
3+
import glamorous from "glamorous";
4+
import styles from "./styleguide";
5+
import { customH1Styles } from "./styleQueries";
6+
7+
// Simulates existing component that is enhanced by the HOC
8+
const ExistingComponent = ({ gqlStyles, ...rest }) => (
9+
<glamorous.Div css={gqlStyles} {...rest} />
10+
);
11+
12+
export default withGqlCSS(styles, customH1Styles)(ExistingComponent);

examples/StatefulComponent.jsx

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import gqlCSS, { GqlCSS } from "../lib";
3+
import glamorous from "glamorous";
4+
import styles from "./styleguide";
5+
import { stateStyles } from "./styleQueries";
6+
7+
class StatefulComponent extends React.Component {
8+
constructor(props) {
9+
super(props);
10+
this.state = {
11+
variant: "normal",
12+
};
13+
this.toggleVariant = this.toggleVariant.bind(this);
14+
}
15+
16+
toggleVariant() {
17+
this.setState(state => ({
18+
variant: state.variant === "normal" ? "done" : "normal",
19+
}));
20+
}
21+
22+
render() {
23+
const { variant } = this.state;
24+
const OtherComponent = gqlCSS(styles)(stateStyles, null, { variant });
25+
26+
return (
27+
<React.Fragment>
28+
<GqlCSS
29+
styles={styles}
30+
query={stateStyles}
31+
variables={{ variant }}
32+
onClick={this.toggleVariant}
33+
>
34+
Using stateful component
35+
</GqlCSS>
36+
<OtherComponent>Other sharing state</OtherComponent>
37+
</React.Fragment>
38+
);
39+
}
40+
}
41+
42+
export default StatefulComponent;

examples/SubscriberComponent.jsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
import { GqlCSS } from "../lib";
3+
import { h1Styles, h2Styles } from "./styleQueries";
4+
5+
// Simulates subscriber component
6+
const SubscriberComponent = () => (
7+
<div>
8+
<div>
9+
<span>
10+
<GqlCSS query={h2Styles}>Using provider</GqlCSS>
11+
</span>
12+
</div>
13+
<GqlCSS query={h1Styles} css={{ marginTop: 30 }}>
14+
Also using provider
15+
</GqlCSS>
16+
</div>
17+
);
18+
19+
export default SubscriberComponent;

examples/styleQueries.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import gql from "graphql-tag";
2+
3+
export const h2Styles = gql`
4+
{
5+
base {
6+
typography {
7+
fontSize: scale {
8+
l
9+
}
10+
fontWeight: weight {
11+
bold
12+
}
13+
}
14+
marginLeft: spacing {
15+
xl
16+
}
17+
color: colors {
18+
green
19+
}
20+
}
21+
}
22+
`;
23+
24+
export const h1Styles = gql`
25+
fragment H1 on styles {
26+
base {
27+
typography {
28+
fontSize: scale {
29+
xl
30+
}
31+
fontWeight: weight {
32+
bold
33+
}
34+
}
35+
marginLeft: spacing {
36+
l
37+
}
38+
color: colors {
39+
red
40+
}
41+
}
42+
}
43+
`;
44+
45+
export const customH1Styles = gql`
46+
${h1Styles}
47+
{
48+
...H1
49+
base {
50+
marginLeft: spacing(unit: "em") {
51+
s
52+
}
53+
color: colors {
54+
blue
55+
}
56+
}
57+
}
58+
`;
59+
60+
export const stateStyles = gql`
61+
{
62+
theme(variant: $variant) {
63+
button
64+
}
65+
}
66+
`;

examples/styleguide.js

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const base = 4
2-
const styles = {
1+
const base = 4;
2+
const baseStyles = {
33
typography: {
44
scale: {
55
s: base * 3,
@@ -8,7 +8,7 @@ const styles = {
88
l: base * 9,
99
xl: base * 13,
1010
xxl: base * 20,
11-
unit: "px"
11+
unit: "px",
1212
},
1313
weight: {
1414
thin: 300,
@@ -32,4 +32,26 @@ const styles = {
3232
},
3333
};
3434

35+
const styles = {
36+
base: baseStyles,
37+
theme: {
38+
normal: {
39+
button: {
40+
fontSize: baseStyles.typography.scale.l,
41+
backgroundColor: baseStyles.colors.red,
42+
padding: baseStyles.spacing.l,
43+
cursor: "pointer"
44+
},
45+
},
46+
done: {
47+
button: {
48+
fontSize: baseStyles.typography.scale.l,
49+
backgroundColor: baseStyles.colors.green,
50+
padding: baseStyles.spacing.l,
51+
cursor: "pointer"
52+
},
53+
},
54+
},
55+
};
56+
3557
export default styles;

0 commit comments

Comments
 (0)