From 5ea8bbe798ed635b6e458beb23bfa884c1b72f06 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Mon, 21 Jan 2019 13:52:07 -0500 Subject: [PATCH] Allow plugins to register new config variables --- __tests__/configFunction.test.js | 56 +++++++++++++++++++++++++++- src/lib/evaluateTailwindFunctions.js | 5 ++- src/processTailwindFeatures.js | 2 +- src/util/processPlugins.js | 5 +++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/__tests__/configFunction.test.js b/__tests__/configFunction.test.js index 5f6037294..0a53a940e 100644 --- a/__tests__/configFunction.test.js +++ b/__tests__/configFunction.test.js @@ -1,8 +1,15 @@ +import _ from 'lodash' import postcss from 'postcss' +import config from '../defaultConfig.stub.js' import plugin from '../src/lib/evaluateTailwindFunctions' +import processPlugins from '../src/util/processPlugins' -function run(input, opts = {}) { - return postcss([plugin(opts)]).process(input, { from: undefined }) +function run(input, opts = config) { + return postcss([ + plugin(opts, processPlugins(_.get(opts, 'plugins', []), opts).configValues), + ]).process(input, { + from: undefined, + }) } test('it looks up values in the config using dot notation', () => { @@ -80,3 +87,48 @@ test('quotes are preserved around default values', () => { expect(result.warnings().length).toBe(0) }) }) + +test('plugins can register values that should be available to the config function', () => { + const input = ` + .banana { color: config('banana.sandwich'); } + ` + + const output = ` + .banana { color: blue; } + ` + + return run(input, { + plugins: [ + function({ addConfig }) { + addConfig('banana', { + sandwich: 'blue', + }) + }, + ], + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + +test('plugin config values do not override first-class config values', () => { + const input = ` + .banana { color: config('separator'); } + ` + + const output = ` + .banana { color: _; } + ` + + return run(input, { + separator: '_', + plugins: [ + function({ addConfig }) { + addConfig('separator', '+') + }, + ], + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js index c071fd800..8f25624b7 100644 --- a/src/lib/evaluateTailwindFunctions.js +++ b/src/lib/evaluateTailwindFunctions.js @@ -1,11 +1,12 @@ import _ from 'lodash' import functions from 'postcss-functions' -export default function(config) { +export default function(config, pluginConfigValues) { return functions({ functions: { config: (path, defaultValue) => { - return _.get(config, _.trim(path, `'"`), defaultValue) + const trimmedPath = _.trim(path, `'"`) + return _.get(config, trimmedPath, _.get(pluginConfigValues, trimmedPath, defaultValue)) }, }, }) diff --git a/src/processTailwindFeatures.js b/src/processTailwindFeatures.js index 34b4299cf..ceb92c38f 100644 --- a/src/processTailwindFeatures.js +++ b/src/processTailwindFeatures.js @@ -18,7 +18,7 @@ export default function(getConfig) { return postcss([ substituteTailwindAtRules(config, processedPlugins), - evaluateTailwindFunctions(config), + evaluateTailwindFunctions(config, processedPlugins.configValues), substituteVariantsAtRules(config, processedPlugins), substituteResponsiveAtRules(config), substituteScreenAtRules(config), diff --git a/src/util/processPlugins.js b/src/util/processPlugins.js index 07c9d3024..bb1d71ac2 100644 --- a/src/util/processPlugins.js +++ b/src/util/processPlugins.js @@ -19,6 +19,7 @@ export default function(plugins, config) { const pluginComponents = [] const pluginUtilities = [] const pluginVariantGenerators = {} + const pluginConfigValues = {} plugins.forEach(plugin => { plugin({ @@ -64,6 +65,9 @@ export default function(plugins, config) { addVariant: (name, generator) => { pluginVariantGenerators[name] = generateVariantFunction(generator) }, + addConfig: (namespace, value) => { + pluginConfigValues[namespace] = value + }, }) }) @@ -71,5 +75,6 @@ export default function(plugins, config) { components: pluginComponents, utilities: pluginUtilities, variantGenerators: pluginVariantGenerators, + configValues: pluginConfigValues, } }