uview-plus
Version:
零云®uview-plus已兼容vue3支持多语言,120+全面的组件和便捷的工具会让您信手拈来。近期新增拖动排序、条码、图片裁剪、下拉刷新、虚拟列表、签名、Markdown等。
682 lines (646 loc) • 26.5 kB
JavaScript
import config from '../config/config.js'
import color from '../config/color.js'
import index from '../function/index.js'
import { trySetTabBarStyle } from './runtime.js'
const DEFAULT_LIGHT_THEME_COLORS = Object.freeze({
primary: '#3c9cff',
info: '#909399',
warning: '#f9ae3d',
error: '#f56c6c',
success: '#5ac725',
mainColor: '#303133',
contentColor: '#606266',
tipsColor: '#909193',
lightColor: '#c0c4cc',
borderColor: '#dadbde',
bgColor: '#f3f4f6',
disabledColor: '#c8c9cc',
primaryDark: '#398ade',
primaryDisabled: '#9acafc',
primaryLight: '#ecf5ff',
warningDark: '#f1a532',
warningDisabled: '#f9d39b',
warningLight: '#fdf6ec',
successDark: '#53c21d',
successDisabled: '#a9e08f',
successLight: '#f5fff0',
errorDark: '#e45656',
errorDisabled: '#f7b2b2',
errorLight: '#fef0f0',
infoDark: '#767a82',
infoDisabled: '#c4c6c9',
infoLight: '#f4f4f5'
})
const DEFAULT_DARK_THEME_COLORS = Object.freeze({
primary: '#3c9cff',
info: '#909399',
warning: '#f9ae3d',
error: '#f56c6c',
success: '#5ac725',
mainColor: '#f5f5f5',
contentColor: '#d1d5db',
tipsColor: '#9ca3af',
lightColor: '#6b7280',
borderColor: '#3a3a3c',
bgColor: '#1f1f1f',
disabledColor: '#4b5563',
primaryDark: '#5aa8ff',
primaryDisabled: '#4c6f92',
primaryLight: '#10243a',
warningDark: '#ffbf66',
warningDisabled: '#8a6a3a',
warningLight: '#3d2f1b',
successDark: '#7ad94b',
successDisabled: '#5f7f4f',
successLight: '#1f3316',
errorDark: '#ff8a8a',
errorDisabled: '#8d5858',
errorLight: '#3a2222',
infoDark: '#b0b3b8',
infoDisabled: '#5f6368',
infoLight: '#2f3238'
})
const DEFAULT_THEME_EXTRA_VARS = Object.freeze({
light: Object.freeze({
'--up-table2-header-bg-color': '#f5f7fa',
'--up-table2-zebra-bg-color': '#fafafa',
'--up-table2-highlight-bg-color': '#f5f7fa',
'--up-gap-bg-color': '#f3f4f6',
'--up-skeleton-bg-color': '#f1f2f4',
'--up-skeleton-shimmer-color': '#e6e6e6',
'--up-swipe-action-button-bg-color': '#c7c6cd',
'--up-index-list-indicator-bg-color': '#c9c9c9',
'--up-calendar-month-mark-color': 'rgba(231, 232, 234, 0.83)'
}),
dark: Object.freeze({
'--up-table2-header-bg-color': '#2a2d33',
'--up-table2-zebra-bg-color': '#23262b',
'--up-table2-highlight-bg-color': '#2f3440',
'--up-gap-bg-color': '#111111',
'--up-skeleton-bg-color': '#2f3135',
'--up-skeleton-shimmer-color': 'rgba(255, 255, 255, 0.12)',
'--up-swipe-action-button-bg-color': '#4b5563',
'--up-index-list-indicator-bg-color': '#4b5563',
'--up-calendar-month-mark-color': 'rgba(255, 255, 255, 0.04)'
})
})
export const themeState = {
preference: 'system',
mode: 'light',
version: 0,
vars: {}
}
const THEME_MODE_STORAGE_KEY = 'u-theme-mode'
const THEME_MODE_SYSTEM = 'system'
const THEME_MODE_MANUAL = ['light', 'dark']
const LIGHT_THEME_TOKEN_FIELD_MAP = Object.freeze({
'primary': 'primary',
'primary-dark': 'primaryDark',
'primary-disabled': 'primaryDisabled',
'primary-light': 'primaryLight',
'warning': 'warning',
'warning-dark': 'warningDark',
'warning-disabled': 'warningDisabled',
'warning-light': 'warningLight',
'success': 'success',
'success-dark': 'successDark',
'success-disabled': 'successDisabled',
'success-light': 'successLight',
'error': 'error',
'error-dark': 'errorDark',
'error-disabled': 'errorDisabled',
'error-light': 'errorLight',
'info': 'info',
'info-dark': 'infoDark',
'info-disabled': 'infoDisabled',
'info-light': 'infoLight',
'main-color': 'mainColor',
'content-color': 'contentColor',
'tips-color': 'tipsColor',
'light-color': 'lightColor',
'border-color': 'borderColor',
'bg-color': 'bgColor',
'disabled-color': 'disabledColor'
})
const LIGHT_THEME_FIELD_TOKEN_MAP = Object.freeze(
Object.fromEntries(
Object.entries(LIGHT_THEME_TOKEN_FIELD_MAP).map(([token, field]) => [field, token])
)
)
const runtimeThemeOverrideState = {
color: Object.create(null),
configColor: Object.create(null)
}
let cachedLightThemeColors = null
let hasRegisterThemeListener = false
let currentThemePreference = THEME_MODE_SYSTEM
function normalizeThemeMode(theme = 'light') {
return theme === 'dark' ? 'dark' : 'light'
}
function normalizeThemePreference(mode = THEME_MODE_SYSTEM) {
if (THEME_MODE_MANUAL.includes(mode)) return mode
return THEME_MODE_SYSTEM
}
function getLightBridgeVar(token, fallback) {
return `var(--up-light-${token}, ${fallback})`
}
function clearOverrideBucket(bucket) {
Object.keys(bucket).forEach((key) => {
delete bucket[key]
})
}
function normalizeLightThemeToken(token = '') {
if (typeof token !== 'string') return ''
if (token.indexOf('up-') === 0) return token.slice(3)
if (token.indexOf('u-') === 0) return token.slice(2)
return token
}
function isLightThemeConfigColorKey(token = '') {
return token.indexOf('up-') === 0 || token.indexOf('u-') === 0
}
export function syncThemeColorOverrideState({
color: colorOverrides,
configColor: configColorOverrides,
reset = false
} = {}) {
if (reset) {
clearOverrideBucket(runtimeThemeOverrideState.color)
clearOverrideBucket(runtimeThemeOverrideState.configColor)
}
if (colorOverrides && typeof colorOverrides === 'object') {
Object.keys(LIGHT_THEME_FIELD_TOKEN_MAP).forEach((field) => {
if (!Object.prototype.hasOwnProperty.call(colorOverrides, field)) return
const value = colorOverrides[field]
if (typeof value === 'string' && value) {
runtimeThemeOverrideState.color[field] = true
return
}
delete runtimeThemeOverrideState.color[field]
})
}
if (configColorOverrides && typeof configColorOverrides === 'object') {
Object.keys(configColorOverrides).forEach((key) => {
const token = normalizeLightThemeToken(key)
if (!Object.prototype.hasOwnProperty.call(LIGHT_THEME_TOKEN_FIELD_MAP, token)) return
const value = configColorOverrides[key]
if (typeof value === 'string' && value) {
const overrideKey = isLightThemeConfigColorKey(key) ? key : `up-${token}`
runtimeThemeOverrideState.configColor[overrideKey] = true
return
}
delete runtimeThemeOverrideState.configColor[key]
delete runtimeThemeOverrideState.configColor[`u-${token}`]
delete runtimeThemeOverrideState.configColor[`up-${token}`]
})
}
}
function getExplicitRuntimeColorValue(token, runtimeColorMap = {}) {
const field = LIGHT_THEME_TOKEN_FIELD_MAP[token]
if (!field) return ''
if (runtimeThemeOverrideState.color[field]) {
const value = color[field]
if (typeof value === 'string' && value) return value
}
const upKey = `up-${token}`
const uKey = `u-${token}`
if (!runtimeThemeOverrideState.configColor[upKey] && !runtimeThemeOverrideState.configColor[uKey]) return ''
const upValue = runtimeColorMap[upKey]
const uValue = runtimeColorMap[uKey]
if (runtimeThemeOverrideState.configColor[upKey] && typeof upValue === 'string' && upValue) return upValue
if (runtimeThemeOverrideState.configColor[uKey] && typeof uValue === 'string' && uValue) return uValue
return ''
}
function readThemePreferenceFromStorage() {
try {
if (typeof uni !== 'undefined' && typeof uni.getStorageSync === 'function') {
const mode = uni.getStorageSync(THEME_MODE_STORAGE_KEY)
return normalizeThemePreference(mode)
}
} catch (e) {}
return THEME_MODE_SYSTEM
}
function writeThemePreferenceToStorage(mode) {
try {
if (typeof uni !== 'undefined' && typeof uni.setStorageSync === 'function') {
uni.setStorageSync(THEME_MODE_STORAGE_KEY, mode)
}
} catch (e) {}
}
export function getSystemTheme() {
let theme = 'light'
try {
if (typeof uni !== 'undefined' && typeof uni.getAppBaseInfo === 'function') {
const appBaseInfo = uni.getAppBaseInfo() || {}
if (appBaseInfo.theme) {
theme = appBaseInfo.theme
}
}
if (typeof uni !== 'undefined' && typeof uni.getSystemInfoSync === 'function') {
const systemInfo = uni.getSystemInfoSync() || {}
if (systemInfo.theme) {
theme = systemInfo.theme
}
}
} catch (e) {
theme = 'light'
}
return normalizeThemeMode(theme)
}
function getCurrentLightThemeColors() {
const runtimeColorMap = config.color || {}
const lightThemeColors = {
...DEFAULT_LIGHT_THEME_COLORS
}
Object.keys(LIGHT_THEME_TOKEN_FIELD_MAP).forEach((token) => {
const explicitValue = getExplicitRuntimeColorValue(token, runtimeColorMap)
if (!explicitValue) return
lightThemeColors[LIGHT_THEME_TOKEN_FIELD_MAP[token]] = explicitValue
})
return lightThemeColors
}
function getThemeColorsByMode(mode) {
if (!cachedLightThemeColors) {
cachedLightThemeColors = getCurrentLightThemeColors()
}
const themeMode = normalizeThemeMode(mode)
if (themeMode === 'dark') {
return {
...DEFAULT_DARK_THEME_COLORS,
primary: cachedLightThemeColors.primary,
info: cachedLightThemeColors.info,
warning: cachedLightThemeColors.warning,
error: cachedLightThemeColors.error,
success: cachedLightThemeColors.success
}
}
return {
...cachedLightThemeColors
}
}
function buildConfigColorMap(themeColors) {
return {
'u-primary': themeColors.primary,
'u-primary-dark': themeColors.primaryDark,
'u-primary-disabled': themeColors.primaryDisabled,
'u-primary-light': themeColors.primaryLight,
'u-warning': themeColors.warning,
'u-warning-dark': themeColors.warningDark,
'u-warning-disabled': themeColors.warningDisabled,
'u-warning-light': themeColors.warningLight,
'u-success': themeColors.success,
'u-success-dark': themeColors.successDark,
'u-success-disabled': themeColors.successDisabled,
'u-success-light': themeColors.successLight,
'u-error': themeColors.error,
'u-error-dark': themeColors.errorDark,
'u-error-disabled': themeColors.errorDisabled,
'u-error-light': themeColors.errorLight,
'u-info': themeColors.info,
'u-info-dark': themeColors.infoDark,
'u-info-disabled': themeColors.infoDisabled,
'u-info-light': themeColors.infoLight,
'u-main-color': themeColors.mainColor,
'u-content-color': themeColors.contentColor,
'u-tips-color': themeColors.tipsColor,
'u-light-color': themeColors.lightColor,
'u-border-color': themeColors.borderColor,
'u-bg-color': themeColors.bgColor,
'u-disabled-color': themeColors.disabledColor,
'up-primary': themeColors.primary,
'up-primary-dark': themeColors.primaryDark,
'up-primary-disabled': themeColors.primaryDisabled,
'up-primary-light': themeColors.primaryLight,
'up-warning': themeColors.warning,
'up-warning-dark': themeColors.warningDark,
'up-warning-disabled': themeColors.warningDisabled,
'up-warning-light': themeColors.warningLight,
'up-success': themeColors.success,
'up-success-dark': themeColors.successDark,
'up-success-disabled': themeColors.successDisabled,
'up-success-light': themeColors.successLight,
'up-error': themeColors.error,
'up-error-dark': themeColors.errorDark,
'up-error-disabled': themeColors.errorDisabled,
'up-error-light': themeColors.errorLight,
'up-info': themeColors.info,
'up-info-dark': themeColors.infoDark,
'up-info-disabled': themeColors.infoDisabled,
'up-info-light': themeColors.infoLight,
'up-main-color': themeColors.mainColor,
'up-content-color': themeColors.contentColor,
'up-tips-color': themeColors.tipsColor,
'up-light-color': themeColors.lightColor,
'up-border-color': themeColors.borderColor,
'up-bg-color': themeColors.bgColor,
'up-disabled-color': themeColors.disabledColor
}
}
function buildAliasCssVars(vars = {}) {
const aliasVars = {}
Object.keys(vars).forEach((key) => {
if (typeof key !== 'string') return
if (key.indexOf('--up-') === 0) {
aliasVars[key.replace('--up-', '--u-')] = vars[key]
return
}
if (key.indexOf('--u-') === 0) {
aliasVars[key.replace('--u-', '--up-')] = vars[key]
}
})
return aliasVars
}
function buildThemeCssVars(themeColors, mode = 'light') {
const themeMode = normalizeThemeMode(mode)
const isDark = themeMode === 'dark'
const useBridge = !isDark
const runtimeColorMap = config.color || {}
const defaultExtraVars = DEFAULT_THEME_EXTRA_VARS[themeMode] || DEFAULT_THEME_EXTRA_VARS.light
const pageBgColor = themeColors.bgColor || (isDark ? '#1f1f1f' : '#f3f4f6')
const hoverBgColor = runtimeColorMap['up-hover-bg-color']
|| runtimeColorMap['u-hover-bg-color']
|| (isDark ? '#343741' : '#e7ebf0')
const navbarBgColor = runtimeColorMap['up-navbar-bg-color']
|| runtimeColorMap['u-navbar-bg-color']
|| (isDark ? '#1c1c1e' : '#ffffff')
const resolveLightTokenValue = (token, fallback) => {
if (!useBridge) return fallback
const explicitValue = getExplicitRuntimeColorValue(token, runtimeColorMap)
return explicitValue || getLightBridgeVar(token, fallback)
}
const resolvedMainColor = resolveLightTokenValue('main-color', themeColors.mainColor)
const resolvedContentColor = resolveLightTokenValue('content-color', themeColors.contentColor)
const resolvedTipsColor = resolveLightTokenValue('tips-color', themeColors.tipsColor)
const resolvedLightColor = resolveLightTokenValue('light-color', themeColors.lightColor)
const resolvedBorderColor = resolveLightTokenValue('border-color', themeColors.borderColor)
const resolvedBgColor = resolveLightTokenValue('bg-color', themeColors.bgColor)
const resolvedDisabledColor = resolveLightTokenValue('disabled-color', themeColors.disabledColor)
const resolvedPrimary = resolveLightTokenValue('primary', themeColors.primary)
const resolvedPrimaryDark = resolveLightTokenValue('primary-dark', themeColors.primaryDark)
const resolvedPrimaryDisabled = resolveLightTokenValue('primary-disabled', themeColors.primaryDisabled)
const resolvedPrimaryLight = resolveLightTokenValue('primary-light', themeColors.primaryLight)
const resolvedWarning = resolveLightTokenValue('warning', themeColors.warning)
const resolvedWarningDark = resolveLightTokenValue('warning-dark', themeColors.warningDark)
const resolvedWarningDisabled = resolveLightTokenValue('warning-disabled', themeColors.warningDisabled)
const resolvedWarningLight = resolveLightTokenValue('warning-light', themeColors.warningLight)
const resolvedSuccess = resolveLightTokenValue('success', themeColors.success)
const resolvedSuccessDark = resolveLightTokenValue('success-dark', themeColors.successDark)
const resolvedSuccessDisabled = resolveLightTokenValue('success-disabled', themeColors.successDisabled)
const resolvedSuccessLight = resolveLightTokenValue('success-light', themeColors.successLight)
const resolvedError = resolveLightTokenValue('error', themeColors.error)
const resolvedErrorDark = resolveLightTokenValue('error-dark', themeColors.errorDark)
const resolvedErrorDisabled = resolveLightTokenValue('error-disabled', themeColors.errorDisabled)
const resolvedErrorLight = resolveLightTokenValue('error-light', themeColors.errorLight)
const resolvedInfo = resolveLightTokenValue('info', themeColors.info)
const resolvedInfoDark = resolveLightTokenValue('info-dark', themeColors.infoDark)
const resolvedInfoDisabled = resolveLightTokenValue('info-disabled', themeColors.infoDisabled)
const resolvedInfoLight = resolveLightTokenValue('info-light', themeColors.infoLight)
const coreVars = {
'--u-main-color': resolvedMainColor,
'--u-content-color': resolvedContentColor,
'--u-tips-color': resolvedTipsColor,
'--u-light-color': resolvedLightColor,
'--u-border-color': resolvedBorderColor,
'--u-bg-color': resolvedBgColor,
'--u-hover-bg-color': hoverBgColor,
'--u-disabled-color': resolvedDisabledColor,
'--u-primary': resolvedPrimary,
'--u-primary-dark': resolvedPrimaryDark,
'--u-primary-disabled': resolvedPrimaryDisabled,
'--u-primary-light': resolvedPrimaryLight,
'--u-warning': resolvedWarning,
'--u-warning-dark': resolvedWarningDark,
'--u-warning-disabled': resolvedWarningDisabled,
'--u-warning-light': resolvedWarningLight,
'--u-success': resolvedSuccess,
'--u-success-dark': resolvedSuccessDark,
'--u-success-disabled': resolvedSuccessDisabled,
'--u-success-light': resolvedSuccessLight,
'--u-error': resolvedError,
'--u-error-dark': resolvedErrorDark,
'--u-error-disabled': resolvedErrorDisabled,
'--u-error-light': resolvedErrorLight,
'--u-info': resolvedInfo,
'--u-info-dark': resolvedInfoDark,
'--u-info-disabled': resolvedInfoDisabled,
'--u-info-light': resolvedInfoLight,
'--up-main-color': resolvedMainColor,
'--up-content-color': resolvedContentColor,
'--up-tips-color': resolvedTipsColor,
'--up-light-color': resolvedLightColor,
'--up-border-color': resolvedBorderColor,
'--up-bg-color': resolvedBgColor,
'--up-hover-bg-color': hoverBgColor,
'--up-disabled-color': resolvedDisabledColor,
'--up-primary': resolvedPrimary,
'--up-primary-dark': resolvedPrimaryDark,
'--up-primary-disabled': resolvedPrimaryDisabled,
'--up-primary-light': resolvedPrimaryLight,
'--up-warning': resolvedWarning,
'--up-warning-dark': resolvedWarningDark,
'--up-warning-disabled': resolvedWarningDisabled,
'--up-warning-light': resolvedWarningLight,
'--up-success': resolvedSuccess,
'--up-success-dark': resolvedSuccessDark,
'--up-success-disabled': resolvedSuccessDisabled,
'--up-success-light': resolvedSuccessLight,
'--up-error': resolvedError,
'--up-error-dark': resolvedErrorDark,
'--up-error-disabled': resolvedErrorDisabled,
'--up-error-light': resolvedErrorLight,
'--up-info': resolvedInfo,
'--up-info-dark': resolvedInfoDark,
'--up-info-disabled': resolvedInfoDisabled,
'--up-info-light': resolvedInfoLight,
'--up-page-bg-color': pageBgColor,
'--up-card-bg-color': isDark ? '#1c1c1e' : '#ffffff',
'--up-navbar-bg-color': navbarBgColor
}
const extraVars = {}
Object.keys(runtimeColorMap).forEach((key) => {
if (typeof key !== 'string') return
const isThemeToken = key.indexOf('up-') === 0 || key.indexOf('u-') === 0
if (!isThemeToken) return
const cssVarName = `--${key}`
if (Object.prototype.hasOwnProperty.call(coreVars, cssVarName)) return
const value = runtimeColorMap[key]
if (typeof value === 'string' && value) {
extraVars[cssVarName] = value
}
})
return {
...coreVars,
...defaultExtraVars,
...buildAliasCssVars(defaultExtraVars),
...extraVars,
...buildAliasCssVars(extraVars)
}
}
export function getThemeVars(mode) {
if (mode) {
return buildThemeCssVars(getThemeColorsByMode(mode), mode)
}
if (themeState.vars && Object.keys(themeState.vars).length > 0) {
return { ...themeState.vars }
}
return buildThemeCssVars(getThemeColorsByMode(themeState.mode), themeState.mode)
}
function syncThemeToH5(mode) {
// #ifdef H5
if (typeof document !== 'undefined' && document.documentElement) {
document.documentElement.setAttribute('data-up-theme', mode)
}
// #endif
}
function hasActiveRuntimePage() {
try {
if (typeof getCurrentPages === 'function') {
const pages = getCurrentPages()
return Array.isArray(pages) && pages.length > 0
}
} catch (e) {}
return false
}
function trySetNavigationBarColor(options) {
if (typeof uni === 'undefined' || typeof uni.setNavigationBarColor !== 'function') return
if (!hasActiveRuntimePage()) return
try {
const result = uni.setNavigationBarColor(options)
if (result && typeof result.catch === 'function') {
result.catch(() => {})
}
} catch (e) {}
}
function applyNativeThemeUI(mode, themeColors, themeVars = {}) {
if (typeof uni === 'undefined') return
if (config.nativeThemeSync !== true) return
const isDark = normalizeThemeMode(mode) === 'dark'
const pageBg = themeColors?.bgColor || (isDark ? '#1f1f1f' : '#f3f4f6')
const navBg = themeVars?.['--up-navbar-bg-color']
|| themeVars?.['--u-navbar-bg-color']
|| config.color?.['up-navbar-bg-color']
|| config.color?.['u-navbar-bg-color']
|| (isDark ? '#1c1c1e' : '#ffffff')
trySetNavigationBarColor({
frontColor: isDark ? '#ffffff' : '#000000',
backgroundColor: navBg,
animation: {
duration: 0,
timingFunc: 'linear'
}
})
if (typeof uni.setBackgroundColor === 'function') {
uni.setBackgroundColor({
backgroundColor: pageBg,
backgroundColorTop: pageBg,
backgroundColorBottom: pageBg
})
}
trySetTabBarStyle({
color: isDark ? '#8e8e93' : '#909399',
selectedColor: isDark ? '#f2f2f7' : '#303133',
backgroundColor: isDark ? '#111111' : '#ffffff',
borderStyle: isDark ? 'white' : 'black'
})
}
function applyTheme(mode = 'light') {
const themeMode = normalizeThemeMode(mode)
const themeColors = getThemeColorsByMode(themeMode)
const themeVars = buildThemeCssVars(themeColors, themeMode)
index.shallowMerge(color, {
primary: themeColors.primary,
primaryDark: themeColors.primaryDark,
primaryDisabled: themeColors.primaryDisabled,
primaryLight: themeColors.primaryLight,
info: themeColors.info,
infoDark: themeColors.infoDark,
infoDisabled: themeColors.infoDisabled,
infoLight: themeColors.infoLight,
default: themeColors.info,
warning: themeColors.warning,
warningDark: themeColors.warningDark,
warningDisabled: themeColors.warningDisabled,
warningLight: themeColors.warningLight,
error: themeColors.error,
errorDark: themeColors.errorDark,
errorDisabled: themeColors.errorDisabled,
errorLight: themeColors.errorLight,
success: themeColors.success,
successDark: themeColors.successDark,
successDisabled: themeColors.successDisabled,
successLight: themeColors.successLight,
mainColor: themeColors.mainColor,
contentColor: themeColors.contentColor,
tipsColor: themeColors.tipsColor,
lightColor: themeColors.lightColor,
borderColor: themeColors.borderColor,
bgColor: themeColors.bgColor,
disabledColor: themeColors.disabledColor
})
index.shallowMerge(config.color, buildConfigColorMap(themeColors))
config.themeMode = themeMode
themeState.preference = currentThemePreference
themeState.mode = themeMode
themeState.vars = { ...themeVars }
themeState.version = Number(themeState.version || 0) + 1
syncThemeToH5(themeMode)
applyNativeThemeUI(themeMode, themeColors, themeVars)
if (typeof uni !== 'undefined' && uni.$u && uni.$u.theme) {
uni.$u.theme.mode = themeState.mode
if (Object.prototype.hasOwnProperty.call(uni.$u.theme, 'colors')) {
delete uni.$u.theme.colors
}
uni.$u.theme.vars = { ...themeState.vars }
uni.$u.theme.version = themeState.version
}
if (typeof uni !== 'undefined' && typeof uni.$emit === 'function') {
uni.$emit('uThemeChange', {
mode: themeState.mode,
colors: { ...themeColors },
version: themeState.version,
vars: { ...themeState.vars }
})
}
return themeState
}
export function setTheme(mode = 'light') {
currentThemePreference = normalizeThemeMode(mode)
writeThemePreferenceToStorage(currentThemePreference)
return applyTheme(currentThemePreference)
}
export function setThemePreference(mode = THEME_MODE_SYSTEM) {
currentThemePreference = normalizeThemePreference(mode)
writeThemePreferenceToStorage(currentThemePreference)
if (currentThemePreference === THEME_MODE_SYSTEM) {
return applyTheme(getSystemTheme())
}
return applyTheme(currentThemePreference)
}
export function getThemePreference() {
return currentThemePreference
}
export function refreshThemeFromConfig() {
cachedLightThemeColors = getCurrentLightThemeColors()
if (themeState.version > 0) {
applyTheme(themeState.mode)
}
}
export function initThemeSystem() {
if (typeof uni === 'undefined') return
if (!cachedLightThemeColors) {
cachedLightThemeColors = getCurrentLightThemeColors()
}
currentThemePreference = readThemePreferenceFromStorage()
if (currentThemePreference === THEME_MODE_SYSTEM) {
applyTheme(getSystemTheme())
} else {
applyTheme(currentThemePreference)
}
if (!hasRegisterThemeListener && typeof uni.onThemeChange === 'function') {
uni.onThemeChange((res = {}) => {
if (currentThemePreference === THEME_MODE_SYSTEM) {
applyTheme(res.theme)
}
})
hasRegisterThemeListener = true
}
}