Skip to content

Commit 4bcbd6f

Browse files
Replace Dynamic API with assignInlineVars and setElementVars (#276)
1 parent 38376b3 commit 4bcbd6f

20 files changed

+437
-153
lines changed

.changeset/clever-vans-prove.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
'@vanilla-extract/dynamic': major
3+
---
4+
5+
Add `assignInlineVars` and `setElementVars` functions
6+
7+
**assignInlineVars**
8+
9+
Assigns CSS Variables as inline styles.
10+
11+
```tsx
12+
// app.tsx
13+
14+
import { assignInlineVars } from '@vanilla-extract/dynamic';
15+
import { vars } from './vars.css.ts';
16+
17+
const MyComponent = () => (
18+
<section
19+
style={assignInlineVars({
20+
[vars.colors.brand]: 'pink',
21+
[vars.colors.accent]: 'green'
22+
})}
23+
>
24+
...
25+
</section>
26+
);
27+
```
28+
29+
You can also assign collections of variables by passing a theme contract as the first argument. All variables must be assigned or it’s a type error.
30+
31+
```tsx
32+
// app.tsx
33+
34+
import { assignInlineVars } from '@vanilla-extract/dynamic';
35+
import { vars } from './vars.css.ts';
36+
37+
const MyComponent = () => (
38+
<section
39+
style={assignInlineVars(vars.colors, {
40+
brand: 'pink',
41+
accent: 'green'
42+
})}
43+
>
44+
...
45+
</section>
46+
);
47+
```
48+
49+
Even though this function returns an object of inline styles, its `toString` method returns a valid `style` attribute value so that it can be used in string templates.
50+
51+
```tsx
52+
// app.ts
53+
54+
import { assignInlineVars } from '@vanilla-extract/dynamic';
55+
import { vars } from './vars.css.ts';
56+
57+
document.write(`
58+
<section style="${assignInlineVars({
59+
[vars.colors.brand]: 'pink',
60+
[vars.colors.accent]: 'green'
61+
})}">
62+
...
63+
</section>
64+
`);
65+
```
66+
67+
**setElementVars**
68+
69+
Sets CSS Variables on a DOM element.
70+
71+
```tsx
72+
// app.ts
73+
74+
import { setElementVars } from '@vanilla-extract/dynamic';
75+
import { vars } from './styles.css.ts';
76+
77+
const el = document.getElementById('myElement');
78+
79+
setElementVars(el, {
80+
[vars.colors.brand]: 'pink',
81+
[vars.colors.accent]: 'green'
82+
});
83+
```
84+
85+
You can also set collections of variables by passing a theme contract as the second argument. All variables must be set or it’s a type error.
86+
87+
```tsx
88+
// app.ts
89+
90+
import { setElementVars } from '@vanilla-extract/dynamic';
91+
import { vars } from './styles.css.ts';
92+
93+
const el = document.getElementById('myElement');
94+
95+
setElementVars(el, vars.colors, {
96+
brand: 'pink',
97+
accent: 'green'
98+
});
99+
```
100+
101+
**BREAKING CHANGE**
102+
103+
These functions replace `createInlineTheme`, `setElementTheme` and `setElementVar`.
104+
105+
`assignInlineVars` works as a drop-in replacement for `createInlineTheme`.
106+
107+
```diff
108+
-createInlineTheme(vars, { brandColor: 'red' });
109+
+assignInlineVars(vars, { brandColor: 'red' });
110+
```
111+
112+
`setElementVars` works as a drop-in replacement for `setElementTheme`.
113+
114+
```diff
115+
-setElementTheme(el, vars, { brandColor: 'red' });
116+
+setElementVars(el, vars, { brandColor: 'red' });
117+
```
118+
119+
You can replicate the functionality of `setElementVar` by passing an object with dynamic keys to `setElementVars`. This now makes it easy to support setting multiple vars at once.
120+
121+
```diff
122+
-setElementVar(el, vars.brandColor, 'red');
123+
+setElementVars(el, {
124+
+ [vars.brandColor]: 'red'
125+
+});
126+
```

README.md

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,8 @@ Want to work at a higher level while maximising style re-use? Check out 🍨 [S
101101
- [keyframes](#keyframes)
102102
- [globalKeyframes](#globalkeyframes)
103103
- [Dynamic API](#dynamic-api)
104-
- [createInlineTheme](#createinlinetheme)
105-
- [setElementTheme](#setelementtheme)
106-
- [setElementVar](#setelementvar)
104+
- [assignInlineVars](#assigninlinevars)
105+
- [setElementVars](#setelementvars)
107106
- [Utility functions](#utility-functions)
108107
- [calc](#calc)
109108
- [Thanks](#thanks)
@@ -761,55 +760,98 @@ We also provide a lightweight standalone package to support dynamic runtime them
761760
npm install @vanilla-extract/dynamic
762761
```
763762

764-
### createInlineTheme
763+
### assignInlineVars
765764

766-
Implements a theme contract at runtime as an inline style object.
765+
Assigns CSS Variables as inline styles.
767766

768-
```ts
769-
import { createInlineTheme } from '@vanilla-extract/dynamic';
770-
import { vars, exampleStyle } from './styles.css.ts';
767+
```tsx
768+
// app.tsx
771769

772-
const customTheme = createInlineTheme(vars, {
773-
small: '4px',
774-
medium: '8px',
775-
large: '16px'
776-
});
770+
import { assignInlineVars } from '@vanilla-extract/dynamic';
771+
import { vars } from './vars.css.ts';
772+
773+
const MyComponent = () => (
774+
<section
775+
style={assignInlineVars({
776+
[vars.colors.brand]: 'pink',
777+
[vars.colors.accent]: 'green'
778+
})}
779+
>
780+
...
781+
</section>
782+
);
783+
```
784+
785+
You can also assign collections of variables by passing a theme contract as the first argument. All variables must be assigned or it’s a type error.
786+
787+
```tsx
788+
// app.tsx
789+
790+
import { assignInlineVars } from '@vanilla-extract/dynamic';
791+
import { vars } from './vars.css.ts';
792+
793+
const MyComponent = () => (
794+
<section
795+
style={assignInlineVars(vars.colors, {
796+
brand: 'pink',
797+
accent: 'green'
798+
})}
799+
>
800+
...
801+
</section>
802+
);
803+
```
804+
805+
Even though this function returns an object of inline styles, its `toString` method returns a valid `style` attribute value so that it can be used in string templates.
806+
807+
```tsx
808+
// app.ts
809+
810+
import { assignInlineVars } from '@vanilla-extract/dynamic';
811+
import { vars } from './vars.css.ts';
777812

778813
document.write(`
779-
<section style="${customTheme}">
780-
<h1 class="${exampleStyle}">Hello world!</h1>
814+
<section style="${assignInlineVars({
815+
[vars.colors.brand]: 'pink',
816+
[vars.colors.accent]: 'green'
817+
})}">
818+
...
781819
</section>
782820
`);
783821
```
784822

785-
### setElementTheme
823+
### setElementVars
786824

787-
Implements a theme contract on an element.
825+
Sets CSS Variables on a DOM element.
788826

789-
```ts
790-
import { setElementTheme } from '@vanilla-extract/dynamic';
827+
```tsx
828+
// app.ts
829+
830+
import { setElementVars } from '@vanilla-extract/dynamic';
791831
import { vars } from './styles.css.ts';
792832

793-
const element = document.getElementById('myElement');
794-
setElementTheme(element, vars, {
795-
small: '4px',
796-
medium: '8px',
797-
large: '16px'
833+
const el = document.getElementById('myElement');
834+
835+
setElementVars(el, {
836+
[vars.colors.brand]: 'pink',
837+
[vars.colors.accent]: 'green'
798838
});
799839
```
800840

801-
> 💡 All variables passed into this function must be assigned or it’s a type error.
802-
803-
### setElementVar
841+
You can also set collections of variables by passing a theme contract as the second argument. All variables must be set or it’s a type error.
804842

805-
Sets a single var on an element.
843+
```tsx
844+
// app.ts
806845

807-
```ts
808-
import { setElementVar } from '@vanilla-extract/dynamic';
846+
import { setElementVars } from '@vanilla-extract/dynamic';
809847
import { vars } from './styles.css.ts';
810848

811-
const element = document.getElementById('myElement');
812-
setElementVar(element, vars.color.brand, 'darksalmon');
849+
const el = document.getElementById('myElement');
850+
851+
setElementVars(el, vars.colors, {
852+
brand: 'pink',
853+
accent: 'green'
854+
});
813855
```
814856

815857
## Utility functions

babel-jest.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const baseConfig = require('./babel.config');
2+
3+
module.exports = {
4+
...baseConfig,
5+
plugins: [...(baseConfig.plugins ?? []), '@vanilla-extract/babel-plugin'],
6+
};

fixtures/themed/src/index.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import {
2-
createInlineTheme,
3-
setElementTheme,
4-
setElementVar,
5-
} from '@vanilla-extract/dynamic';
1+
import { assignInlineVars, setElementVars } from '@vanilla-extract/dynamic';
62

73
import { theme, altTheme, responsiveTheme, vars } from './themes.css';
84
import { button, container, opacity } from './styles.css';
95
import { shadow } from './shared.css';
106
import testNodes from '../test-nodes.json';
117

12-
const inlineTheme = createInlineTheme(vars, {
8+
const inlineTheme = assignInlineVars(vars, {
139
colors: {
1410
backgroundColor: 'orange',
1511
text: 'black',
@@ -71,7 +67,7 @@ function render() {
7167
throw new Error('Dynamic vars container not found.');
7268
}
7369

74-
setElementTheme(dynamicVarsContainer, vars, {
70+
setElementVars(dynamicVarsContainer, vars, {
7571
colors: {
7672
backgroundColor: 'transparent',
7773
text: 'papayawhip',
@@ -83,11 +79,9 @@ function render() {
8379
},
8480
});
8581

86-
setElementVar(
87-
dynamicVarsContainer,
88-
vars.colors.backgroundColor,
89-
'darksalmon',
90-
);
82+
setElementVars(dynamicVarsContainer, {
83+
[vars.colors.backgroundColor]: 'darksalmon',
84+
});
9185
}
9286

9387
render();

jest.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
module.exports = {
22
preset: 'jest-puppeteer',
33
setupFilesAfterEnv: ['./jest.setup.ts'],
4+
transform: {
5+
'\\.tsx?$': ['babel-jest', { configFile: './babel-jest.config.js' }],
6+
},
47
};

packages/dynamic/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717
"license": "MIT",
1818
"dependencies": {
1919
"@vanilla-extract/private": "^1.0.0"
20+
},
21+
"devDependencies": {
22+
"@vanilla-extract/css": "*"
2023
}
2124
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { createThemeContract } from '@vanilla-extract/css';
2+
3+
export const vars = createThemeContract({
4+
foo: { bar: null },
5+
baz: { qux: null },
6+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { assignInlineVars } from './';
2+
import { vars } from './assignInlineVars.test.css';
3+
4+
describe('assignInlineVars', () => {
5+
describe('basic assignment', () => {
6+
const style = assignInlineVars({
7+
[vars.foo.bar]: '1',
8+
[vars.baz.qux]: '2',
9+
'--global-var-1': '3',
10+
'--global-var-2': '4',
11+
});
12+
13+
it('assigns vars', () => {
14+
expect(style).toMatchInlineSnapshot(`
15+
Object {
16+
"--baz-qux__1byvgzh1": "2",
17+
"--foo-bar__1byvgzh0": "1",
18+
"--global-var-1": "3",
19+
"--global-var-2": "4",
20+
}
21+
`);
22+
});
23+
24+
it('converts to valid inline styles when calling toString', () => {
25+
expect(style.toString()).toMatchInlineSnapshot(
26+
`"--foo-bar__1byvgzh0:1;--baz-qux__1byvgzh1:2;--global-var-1:3;--global-var-2:4"`,
27+
);
28+
});
29+
});
30+
31+
describe('contract assignment', () => {
32+
const style = assignInlineVars(vars, {
33+
foo: { bar: '1' },
34+
baz: { qux: '2' },
35+
});
36+
37+
it('assigns contract vars', () => {
38+
expect(style).toMatchInlineSnapshot(`
39+
Object {
40+
"--baz-qux__1byvgzh1": "2",
41+
"--foo-bar__1byvgzh0": "1",
42+
}
43+
`);
44+
});
45+
46+
it('converts to valid inline styles when calling toString', () => {
47+
expect(style.toString()).toMatchInlineSnapshot(
48+
`"--foo-bar__1byvgzh0:1;--baz-qux__1byvgzh1:2"`,
49+
);
50+
});
51+
});
52+
});

0 commit comments

Comments
 (0)