diff --git a/__tests__/resolveConfig.test.js b/__tests__/resolveConfig.test.js index 7295717a65b7..e7a728d6922d 100644 --- a/__tests__/resolveConfig.test.js +++ b/__tests__/resolveConfig.test.js @@ -229,6 +229,55 @@ test('theme key is merged instead of replaced', () => { }) }) +test('theme key is deeply merged instead of replaced', () => { + const userConfig = { + theme: { + extend: { + colors: { + grey: { + darker: '#606f7b', + dark: '#8795a1', + }, + }, + }, + }, + } + + const defaultConfig = { + prefix: '-', + important: false, + separator: ':', + theme: { + colors: { + grey: { + grey: '#b8c2cc', + light: '#dae1e7', + lighter: '#f1f5f8', + }, + }, + }, + } + + const result = resolveConfig([userConfig, defaultConfig]) + + expect(result).toMatchObject({ + prefix: '-', + important: false, + separator: ':', + theme: { + colors: { + grey: { + darker: '#606f7b', + dark: '#8795a1', + grey: '#b8c2cc', + light: '#dae1e7', + lighter: '#f1f5f8', + }, + }, + }, + }) +}) + test('variants key is merged instead of replaced', () => { const userConfig = { variants: { @@ -1779,6 +1828,70 @@ test('variants can be extended', () => { }) }) +test('extensions are applied in the right order', () => { + const userConfig = { + theme: { + extend: { + colors: { + grey: { + light: '#eee', + }, + }, + }, + }, + } + + const otherConfig = { + theme: { + extend: { + colors: { + grey: { + light: '#ddd', + darker: '#111', + }, + }, + }, + }, + } + + const anotherConfig = { + theme: { + extend: { + colors: { + grey: { + darker: '#222', + }, + }, + }, + }, + } + + const defaultConfig = { + theme: { + colors: { + grey: { + light: '#ccc', + dark: '#333', + }, + }, + }, + } + + const result = resolveConfig([userConfig, otherConfig, anotherConfig, defaultConfig]) + + expect(result).toMatchObject({ + theme: { + colors: { + grey: { + light: '#eee', + dark: '#333', + darker: '#111', + }, + }, + }, + }) +}) + test('variant sort order can be customized', () => { const userConfig = { variantOrder: [ diff --git a/src/util/resolveConfig.js b/src/util/resolveConfig.js index f682214b175f..7b6c9c447811 100644 --- a/src/util/resolveConfig.js +++ b/src/util/resolveConfig.js @@ -67,20 +67,23 @@ function mergeThemes(themes) { } } +function mergeExtensionCustomizer(_merged, value) { + if (Array.isArray(value)) return value +} + function mergeExtensions({ extend, ...theme }) { return mergeWith(theme, extend, (themeValue, extensions) => { // The `extend` property is an array, so we need to check if it contains any functions if (!isFunction(themeValue) && !some(extensions, isFunction)) { - return { - ...themeValue, - ...Object.assign({}, ...extensions), - } + return mergeWith({}, themeValue, ...extensions, mergeExtensionCustomizer) } - return (resolveThemePath, utils) => ({ - ...value(themeValue, resolveThemePath, utils), - ...Object.assign({}, ...extensions.map((e) => value(e, resolveThemePath, utils))), - }) + return (resolveThemePath, utils) => + mergeWith( + {}, + ...[themeValue, ...extensions].map((e) => value(e, resolveThemePath, utils)), + mergeExtensionCustomizer + ) }) }