Skip to content

Commit e65946c

Browse files
authored
Merge pull request #235 from alex-page/master
Implement Theme UI to CSS variables utility transformer
2 parents 786d481 + b16e98f commit e65946c

File tree

8 files changed

+209
-0
lines changed

8 files changed

+209
-0
lines changed

packages/custom-properties/.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
babel.config.js
2+
test
3+
coverage

packages/custom-properties/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# @theme-ui/custom-properties
2+
3+
Generate CSS custom properties for use with Theme UI.
4+
5+
6+
## Installation
7+
8+
```
9+
yarn add @theme-ui/custom-properties
10+
```
11+
12+
13+
## Usage
14+
15+
Transform your Theme UI compliant theme config with the library:
16+
17+
```js
18+
const toCustomProperties = require('@theme-ui/custom-properties')
19+
const theme = require('../theme');
20+
21+
module.exports = () => {
22+
const customProperties = toCustomProperties(theme, '🍭');
23+
24+
return customProperties;
25+
}
26+
```
27+
28+
29+
## Parameters
30+
31+
The @theme-ui/custom-properties function takes two parameters:
32+
33+
```js
34+
toCustomProperties( $theme, $prefix );
35+
```
36+
37+
1. theme - The theme ui specification object
38+
1. prefix - An optional prefix for the css custom property _optional_
39+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../babel.config')
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@theme-ui/custom-properties",
3+
"description": "Generate CSS custom properties for use with Theme UI",
4+
"version": "0.0.0",
5+
"main": "dist/index.js",
6+
"module": "dist/index.esm.js",
7+
"author": "Alex Page <[email protected]>",
8+
"license": "MIT",
9+
"scripts": {
10+
"prepare": "microbundle --no-compress",
11+
"watch": "microbundle watch --no-compress"
12+
},
13+
"devDependencies": {},
14+
"publishConfig": {
15+
"access": "public"
16+
},
17+
"dependencies": {
18+
"pluralize": "^8.0.0"
19+
}
20+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pluralize from 'pluralize'
2+
3+
export default (theme, prefix) => {
4+
const customProperties = {}
5+
6+
const generateProperties = (object, previousKey) => {
7+
Object.entries(object).forEach(([key, value]) => {
8+
let formattedKey = pluralize(key, 1)
9+
10+
if (prefix && !previousKey) {
11+
formattedKey = `${prefix}-${formattedKey}`
12+
}
13+
14+
const newKey = previousKey
15+
? previousKey + '-' + formattedKey
16+
: formattedKey
17+
18+
if (Array.isArray(value)) {
19+
value.forEach((item, i) => {
20+
customProperties[`--${newKey}-${i}`] = item
21+
})
22+
} else if (Object(value) === value) {
23+
generateProperties(value, newKey)
24+
} else {
25+
customProperties[`--${newKey}`] = value
26+
}
27+
})
28+
}
29+
30+
generateProperties(theme)
31+
32+
return customProperties
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`transforms a theme config to CSS custom properties 1`] = `
4+
Object {
5+
"--color-accent": "#609",
6+
"--color-background": "#fff",
7+
"--color-dark-background-surface": "#fff",
8+
"--color-dark-foreground-text": "#000",
9+
"--color-muted": "#f6f6f6",
10+
"--color-primary": "#07c",
11+
"--color-secondary": "#05a",
12+
"--color-text": "#000",
13+
"--font-body": "system-ui, sans-serif",
14+
"--font-heading": "system-ui, sans-serif",
15+
"--font-monospace": "Menlo, monospace",
16+
"--fontWeight-body": 400,
17+
"--fontWeight-bold": 700,
18+
"--fontWeight-heading": 700,
19+
"--lineHeight-0": 1.5,
20+
"--lineHeight-1": 1.125,
21+
"--size-0": "10em",
22+
"--size-1": "20em",
23+
"--size-2": "30em",
24+
"--size-3": "40em",
25+
"--space-0": 0,
26+
"--space-1": 2,
27+
"--space-2": 3,
28+
"--space-3": 4,
29+
"--space-4": 5,
30+
"--space-5": 6,
31+
}
32+
`;
33+
34+
exports[`transforms a theme config to CSS custom properties with prefix 1`] = `
35+
Object {
36+
"--🍭-color-accent": "#609",
37+
"--🍭-color-background": "#fff",
38+
"--🍭-color-dark-background-surface": "#fff",
39+
"--🍭-color-dark-foreground-text": "#000",
40+
"--🍭-color-muted": "#f6f6f6",
41+
"--🍭-color-primary": "#07c",
42+
"--🍭-color-secondary": "#05a",
43+
"--🍭-color-text": "#000",
44+
"--🍭-font-body": "system-ui, sans-serif",
45+
"--🍭-font-heading": "system-ui, sans-serif",
46+
"--🍭-font-monospace": "Menlo, monospace",
47+
"--🍭-fontWeight-body": 400,
48+
"--🍭-fontWeight-bold": 700,
49+
"--🍭-fontWeight-heading": 700,
50+
"--🍭-lineHeight-0": 1.5,
51+
"--🍭-lineHeight-1": 1.125,
52+
"--🍭-size-0": "10em",
53+
"--🍭-size-1": "20em",
54+
"--🍭-size-2": "30em",
55+
"--🍭-size-3": "40em",
56+
"--🍭-space-0": 0,
57+
"--🍭-space-1": 2,
58+
"--🍭-space-2": 3,
59+
"--🍭-space-3": 4,
60+
"--🍭-space-4": 5,
61+
"--🍭-space-5": 6,
62+
}
63+
`;
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import toCustomProperties from '../src'
2+
3+
const theme = {
4+
colors: {
5+
text: '#000',
6+
background: '#fff',
7+
primary: '#07c',
8+
secondary: '#05a',
9+
accent: '#609',
10+
muted: '#f6f6f6',
11+
dark: {
12+
foreground: {
13+
text: '#000',
14+
},
15+
background: {
16+
surface: '#fff',
17+
},
18+
},
19+
},
20+
fonts: {
21+
body: 'system-ui, sans-serif',
22+
heading: 'system-ui, sans-serif',
23+
monospace: 'Menlo, monospace',
24+
},
25+
fontWeights: {
26+
body: 400,
27+
heading: 700,
28+
bold: 700,
29+
},
30+
lineHeights: [1.5, 1.125],
31+
space: [0, 2, 3, 4, 5, 6],
32+
size: ['10em', '20em', '30em', '40em'],
33+
}
34+
35+
it('transforms a theme config to CSS custom properties', () => {
36+
const result = toCustomProperties(theme)
37+
38+
expect(result).toMatchSnapshot()
39+
})
40+
41+
it('transforms a theme config to CSS custom properties with prefix', () => {
42+
const result = toCustomProperties(theme, '🍭')
43+
44+
expect(result).toMatchSnapshot()
45+
})

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -15979,6 +15979,11 @@ please-upgrade-node@^3.1.1:
1597915979
dependencies:
1598015980
semver-compare "^1.0.0"
1598115981

15982+
pluralize@^8.0.0:
15983+
version "8.0.0"
15984+
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
15985+
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
15986+
1598215987
pn@^1.1.0:
1598315988
version "1.1.0"
1598415989
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"

0 commit comments

Comments
 (0)