naive-ui
Version:
A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast
248 lines (247 loc) • 11.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vdirs_1 = require("vdirs");
const vue_1 = require("vue");
const vueuc_1 = require("vueuc");
const _internal_1 = require("../../_internal");
const _utils_1 = require("../../_utils");
const card_1 = require("../../card");
const Card_1 = require("../../card/src/Card");
const Dialog_1 = require("../../dialog/src/Dialog");
const dialogProps_1 = require("../../dialog/src/dialogProps");
const interface_1 = require("../../drawer/src/interface");
const interface_2 = require("../../popover/src/interface");
const composables_1 = require("./composables");
const interface_3 = require("./interface");
const presetProps_1 = require("./presetProps");
exports.default = (0, vue_1.defineComponent)({
name: 'ModalBody',
inheritAttrs: false,
slots: Object,
props: Object.assign(Object.assign({ show: {
type: Boolean,
required: true
}, preset: String, displayDirective: {
type: String,
required: true
}, trapFocus: {
type: Boolean,
default: true
}, autoFocus: {
type: Boolean,
default: true
}, blockScroll: Boolean, draggable: {
type: [Boolean, Object],
default: false
} }, presetProps_1.presetProps), { renderMask: Function,
// events
onClickoutside: Function, onBeforeLeave: {
type: Function,
required: true
}, onAfterLeave: {
type: Function,
required: true
}, onPositiveClick: {
type: Function,
required: true
}, onNegativeClick: {
type: Function,
required: true
}, onClose: {
type: Function,
required: true
}, onAfterEnter: Function, onEsc: Function }),
setup(props) {
const bodyRef = (0, vue_1.ref)(null);
const scrollbarRef = (0, vue_1.ref)(null);
const displayedRef = (0, vue_1.ref)(props.show);
const transformOriginXRef = (0, vue_1.ref)(null);
const transformOriginYRef = (0, vue_1.ref)(null);
const NModal = (0, vue_1.inject)(interface_3.modalInjectionKey);
let mousePosition = null;
(0, vue_1.watch)((0, vue_1.toRef)(props, 'show'), (value) => {
if (value) {
mousePosition = NModal.getMousePosition();
}
}, {
immediate: true
});
const { stopDrag, startDrag, draggableRef, draggableClassRef } = (0, composables_1.useDragModal)((0, vue_1.toRef)(props, 'draggable'), {
onEnd: (el) => {
syncTransformOrigin(el);
}
});
const dialogTitleClassRef = (0, vue_1.computed)(() => {
return (0, vue_1.normalizeClass)([props.titleClass, draggableClassRef.value]);
});
const cardHeaderClassRef = (0, vue_1.computed)(() => {
return (0, vue_1.normalizeClass)([props.headerClass, draggableClassRef.value]);
});
(0, vue_1.watch)((0, vue_1.toRef)(props, 'show'), (value) => {
if (value)
displayedRef.value = true;
});
(0, _utils_1.useLockHtmlScroll)((0, vue_1.computed)(() => props.blockScroll && displayedRef.value));
function styleTransformOrigin() {
if (NModal.transformOriginRef.value === 'center') {
return '';
}
const { value: transformOriginX } = transformOriginXRef;
const { value: transformOriginY } = transformOriginYRef;
if (transformOriginX === null || transformOriginY === null) {
return '';
}
else if (scrollbarRef.value) {
const scrollTop = scrollbarRef.value.containerScrollTop;
return `${transformOriginX}px ${transformOriginY + scrollTop}px`;
}
return '';
}
function syncTransformOrigin(el) {
if (NModal.transformOriginRef.value === 'center') {
return;
}
if (!mousePosition) {
return;
}
if (!scrollbarRef.value)
return;
const scrollTop = scrollbarRef.value.containerScrollTop;
const { offsetLeft, offsetTop } = el;
const top = mousePosition.y;
const left = mousePosition.x;
transformOriginXRef.value = -(offsetLeft - left);
transformOriginYRef.value = -(offsetTop - top - scrollTop);
el.style.transformOrigin = styleTransformOrigin();
}
function handleEnter(el) {
void (0, vue_1.nextTick)(() => {
syncTransformOrigin(el);
});
}
function handleBeforeLeave(el) {
el.style.transformOrigin = styleTransformOrigin();
props.onBeforeLeave();
}
function handleAfterEnter(el) {
const element = el;
draggableRef.value && startDrag(element);
props.onAfterEnter && props.onAfterEnter(element);
}
function handleAfterLeave() {
displayedRef.value = false;
transformOriginXRef.value = null;
transformOriginYRef.value = null;
stopDrag();
props.onAfterLeave();
}
function handleCloseClick() {
const { onClose } = props;
if (onClose) {
onClose();
}
}
function handleNegativeClick() {
props.onNegativeClick();
}
function handlePositiveClick() {
props.onPositiveClick();
}
const childNodeRef = (0, vue_1.ref)(null);
(0, vue_1.watch)(childNodeRef, (node) => {
if (node) {
void (0, vue_1.nextTick)(() => {
const el = node.el;
if (el && bodyRef.value !== el) {
bodyRef.value = el;
}
});
}
});
(0, vue_1.provide)(interface_3.modalBodyInjectionKey, bodyRef);
(0, vue_1.provide)(interface_1.drawerBodyInjectionKey, null);
(0, vue_1.provide)(interface_2.popoverBodyInjectionKey, null);
return {
mergedTheme: NModal.mergedThemeRef,
appear: NModal.appearRef,
isMounted: NModal.isMountedRef,
mergedClsPrefix: NModal.mergedClsPrefixRef,
bodyRef,
scrollbarRef,
draggableClass: draggableClassRef,
displayed: displayedRef,
childNodeRef,
cardHeaderClass: cardHeaderClassRef,
dialogTitleClass: dialogTitleClassRef,
handlePositiveClick,
handleNegativeClick,
handleCloseClick,
handleAfterEnter,
handleAfterLeave,
handleBeforeLeave,
handleEnter
};
},
render() {
const { $slots, $attrs, handleEnter, handleAfterEnter, handleAfterLeave, handleBeforeLeave, preset, mergedClsPrefix } = this;
let childNode = null;
if (!preset) {
childNode = (0, _utils_1.getFirstSlotVNodeWithTypedProps)('default', $slots.default, {
draggableClass: this.draggableClass
});
if (!childNode) {
(0, _utils_1.warn)('modal', 'default slot is empty');
return;
}
childNode = (0, vue_1.cloneVNode)(childNode);
childNode.props = (0, vue_1.mergeProps)({
class: `${mergedClsPrefix}-modal`
}, $attrs, childNode.props || {});
}
return this.displayDirective === 'show' || this.displayed || this.show
? (0, vue_1.withDirectives)((0, vue_1.h)("div", { role: "none", class: `${mergedClsPrefix}-modal-body-wrapper` },
(0, vue_1.h)(_internal_1.NScrollbar, { ref: "scrollbarRef", theme: this.mergedTheme.peers.Scrollbar, themeOverrides: this.mergedTheme.peerOverrides.Scrollbar, contentClass: `${mergedClsPrefix}-modal-scroll-content` }, {
default: () => {
var _a;
return [
(_a = this.renderMask) === null || _a === void 0 ? void 0 : _a.call(this),
(0, vue_1.h)(vueuc_1.VFocusTrap, { disabled: !this.trapFocus, active: this.show, onEsc: this.onEsc, autoFocus: this.autoFocus }, {
default: () => {
var _a;
return ((0, vue_1.h)(vue_1.Transition, { name: "fade-in-scale-up-transition", appear: (_a = this.appear) !== null && _a !== void 0 ? _a : this.isMounted, onEnter: handleEnter, onAfterEnter: handleAfterEnter, onAfterLeave: handleAfterLeave, onBeforeLeave: handleBeforeLeave }, {
default: () => {
const dirs = [
[vue_1.vShow, this.show]
];
const { onClickoutside } = this;
if (onClickoutside) {
dirs.push([
vdirs_1.clickoutside,
this.onClickoutside,
undefined,
{ capture: true }
]);
}
return (0, vue_1.withDirectives)((this.preset === 'confirm'
|| this.preset === 'dialog' ? ((0, vue_1.h)(Dialog_1.NDialog, Object.assign({}, this.$attrs, { class: [
`${mergedClsPrefix}-modal`,
this.$attrs.class
], ref: "bodyRef", theme: this.mergedTheme.peers.Dialog, themeOverrides: this.mergedTheme.peerOverrides.Dialog }, (0, _utils_1.keep)(this.$props, dialogProps_1.dialogPropKeys), { titleClass: this.dialogTitleClass, "aria-modal": "true" }), $slots)) : this.preset === 'card' ? ((0, vue_1.h)(card_1.NCard, Object.assign({}, this.$attrs, { ref: "bodyRef", class: [
`${mergedClsPrefix}-modal`,
this.$attrs.class
], theme: this.mergedTheme.peers.Card, themeOverrides: this.mergedTheme.peerOverrides.Card }, (0, _utils_1.keep)(this.$props, Card_1.cardBasePropKeys), { headerClass: this.cardHeaderClass, "aria-modal": "true", role: "dialog" }), $slots)) : ((this.childNodeRef = childNode))), dirs);
}
}));
}
})
];
}
})), [
[
vue_1.vShow,
this.displayDirective === 'if' || this.displayed || this.show
]
])
: null;
}
});