From 8f4f6b7503ad8bc1565755b9352ff42df135f713 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 19 Jul 2022 15:46:13 +0800 Subject: [PATCH] fix(core): only deep merge theme by one level, fix #1298 --- packages/core/src/config.ts | 2 +- packages/core/src/utils/object.ts | 6 ++--- test/__snapshots__/preset-mini.test.ts.snap | 8 ++++++ test/preset-mini.test.ts | 27 +++++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index cec533db74..5ca028c3e5 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -79,7 +79,7 @@ export function resolveConfig( const theme = clone([ ...sortedPresets.map(p => p.theme || {}), config.theme || {}, - ].reduce((a, p) => mergeDeep(a, p), {})) + ].reduce((a, p) => mergeDeep(a, p, 1), {})) ;(mergePresets('extendTheme') as ThemeExtender[]).forEach(extendTheme => extendTheme(theme)) diff --git a/packages/core/src/utils/object.ts b/packages/core/src/utils/object.ts index c468e4dd91..9a5b0ca4b7 100644 --- a/packages/core/src/utils/object.ts +++ b/packages/core/src/utils/object.ts @@ -47,7 +47,7 @@ export function isObject(item: any): item is Record { return (item && typeof item === 'object' && !Array.isArray(item)) } -export function mergeDeep(original: T, patch: DeepPartial): T { +export function mergeDeep(original: T, patch: DeepPartial, level = Infinity): T { const o = original as any const p = patch as any @@ -60,8 +60,8 @@ export function mergeDeep(original: T, patch: DeepPartial): T { const output = { ...o } if (isObject(o) && isObject(p)) { Object.keys(p).forEach((key) => { - if ((isObject(o[key]) && isObject(p[key])) || (Array.isArray(o[key]) && Array.isArray(p[key]))) - output[key] = mergeDeep(o[key], p[key]) + if (level > 0 && ((isObject(o[key]) && isObject(p[key])) || (Array.isArray(o[key]) && Array.isArray(p[key])))) + output[key] = mergeDeep(o[key], p[key], level - 1) else Object.assign(output, { [key]: p[key] }) }) diff --git a/test/__snapshots__/preset-mini.test.ts.snap b/test/__snapshots__/preset-mini.test.ts.snap index 3690913c2f..b611885871 100644 --- a/test/__snapshots__/preset-mini.test.ts.snap +++ b/test/__snapshots__/preset-mini.test.ts.snap @@ -17,6 +17,14 @@ exports[`preset-mini > dark customizing selector 1`] = ` [data-mode=\\"light\\"] .light\\\\:disabled\\\\:w-full:disabled{width:100%;}" `; +exports[`preset-mini > fontSize theme 1`] = ` +"/* layer: default */ +.text-lg{font-size:3rem;line-height:1.5em;} +.text-medium{font-size:2rem;line-height:1.5em;} +.text-small{font-size:1rem;line-height:1;} +.text-xs{font-size:2rem;line-height:1;}" +`; + exports[`preset-mini > nested theme colors 1`] = ` "/* layer: default */ .bg-a-b-c{--un-bg-opacity:1;background-color:rgba(81,69,67,var(--un-bg-opacity));} diff --git a/test/preset-mini.test.ts b/test/preset-mini.test.ts index 89558da446..f490b92d45 100644 --- a/test/preset-mini.test.ts +++ b/test/preset-mini.test.ts @@ -111,4 +111,31 @@ describe('preset-mini', () => { expect(css).toMatchInlineSnapshot('""') expect([...matched]).toEqual([]) }) + + test('fontSize theme', async () => { + const uno = createGenerator({ + presets: [ + presetMini(), + ], + theme: { + fontSize: { + small: '1rem', + medium: ['2rem', '1.5em'], + xs: '2rem', + lg: ['3rem', '1.5em'], + }, + }, + }) + + const { css } = await uno.generate([ + 'text-small', + 'text-medium', + 'text-xs', + 'text-lg', + ].join(' '), { preflights: false }) + + // @ts-expect-error types + expect(uno.config.theme.fontSize.lg).toEqual(['3rem', '1.5em']) + expect(css).toMatchSnapshot() + }) })