373 lines
9.4 KiB
Plaintext
373 lines
9.4 KiB
Plaintext
<template>
|
|
<view v-if="showAlert" @click="onclickbar" class="xAlert" :style="_styleMap.bgStyle">
|
|
<!--
|
|
@slot 左边图标插槽
|
|
-->
|
|
<slot name="left">
|
|
<view class="xAlertLeft">
|
|
<x-icon :font-size="props.iconSize" :color="(_styleMap.textStyle.get('color')! as string)"
|
|
:dark-color="(_styleMap.textStyle.get('color')! as string)" :name="_iconName"></x-icon>
|
|
</view>
|
|
</slot>
|
|
<view class="xAlertContent">
|
|
<text :style="_styleMap.textStyle">
|
|
<!--
|
|
@slot 默认插槽内容
|
|
-->
|
|
<slot></slot>
|
|
</text>
|
|
</view>
|
|
<view @click="closeAlert" v-if="_showClose" class="xAlertRight">
|
|
<x-icon :font-size="props.iconSize" :color="(_styleMap.textStyle.get('color')! as string)"
|
|
:dark-color="(_styleMap.textStyle.get('color')! as string)" :name="props.closeIcon"></x-icon>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, ref, onMounted } from "vue"
|
|
import { xDate } from "../../core/util/xDate.uts"
|
|
import { checkIsCssUnit, getUnit, fillArrayCssValue, fillArrayCssValueByround, fillArrayCssValueBycolor } from "../../core/util/xCoreUtil.uts"
|
|
import { getDefaultColor, getDefaultColorObj, getThinColorObj } from "../../core/util/xCoreColorUtil.uts"
|
|
import { xConfig } from "../../config/xConfig.uts"
|
|
|
|
type styleMapType = {
|
|
textStyle: Map<string, any>,
|
|
bgStyle: Map<string, any>
|
|
}
|
|
|
|
type xAlertStatusType = "primary"|"warn"|"success"|"error"|"info"
|
|
|
|
/**
|
|
* @name 警告 xAlert
|
|
* @page /pages/index/alert
|
|
* @category 展示组件
|
|
* @description 样式丰富常用警告提醒
|
|
* @constant 平台兼容
|
|
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
|
|
*/
|
|
defineOptions({ name: "xAlert" })
|
|
|
|
defineSlots<{
|
|
left(): any
|
|
default(): any
|
|
}>()
|
|
|
|
const emits = defineEmits([
|
|
/**
|
|
* 关闭时触发
|
|
*/
|
|
"close",
|
|
/**
|
|
* 组件被点击时触发
|
|
*/
|
|
"click"
|
|
])
|
|
|
|
export type xAlertPropsType = {
|
|
/**
|
|
* 类型
|
|
* warn:警告
|
|
* success:成功
|
|
* error:错误
|
|
* info:信息
|
|
* primary:正常主题
|
|
*/
|
|
status: xAlertStatusType,
|
|
/**
|
|
* 警告图标,不填写取status默认图标
|
|
* 填写以填写为准
|
|
*/
|
|
icon: string,
|
|
/**
|
|
* 警告图标大小
|
|
*/
|
|
iconSize: string,
|
|
/**
|
|
* 关闭图标
|
|
*/
|
|
closeIcon: string,
|
|
/**
|
|
* 显示还是隐藏关闭按钮
|
|
*/
|
|
showClose: boolean,
|
|
/**
|
|
* 文字大小
|
|
*/
|
|
fontSize: string,
|
|
/**
|
|
* 主题色,如果不填写以status为准
|
|
*/
|
|
color: string,
|
|
/**
|
|
* 文字颜色,如果不填写以status为准
|
|
*/
|
|
fontColor: string,
|
|
/**
|
|
* 暗黑主题颜色,如果不填写自动计算
|
|
*/
|
|
darkColor: string,
|
|
/**
|
|
* 暗黑文字颜色,如果不填写自动计算
|
|
*/
|
|
fontDarkColor: string,
|
|
/**
|
|
* 它是建立在你没有提供color时才有效。
|
|
* 如果提供了color是以你color为背景最终色。
|
|
* thin浅色模式,
|
|
* normal标准背景色
|
|
*/
|
|
skin: string,
|
|
/**
|
|
* 圆角
|
|
* 数组数字时
|
|
* [全部]
|
|
* [顶左,顶右,底右,底左]
|
|
* [顶左,底右]
|
|
* [顶左,顶右,底右]
|
|
* 空数组时取全局值
|
|
*/
|
|
round: string[],
|
|
/**
|
|
* 边线
|
|
* 数组数字时
|
|
* 数组数字时
|
|
* [全部]
|
|
* [左,上,右,下]
|
|
* [左右,上下]
|
|
* [左,上,右]
|
|
* 空数组时取全局值
|
|
*/
|
|
border: string[],
|
|
/**
|
|
* 边框颜色
|
|
* 格式同border边线。
|
|
* 空数组时取全局值
|
|
*/
|
|
borderColor: string[],
|
|
/**
|
|
* 如果不填写,自动计算
|
|
*/
|
|
darkBorderColor: string[],
|
|
/**
|
|
* 边线类型,默认solid,可以为none
|
|
*/
|
|
borderStyle: string,
|
|
/**
|
|
* 间隙[x]全部,[x,x]左右,上下,[x,x,x]左上右,[x,x,x,x]左上右下
|
|
* 空数组时取全局值
|
|
*/
|
|
margin: string[],
|
|
/**
|
|
* 内间隙[x]全部,[x,x]左右,上下,[x,x,x]左上右,[x,x,x,x]左上右下
|
|
* 空数组时取全局值
|
|
*/
|
|
padding: string[],
|
|
/**
|
|
* 自定义高度,可以是数字,单位或者百分比,auto
|
|
*/
|
|
height: string,
|
|
/**
|
|
* 宽,单位合法即可数字,字符串带单位,百分比,auto
|
|
*/
|
|
width: string
|
|
}
|
|
|
|
const props = withDefaults(defineProps<xAlertPropsType>(), {
|
|
status: "primary",
|
|
icon: "",
|
|
iconSize: "20",
|
|
closeIcon: "close-line",
|
|
showClose: true,
|
|
fontSize: "15",
|
|
color: "",
|
|
fontColor: "",
|
|
darkColor: "",
|
|
fontDarkColor: "",
|
|
skin: "thin",
|
|
round:():string[] => [] as string[],
|
|
border: ():string[] => [] as string[],
|
|
borderColor: ():string[] => [] as string[],
|
|
darkBorderColor: ():string[] => [] as string[],
|
|
borderStyle: 'solid',
|
|
margin: ():string[] => ['16', '0', '16', '16'] as string[],
|
|
padding: ():string[] => ['16', '12'] as string[],
|
|
height: "auto",
|
|
width: "auto"
|
|
})
|
|
|
|
// 响应式数据
|
|
const showAlert = ref(true)
|
|
|
|
// 计算属性
|
|
const _color = computed((): string => {
|
|
let tcolor = props.color;
|
|
if (tcolor == '') {
|
|
tcolor = props.status;
|
|
}
|
|
if (xConfig.dark == 'dark' && props.darkColor != '') {
|
|
tcolor = props.darkColor
|
|
}
|
|
let color = getDefaultColor(tcolor)
|
|
return color;
|
|
})
|
|
|
|
const _fontColor = computed((): string => {
|
|
let tcolor = props.fontColor;
|
|
if (xConfig.dark == 'dark' && props.fontDarkColor != '') {
|
|
tcolor = props.fontDarkColor
|
|
}
|
|
return tcolor;
|
|
})
|
|
|
|
const _isDark = computed((): boolean => xConfig.dark == 'dark')
|
|
const _showClose = computed((): boolean => props.showClose)
|
|
|
|
const _fontSize = computed((): string => {
|
|
let fontSize = checkIsCssUnit(props.fontSize, xConfig.unit);
|
|
if (xConfig.fontScale == 1) return fontSize;
|
|
let sizeNumber = parseInt(fontSize)
|
|
if (isNaN(sizeNumber)) {
|
|
sizeNumber = 16
|
|
}
|
|
return (sizeNumber * xConfig.fontScale).toString() + getUnit(fontSize)
|
|
})
|
|
|
|
const _margin = computed((): string => {
|
|
if (props.margin.length == 0) {
|
|
let par = fillArrayCssValue(xConfig.sheetMargin)
|
|
if (par.length == 0) return "0px 0px 0px 0px";
|
|
return par.join(" ")
|
|
}
|
|
let ar: string[] = fillArrayCssValue(props.margin as string[])
|
|
if (ar.length == 0) return "0px 0px 0px 0px";
|
|
return ar.join(" ")
|
|
})
|
|
|
|
const _padding = computed((): string => {
|
|
if (props.padding.length == 0) {
|
|
let par = fillArrayCssValue(xConfig.sheetMargin)
|
|
if (par.length == 0) return "0px 0px 0px 0px";
|
|
return par.join(" ")
|
|
}
|
|
let ar: string[] = fillArrayCssValue(props.padding as string[])
|
|
if (ar.length == 0) return "0px 0px 0px 0px";
|
|
return ar.join(" ")
|
|
})
|
|
|
|
const _round = computed((): string => {
|
|
if (props.round.length == 0) {
|
|
let par = fillArrayCssValueByround(xConfig.sheetRadius)
|
|
if (par.length == 0) return "0px 0px 0px 0px";
|
|
return par.join(" ")
|
|
}
|
|
let ar: string[] = fillArrayCssValueByround(props.round as string[])
|
|
if (ar.length == 0) return "0px 0px 0px 0px";
|
|
return ar.join(" ")
|
|
})
|
|
|
|
const _border = computed((): string => {
|
|
let ar: string[] = fillArrayCssValue(props.border as string[])
|
|
if (ar.length == 0) return "0px 0px 0px 0px";
|
|
return ar.join(" ")
|
|
})
|
|
|
|
const _borderColor = computed((): string => {
|
|
let bordercolor = props.borderColor as string[];
|
|
if (xConfig.dark == 'dark') {
|
|
bordercolor = props.darkBorderColor.length == 0 ? xConfig.sheetDarkBorderColor : props.darkBorderColor
|
|
}
|
|
let ar: string[] = fillArrayCssValueBycolor(bordercolor as string[])
|
|
if (ar.length == 0) return "transparent transparent transparent transparent";
|
|
return ar.join(" ")
|
|
})
|
|
|
|
const _iconName = computed((): string => {
|
|
const iconsmap = new Map<string, string>([
|
|
['warn', 'alert-line'],
|
|
['success', 'check-double-line'],
|
|
['error', 'close-circle-line'],
|
|
['info', 'information-2-line'],
|
|
['primary', 'notification-line'],
|
|
])
|
|
let dicon = iconsmap.get(props.status)
|
|
return props.icon == '' ? (dicon == null ? '' : dicon!) : props.icon
|
|
})
|
|
|
|
const _styleMap = computed((): styleMapType => {
|
|
let bgStylemap = new Map<string, any>()
|
|
let textStylemap = new Map<string, any>()
|
|
let colorObj = getDefaultColorObj(_color.value, _color.value)
|
|
|
|
if (props.skin == 'thin') {
|
|
colorObj = getThinColorObj(_color.value, _color.value, _isDark.value)
|
|
}
|
|
let defaultObj: UTSJSONObject = colorObj.getJSON("default")!
|
|
bgStylemap.set("backgroundColor", defaultObj.getString("background")!)
|
|
bgStylemap.set("margin", _margin.value)
|
|
bgStylemap.set("padding", _padding.value)
|
|
bgStylemap.set("border-radius", _round.value)
|
|
bgStylemap.set("border-width", _border.value)
|
|
bgStylemap.set("height", checkIsCssUnit(props.height, xConfig.unit))
|
|
bgStylemap.set("width", checkIsCssUnit(props.width, xConfig.unit))
|
|
|
|
bgStylemap.set("border-style", props.borderStyle)
|
|
if (props.borderColor.length > 0) {
|
|
bgStylemap.set("border-color", _borderColor.value)
|
|
} else {
|
|
bgStylemap.set("border-color", getDefaultColor(_color.value))
|
|
}
|
|
|
|
if (_fontColor.value == '') {
|
|
textStylemap.set("color", defaultObj.getString("fontColor")!)
|
|
} else {
|
|
textStylemap.set("color", _fontColor.value)
|
|
}
|
|
textStylemap.set("font-size", _fontSize.value)
|
|
return {
|
|
bgStyle: bgStylemap,
|
|
textStyle: textStylemap
|
|
} as styleMapType;
|
|
})
|
|
|
|
// 方法
|
|
function closeAlert(): void {
|
|
emits('close')
|
|
showAlert.value = false
|
|
}
|
|
|
|
function onclickbar(): void {
|
|
emits('click')
|
|
}
|
|
|
|
</script>
|
|
|
|
<style>
|
|
.xAlert {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
|
|
}
|
|
|
|
.xAlertContent {
|
|
flex: 1;
|
|
}
|
|
|
|
.xAlertLeft {
|
|
margin-right: 8rpx;
|
|
}
|
|
|
|
.xAlertLeft {
|
|
flex-shrink: 0;
|
|
padding-right: 6px;
|
|
}
|
|
|
|
.xAlertRight {
|
|
flex-shrink: 0;
|
|
padding-left: 20px;
|
|
}
|
|
</style> |