UNPKG

@fesjs/fes-design

Version:
189 lines (186 loc) 7.39 kB
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 };