264 lines
12 KiB
JavaScript
264 lines
12 KiB
JavaScript
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
const vue_1 = require("vue");
|
||
|
const vueuc_1 = require("vueuc");
|
||
|
const vdirs_1 = require("vdirs");
|
||
|
const _mixins_1 = require("../../_mixins");
|
||
|
const interface_1 = require("../../popover/src/interface");
|
||
|
const interface_2 = require("../../modal/src/interface");
|
||
|
const _internal_1 = require("../../_internal");
|
||
|
const _utils_1 = require("../../_utils");
|
||
|
const interface_3 = require("./interface");
|
||
|
exports.default = (0, vue_1.defineComponent)({
|
||
|
name: 'NDrawerContent',
|
||
|
inheritAttrs: false,
|
||
|
props: {
|
||
|
blockScroll: Boolean,
|
||
|
show: {
|
||
|
type: Boolean,
|
||
|
default: undefined
|
||
|
},
|
||
|
displayDirective: {
|
||
|
type: String,
|
||
|
required: true
|
||
|
},
|
||
|
placement: {
|
||
|
type: String,
|
||
|
required: true
|
||
|
},
|
||
|
contentClass: String,
|
||
|
contentStyle: [Object, String],
|
||
|
nativeScrollbar: {
|
||
|
type: Boolean,
|
||
|
required: true
|
||
|
},
|
||
|
scrollbarProps: Object,
|
||
|
trapFocus: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
autoFocus: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
showMask: {
|
||
|
type: [Boolean, String],
|
||
|
required: true
|
||
|
},
|
||
|
maxWidth: Number,
|
||
|
maxHeight: Number,
|
||
|
minWidth: Number,
|
||
|
minHeight: Number,
|
||
|
resizable: Boolean,
|
||
|
onClickoutside: Function,
|
||
|
onAfterLeave: Function,
|
||
|
onAfterEnter: Function,
|
||
|
onEsc: Function
|
||
|
},
|
||
|
setup(props) {
|
||
|
const displayedRef = (0, vue_1.ref)(!!props.show);
|
||
|
const bodyRef = (0, vue_1.ref)(null); // used for detached content
|
||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||
|
const NDrawer = (0, vue_1.inject)(interface_3.drawerInjectionKey);
|
||
|
let startPosition = 0;
|
||
|
let memoizedBodyStyleCursor = '';
|
||
|
let hoverTimerId = null;
|
||
|
const isHoverOnResizeTriggerRef = (0, vue_1.ref)(false);
|
||
|
const isDraggingRef = (0, vue_1.ref)(false);
|
||
|
const isVertical = (0, vue_1.computed)(() => {
|
||
|
return props.placement === 'top' || props.placement === 'bottom';
|
||
|
});
|
||
|
const { mergedClsPrefixRef, mergedRtlRef } = (0, _mixins_1.useConfig)(props);
|
||
|
const rtlEnabledRef = (0, _mixins_1.useRtl)('Drawer', mergedRtlRef, mergedClsPrefixRef);
|
||
|
const handleMousedownResizeTrigger = (e) => {
|
||
|
isDraggingRef.value = true;
|
||
|
startPosition = isVertical.value ? e.clientY : e.clientX;
|
||
|
memoizedBodyStyleCursor = document.body.style.cursor;
|
||
|
document.body.style.cursor = isVertical.value ? 'ns-resize' : 'ew-resize';
|
||
|
document.body.addEventListener('mousemove', handleBodyMousemove);
|
||
|
document.body.addEventListener('mouseleave', handleBodyMouseleave);
|
||
|
document.body.addEventListener('mouseup', handleBodyMouseup);
|
||
|
};
|
||
|
const handleMouseenterResizeTrigger = () => {
|
||
|
if (hoverTimerId !== null) {
|
||
|
window.clearTimeout(hoverTimerId);
|
||
|
hoverTimerId = null;
|
||
|
}
|
||
|
if (isDraggingRef.value) {
|
||
|
isHoverOnResizeTriggerRef.value = true;
|
||
|
}
|
||
|
else {
|
||
|
hoverTimerId = window.setTimeout(() => {
|
||
|
isHoverOnResizeTriggerRef.value = true;
|
||
|
}, 300);
|
||
|
}
|
||
|
};
|
||
|
const handleMouseleaveResizeTrigger = () => {
|
||
|
if (hoverTimerId !== null) {
|
||
|
window.clearTimeout(hoverTimerId);
|
||
|
hoverTimerId = null;
|
||
|
}
|
||
|
isHoverOnResizeTriggerRef.value = false;
|
||
|
};
|
||
|
const { doUpdateHeight, doUpdateWidth } = NDrawer;
|
||
|
const regulateWidth = (size) => {
|
||
|
const { maxWidth } = props;
|
||
|
if (maxWidth && size > maxWidth)
|
||
|
return maxWidth;
|
||
|
const { minWidth } = props;
|
||
|
if (minWidth && size < minWidth)
|
||
|
return minWidth;
|
||
|
return size;
|
||
|
};
|
||
|
const regulateHeight = (size) => {
|
||
|
const { maxHeight } = props;
|
||
|
if (maxHeight && size > maxHeight)
|
||
|
return maxHeight;
|
||
|
const { minHeight } = props;
|
||
|
if (minHeight && size < minHeight)
|
||
|
return minHeight;
|
||
|
return size;
|
||
|
};
|
||
|
const handleBodyMousemove = (e) => {
|
||
|
var _a, _b;
|
||
|
if (isDraggingRef.value) {
|
||
|
if (isVertical.value) {
|
||
|
let height = ((_a = bodyRef.value) === null || _a === void 0 ? void 0 : _a.offsetHeight) || 0;
|
||
|
const increment = startPosition - e.clientY;
|
||
|
height += props.placement === 'bottom' ? increment : -increment;
|
||
|
height = regulateHeight(height);
|
||
|
doUpdateHeight(height);
|
||
|
startPosition = e.clientY;
|
||
|
}
|
||
|
else {
|
||
|
let width = ((_b = bodyRef.value) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0;
|
||
|
const increment = startPosition - e.clientX;
|
||
|
width += props.placement === 'right' ? increment : -increment;
|
||
|
width = regulateWidth(width);
|
||
|
doUpdateWidth(width);
|
||
|
startPosition = e.clientX;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
const handleBodyMouseup = () => {
|
||
|
if (isDraggingRef.value) {
|
||
|
startPosition = 0;
|
||
|
isDraggingRef.value = false;
|
||
|
document.body.style.cursor = memoizedBodyStyleCursor;
|
||
|
document.body.removeEventListener('mousemove', handleBodyMousemove);
|
||
|
document.body.removeEventListener('mouseup', handleBodyMouseup);
|
||
|
document.body.removeEventListener('mouseleave', handleBodyMouseleave);
|
||
|
}
|
||
|
};
|
||
|
const handleBodyMouseleave = handleBodyMouseup;
|
||
|
(0, vue_1.watchEffect)(() => {
|
||
|
if (props.show)
|
||
|
displayedRef.value = true;
|
||
|
});
|
||
|
(0, vue_1.watch)(() => props.show, (value) => {
|
||
|
if (!value) {
|
||
|
handleBodyMouseup();
|
||
|
}
|
||
|
});
|
||
|
(0, vue_1.onBeforeUnmount)(() => {
|
||
|
handleBodyMouseup();
|
||
|
});
|
||
|
const bodyDirectivesRef = (0, vue_1.computed)(() => {
|
||
|
const { show } = props;
|
||
|
const directives = [[vue_1.vShow, show]];
|
||
|
if (!props.showMask) {
|
||
|
directives.push([
|
||
|
vdirs_1.clickoutside,
|
||
|
props.onClickoutside,
|
||
|
undefined,
|
||
|
{ capture: true }
|
||
|
]);
|
||
|
}
|
||
|
return directives;
|
||
|
});
|
||
|
function handleAfterLeave() {
|
||
|
var _a;
|
||
|
displayedRef.value = false;
|
||
|
(_a = props.onAfterLeave) === null || _a === void 0 ? void 0 : _a.call(props);
|
||
|
}
|
||
|
(0, _utils_1.useLockHtmlScroll)((0, vue_1.computed)(() => props.blockScroll && displayedRef.value));
|
||
|
(0, vue_1.provide)(interface_3.drawerBodyInjectionKey, bodyRef);
|
||
|
(0, vue_1.provide)(interface_1.popoverBodyInjectionKey, null);
|
||
|
(0, vue_1.provide)(interface_2.modalBodyInjectionKey, null);
|
||
|
return {
|
||
|
bodyRef,
|
||
|
rtlEnabled: rtlEnabledRef,
|
||
|
mergedClsPrefix: NDrawer.mergedClsPrefixRef,
|
||
|
isMounted: NDrawer.isMountedRef,
|
||
|
mergedTheme: NDrawer.mergedThemeRef,
|
||
|
displayed: displayedRef,
|
||
|
transitionName: (0, vue_1.computed)(() => {
|
||
|
return {
|
||
|
right: 'slide-in-from-right-transition',
|
||
|
left: 'slide-in-from-left-transition',
|
||
|
top: 'slide-in-from-top-transition',
|
||
|
bottom: 'slide-in-from-bottom-transition'
|
||
|
}[props.placement];
|
||
|
}),
|
||
|
handleAfterLeave,
|
||
|
bodyDirectives: bodyDirectivesRef,
|
||
|
handleMousedownResizeTrigger,
|
||
|
handleMouseenterResizeTrigger,
|
||
|
handleMouseleaveResizeTrigger,
|
||
|
isDragging: isDraggingRef,
|
||
|
isHoverOnResizeTrigger: isHoverOnResizeTriggerRef
|
||
|
};
|
||
|
},
|
||
|
render() {
|
||
|
const { $slots, mergedClsPrefix } = this;
|
||
|
return this.displayDirective === 'show' || this.displayed || this.show
|
||
|
? (0, vue_1.withDirectives)(
|
||
|
/* Keep the wrapper dom. Make sure the drawer has a host.
|
||
|
Nor the detached content will disappear without transition */
|
||
|
(0, vue_1.h)("div", { role: "none" },
|
||
|
(0, vue_1.h)(vueuc_1.VFocusTrap, { disabled: !this.showMask || !this.trapFocus, active: this.show, autoFocus: this.autoFocus, onEsc: this.onEsc }, {
|
||
|
default: () => ((0, vue_1.h)(vue_1.Transition, { name: this.transitionName, appear: this.isMounted, onAfterEnter: this.onAfterEnter, onAfterLeave: this.handleAfterLeave }, {
|
||
|
default: () => (0, vue_1.withDirectives)((0, vue_1.h)('div', (0, vue_1.mergeProps)(this.$attrs, {
|
||
|
role: 'dialog',
|
||
|
ref: 'bodyRef',
|
||
|
'aria-modal': 'true',
|
||
|
class: [
|
||
|
`${mergedClsPrefix}-drawer`,
|
||
|
this.rtlEnabled &&
|
||
|
`${mergedClsPrefix}-drawer--rtl`,
|
||
|
`${mergedClsPrefix}-drawer--${this.placement}-placement`,
|
||
|
/**
|
||
|
* When the mouse is pressed to resize the drawer,
|
||
|
* disable text selection
|
||
|
*/
|
||
|
this.isDragging &&
|
||
|
`${mergedClsPrefix}-drawer--unselectable`,
|
||
|
this.nativeScrollbar &&
|
||
|
`${mergedClsPrefix}-drawer--native-scrollbar`
|
||
|
]
|
||
|
}), [
|
||
|
this.resizable ? ((0, vue_1.h)("div", { class: [
|
||
|
`${mergedClsPrefix}-drawer__resize-trigger`,
|
||
|
(this.isDragging ||
|
||
|
this.isHoverOnResizeTrigger) &&
|
||
|
`${mergedClsPrefix}-drawer__resize-trigger--hover`
|
||
|
], onMouseenter: this.handleMouseenterResizeTrigger, onMouseleave: this.handleMouseleaveResizeTrigger, onMousedown: this.handleMousedownResizeTrigger })) : null,
|
||
|
this.nativeScrollbar ? ((0, vue_1.h)("div", { class: [
|
||
|
`${mergedClsPrefix}-drawer-content-wrapper`,
|
||
|
this.contentClass
|
||
|
], style: this.contentStyle, role: "none" }, $slots)) : ((0, vue_1.h)(_internal_1.NScrollbar, Object.assign({}, this.scrollbarProps, { contentStyle: this.contentStyle, contentClass: [
|
||
|
`${mergedClsPrefix}-drawer-content-wrapper`,
|
||
|
this.contentClass
|
||
|
], theme: this.mergedTheme.peers.Scrollbar, themeOverrides: this.mergedTheme.peerOverrides.Scrollbar }), $slots))
|
||
|
]), this.bodyDirectives)
|
||
|
}))
|
||
|
})), [
|
||
|
[
|
||
|
vue_1.vShow,
|
||
|
this.displayDirective === 'if' || this.displayed || this.show
|
||
|
]
|
||
|
])
|
||
|
: null;
|
||
|
}
|
||
|
});
|