feat(themes): deep merge themes by default

This commit is contained in:
unix
2020-04-08 19:18:26 +08:00
parent c716090dd1
commit 44ac746fba
3 changed files with 37 additions and 4 deletions

View File

@@ -5,14 +5,43 @@ import lightTheme from '../themes/default'
import { ZeitUIThemes } from '../themes/index'
import ThemeContext from '../use-theme/theme-context'
import useWarning from '../../utils/use-warning'
import { DeepPartial } from '../../utils/types'
type PartialTheme = Partial<ZeitUIThemes>
type PartialTheme = DeepPartial<ZeitUIThemes>
export type ThemeParam = PartialTheme | ((theme: PartialTheme) => PartialTheme) | undefined
export interface Props {
theme?: ThemeParam
}
interface MergeObject {
[key: string]: any
}
const isObject = (target: any) => target && typeof target === 'object'
const deepMergeObject = <T extends MergeObject,>(source: T, target: T): T => {
if (!isObject(target) || !isObject(source)) return source
const sourceKeys = Object.keys(source) as Array<keyof T>
let result = {} as T
for (const key of sourceKeys) {
const sourceValue = source[key]
const targetValue = target[key]
if (Array.isArray(sourceValue) && Array.isArray(targetValue)) {
result[key] = targetValue.concat(sourceValue)
} else if (isObject(sourceValue) && isObject(targetValue)) {
result[key] = deepMergeObject(sourceValue, { ...targetValue })
} else if (targetValue) {
result[key] = targetValue
} else {
result[key] = sourceValue
}
}
return result
}
const mergeTheme = (current: ZeitUIThemes, custom: ThemeParam): ZeitUIThemes => {
if (!custom) return current
if (typeof custom === 'function') {
@@ -22,7 +51,7 @@ const mergeTheme = (current: ZeitUIThemes, custom: ThemeParam): ZeitUIThemes =>
}
return merged as ZeitUIThemes
}
return {...current, ...custom}
return deepMergeObject<ZeitUIThemes>(current, custom as ZeitUIThemes)
}
const switchTheme = (mergedTheme: ZeitUIThemes): ZeitUIThemes => {

4
components/utils/types.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends Record<string, any> ? DeepPartial<T[P]> : T[P]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@zeit-ui/react",
"version": "0.0.1-beta.15",
"version": "0.0.1-beta.16",
"main": "dist/index.js",
"module": "dist/index.es.js",
"browser": "dist/index.umd.js",
@@ -69,4 +69,4 @@
"webpack-cli": "^3.3.11"
},
"dependencies": {}
}
}