84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import type { CSSProperties } from 'vue';
|
|
import trim from './trim';
|
|
import test from './test';
|
|
|
|
function isValidValue(value: any): boolean {
|
|
if (test.isEmpty(value)) return false;
|
|
if (typeof value === 'string') {
|
|
const trimmed = trim(value).toLowerCase();
|
|
return trimmed !== 'null' && trimmed !== 'undefined' && trimmed !== '';
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 将 CSS 字符串解析为对象
|
|
*/
|
|
function cssStrToObj(str: string): object {
|
|
const result = {};
|
|
if (!isValidValue(str)) return result;
|
|
const styleStr = trim(String(str));
|
|
if (!isValidValue(styleStr)) return result;
|
|
const declarations = styleStr.split(';');
|
|
declarations.forEach(decl => {
|
|
const [prop, ...values] = decl.split(':').map(s => s.trim());
|
|
const value = values.join(':');
|
|
if (prop && value) {
|
|
const camelProp = prop.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
|
|
(result as Record<string, string>)[camelProp] = value;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 将 CSS 对象转换为 CSS 字符串
|
|
*/
|
|
function cssObjToStr(obj: object): string {
|
|
if (!isValidValue(obj) || typeof obj !== 'object') return '';
|
|
return (
|
|
Object.entries(obj)
|
|
.map(([key, value]) => {
|
|
if (!isValidValue(value)) return '';
|
|
// 驼峰转短横线
|
|
const kebab = key.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
return `${kebab}: ${value}`;
|
|
})
|
|
.filter(Boolean)
|
|
.join('; ') + ';'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 合并多个 CSS 输入(对象或字符串),返回一个 CSS 对象
|
|
*/
|
|
export function mergeStyles(...args: (object | string)[]): CSSProperties {
|
|
const result = {} as Record<string, any>;
|
|
for (let i = 0; i < args.length; i++) {
|
|
const arg = args[i];
|
|
if (!isValidValue(arg)) return result as CSSProperties;
|
|
if (typeof arg === 'string') {
|
|
Object.assign(result, cssStrToObj(arg));
|
|
} else if (test.object(arg)) {
|
|
const cleanedObj: Record<string, any> = {};
|
|
Object.keys(arg).forEach(key => {
|
|
const value = (arg as Record<string, any>)[key];
|
|
if (isValidValue(value)) {
|
|
// 有效
|
|
cleanedObj[key] = value;
|
|
}
|
|
});
|
|
Object.assign(result, cleanedObj);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 合并为 CSS 字符串
|
|
*/
|
|
export function mergeCssStrings(...args: (object | string)[]): string {
|
|
const obj = mergeStyles(...args);
|
|
return cssObjToStr(obj);
|
|
}
|