UNPKG

vui-design

Version:

A high quality UI Toolkit based on Vue.js

151 lines (135 loc) 3.94 kB
import VuiIcon from "../icon"; import PropTypes from "../../utils/prop-types"; import getClassNamePrefix from "../../utils/getClassNamePrefix"; const mapIconTypes = { info: "info", warning: "warning", success: "checkmark-circle", error: "crossmark-circle" }; export const createProps = () => { return { classNamePrefix: PropTypes.string, type: PropTypes.oneOf(["info", "warning", "success", "error"]).def("info"), icon: PropTypes.string, message: PropTypes.string, description: PropTypes.string, showIcon: PropTypes.bool.def(false), banner: PropTypes.bool.def(false), closable: PropTypes.bool.def(false), closeText: PropTypes.string, animation: PropTypes.string.def("vui-alert-slide-up") }; }; export default { name: "vui-alert", components: { VuiIcon }, props: createProps(), data() { const state = { closing: false, closed: false }; return { state }; }, methods: { handleClose(e) { e.preventDefault(); let element = this.$el; element.style.height = `${element.offsetHeight}px`; // 重复一次才能正确设置 height 高度,why? element.style.height = `${element.offsetHeight}px`; this.state.closing = true; this.$emit("close", e); }, handleAfterLeave() { this.state.closing = false; this.state.closed = true; this.$emit("afterClose"); } }, render() { const { $slots: slots, $props: props, state } = this; const { handleClose, handleAfterLeave } = this; const message = slots.default || slots.message || props.message; const description = slots.description || props.description; const closeText = slots.closeText || props.closeText; if (state.closed) { return null; } else { let icon; if (props.showIcon) { if (slots.icon) { icon = slots.icon; } else if (props.icon) { icon = ( <VuiIcon type={props.icon} /> ); } else { let iconType = mapIconTypes[props.type]; if (!description) { iconType = iconType + "-filled"; } icon = ( <VuiIcon type={iconType} /> ); } } let btnClose; if (props.closable) { if (closeText) { btnClose = closeText; } else { btnClose = ( <VuiIcon type="crossmark" /> ); } } const classNamePrefix = getClassNamePrefix(props.classNamePrefix, "alert"); let classes = {}; classes.el = { [`${classNamePrefix}`]: true, [`${classNamePrefix}-${props.type}`]: props.type, [`${classNamePrefix}-banner`]: props.banner, [`${classNamePrefix}-with-icon`]: icon, [`${classNamePrefix}-with-description`]: description, [`${classNamePrefix}-closable`]: btnClose, [`${classNamePrefix}-closing`]: state.closing }; classes.elIcon = `${classNamePrefix}-icon`; classes.elMessage = `${classNamePrefix}-message`; classes.elDescription = `${classNamePrefix}-description`; classes.elBtnClose = `${classNamePrefix}-btn-close`; return ( <transition name={props.animation} onAfterLeave={handleAfterLeave}> <div v-show={!state.closing} class={classes.el}> { icon && ( <div class={classes.elIcon}>{icon}</div> ) } <div class={classes.elMessage}>{message}</div> { description && ( <div class={classes.elDescription}>{description}</div> ) } { btnClose && ( <div class={classes.elBtnClose} onClick={handleClose}>{btnClose}</div> ) } </div> </transition> ); } } };