origin/packages/config/src/styles.ts

90 lines
2.6 KiB
TypeScript
Raw Normal View History

2025-02-06 16:32:31 +08:00
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
}