import { HuiThemes } from './presets/index' import type { DeepPartial } from '../utils/types' import lightTheme from './presets/default' import darkTheme from './presets/dark' export type HuiUserTheme = DeepPartial & { type: string } export const isObject = (target: unknown) => target && typeof target === 'object' export const deepDuplicable = >(source: T, target: T): T => { if (!isObject(target) || !isObject(source)) return source as T const sourceKeys = Object.keys(source) as Array const result = {} as any 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] = deepDuplicable(sourceValue as Record, { ...(targetValue as Record) }) } else if (targetValue) { result[key] = targetValue } else { result[key] = sourceValue } } return result } const getPresets = (): Array => { return [lightTheme, darkTheme] } const getPresetStaticTheme = (): HuiThemes => { return lightTheme } const isAvailableThemeType = (type?: string): boolean => { if (!type) return false const presetThemes = getPresets() const hasType = presetThemes.find((theme) => theme.type === type) return !hasType } const isPresetTheme = (themeOrType?: HuiUserTheme | HuiThemes | string): boolean => { if (!themeOrType) return false const isType = typeof themeOrType === 'string' const type = isType ? (themeOrType as string) : (themeOrType as Exclude).type return !isAvailableThemeType(type) } const hasUserCustomTheme = (themes: Array = []): boolean => { return !!themes.find((item) => isAvailableThemeType(item.type)) } const create = (base: HuiThemes, custom: HuiUserTheme & T): HuiThemes & T => { if (!isAvailableThemeType(custom.type)) { // throw new Error('Duplicate or unavailable theme type') } return deepDuplicable(base as any, custom) as HuiThemes & T } const createFromDark = (custom: HuiUserTheme & T) => create(darkTheme, custom) const createFromLight = (custom: HuiUserTheme & T) => create(lightTheme, custom) const Themes = { isPresetTheme, isAvailableThemeType, hasUserCustomTheme, getPresets, getPresetStaticTheme, create, createFromDark, createFromLight } export default Themes