diff --git a/__tests__/resolveConfig.test.js b/__tests__/resolveConfig.test.js index d89471e3d..f1e13a2a4 100644 --- a/__tests__/resolveConfig.test.js +++ b/__tests__/resolveConfig.test.js @@ -767,8 +767,12 @@ test('theme values in the extend section are lazily evaluated', () => { blue: 'blue', }, extend: { + colors: { + orange: 'orange', + }, borderColor: theme => ({ - default: theme('colors.red'), + foo: theme('colors.orange'), + bar: theme('colors.red'), }), }, }, @@ -802,12 +806,16 @@ test('theme values in the extend section are lazily evaluated', () => { separator: ':', theme: { colors: { + orange: 'orange', red: 'red', green: 'green', blue: 'blue', }, borderColor: { - default: 'red', + default: 'currentColor', + foo: 'orange', + bar: 'red', + orange: 'orange', red: 'red', green: 'green', blue: 'blue', diff --git a/src/util/resolveConfig.js b/src/util/resolveConfig.js index 1a875a945..913af7ca4 100644 --- a/src/util/resolveConfig.js +++ b/src/util/resolveConfig.js @@ -4,34 +4,7 @@ import defaults from 'lodash/defaults' import map from 'lodash/map' import get from 'lodash/get' -function resolveFunctionKeys(object) { - const getKey = (key, defaultValue) => get(object, key, defaultValue) - - return Object.keys(object).reduce((resolved, key) => { - return { - ...resolved, - [key]: isFunction(object[key]) ? object[key](getKey) : object[key], - } - }, {}) -} - -function mergeExtensions({ extend, ...theme }) { - return mergeWith({}, theme, extend, (_, extensions, key) => { - if (isFunction(theme[key]) || (extend && isFunction(extend[key]))) { - return mergedTheme => ({ - ...(isFunction(theme[key]) ? theme[key](mergedTheme) : theme[key]), - ...(extend && isFunction(extend[key]) ? extend[key](mergedTheme) : extensions), - }) - } else { - return { - ...theme[key], - ...extensions, - } - } - }) -} - -export default function(configs) { +function resolveConfig(configs) { return defaults( { theme: resolveFunctionKeys(mergeExtensions(defaults(...map(configs, 'theme')))), @@ -40,3 +13,36 @@ export default function(configs) { ...configs ) } + +function mergeExtensions({ extend, ...theme }) { + return mergeWith(theme, extend, (themeValue, extensions, key) => { + if (!isFunction(themeValue) && !(isFunction(extensions))) { + return { + ...themeValue, + ...extensions, + } + } + + return resolveThemePath => ({ + ...value(themeValue, resolveThemePath), + ...value(extensions, resolveThemePath), + }) + }) +} + +function resolveFunctionKeys(object) { + const resolveObjectPath = (key, defaultValue) => get(object, key, defaultValue) + + return Object.keys(object).reduce((resolved, key) => { + return { + ...resolved, + [key]: isFunction(object[key]) ? object[key](resolveObjectPath) : object[key], + } + }, {}) +} + +function value(valueToResolve, ...args) { + return isFunction(valueToResolve) ? valueToResolve(...args) : valueToResolve +} + +export default resolveConfig