Skip to content

Commit 18d2529

Browse files
Update the website to document the end-to-end lifecycle of Compiled (#1738)
* Update the website to document the end-to-end lifecycle of Compiled * Don't Prettier css * Minor documentation * Updates from review
1 parent 29b3e81 commit 18d2529

File tree

13 files changed

+260
-186
lines changed

13 files changed

+260
-186
lines changed

website/packages/docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"dependencies": {
1010
"@babel/core": "^7.24.5",
1111
"@babel/preset-typescript": "^7.24.1",
12-
"@compiled/babel-plugin": "^0.28.8",
13-
"@compiled/react": "^0.17.1",
12+
"@compiled/babel-plugin": "latest",
13+
"@compiled/react": "latest",
1414
"@compiled/website-examples": "^1.0.0",
1515
"@compiled/website-ui": "^1.0.0",
1616
"@mdx-js/loader": "^1.6.22",

website/packages/docs/src/examples/css-prop.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { cssProp } from '@compiled/website-examples';
22
import { Example } from '@compiled/website-ui';
3+
import { Fragment } from 'react';
34

45
export const CssPropObj = (): JSX.Element => {
56
return (
@@ -116,7 +117,7 @@ export const CssPropCompositionNoStyle = (): JSX.Element => {
116117
export const CssPropConditionalRules = (): JSX.Element => {
117118
return (
118119
<Example
119-
exampleCode="<Lozenge primary>Arrange</Lozenge>"
120+
exampleCode="<LargeText>Hello</LargeText><LargeText inverted>world</LargeText>"
120121
before={
121122
// eslint-disable-next-line @typescript-eslint/no-var-requires
122123
require('!!raw-loader!@compiled/website-examples/dist/jsx/css-prop-conditional-rules.js')
@@ -127,7 +128,10 @@ export const CssPropConditionalRules = (): JSX.Element => {
127128
require('!!raw-loader!@compiled/website-examples/dist/js/css-prop-conditional-rules.js')
128129
.default
129130
}>
130-
<cssProp.CssPropConditionalRules primary>Arrange</cssProp.CssPropConditionalRules>
131+
<Fragment>
132+
<cssProp.CssPropConditionalRules>Hello</cssProp.CssPropConditionalRules>
133+
<cssProp.CssPropConditionalRules inverted>world</cssProp.CssPropConditionalRules>
134+
</Fragment>
131135
</Example>
132136
);
133137
};

website/packages/docs/src/pages/about-compiled.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
section: 1-Getting started
33
name: About Compiled
4-
order: 2
4+
order: 1
55
---
66

77
# About Compiled
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
order: 3
3+
section: 1-Getting started
4+
---
5+
6+
# How it Works
7+
8+
Once you've [installed and configured](/installation) everything, you can start using it,
9+
but it's best to explain what happens under the hood.
10+
11+
Compiled uses Babel (with pre-configuration options via Webpack and Parcel) to transform styles
12+
into atomic CSS determined at build time, resulting in **very performant components**.
13+
14+
Let's take a typical component you might write:
15+
16+
```jsx
17+
/** @jsxImportSource @compiled/react */
18+
import { css } from '@compiled/react';
19+
import type { ReactNode } from 'react';
20+
21+
type Props = { inverted?: boolean, children: ReactNode };
22+
23+
const largeTextStyles = css({
24+
fontSize: '48px',
25+
padding: '8px',
26+
background: '#eee',
27+
});
28+
const invertedStyles = css({
29+
background: '#333',
30+
color: '#fff',
31+
});
32+
33+
export const LargeText = ({ inverted, children }: Props): JSX.Element => {
34+
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
35+
};
36+
```
37+
38+
## Runtime styles (unperformant)
39+
40+
With the most basic Babel setup, Compiled will be transformed to **runtime styles**.
41+
This is typically used in a development or testing environments.
42+
43+
It is **not recommended in production environments** as it will be less performant, but also mixing
44+
runtime and extraction can result in breaking visual changes from atomic specificity conflicts.
45+
Refer to [extracted styles](#extracted-styles) below for the recommendation.
46+
47+
```bash
48+
$ babel src
49+
Successfully compiled 1 file with Babel (9ms)
50+
```
51+
52+
You'll see a few things happening in the code below:
53+
54+
1. All styles are converted into [Atomic CSS](/atomic-css) for reuse.
55+
2. Some styles, such as `padding:8px` will be expanded out to `padding-left`, `padding-right`, etc,
56+
while others might be sorted. [Read more about this](shorthand)
57+
3. All `css()` calls are replaced with `null` and instead the styles are injected at runtime with the
58+
`className` inlined. Note that `cssMap()` works slightly differently and maintains the object syntax.
59+
4. There are a few internal runtime functions that are used to manage the styles like `ax` and `CC`.
60+
[Read more about this](/pkg-react-runtime)
61+
5. [Postcss](https://postcss.org/), [autoprefixer](https://github.com/postcss/autoprefixer), and some other
62+
optimizations will run over your code to make it more performant and safer for use.
63+
64+
```jsx
65+
import { ax, ix, CC, CS } from '@compiled/react/runtime';
66+
const _8 = '._syazu67f{color:#fff}';
67+
const _7 = '._bfhk1d6m{background-color:#333}';
68+
const _6 = '._bfhkr75e{background-color:#eee}';
69+
const _5 = '._19bvftgi{padding-left:1pc}';
70+
const _4 = '._n3tdftgi{padding-bottom:1pc}';
71+
const _3 = '._u5f3ftgi{padding-right:1pc}';
72+
const _2 = '._ca0qftgi{padding-top:1pc}';
73+
const _ = '._1wybckbl{font-size:3pc}';
74+
const largeTextStyles = null;
75+
const invertedStyles = null;
76+
export const LargeText = ({ inverted, children }) => {
77+
return (
78+
<CC>
79+
<CS>{[_, _2, _3, _4, _5, _6, _7, _8]}</CS>
80+
<span
81+
className={ax([
82+
'_1wybckbl _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi _bfhkr75e',
83+
inverted && '_bfhk1d6m _syazu67f',
84+
])}>
85+
{children}
86+
</span>
87+
</CC>
88+
);
89+
};
90+
```
91+
92+
## Extracted styles
93+
94+
We highly suggest you turn on style extraction to distribute styles statically at build time,
95+
either through [NPM](https://npmjs.com/) or Production environments. Doing this, styles will
96+
have their **runtime stripped and styles extracted** to an [atomic style sheet](/atomic-css).
97+
98+
Refer to [stylesheet extraction](/css-extraction-webpack) for more details.
99+
100+
Let's compare this to runtime styles, assuming we have Parcel configured
101+
102+
```bash
103+
$ parcel build ./src/index.html
104+
✨ Built in 4.94s
105+
dist/index.html 246 B 349ms
106+
dist/index.019bae5f.js 136.13 KB 806ms
107+
# This generates `index.compiled.css` file(s) too.
108+
🌽 ✅ Done in 6.26s
109+
```
110+
111+
You'll see a few different things are happening in the code below:
112+
113+
1. All styles are moved into a separate file, `index.compiled.css`, that is imported into this file for
114+
your bundler to pick up and combine and serve to the user.
115+
2. The runtime injection of `<CS>` is no longer required because the styles are statically available.
116+
117+
The main difference beyond the greatly reduced runtime cost is that the atomic styles can be completely deduplicated.
118+
119+
```diff
120+
+import "./index.compiled.css";
121+
-import { ax, ix, CC, CS } from '@compiled/react/runtime';
122+
+import { ax, ix } from "@compiled/react/runtime";
123+
-const _8 = '._syazu67f{color:#fff}';
124+
-const _7 = '._bfhk1d6m{background-color:#333}';
125+
-const _6 = '._bfhkr75e{background-color:#eee}';
126+
-const _5 = '._19bvftgi{padding-left:8px}';
127+
-const _4 = '._n3tdftgi{padding-bottom:8px}';
128+
-const _3 = '._u5f3ftgi{padding-right:8px}';
129+
-const _2 = '._ca0qftgi{padding-top:8px}';
130+
-const _ = '._1wybckbl{font-size:3pc}';
131+
var largeTextStyles = null;
132+
var invertedStyles = null;
133+
export const LargeText = ({ inverted, children }) => {
134+
return (
135+
- <CC>
136+
- <CS>{[_, _2, _3, _4, _5, _6, _7, _8]}</CS>
137+
<span
138+
className={ax([
139+
'_1wybckbl _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi _bfhkr75e',
140+
inverted && '_bfhk1d6m _syazu67f',
141+
])}>
142+
{children}
143+
</span>
144+
- </CC>
145+
);
146+
};
147+
```
148+
149+
For reference, the atomic stylesheet is created just as before, now in `index.compiled.css`, and with
150+
the bundler config, these `*.compiled.css` files will be merged together with duplicates removed, resulting
151+
in a drastically smaller CSS payload to the customer.
152+
153+
These `*.compiled.css` files could be distributed via NPM or collected and bundled to customers.
154+
155+
<!-- prettier-ignore -->
156+
```css
157+
._19bvftgi{padding-left:8px}
158+
._1wybckbl{font-size:3pc}
159+
._bfhk1d6m{background-color:#333}
160+
._bfhkr75e{background-color:#eee}
161+
._ca0qftgi{padding-top:8px}
162+
._n3tdftgi{padding-bottom:8px}
163+
._syazu67f{color:#fff}
164+
._u5f3ftgi{padding-right:8px}
165+
```

website/packages/docs/src/pages/installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
order: 3
2+
order: 2
33
section: 1-Getting started
44
---
55

website/packages/examples/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
"@babel/core": "^7.24.5",
1717
"@babel/preset-react": "^7.24.1",
1818
"@babel/preset-typescript": "^7.24.1",
19-
"@compiled/babel-plugin": "^0.28.8",
20-
"@compiled/react": "^0.17.1",
19+
"@compiled/babel-plugin": "latest",
20+
"@compiled/react": "latest",
2121
"@types/react": "^18.3.1",
2222
"@types/react-dom": "^18.3.0",
2323
"typescript": "^5.4.5"

website/packages/examples/src/css-prop-conditional-rules.tsx

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,18 @@
22
import { css } from '@compiled/react';
33
import type { ReactNode } from 'react';
44

5-
type LozengeProps = {
6-
children: ReactNode;
7-
primary: boolean;
8-
};
5+
type Props = { inverted?: boolean; children: ReactNode };
96

10-
const primaryStyles = css({
11-
border: '3px solid pink',
12-
color: 'pink',
7+
const largeTextStyles = css({
8+
fontSize: '48px',
9+
padding: '8px',
10+
background: '#eee',
1311
});
14-
15-
const notPrimaryStyles = css({
16-
border: '3px solid blue',
17-
color: 'blue',
12+
const invertedStyles = css({
13+
background: '#333',
14+
color: '#fff',
1815
});
1916

20-
const moreStyles = css({
21-
// any styles here will override what is in
22-
// primaryStyles and notPrimaryStyles
23-
padding: '4px 8px',
24-
fontWeight: 600,
25-
borderRadius: 3,
26-
});
27-
28-
export const Lozenge = ({ children, primary }: LozengeProps): JSX.Element => (
29-
<span css={[primary && primaryStyles, !primary && notPrimaryStyles, moreStyles]}>{children}</span>
30-
);
17+
export const LargeText = ({ inverted, children }: Props): JSX.Element => {
18+
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
19+
};

website/packages/examples/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CompositionIdentifier } from './css-prop-composition-identifier';
88
import { CustomColorText as CssPropCompositionIncorrect } from './css-prop-composition-incorrect';
99
import { CompositionMultiple } from './css-prop-composition-multiple';
1010
import { CustomColorText as CssPropCompositionNoStyle } from './css-prop-composition-no-style';
11-
import { Lozenge as CssPropConditionalRules } from './css-prop-conditional-rules';
11+
import { LargeText as CssPropConditionalRules } from './css-prop-conditional-rules';
1212
import { EmphasisText as CssPropDynamic } from './css-prop-dynamic-decl';
1313
import { EmphasisText as CssPropObj } from './css-prop-obj';
1414
import { EmphasisText as CssPropString } from './css-prop-string';

website/packages/landing/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"start": "webpack serve"
1010
},
1111
"dependencies": {
12-
"@compiled/react": "^0.17.1",
13-
"@compiled/webpack-loader": "^0.12.7",
12+
"@compiled/react": "latest",
13+
"@compiled/webpack-loader": "latest",
1414
"@compiled/website-examples": "^1.0.0",
1515
"@compiled/website-ui": "^1.0.0",
1616
"@mdx-js/loader": "^1.6.22",
Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
/** @jsxImportSource @compiled/react */
2-
2+
import { css } from '@compiled/react';
33
import type { ReactNode } from 'react';
44

5-
type Props = {
6-
color: string;
7-
children: ReactNode;
8-
};
5+
type Props = { inverted?: boolean; children: ReactNode };
96

10-
export const LargeText = (props: Props): JSX.Element => (
11-
<span
12-
css={{
13-
color: props.color,
14-
fontSize: 48,
15-
}}>
16-
{props.children}
17-
</span>
18-
);
7+
const largeTextStyles = css({
8+
fontSize: '48px',
9+
padding: '8px',
10+
background: '#eee',
11+
});
12+
const invertedStyles = css({
13+
background: '#333',
14+
color: '#fff',
15+
});
16+
17+
export const LargeText = ({ inverted, children }: Props): JSX.Element => {
18+
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
19+
};

0 commit comments

Comments
 (0)