This commit is contained in:
2026-01-05 12:47:14 +08:00
commit 1fc846fae3
1614 changed files with 162035 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
import type { ExtractPropTypes } from 'vue'
import { makeStringProp } from '../_utils'
export const configProviderProps = {
/**
* @description 主题风格,设置为 `dark` 来开启深色模式,全局生效
*/
theme: makeStringProp<string | 'dark' & {}>(''),
/**
* @description 自定义主题变量
*/
themeVars: { type: Object, default: {} },
/**
* @description 设置所有弹窗类组件的 z-index该属性对全局生效
*/
zIndex: Number,
}
export type ConfigProviderProps = ExtractPropTypes<typeof configProviderProps>

View File

@@ -0,0 +1,80 @@
<script setup lang="ts">
import { defineComponent, watchEffect } from 'vue'
import { PREFIX } from '../_constants'
import { setGlobalZIndex } from '../_hooks'
import { configProviderProps } from './configprovider'
const props = defineProps(configProviderProps)
function kebabCase(str: string): string {
str = str.replace(str.charAt(0), str.charAt(0).toLocaleLowerCase())
return str.replace(/([a-z])([A-Z])/g, (_, p1, p2) => `${p1}-${p2.toLowerCase()}`)
}
function colorRgb(str: string) {
if (!str)
return
let sColor = str.toLowerCase()
// 十六进制颜色值的正则表达式
const reg = /^#([0-9A-f]{3}|[0-9A-f]{6})$/
// 如果是16进制颜色
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
let sColorNew = '#'
for (let i = 1; i < 4; i += 1)
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
sColor = sColorNew
}
// 处理六位的颜色值
const sColorChange = []
for (let i = 1; i < 7; i += 2)
sColorChange.push(Number.parseInt(`0x${sColor.slice(i, i + 2)}`))
return sColorChange.join(',')
}
return null
}
function mapThemeVarsToCSSVars(themeVars: Record<string, string>) {
if (!themeVars)
return
const cssVars: Record<string, string> = {}
const primaryColor = props?.themeVars?.primaryColor
// 为了处理一些组件的rgba透明颜色
if (primaryColor) {
cssVars['--nut-address-region-tab-line'] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${colorRgb(primaryColor)},0.15) 100%) `
cssVars['--nut-tabs-horizontal-tab-line-color'] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${colorRgb(primaryColor)},0.15)100%)`
cssVars['--nut-tabs-vertical-tab-line-color'] = `linear-gradient(180deg, ${primaryColor} 0%, rgba(${colorRgb(primaryColor)},0.15) 100%) `
}
Object.keys(themeVars).forEach((key) => {
cssVars[`--nut-${kebabCase(key)}`] = themeVars[key]
})
return cssVars
}
watchEffect(() => {
if (props.zIndex !== undefined)
setGlobalZIndex(props.zIndex)
})
</script>
<script lang="ts">
const componentName = `${PREFIX}-config-provider`
export default defineComponent ({
name: componentName,
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared',
},
})
</script>
<template>
<view :class="`nut-theme-${props.theme}`" :style="mapThemeVarsToCSSVars(themeVars)">
<slot />
</view>
</template>
<style lang="scss">
@import './index';
</style>

View File

@@ -0,0 +1 @@
export type * from './configprovider'