Skip to content
Prev Previous commit
Next Next commit
very WIP: render theme-able CSS w/@primer/primitives
  • Loading branch information
shawnbot committed Nov 15, 2019
commit 9f106d08016090a40595c4f70a9f19aca76d4736
30 changes: 30 additions & 0 deletions lib/generate-theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const {theme} = require('@primer/primitives')
const postcss = require('postcss')

module.exports = function generateTheme(transform) {
const {variables} = transform(theme)
const entries = Object.entries(variables).filter(([name, value]) => typeof value !== 'undefined')

const sheet = postcss.root()
const root = postcss.rule({selector: ':root'})
for (const [name, value] of entries) {
const prop = postcss.decl({
prop: `--${name}`,
value: `#{${value}}`,
raws: {after: '\n'}
})
root.append(prop)
}
sheet.append(root)

for (const [name, value] of entries) {
const prop = postcss.decl({
prop: `$${name}`,
value: `var(--${name}, #{${value}})`,
raws: {after: '\n'}
})
sheet.append(prop)
}

return sheet
}
34 changes: 33 additions & 1 deletion script/dist.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ const postcss = require('postcss')
const loadConfig = require('postcss-load-config')
const {remove, mkdirp, readFile, writeFile} = require('fs-extra')
const {dirname, join} = require('path')
const generateTheme = require('../lib/generate-theme')

const inDir = 'src'
const outDir = 'dist'
const statsDir = join(outDir, 'stats')
const themeDir = join(outDir, 'themes')
const encoding = 'utf8'

// Bundle paths are normalized in getPathName() using dirname() and then
Expand All @@ -24,11 +26,14 @@ const bundleNames = {
async function dist() {
try {
const bundles = {}
const themes = {}
const {plugins, options} = await loadConfig()
const processor = postcss(plugins)

await remove(outDir)
await mkdirp(statsDir)
await mkdirp(themeDir)

const files = await globby([`${inDir}/**/index.scss`])

const inPattern = new RegExp(`^${inDir}/`)
Expand Down Expand Up @@ -60,9 +65,36 @@ async function dist() {
bundles[name] = meta
})

const themeFiles = await globby(`${inDir}/themes/*.js`)
for (const themeFile of themeFiles) {
const name = themeFile.split('/').pop().replace('.js', '')
const theme = require(`../${themeFile}`)
const preamble = generateTheme(theme)

const root = postcss.root()
root.append(preamble)
root.append(postcss.atRule({name: 'import', params: `"../index.scss"`}))

const scss = root.toString()
const from = join(inDir, 'themes', `${name}.scss`)
await writeFile(from, scss, encoding)

const to = join(themeDir, `${name}.css`)
const map = `${to}.map`
const result = await processor.process(scss, Object.assign({from, to}, options))
await Promise.all([
writeFile(to, result.css, encoding),
result.map ? writeFile(map, result.map, encoding) : null
])
themes[name] = {
css: to,
map
}
}

await Promise.all(tasks)

const meta = {bundles}
const meta = {bundles, themes}
await writeFile(join(outDir, 'meta.json'), JSON.stringify(meta, null, 2), encoding)
await writeVariableData()
await writeDeprecationData()
Expand Down
60 changes: 60 additions & 0 deletions src/themes/light.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const dot = require('dotmap')

module.exports = ({colors}) => {
const color = key => dot.get(colors, key)

const variables = {
'border-white': color('white'),
'border-black-fade': color('blackFade15'),
'border-white-fade': color('whiteFade15'),
'border-gray': color('gray.2'),
'border-gray-dark': color('gray.3'),
'border-gray-darker': color('gray.7'),
'border-gray-light': `lighten(${color('gray.2')}, 3%)`,
'border-blue': color('blue.5'),
'border-blue-light': color('blue.2'),
'border-green': color('green.4'),
'border-green-light': `desaturate(${color('green.3')}, 40%)`,
'border-purple': color('purple.5'),
'border-red': color('red.5'),
'border-red-light': `desaturate(${color('red.3')}, 60%)`,
'border-yellow': `desaturate(${color('yellow.3')}, 60%)`,
'border-color-button': `rgba(${color('black')}, 0.2)`,

'bg-white': color('white'),
'bg-black': color('black'),
'bg-black-fade': color('blackFade50'),
'bg-blue-light': color('blue.0'),
'bg-blue': color('blue.5'),
'bg-gray-dark': color('gray.9'),
'bg-gray-light': color('gray.0'),
'bg-gray': color('gray.1'),
'bg-green': color('green.5'),
'bg-green-light': color('green.1'),
'bg-orange': color('orange.7'),
'bg-purple': color('purple.5'),
'bg-purple-light': color('purple.0'),
'bg-pink': color('pink.5'),
'bg-red': color('red.5'),
'bg-red-light': color('red.1'),
'bg-yellow': color('yellow.5'),
'bg-yellow-light': color('yellow.2'),
'bg-yellow-dark': color('yellow.7'),

'text-black': color('black'),
'text-white': color('white'),
'text-blue': color('blue.5'),
'text-gray-dark': color('gray.9'),
'text-gray-light': color('gray.5'),
'text-gray': color('gray.6'),
'text-green': color('green.5'),
'text-orange': color('orange.9'),
'text-orange-light': color('orange.6'),
'text-purple': color('purple.5'),
'text-pink': color('pink.5'),
'text-red': color('red.6'),
'text-yellow': color('yellow.8')
}

return {variables}
}