90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
![]() |
import { Theme, ThemeToken } from './types'
|
|||
|
import { flattenObject, toKebabCase } from './utils'
|
|||
|
import type { Config } from 'tailwindcss'
|
|||
|
|
|||
|
const PREFIX = '--nice'
|
|||
|
|
|||
|
/**
|
|||
|
* 生成CSS变量键名
|
|||
|
*/
|
|||
|
function createCssVariableName(path: string[]): string {
|
|||
|
return `${PREFIX}-${path.map(p => toKebabCase(p.toLowerCase())).join('-')}`
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 将主题对象转换为CSS变量对象
|
|||
|
*/
|
|||
|
export function themeToCssVariables(theme: Theme): Record<string, string> {
|
|||
|
const flattenedToken = flattenObject(theme.token)
|
|||
|
console.log(flattenedToken)
|
|||
|
const cssVars: Record<string, string> = {}
|
|||
|
|
|||
|
for (const [path, value] of Object.entries(flattenedToken)) {
|
|||
|
const cssVarName = createCssVariableName(path.split('.'))
|
|||
|
|
|||
|
cssVars[cssVarName] = value
|
|||
|
}
|
|||
|
|
|||
|
return cssVars
|
|||
|
}
|
|||
|
|
|||
|
export function injectThemeVariables(theme: Theme) {
|
|||
|
const cssVars = themeToCssVariables(theme)
|
|||
|
const root = document.documentElement
|
|||
|
|
|||
|
Object.entries(cssVars).forEach(([key, value]) => {
|
|||
|
console.log(key, value)
|
|||
|
root.style.setProperty(key, value)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 将扁平化的主题对象转换为Tailwind主题配置
|
|||
|
*/
|
|||
|
function transformToTailwindConfig(flattenedToken: Record<string, any>): Record<string, any> {
|
|||
|
const result: Record<string, any> = {}
|
|||
|
|
|||
|
// 处理对象路径,将其转换为嵌套结构
|
|||
|
for (const [path, _] of Object.entries(flattenedToken)) {
|
|||
|
const parts = path.split('.')
|
|||
|
let current = result
|
|||
|
|
|||
|
// 遍历路径的每一部分,构建嵌套结构
|
|||
|
for (let i = 0; i < parts.length; i++) {
|
|||
|
const part = parts[i]
|
|||
|
const isLast = i === parts.length - 1
|
|||
|
|
|||
|
// 如果是最后一个部分,设置CSS变量引用
|
|||
|
if (isLast) {
|
|||
|
current[part] = `var(${createCssVariableName(parts)})`
|
|||
|
} else {
|
|||
|
// 如果不是最后一个部分,确保存在嵌套对象
|
|||
|
current[part] = current[part] || {}
|
|||
|
current = current[part]
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 创建引用CSS变量的Tailwind主题配置
|
|||
|
*/
|
|||
|
export function createTailwindTheme(theme: Theme): Partial<Config["theme"]> {
|
|||
|
const flattenedToken = flattenObject(theme.token)
|
|||
|
const themeConfig = transformToTailwindConfig(flattenedToken)
|
|||
|
|
|||
|
// 将主题配置映射到Tailwind的结构
|
|||
|
const result = {
|
|||
|
extend: {
|
|||
|
colors: themeConfig.colors,
|
|||
|
textColor: themeConfig.textColor,
|
|||
|
backgroundColor: themeConfig.backgroundColor,
|
|||
|
borderColor: themeConfig.border,
|
|||
|
}
|
|||
|
}
|
|||
|
console.log(result)
|
|||
|
return result
|
|||
|
}
|