Skip to content

Commit

Permalink
feat: add flags option
Browse files Browse the repository at this point in the history
  • Loading branch information
ambar committed Apr 21, 2024
1 parent df4f1fc commit 5c2f0ce
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 54 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ postcss([

```ts
type Options = {
/** color groups */
colors: Record<string, string | string[]>
/**
* var flags
* @default ['--flag-light', '--flag-dark']
*/
flags?: string[]
}
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
}
},
"scripts": {
"prepack": "yarn build",
"build": "rm -rf dist && pkgroll",
"test": "vitest",
"test:coverage": "vitest run --coverage",
Expand Down
45 changes: 19 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import {PluginCreator} from 'postcss'

type Options = {
export type Options = {
/** color groups */
colors: Record<string, string | string[]>
/**
* var flags
* @default ['--flag-light', '--flag-dark']
*/
flags?: string[]
}
const defaults: Options = {
const defaults: Required<Options> = {
colors: {},
flags: ['--flag-light', '--flag-dark'],
}
const reRelativeColor = /\(\s*?from/i
const reMixColor = /\bcolor-mix\(/i

const themeColors: PluginCreator<Options> = (options) => {
const {colors} = {...defaults, ...options}
const reGroup = new RegExp(
`\\b${'var'}\\((${Object.keys(colors).join('|')})\\)`,
'g'
)
const resolveColor = (
theme: 'dark' | 'light',
group: string,
fallback: string
) => {
const {
colors,
flags: [lightFlag, darkFlag],
} = {...defaults, ...options}
const reGroup = new RegExp(`\\b${'var'}\\((${Object.keys(colors).join('|')})\\)`, 'g')
const resolveColor = (theme: 'dark' | 'light', group: string, fallback: string) => {
const [lightKey, darkKey] = colors[group] || []
const colorKey = theme === 'light' ? lightKey : darkKey
if (!colorKey) {
Expand All @@ -37,21 +40,11 @@ const themeColors: PluginCreator<Options> = (options) => {
if (!reGroup.test(value)) {
return
}
const lightValue = value.replace(reGroup, (match, group) =>
resolveColor('light', group, match)
)
const darkValue = value.replace(reGroup, (match, group) =>
resolveColor('dark', group, match)
)
const lightValue = value.replace(reGroup, (match, group) => resolveColor('light', group, match))
const darkValue = value.replace(reGroup, (match, group) => resolveColor('dark', group, match))
const name = '--v' + hash(value)
decl.cloneBefore({
prop: name,
value: `var(--flag-light, ${lightValue}) var(--flag-dark, ${darkValue})`,
})
decl.cloneBefore({
prop: decl.prop,
value: `var(${name})`,
})
decl.cloneBefore({prop: name, value: `var(${lightFlag}, ${lightValue}) var(${darkFlag}, ${darkValue})`})
decl.cloneBefore({prop: decl.prop, value: `var(${name})`})
},
}
}
Expand Down
18 changes: 4 additions & 14 deletions test/index-with-vars.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import postcss from 'postcss'
import type {Plugin} from 'postcss'
import {test, expect} from 'vitest'
import dedent from 'dedent'
import presetEnv from 'postcss-preset-env'
import globalData from '@csstools/postcss-global-data'
import themeColors from '../src'
import themeColors, {type Options} from '../src'

const colors = {
'--G01': ['#eee', '#111'],
Expand All @@ -14,15 +13,7 @@ const colors = {
'--G03': ['red', 'blue'],
}

type ExtraOpts = {
plugins?: (Plugin | any)[]
}

const process = async (
css: string,
options?: Omit<Parameters<typeof themeColors>[0], 'colors'> | null,
{plugins = []}: ExtraOpts = {}
) => {
const process = async (css: string, options?: Omit<Options, 'colors'> | null) => {
return postcss([
globalData({
files: [
Expand All @@ -33,7 +24,6 @@ const process = async (
}),
themeColors({colors, ...options}),
presetEnv(),
...plugins,
]).process(css, {
from: undefined,
})
Expand All @@ -45,7 +35,7 @@ test('use with relative color syntax', async () => {
border: 1px solid oklch(from var(--G01) .8 c h);
box-shadow: 0 0 0 2px var(--G01), 0 0 0 4px oklch(from var(--G01) l c h / .1);
}`
const result = await process(input, null, {})
const result = await process(input)
expect(result.css).toMatchInlineSnapshot(`
"a {
--v1868641404: var(--flag-light, rgba(238, 238, 238, 0.1)) var(--flag-dark, rgba(17, 17, 17, 0.1));
Expand Down Expand Up @@ -80,7 +70,7 @@ test('use with color-mix()', async () => {
a {
color: color-mix(in srgb, var(--G01), transparent 20%);
}`
const result = await process(input, null, {})
const result = await process(input)
expect(result.css).toMatchInlineSnapshot(`
"a {
--v546761730: var(--flag-light, rgba(238, 238, 238, 0.8)) var(--flag-dark, rgba(17, 17, 17, 0.8));
Expand Down
44 changes: 30 additions & 14 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import postcss from 'postcss'
import type {Plugin} from 'postcss'
import {test, expect} from 'vitest'
import dedent from 'dedent'
import presetEnv from 'postcss-preset-env'
import globalData from '@csstools/postcss-global-data'
import themeColors from '../src'
import themeColors, {type Options} from '../src'

const colors = {
'--G01': ['#eee', '#111'],
Expand All @@ -14,15 +13,7 @@ const colors = {
'--G03': ['red', 'blue'],
}

type ExtraOpts = {
plugins?: (Plugin | any)[]
}

const process = async (
css: string,
options?: Omit<Parameters<typeof themeColors>[0], 'colors'> | null,
{plugins = []}: ExtraOpts = {}
) => {
const process = async (css: string, options?: Omit<Options, 'colors'> | null) => {
return postcss([
globalData({
files: [
Expand All @@ -32,7 +23,6 @@ const process = async (
}),
themeColors({colors, ...options}),
presetEnv(),
...plugins,
]).process(css, {
from: undefined,
})
Expand All @@ -44,7 +34,7 @@ test('use with relative color syntax', async () => {
border: 1px solid oklch(from var(--G01) .8 c h);
box-shadow: 0 0 0 2px var(--G01), 0 0 0 4px oklch(from var(--G01) l c h / .1);
}`
const result = await process(input, null, {})
const result = await process(input)
expect(result.css).toMatchInlineSnapshot(`
"a {
--v1868641404: var(--flag-light, rgba(238, 238, 238, 0.1)) var(--flag-dark, rgba(17, 17, 17, 0.1));
Expand Down Expand Up @@ -72,7 +62,7 @@ test('use with color-mix()', async () => {
color: color-mix(in srgb, var(--G01), transparent 20%);
}
`
const result = await process(input, null, {})
const result = await process(input)
expect(result.css).toMatchInlineSnapshot(`
"
a {
Expand Down Expand Up @@ -125,3 +115,29 @@ test('process undefined group', async () => {
const result = await process(input)
expect(result.css).toBe(input)
})

test('flags option', async () => {
const input = `
a {
color: rgba(from var(--G03) r g b / .1);
}
`
const result = await process(input, {
flags: ['--isLight', '--isDark'],
})
expect(result.css).toMatchInlineSnapshot(`
"
a {
--v3204038125: var(--isLight, rgba(255, 0, 0, 0.1)) var(--isDark, rgba(0, 0, 255, 0.1));
color: rgba(255, 0, 0, 0.1) rgba(0, 0, 255, 0.1);
color: var(--v3204038125);
}
@supports (color: lab(from red l 1 1% / calc(alpha + 0.1))) {
a {
color: rgba(from var(--G03) r g b / .1);
}
}
"
`)
})

0 comments on commit 5c2f0ce

Please sign in to comment.