小程序初始提交
This commit is contained in:
162
cool-unix/uni_modules/cool-ui/components/cl-icon/cl-icon.uvue
Normal file
162
cool-unix/uni_modules/cool-ui/components/cl-icon/cl-icon.uvue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<text class="cl-icon" :class="[ptClassName]" :style="iconStyle" :key="cache.key">
|
||||
{{ icon.text }}
|
||||
</text>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, type PropType } from "vue";
|
||||
import {
|
||||
forInObject,
|
||||
get,
|
||||
has,
|
||||
parsePt,
|
||||
useCache,
|
||||
isDark,
|
||||
ctx,
|
||||
hasTextColor,
|
||||
isNull
|
||||
} from "@/cool";
|
||||
import { icons } from "@/icons";
|
||||
import { useSize } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-icon"
|
||||
});
|
||||
|
||||
// 定义组件属性
|
||||
const props = defineProps({
|
||||
// 透传样式
|
||||
pt: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
// 图标名称
|
||||
name: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
// 图标大小
|
||||
size: {
|
||||
type: [String, Number] as PropType<string | number>,
|
||||
default: 32
|
||||
},
|
||||
// 图标高度
|
||||
height: {
|
||||
type: [String, Number] as PropType<string | number>,
|
||||
default: null
|
||||
},
|
||||
// 图标宽度
|
||||
width: {
|
||||
type: [String, Number] as PropType<string | number>,
|
||||
default: null
|
||||
},
|
||||
// 图标颜色
|
||||
color: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
});
|
||||
|
||||
// 透传样式类型定义
|
||||
type PassThrough = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
// 解析透传样式
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// 缓存
|
||||
const { cache } = useCache(() => [props.color]);
|
||||
|
||||
// 字号
|
||||
const { getRpx, ptClassName } = useSize(() => pt.value.className ?? "");
|
||||
|
||||
// 图标类型定义
|
||||
type Icon = {
|
||||
font: string; // 字体名称
|
||||
text: string; // 图标文本
|
||||
};
|
||||
|
||||
// 图标信息
|
||||
const icon = computed<Icon>(() => {
|
||||
let font = "";
|
||||
let text = "";
|
||||
|
||||
try {
|
||||
let code = "";
|
||||
|
||||
// 遍历字体库查找对应图标
|
||||
forInObject(icons, (value, key) => {
|
||||
if (has(value, props.name)) {
|
||||
font = key;
|
||||
code = get(value, props.name) as string;
|
||||
}
|
||||
});
|
||||
|
||||
text = String.fromCharCode(parseInt(code, 16));
|
||||
} catch (e) {
|
||||
console.error(`图标 ${props.name} 不存在`, e);
|
||||
}
|
||||
|
||||
return {
|
||||
font,
|
||||
text
|
||||
};
|
||||
});
|
||||
|
||||
// 图标颜色
|
||||
const color = computed(() => {
|
||||
if (props.color != "" && !isNull(props.color)) {
|
||||
switch (props.color) {
|
||||
case "primary":
|
||||
return ctx.color["primary-500"] as string;
|
||||
case "success":
|
||||
return "#22c55e";
|
||||
case "warn":
|
||||
return "#eab308";
|
||||
case "error":
|
||||
return "#ef4444";
|
||||
case "info":
|
||||
return ctx.color["surface-500"] as string;
|
||||
case "dark":
|
||||
return ctx.color["surface-700"] as string;
|
||||
case "light":
|
||||
return ctx.color["surface-50"] as string;
|
||||
case "disabled":
|
||||
return ctx.color["surface-300"] as string;
|
||||
default:
|
||||
return props.color;
|
||||
}
|
||||
}
|
||||
|
||||
return isDark.value ? "white" : (ctx.color["surface-700"] as string);
|
||||
});
|
||||
|
||||
// 图标样式
|
||||
const iconStyle = computed(() => {
|
||||
const style = {};
|
||||
|
||||
// 判断是不是有颜色样式
|
||||
if (!hasTextColor(ptClassName.value)) {
|
||||
style["color"] = color.value;
|
||||
}
|
||||
|
||||
// 设置字体
|
||||
if (icon.value.font != "") {
|
||||
style["fontFamily"] = icon.value.font;
|
||||
}
|
||||
|
||||
// 设置字体大小
|
||||
style["fontSize"] = getRpx(props.size!);
|
||||
|
||||
// 设置高度
|
||||
style["height"] = getRpx(props.height ?? props.size!);
|
||||
style["lineHeight"] = getRpx(props.size!);
|
||||
|
||||
// 设置宽度
|
||||
style["width"] = getRpx(props.width ?? props.size!);
|
||||
|
||||
return style;
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user