CNCEC_APP/uni_modules/uview-pro/libs/function/styleUtils.ts

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);
}