2025-02-28 19:43:11 +08:00

202 lines
7.1 KiB
JavaScript

import { h, ref, computed, defineComponent, mergeProps, watchEffect } from 'vue';
import { getMargin } from 'seemly';
import { InfoIcon, SuccessIcon, WarningIcon, ErrorIcon } from "../../_internal/icons/index.mjs";
import { NFadeInExpandTransition, NBaseClose, NBaseIcon } from "../../_internal/index.mjs";
import { useRtl } from "../../_mixins/use-rtl.mjs";
import { useConfig, useTheme, useThemeClass } from "../../_mixins/index.mjs";
import { createKey, resolveSlot, resolveWrappedSlot, warnOnce } from "../../_utils/index.mjs";
import { alertLight } from "../styles/index.mjs";
import style from "./styles/index.cssr.mjs";
export const alertProps = Object.assign(Object.assign({}, useTheme.props), {
title: String,
showIcon: {
type: Boolean,
default: true
},
type: {
type: String,
default: 'default'
},
bordered: {
type: Boolean,
default: true
},
closable: Boolean,
onClose: Function,
onAfterLeave: Function,
/** @deprecated */
onAfterHide: Function
});
export default defineComponent({
name: 'Alert',
inheritAttrs: false,
props: alertProps,
setup(props) {
if (process.env.NODE_ENV !== 'production') {
watchEffect(() => {
if (props.onAfterHide !== undefined) {
warnOnce('alert', '`on-after-hide` is deprecated, please use `on-after-leave` instead.');
}
});
}
const {
mergedClsPrefixRef,
mergedBorderedRef,
inlineThemeDisabled,
mergedRtlRef
} = useConfig(props);
const themeRef = useTheme('Alert', '-alert', style, alertLight, props, mergedClsPrefixRef);
const rtlEnabledRef = useRtl('Alert', mergedRtlRef, mergedClsPrefixRef);
const cssVarsRef = computed(() => {
const {
common: {
cubicBezierEaseInOut
},
self
} = themeRef.value;
const {
fontSize,
borderRadius,
titleFontWeight,
lineHeight,
iconSize,
iconMargin,
iconMarginRtl,
closeIconSize,
closeBorderRadius,
closeSize,
closeMargin,
closeMarginRtl,
padding
} = self;
const {
type
} = props;
const {
left,
right
} = getMargin(iconMargin);
return {
'--n-bezier': cubicBezierEaseInOut,
'--n-color': self[createKey('color', type)],
'--n-close-icon-size': closeIconSize,
'--n-close-border-radius': closeBorderRadius,
'--n-close-color-hover': self[createKey('closeColorHover', type)],
'--n-close-color-pressed': self[createKey('closeColorPressed', type)],
'--n-close-icon-color': self[createKey('closeIconColor', type)],
'--n-close-icon-color-hover': self[createKey('closeIconColorHover', type)],
'--n-close-icon-color-pressed': self[createKey('closeIconColorPressed', type)],
'--n-icon-color': self[createKey('iconColor', type)],
'--n-border': self[createKey('border', type)],
'--n-title-text-color': self[createKey('titleTextColor', type)],
'--n-content-text-color': self[createKey('contentTextColor', type)],
'--n-line-height': lineHeight,
'--n-border-radius': borderRadius,
'--n-font-size': fontSize,
'--n-title-font-weight': titleFontWeight,
'--n-icon-size': iconSize,
'--n-icon-margin': iconMargin,
'--n-icon-margin-rtl': iconMarginRtl,
'--n-close-size': closeSize,
'--n-close-margin': closeMargin,
'--n-close-margin-rtl': closeMarginRtl,
'--n-padding': padding,
'--n-icon-margin-left': left,
'--n-icon-margin-right': right
};
});
const themeClassHandle = inlineThemeDisabled ? useThemeClass('alert', computed(() => {
return props.type[0];
}), cssVarsRef, props) : undefined;
const visibleRef = ref(true);
const doAfterLeave = () => {
const {
onAfterLeave,
onAfterHide // deprecated
} = props;
if (onAfterLeave) onAfterLeave();
if (onAfterHide) onAfterHide();
};
const handleCloseClick = () => {
var _a;
void Promise.resolve((_a = props.onClose) === null || _a === void 0 ? void 0 : _a.call(props)).then(result => {
if (result === false) return;
visibleRef.value = false;
});
};
const handleAfterLeave = () => {
doAfterLeave();
};
return {
rtlEnabled: rtlEnabledRef,
mergedClsPrefix: mergedClsPrefixRef,
mergedBordered: mergedBorderedRef,
visible: visibleRef,
handleCloseClick,
handleAfterLeave,
mergedTheme: themeRef,
cssVars: inlineThemeDisabled ? undefined : cssVarsRef,
themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass,
onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender
};
},
render() {
var _a;
(_a = this.onRender) === null || _a === void 0 ? void 0 : _a.call(this);
return h(NFadeInExpandTransition, {
onAfterLeave: this.handleAfterLeave
}, {
default: () => {
const {
mergedClsPrefix,
$slots
} = this;
const attrs = {
class: [`${mergedClsPrefix}-alert`, this.themeClass, this.closable && `${mergedClsPrefix}-alert--closable`, this.showIcon && `${mergedClsPrefix}-alert--show-icon`,
// fix: https://github.com/tusen-ai/naive-ui/issues/4588
!this.title && this.closable && `${mergedClsPrefix}-alert--right-adjust`, this.rtlEnabled && `${mergedClsPrefix}-alert--rtl`],
style: this.cssVars,
role: 'alert'
};
return this.visible ?
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
h("div", Object.assign({}, mergeProps(this.$attrs, attrs)), this.closable && h(NBaseClose, {
clsPrefix: mergedClsPrefix,
class: `${mergedClsPrefix}-alert__close`,
onClick: this.handleCloseClick
}), this.bordered && h("div", {
class: `${mergedClsPrefix}-alert__border`
}), this.showIcon && h("div", {
class: `${mergedClsPrefix}-alert__icon`,
"aria-hidden": "true"
}, resolveSlot($slots.icon, () => [h(NBaseIcon, {
clsPrefix: mergedClsPrefix
}, {
default: () => {
switch (this.type) {
case 'success':
return h(SuccessIcon, null);
case 'info':
return h(InfoIcon, null);
case 'warning':
return h(WarningIcon, null);
case 'error':
return h(ErrorIcon, null);
default:
return null;
}
}
})])), h("div", {
class: [`${mergedClsPrefix}-alert-body`, this.mergedBordered && `${mergedClsPrefix}-alert-body--bordered`]
}, resolveWrappedSlot($slots.header, children => {
const mergedChildren = children || this.title;
return mergedChildren ? h("div", {
class: `${mergedClsPrefix}-alert-body__title`
}, mergedChildren) : null;
}), $slots.default && h("div", {
class: `${mergedClsPrefix}-alert-body__content`
}, $slots))) : null;
}
});
}
});