Files
WAI_Project_UNIX/uni_modules/cool-ui/hooks/size.ts
2025-09-04 20:18:18 +08:00

160 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { computed, type ComputedRef } from "vue";
import { config } from "../config";
import { rpx2px } from "@/cool";
/**
* 字号管理类
* 用于处理文本大小的缩放和样式
*/
class Size {
// 预设的字号类名
public names = [
"text-xs",
"text-sm",
"text-md",
"text-lg",
"text-xl",
"text-2xl",
"text-3xl",
"text-4xl",
"text-5xl",
"text-6xl",
"text-7xl",
"text-8xl",
"text-9xl"
];
// 对应的字号大小
public sizes = [20, 24, 28, 32, 36, 44, 52, 60, 72, 84, 96, 120, 152];
// 对应的行高
public lineHeights = [28, 36, 44, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1];
// 原始类名
public className: ComputedRef<string> = computed(() => "");
// 计算后的类名
public ptClassName: ComputedRef<string>;
constructor(cb: (() => string) | null) {
this.className = computed(cb ?? (() => ""));
// 根据全局字号配置动态计算类名
this.ptClassName = computed(() => {
if (config.fontSize == null) {
return this.className.value;
}
const name = this.names[this.getIndex()];
return this.className.value.replace(`-important-${name}`, "").replace(name, "");
});
}
/**
* 获取全局字号缩放比例
*/
getScale = () => {
return config.fontSize ?? 1;
};
/**
* 根据缩放比例计算rpx值
* @param val - 需要转换的值
*/
getRpx = (val: number | string) => {
const scale = this.getScale();
if (typeof val == "number") {
return val * scale + "rpx";
} else {
const num = parseFloat(val);
const unit = val.replace(`${num}`, "");
return num * scale + unit;
}
};
/**
* 获取px值
* @param val - 需要转换的值 10、10rpx、10px
* @returns 转换后的px值
*/
getPxValue = (val: number | string) => {
const scale = this.getScale();
if (typeof val == "string") {
const num = parseFloat(val);
const unit = val.replace(`${num}`, "");
if (unit == "px") {
return num * scale;
} else {
return rpx2px(num * scale);
}
} else {
return rpx2px(val * scale);
}
};
/**
* 获取px值
*/
getPx = (val: number | string) => {
return this.getPxValue(val) + "px";
};
/**
* 获取当前字号在预设中的索引
*/
getIndex = () => {
let index = this.names.findIndex((name) => {
if (this.className.value.includes(name)) {
return true;
}
return false;
});
// 默认使用 text-md (14px)
if (index < 0) {
index = 2;
}
return index;
};
/**
* 获取最终的字号大小
* @param size - 指定字号大小,为空则使用预设值
*/
getSize = (size: number | string | null): null | string => {
// 如果未设置全局字号且未指定size直接返回null否则返回对应rpx值
if (config.fontSize == null && size == null) {
return null;
}
return this.getRpx(size ?? this.sizes[this.getIndex()]);
};
/**
* 获取当前行高
*/
getLineHeight = (): null | string => {
// 未设置全局字号时返回null
if (config.fontSize == null) {
return null;
}
const lineHeight = this.lineHeights[this.getIndex()];
return lineHeight == 1 ? `1` : this.getRpx(lineHeight);
};
}
/**
* 字号管理Hook
* @param className - 类名
*/
export function useSize(cb: (() => string) | null = null): Size {
return new Size(cb);
}