@fesjs/fes-design
Version:
fes-design for PC
189 lines (186 loc) • 7.39 kB
JavaScript
import { defineComponent, ref, watch, nextTick, computed, createVNode, Teleport, Transition, withDirectives, vShow, Fragment } from 'vue';
import { isNumber } from 'lodash-es';
import FButton from '../button';
import FScrollbar from '../scrollbar';
import { CloseOutlined } from '../icon';
import PopupManager from '../_util/popupManager';
import useLockScreen from '../_util/use/useLockScreen';
import { useConfig } from '../config-provider';
import { useTheme } from '../_theme/useTheme';
import { pxfy } from '../_util/utils';
import useEsc from '../_util/use/useEsc';
import { useLocale } from '../config-provider/useLocale';
import { useResizable } from './useResizable';
import { COMPONENT_NAME, prefixCls } from './const';
import { drawerProps, UPDATE_SHOW_EVENT, OK_EVENT, CANCEL_EVENT, AFTER_ENTER_EVENT, AFTER_LEAVE_EVENT } from './props';
import { useDrawerDimension } from './useDimension';
const Drawer = defineComponent({
name: COMPONENT_NAME,
props: drawerProps,
emits: [UPDATE_SHOW_EVENT, OK_EVENT, CANCEL_EVENT, AFTER_ENTER_EVENT, AFTER_LEAVE_EVENT],
setup(props, ctx) {
useTheme();
const zIndex = ref(PopupManager.nextZIndex());
const visible = ref(false);
useLockScreen(visible);
watch(() => props.show, () => {
if (props.show) {
zIndex.value = PopupManager.nextZIndex();
}
nextTick(() => {
visible.value = props.show;
});
}, {
immediate: true
});
const config = useConfig();
const getContainer = computed(() => {
var _config$getContainer;
return props.getContainer || ((_config$getContainer = config.getContainer) === null || _config$getContainer === void 0 ? void 0 : _config$getContainer.value);
});
const {
t
} = useLocale();
function handleCancel(event) {
ctx.emit(UPDATE_SHOW_EVENT, false);
ctx.emit(CANCEL_EVENT, event);
}
const escClosable = computed(() => props.escClosable);
useEsc(handleCancel, escClosable);
function handleOk(event) {
ctx.emit(OK_EVENT, event);
}
function handleTransitionAfterEnter(el) {
ctx.emit(AFTER_ENTER_EVENT, el);
}
function handleTransitionAfterLeave(el) {
ctx.emit(AFTER_LEAVE_EVENT, el);
}
const hasHeader = () => ctx.slots.title || props.title;
function getHeader() {
var _ctx$slots$title, _ctx$slots;
const closeJsx = props.closable && createVNode("div", {
"class": `${prefixCls}-close`,
"onClick": handleCancel
}, [createVNode(CloseOutlined, null, null)]);
if (!hasHeader()) {
return closeJsx;
}
const header = ((_ctx$slots$title = (_ctx$slots = ctx.slots).title) === null || _ctx$slots$title === void 0 ? void 0 : _ctx$slots$title.call(_ctx$slots)) || props.title;
return createVNode("div", {
"class": `${prefixCls}-header`
}, [header, closeJsx]);
}
function getFooter() {
if (!props.footer) {
return null;
}
let footer;
if (ctx.slots.footer) {
footer = ctx.slots.footer();
} else {
footer = createVNode(Fragment, null, [createVNode(FButton, {
"type": "primary",
"class": "btn-margin",
"size": "middle",
"onClick": handleOk,
"loading": props.okLoading
}, {
default: () => [props.okText || t('drawer.okText')]
}), props.showCancel && createVNode(FButton, {
"size": "middle",
"onClick": handleCancel
}, {
default: () => [props.cancelText || t('drawer.cancelText')]
})]);
}
return createVNode("div", {
"class": {
[`${prefixCls}-footer`]: true,
[`${prefixCls}-footer-has-border`]: props.footerBorder
}
}, [footer]);
}
const drawerDimension = useDrawerDimension(props);
const styles = computed(() => {
const sizeStyle = {
width: '100%',
height: '100%'
};
const dimensionKey = ['top', 'bottom'].includes(props.placement) ? 'height' : 'width';
sizeStyle[dimensionKey] = isNumber(drawerDimension.value) ? pxfy(drawerDimension.value) : drawerDimension.value;
return sizeStyle;
});
const {
onMousedown,
drawerRef,
dragClass
} = useResizable({
props,
drawerDimension
});
const showDom = computed(() => props.displayDirective === 'if' && visible.value || props.displayDirective === 'show');
const wrapperClass = computed(() => {
return [`${prefixCls}-wrapper`, props.contentClass].filter(Boolean);
});
const rootClass = computed(() => {
return [prefixCls, `${prefixCls}-${props.placement}`, props.wrapperClass].filter(Boolean);
});
return () => {
var _getContainer$value, _getContainer$value2, _ctx$slots$default, _ctx$slots2;
return createVNode(Teleport, {
"disabled": !((_getContainer$value = getContainer.value) !== null && _getContainer$value !== void 0 && _getContainer$value.call(getContainer)),
"to": (_getContainer$value2 = getContainer.value) === null || _getContainer$value2 === void 0 ? void 0 : _getContainer$value2.call(getContainer)
}, {
default: () => [createVNode("div", {
"class": rootClass.value
}, [createVNode(Transition, {
"name": `${prefixCls}-mask-fade`
}, {
default: () => [props.mask && showDom.value && withDirectives(createVNode("div", {
"class": `${prefixCls}-mask`,
"style": {
zIndex: zIndex.value
}
}, null), [[vShow, visible.value]])]
}), createVNode(Transition, {
"name": `${prefixCls}-fade`,
"onAfterEnter": handleTransitionAfterEnter,
"onAfterLeave": handleTransitionAfterLeave
}, {
default: () => [showDom.value && withDirectives(createVNode("div", {
"class": {
[`${prefixCls}-container`]: true,
// 没有蒙层时,该属性才生效
[`${prefixCls}-operable`]: !props.mask && props.operable,
[`${prefixCls}-mask-closable`]: props.mask && props.maskClosable,
[`${prefixCls}-no-header`]: !hasHeader(),
[`${prefixCls}-no-footer`]: !props.footer
},
"style": {
zIndex: zIndex.value
},
"onClick": event => props.maskClosable && props.mask && handleCancel(event)
}, [createVNode("div", {
"class": wrapperClass.value,
"ref": drawerRef,
"style": styles.value,
"onClick": event => event.stopPropagation()
}, [props.resizable && createVNode("div", {
"class": dragClass.value,
"onMousedown": onMousedown
}, [createVNode("div", {
"class": `${prefixCls}-drag-icon`
}, null)]), getHeader(), createVNode(FScrollbar, {
"class": `${prefixCls}-body-wrapper`,
"containerClass": `${prefixCls}-body-container`,
"always": true
}, {
default: () => [(_ctx$slots$default = (_ctx$slots2 = ctx.slots).default) === null || _ctx$slots$default === void 0 ? void 0 : _ctx$slots$default.call(_ctx$slots2)]
}), getFooter()])]), [[vShow, visible.value]])]
})])]
});
};
}
});
export { Drawer as default };