Skip to content

Commit

Permalink
Add recipes packages (#348)
Browse files Browse the repository at this point in the history
Co-authored-by: Mark Dalgleish <[email protected]>
  • Loading branch information
mattcompiles and markdalgleish authored Sep 10, 2021
1 parent d101b43 commit c6cd1f2
Show file tree
Hide file tree
Showing 34 changed files with 962 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-stingrays-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@vanilla-extract/babel-plugin': minor
---

Add debug IDs to `recipe` function
8 changes: 8 additions & 0 deletions .changeset/nervous-ducks-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@vanilla-extract/css': minor
'@vanilla-extract/integration': minor
---

Add `addFunctionSerializer` function

This also marks `addRecipe` as deprecated.
112 changes: 111 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Want to work at a higher level while maximising style re-use? Check out 🍨 [S
- [globalFontFace](#globalfontface)
- [keyframes](#keyframes)
- [globalKeyframes](#globalkeyframes)
- [Recipes API](#recipes-api)
- [recipe](#recipe)
- [Dynamic API](#dynamic-api)
- [assignInlineVars](#assigninlinevars)
- [setElementVars](#setelementvars)
Expand Down Expand Up @@ -936,9 +938,117 @@ export const animated = style({
});
```
## Recipes API
Create multi-variant styles with a type-safe runtime API, heavily inspired by [Stitches.](https://stitches.dev)
As with the rest of vanilla-extract, all styles are generated at build time.
```bash
$ npm install @vanilla-extract/recipes
```
### recipe
Creates a multi-variant style function that can be used at runtime or statically in `.css.ts` files.
Accepts an optional set of `base` styles, `variants`, `compoundVariants` and `defaultVariants`.
```ts
import { recipe } from '@vanilla-extract/recipes';

export const button = recipe({
base: {
borderRadius: 6
},

variants: {
color: {
neutral: { background: 'whitesmoke' },
brand: { background: 'blueviolet' },
accent: { background: 'slateblue' }
},
size: {
small: { padding: 12 },
medium: { padding: 16 },
large: { padding: 24 }
},
rounded: {
true: { borderRadius: 999 }
}
},

// Applied when multiple variants are set at once
compoundVariants: [
{
variants: {
color: 'neutral',
size: 'large'
},
style: {
background: 'ghostwhite'
}
}
],

defaultVariants: {
color: 'accent',
size: 'medium'
}
});
```
With this recipe configured, you can now use it in your templates.
```ts
import { button } from './button.css.ts';

document.write(`
<button class="${button({
color: 'accent',
size: 'large',
rounded: true
})}">
Hello world
</button>
`);
```
Your recipe configuration can also make use of existing variables, classes and styles.
For example, you can use your `atoms` function from [Sprinkles.](https://github.com/seek-oss/vanilla-extract/tree/master/packages/sprinkles)
```ts
import { recipe } from '@vanilla-extract/recipes';
import { reset } from './reset.css.ts';
import { atoms } from './sprinkles.css.ts';

export const button = recipe({
base: [reset, atoms({ borderRadius: 'round' })],

variants: {
color: {
neutral: atoms({ background: 'neutral' }),
brand: atoms({ background: 'brand' }),
accent: atoms({ background: 'accent' })
},
size: {
small: atoms({ padding: 'small' }),
medium: atoms({ padding: 'medium' }),
large: atoms({ padding: 'large' })
}
},

defaultVariants: {
color: 'accent',
size: 'medium'
}
});
```
## Dynamic API
We also provide a lightweight standalone package to support dynamic runtime theming.
Dynamically update theme variables at runtime.
```bash
npm install @vanilla-extract/dynamic
Expand Down
12 changes: 12 additions & 0 deletions fixtures/recipes/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
12 changes: 12 additions & 0 deletions fixtures/recipes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@fixtures/recipes",
"version": "0.0.0",
"main": "src/index.ts",
"sideEffects": true,
"author": "SEEK",
"private": true,
"dependencies": {
"@vanilla-extract/css": "1.4.1",
"@vanilla-extract/recipes": "0.1.0"
}
}
12 changes: 12 additions & 0 deletions fixtures/recipes/snowpack-public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Snowpack App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/dist/index.js"></script>
</body>
</html>
26 changes: 26 additions & 0 deletions fixtures/recipes/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { button, stack } from './styles.css';

function render() {
document.body.innerHTML = `
<div class="${stack()}">
<button class="${button()}">
Standard calm button
</button>
<button class="${button({ size: 'small' })}">
Small calm button
</button>
<button class="${button({ tone: 'angry' })}">
Standard angry button
</button>
<button class="${button({
size: 'small',
tone: 'angry',
bold: true,
})}">
Small angry button
</button>
</div>
`;
}

render();
115 changes: 115 additions & 0 deletions fixtures/recipes/src/styles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { style, createThemeContract, createTheme } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';

const vars = createThemeContract({
bg: null,
fg: null,
});

const calm = createTheme(vars, {
bg: 'powderblue',
fg: 'white',
});

const angry = createTheme(vars, {
bg: 'crimson',
fg: 'black',
});

export const reset = style({
border: 0,
});

export const button = recipe(
{
base: [
reset,
{
borderRadius: '6px',
background: vars.bg,
color: vars.fg,
transition: 'all 0.2s ease',

':hover': {
transform: 'translateY(-3px)',
},
},
],

variants: {
size: {
small: {
fontSize: '16px',
lineHeight: '24px',
},
standard: {
fontSize: '24px',
lineHeight: '40px',
},
},
tone: {
calm,
angry: [
angry,
{
':hover': {
boxShadow: '0 10px 6px -6px #777',
},
},
],
},
bold: {
true: {
fontWeight: 'bold',
},
},
},

defaultVariants: {
size: 'standard',
tone: 'calm',
},

compoundVariants: [
{
variants: {
size: 'small',
bold: true,
},
style: {
'@media': {
'only screen and (min-width: 600px)': {
border: '2px green solid',
},
},
},
},
],
},
'button',
);

export const stack = recipe({
base: {
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
},

variants: {
space: {
medium: {
gap: 20,
'@media': {
'only screen and (min-width: 600px)': {
gap: 30,
},
},
},
},
},

defaultVariants: {
space: 'medium',
},
});
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ module.exports = {
'\\.tsx?$': ['babel-jest', { configFile: './babel-jest.config.js' }],
},
testMatch: ['**/?(*.)+(test).[jt]s?(x)'],
testTimeout: 10000,
};
19 changes: 19 additions & 0 deletions packages/babel-plugin/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,25 @@ describe('babel plugin', () => {
`);
});

it('should handle recipe assigned to const', () => {
const source = `
import { recipe } from '@vanilla-extract/recipes';
const button = recipe({});
`;

expect(transform(source)).toMatchInlineSnapshot(`
"import * as __vanilla_filescope__ from '@vanilla-extract/css/fileScope';
__vanilla_filescope__.setFileScope(\\"src/dir/mockFilename.css.ts\\", \\"@vanilla-extract/babel-plugin\\");
import { recipe } from '@vanilla-extract/recipes';
const button = recipe({}, \\"button\\");
__vanilla_filescope__.endFileScope();"
`);
});

it('should ignore functions that already supply a debug name', () => {
const source = `
import { style, styleVariants } from '@vanilla-extract/css';
Expand Down
Loading

0 comments on commit c6cd1f2

Please sign in to comment.