Skip to content

Commit

Permalink
Update the website to document the end-to-end lifecycle of Compiled (#…
Browse files Browse the repository at this point in the history
…1738)

* Update the website to document the end-to-end lifecycle of Compiled

* Don't Prettier css

* Minor documentation

* Updates from review
  • Loading branch information
kylorhall-atlassian authored Oct 30, 2024
1 parent 29b3e81 commit 18d2529
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 186 deletions.
4 changes: 2 additions & 2 deletions website/packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"dependencies": {
"@babel/core": "^7.24.5",
"@babel/preset-typescript": "^7.24.1",
"@compiled/babel-plugin": "^0.28.8",
"@compiled/react": "^0.17.1",
"@compiled/babel-plugin": "latest",
"@compiled/react": "latest",
"@compiled/website-examples": "^1.0.0",
"@compiled/website-ui": "^1.0.0",
"@mdx-js/loader": "^1.6.22",
Expand Down
8 changes: 6 additions & 2 deletions website/packages/docs/src/examples/css-prop.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cssProp } from '@compiled/website-examples';
import { Example } from '@compiled/website-ui';
import { Fragment } from 'react';

export const CssPropObj = (): JSX.Element => {
return (
Expand Down Expand Up @@ -116,7 +117,7 @@ export const CssPropCompositionNoStyle = (): JSX.Element => {
export const CssPropConditionalRules = (): JSX.Element => {
return (
<Example
exampleCode="<Lozenge primary>Arrange</Lozenge>"
exampleCode="<LargeText>Hello</LargeText><LargeText inverted>world</LargeText>"
before={
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('!!raw-loader!@compiled/website-examples/dist/jsx/css-prop-conditional-rules.js')
Expand All @@ -127,7 +128,10 @@ export const CssPropConditionalRules = (): JSX.Element => {
require('!!raw-loader!@compiled/website-examples/dist/js/css-prop-conditional-rules.js')
.default
}>
<cssProp.CssPropConditionalRules primary>Arrange</cssProp.CssPropConditionalRules>
<Fragment>
<cssProp.CssPropConditionalRules>Hello</cssProp.CssPropConditionalRules>
<cssProp.CssPropConditionalRules inverted>world</cssProp.CssPropConditionalRules>
</Fragment>
</Example>
);
};
2 changes: 1 addition & 1 deletion website/packages/docs/src/pages/about-compiled.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
section: 1-Getting started
name: About Compiled
order: 2
order: 1
---

# About Compiled
Expand Down
165 changes: 165 additions & 0 deletions website/packages/docs/src/pages/how-it-works.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
order: 3
section: 1-Getting started
---

# How it Works

Once you've [installed and configured](/installation) everything, you can start using it,
but it's best to explain what happens under the hood.

Compiled uses Babel (with pre-configuration options via Webpack and Parcel) to transform styles
into atomic CSS determined at build time, resulting in **very performant components**.

Let's take a typical component you might write:

```jsx
/** @jsxImportSource @compiled/react */
import { css } from '@compiled/react';
import type { ReactNode } from 'react';

type Props = { inverted?: boolean, children: ReactNode };

const largeTextStyles = css({
fontSize: '48px',
padding: '8px',
background: '#eee',
});
const invertedStyles = css({
background: '#333',
color: '#fff',
});

export const LargeText = ({ inverted, children }: Props): JSX.Element => {
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
};
```

## Runtime styles (unperformant)

With the most basic Babel setup, Compiled will be transformed to **runtime styles**.
This is typically used in a development or testing environments.

It is **not recommended in production environments** as it will be less performant, but also mixing
runtime and extraction can result in breaking visual changes from atomic specificity conflicts.
Refer to [extracted styles](#extracted-styles) below for the recommendation.

```bash
$ babel src
Successfully compiled 1 file with Babel (9ms)
```

You'll see a few things happening in the code below:

1. All styles are converted into [Atomic CSS](/atomic-css) for reuse.
2. Some styles, such as `padding:8px` will be expanded out to `padding-left`, `padding-right`, etc,
while others might be sorted. [Read more about this](shorthand)
3. All `css()` calls are replaced with `null` and instead the styles are injected at runtime with the
`className` inlined. Note that `cssMap()` works slightly differently and maintains the object syntax.
4. There are a few internal runtime functions that are used to manage the styles like `ax` and `CC`.
[Read more about this](/pkg-react-runtime)
5. [Postcss](https://postcss.org/), [autoprefixer](https://github.com/postcss/autoprefixer), and some other
optimizations will run over your code to make it more performant and safer for use.

```jsx
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _8 = '._syazu67f{color:#fff}';
const _7 = '._bfhk1d6m{background-color:#333}';
const _6 = '._bfhkr75e{background-color:#eee}';
const _5 = '._19bvftgi{padding-left:1pc}';
const _4 = '._n3tdftgi{padding-bottom:1pc}';
const _3 = '._u5f3ftgi{padding-right:1pc}';
const _2 = '._ca0qftgi{padding-top:1pc}';
const _ = '._1wybckbl{font-size:3pc}';
const largeTextStyles = null;
const invertedStyles = null;
export const LargeText = ({ inverted, children }) => {
return (
<CC>
<CS>{[_, _2, _3, _4, _5, _6, _7, _8]}</CS>
<span
className={ax([
'_1wybckbl _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi _bfhkr75e',
inverted && '_bfhk1d6m _syazu67f',
])}>
{children}
</span>
</CC>
);
};
```

## Extracted styles

We highly suggest you turn on style extraction to distribute styles statically at build time,
either through [NPM](https://npmjs.com/) or Production environments. Doing this, styles will
have their **runtime stripped and styles extracted** to an [atomic style sheet](/atomic-css).

Refer to [stylesheet extraction](/css-extraction-webpack) for more details.

Let's compare this to runtime styles, assuming we have Parcel configured

```bash
$ parcel build ./src/index.html
✨ Built in 4.94s
dist/index.html 246 B 349ms
dist/index.019bae5f.js 136.13 KB 806ms
# This generates `index.compiled.css` file(s) too.
🌽 ✅ Done in 6.26s
```

You'll see a few different things are happening in the code below:

1. All styles are moved into a separate file, `index.compiled.css`, that is imported into this file for
your bundler to pick up and combine and serve to the user.
2. The runtime injection of `<CS>` is no longer required because the styles are statically available.

The main difference beyond the greatly reduced runtime cost is that the atomic styles can be completely deduplicated.

```diff
+import "./index.compiled.css";
-import { ax, ix, CC, CS } from '@compiled/react/runtime';
+import { ax, ix } from "@compiled/react/runtime";
-const _8 = '._syazu67f{color:#fff}';
-const _7 = '._bfhk1d6m{background-color:#333}';
-const _6 = '._bfhkr75e{background-color:#eee}';
-const _5 = '._19bvftgi{padding-left:8px}';
-const _4 = '._n3tdftgi{padding-bottom:8px}';
-const _3 = '._u5f3ftgi{padding-right:8px}';
-const _2 = '._ca0qftgi{padding-top:8px}';
-const _ = '._1wybckbl{font-size:3pc}';
var largeTextStyles = null;
var invertedStyles = null;
export const LargeText = ({ inverted, children }) => {
return (
- <CC>
- <CS>{[_, _2, _3, _4, _5, _6, _7, _8]}</CS>
<span
className={ax([
'_1wybckbl _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi _bfhkr75e',
inverted && '_bfhk1d6m _syazu67f',
])}>
{children}
</span>
- </CC>
);
};
```

For reference, the atomic stylesheet is created just as before, now in `index.compiled.css`, and with
the bundler config, these `*.compiled.css` files will be merged together with duplicates removed, resulting
in a drastically smaller CSS payload to the customer.

These `*.compiled.css` files could be distributed via NPM or collected and bundled to customers.

<!-- prettier-ignore -->
```css
._19bvftgi{padding-left:8px}
._1wybckbl{font-size:3pc}
._bfhk1d6m{background-color:#333}
._bfhkr75e{background-color:#eee}
._ca0qftgi{padding-top:8px}
._n3tdftgi{padding-bottom:8px}
._syazu67f{color:#fff}
._u5f3ftgi{padding-right:8px}
```
2 changes: 1 addition & 1 deletion website/packages/docs/src/pages/installation.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 3
order: 2
section: 1-Getting started
---

Expand Down
4 changes: 2 additions & 2 deletions website/packages/examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"@babel/core": "^7.24.5",
"@babel/preset-react": "^7.24.1",
"@babel/preset-typescript": "^7.24.1",
"@compiled/babel-plugin": "^0.28.8",
"@compiled/react": "^0.17.1",
"@compiled/babel-plugin": "latest",
"@compiled/react": "latest",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"typescript": "^5.4.5"
Expand Down
33 changes: 11 additions & 22 deletions website/packages/examples/src/css-prop-conditional-rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,18 @@
import { css } from '@compiled/react';
import type { ReactNode } from 'react';

type LozengeProps = {
children: ReactNode;
primary: boolean;
};
type Props = { inverted?: boolean; children: ReactNode };

const primaryStyles = css({
border: '3px solid pink',
color: 'pink',
const largeTextStyles = css({
fontSize: '48px',
padding: '8px',
background: '#eee',
});

const notPrimaryStyles = css({
border: '3px solid blue',
color: 'blue',
const invertedStyles = css({
background: '#333',
color: '#fff',
});

const moreStyles = css({
// any styles here will override what is in
// primaryStyles and notPrimaryStyles
padding: '4px 8px',
fontWeight: 600,
borderRadius: 3,
});

export const Lozenge = ({ children, primary }: LozengeProps): JSX.Element => (
<span css={[primary && primaryStyles, !primary && notPrimaryStyles, moreStyles]}>{children}</span>
);
export const LargeText = ({ inverted, children }: Props): JSX.Element => {
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
};
2 changes: 1 addition & 1 deletion website/packages/examples/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CompositionIdentifier } from './css-prop-composition-identifier';
import { CustomColorText as CssPropCompositionIncorrect } from './css-prop-composition-incorrect';
import { CompositionMultiple } from './css-prop-composition-multiple';
import { CustomColorText as CssPropCompositionNoStyle } from './css-prop-composition-no-style';
import { Lozenge as CssPropConditionalRules } from './css-prop-conditional-rules';
import { LargeText as CssPropConditionalRules } from './css-prop-conditional-rules';
import { EmphasisText as CssPropDynamic } from './css-prop-dynamic-decl';
import { EmphasisText as CssPropObj } from './css-prop-obj';
import { EmphasisText as CssPropString } from './css-prop-string';
Expand Down
4 changes: 2 additions & 2 deletions website/packages/landing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"start": "webpack serve"
},
"dependencies": {
"@compiled/react": "^0.17.1",
"@compiled/webpack-loader": "^0.12.7",
"@compiled/react": "latest",
"@compiled/webpack-loader": "latest",
"@compiled/website-examples": "^1.0.0",
"@compiled/website-ui": "^1.0.0",
"@mdx-js/loader": "^1.6.22",
Expand Down
29 changes: 15 additions & 14 deletions website/packages/landing/src/components/example.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
/** @jsxImportSource @compiled/react */

import { css } from '@compiled/react';
import type { ReactNode } from 'react';

type Props = {
color: string;
children: ReactNode;
};
type Props = { inverted?: boolean; children: ReactNode };

export const LargeText = (props: Props): JSX.Element => (
<span
css={{
color: props.color,
fontSize: 48,
}}>
{props.children}
</span>
);
const largeTextStyles = css({
fontSize: '48px',
padding: '8px',
background: '#eee',
});
const invertedStyles = css({
background: '#333',
color: '#fff',
});

export const LargeText = ({ inverted, children }: Props): JSX.Element => {
return <span css={[largeTextStyles, inverted && invertedStyles]}>{children}</span>;
};
Loading

0 comments on commit 18d2529

Please sign in to comment.