diff --git a/components/styles/theme-provider/theme-provider.tsx b/components/styles/theme-provider/theme-provider.tsx index ea82b87..2496eb0 100644 --- a/components/styles/theme-provider/theme-provider.tsx +++ b/components/styles/theme-provider/theme-provider.tsx @@ -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 +type PartialTheme = DeepPartial 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 = (source: T, target: T): T => { + if (!isObject(target) || !isObject(source)) return source + + const sourceKeys = Object.keys(source) as Array + 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(current, custom as ZeitUIThemes) } const switchTheme = (mergedTheme: ZeitUIThemes): ZeitUIThemes => { diff --git a/components/utils/types.d.ts b/components/utils/types.d.ts new file mode 100644 index 0000000..0170fa6 --- /dev/null +++ b/components/utils/types.d.ts @@ -0,0 +1,4 @@ + +export type DeepPartial = { + [P in keyof T]?: T[P] extends Record ? DeepPartial : T[P] +} diff --git a/package.json b/package.json index 8970ab8..c461a04 100644 --- a/package.json +++ b/package.json @@ -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": {} -} \ No newline at end of file +}