taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
147 lines (146 loc) • 4.15 kB
JavaScript
import {h, defineComponent, nextTick, computed, reactive, watch} from "vue";
import {Image, Text, View} from "@tarojs/components";
import statusImg from "./img.js";
const AtToast = defineComponent({
name: "AtToast",
props: {
isOpened: {type: Boolean, default: false},
text: {type: String, default: ""},
icon: {type: String, default: ""},
image: {type: String, default: ""},
status: {
type: String,
default: "",
validator: (val) => ["", "error", "loading", "success"].includes(val)
},
duration: {type: Number, default: 3e3},
hasMask: Boolean,
onClick: Function,
onClose: Function
},
setup(props, {attrs}) {
const state = reactive({
_timer: null,
_isOpened: props.isOpened
});
if (props.isOpened) {
makeTimer(props.duration || 0);
}
const realImg = computed(() => props.image || statusImg[props.status] || null);
const isRenderIcon = computed(() => !!(props.icon && !(props.image || statusImg[props.status])));
const rootClasses = computed(() => ({
"at-toast": true,
[`${attrs.class}`]: Boolean(attrs.class)
}));
const bodyClasses = computed(() => ({
"toast-body": true,
"at-toast__body--custom-image": props.image,
"toast-body--text": !realImg.value && !props.icon,
[`at-toast__body--${props.status}`]: !!props.status
}));
const iconClasses = computed(() => ({
"at-icon": true,
[`at-icon-${props.icon}`]: props.icon
}));
watch(() => [
props.isOpened,
props.duration
], ([isOpened, duration]) => {
if (!isOpened) {
close();
return;
}
if (!state._isOpened) {
state._isOpened = true;
} else {
clearTimer();
}
makeTimer(duration || 0);
});
function clearTimer() {
if (state._timer) {
clearTimeout(state._timer);
state._timer = null;
}
}
function makeTimer(duration) {
if (duration === 0)
return;
state._timer = setTimeout(() => {
close();
}, +duration);
}
function close() {
if (state._isOpened) {
state._isOpened = false;
nextTick(handleClose);
clearTimer();
}
}
function handleClose(e) {
if (typeof props.onClose === "function") {
props.onClose(e);
}
}
function handleClick(e) {
if (props.status === "loading")
return;
if (typeof props.onClick === "function") {
props.onClick(e);
}
close();
}
return () => {
return state._isOpened && h(View, {
class: rootClasses.value
}, {
default: () => [
props.hasMask && h(View, {class: "at-toast__overlay"}),
h(View, {
class: bodyClasses.value,
style: attrs.style,
onTap: handleClick
}, {
default: () => [
h(View, {
class: "toast-body-content"
}, {
default: () => [
realImg.value && h(View, {
class: "toast-body-content__img"
}, {
default: () => [
h(Image, {
class: "toast-body-content__img-item",
src: realImg.value,
mode: "scaleToFill"
})
]
}),
isRenderIcon.value && h(View, {
class: "toast-body-content__icon"
}, {
default: () => [
h(Text, {class: iconClasses.value})
]
}),
props.text && h(View, {
class: "toast-body-content__info"
}, {
default: () => [
h(Text, null, {default: () => props.text})
]
})
]
})
]
})
]
});
};
}
});
var toast_default = AtToast;
export {
toast_default as default
};