1 | Object.defineProperty(exports, '__esModule', { value: true });
|
2 |
|
3 | var vue = require('vue');
|
4 |
|
5 | var bind = function bind(el, binding) {
|
6 | var _binding$instance;
|
7 |
|
8 | var contextmenuKey = binding.arg;
|
9 |
|
10 | if (!contextmenuKey) {
|
11 | console.error("参数有误");
|
12 | return;
|
13 | }
|
14 |
|
15 | var contextmenuOptions = binding.value;
|
16 | var contextmenuRef = vue.isRef(contextmenuKey) ? contextmenuKey.value : (_binding$instance = binding.instance) === null || _binding$instance === void 0 ? void 0 : _binding$instance.$refs[contextmenuKey];
|
17 |
|
18 | if (!contextmenuRef) {
|
19 | console.error("\u6CA1\u6709\u627E\u5230 ".concat(contextmenuKey, " \u5BF9\u5E94\u7684\u5B9E\u4F8B"));
|
20 | return;
|
21 | }
|
22 |
|
23 | if (typeof contextmenuRef.addReference !== "function") {
|
24 | console.error("".concat(contextmenuKey, " \u5BF9\u5E94\u7684\u5B9E\u4F8B\u4E0D\u662F VContextmenu"));
|
25 | return;
|
26 | }
|
27 |
|
28 | el.$contextmenuKey = contextmenuKey;
|
29 | contextmenuRef.addReference(el, contextmenuOptions);
|
30 | };
|
31 |
|
32 | var unbind = function unbind(el, binding) {
|
33 | var _binding$instance2;
|
34 |
|
35 | var contextmenuKey = el.$contextmenuKey;
|
36 | if (!contextmenuKey) return;
|
37 | var contextmenuRef = (_binding$instance2 = binding.instance) === null || _binding$instance2 === void 0 ? void 0 : _binding$instance2.$refs[contextmenuKey];
|
38 | contextmenuRef === null || contextmenuRef === void 0 ? void 0 : contextmenuRef.removeReference(el);
|
39 | };
|
40 |
|
41 | var rebind = function rebind(el, binding) {
|
42 | unbind(el, binding);
|
43 | bind(el, binding);
|
44 | };
|
45 |
|
46 | var contextmenuDirective = {
|
47 | mounted: bind,
|
48 | updated: rebind,
|
49 | beforeUnmount: unbind
|
50 | };
|
51 |
|
52 | var CLASSES = {
|
53 | contextmenu: "v-contextmenu",
|
54 |
|
55 | contextmenuIcon: "v-contextmenu-icon",
|
56 |
|
57 | contextmenuInner: "v-contextmenu-inner",
|
58 |
|
59 | contextmenuDivider: "v-contextmenu-divider",
|
60 |
|
61 | contextmenuItem: "v-contextmenu-item",
|
62 |
|
63 | contextmenuItemHover: "v-contextmenu-item--hover",
|
64 |
|
65 | contextmenuItemDisabled: "v-contextmenu-item--disabled",
|
66 |
|
67 | contextmenuGroup: "v-contextmenu-group",
|
68 |
|
69 | contextmenuGroupTitle: "v-contextmenu-group__title",
|
70 |
|
71 | contextmenuGroupMenus: "v-contextmenu-group__menus",
|
72 |
|
73 | contextmenuSubmenu: "v-contextmenu-submenu",
|
74 |
|
75 | contextmenuSubmenuTitle: "v-contextmenu-submenu__title",
|
76 |
|
77 | contextmenuSubmenuMenus: "v-contextmenu-submenu__menus",
|
78 |
|
79 | contextmenuSubmenuMenusTop: "v-contextmenu-submenu__menus--top",
|
80 |
|
81 | contextmenuSubmenuMenusRight: "v-contextmenu-submenu__menus--right",
|
82 |
|
83 | contextmenuSubmenuMenusBottom: "v-contextmenu-submenu__menus--bottom",
|
84 |
|
85 | contextmenuSubmenuMenusLeft: "v-contextmenu-submenu__menus--left",
|
86 |
|
87 | contextmenuSubmenuArrow: "v-contextmenu-submenu__arrow"
|
88 |
|
89 | };
|
90 |
|
91 | function _isSlot(s) {
|
92 | return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
|
93 | }
|
94 |
|
95 | var DEFAULT_REFERENCE_OPTIONS = {
|
96 | trigger: ["contextmenu"]
|
97 | };
|
98 | var Contextmenu = vue.defineComponent({
|
99 | name: "VContextmenu",
|
100 | props: {
|
101 | modelValue: {
|
102 | type: Boolean,
|
103 | default: false
|
104 | },
|
105 | autoAjustPlacement: {
|
106 | type: Boolean,
|
107 | default: true
|
108 | },
|
109 | disabled: {
|
110 | type: Boolean,
|
111 | default: false
|
112 | },
|
113 | teleport: {
|
114 | type: [String, Object],
|
115 | default: function _default() {
|
116 | return "body";
|
117 | }
|
118 | }
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | },
|
124 | emits: ["show", "hide", "update:modelValue"],
|
125 | setup: function setup(props, _ref) {
|
126 | var emit = _ref.emit;
|
127 | var contextmenuRef = vue.ref(null);
|
128 | var visible = vue.ref(props.modelValue || false);
|
129 |
|
130 | var toggle = function toggle(value) {
|
131 | visible.value = value;
|
132 | emit("update:modelValue", value);
|
133 | };
|
134 |
|
135 | var position = vue.ref({
|
136 | top: 0,
|
137 | left: 0
|
138 | });
|
139 | var style = vue.computed(function () {
|
140 | return {
|
141 | top: "".concat(position.value.top, "px"),
|
142 | left: "".concat(position.value.left, "px")
|
143 | };
|
144 | });
|
145 | var currentOptions = vue.ref(null);
|
146 |
|
147 | var show = function show(evt, options) {
|
148 | var targetOptions = evt instanceof Event ? options : evt;
|
149 | var autoAjustPlacement = (targetOptions === null || targetOptions === void 0 ? void 0 : targetOptions.autoAjustPlacement) || props.autoAjustPlacement;
|
150 | var targetPosition = {
|
151 | top: (targetOptions === null || targetOptions === void 0 ? void 0 : targetOptions.top) || 0,
|
152 | left: (targetOptions === null || targetOptions === void 0 ? void 0 : targetOptions.left) || 0
|
153 | };
|
154 |
|
155 | if (evt instanceof Event) {
|
156 | var _targetOptions$top, _targetOptions$left;
|
157 |
|
158 | evt.preventDefault();
|
159 | targetPosition.top = (_targetOptions$top = targetOptions === null || targetOptions === void 0 ? void 0 : targetOptions.top) !== null && _targetOptions$top !== void 0 ? _targetOptions$top : evt.pageY;
|
160 | targetPosition.left = (_targetOptions$left = targetOptions === null || targetOptions === void 0 ? void 0 : targetOptions.left) !== null && _targetOptions$left !== void 0 ? _targetOptions$left : evt.pageX;
|
161 | }
|
162 |
|
163 | toggle(true);
|
164 | vue.nextTick(function () {
|
165 | if (autoAjustPlacement) {
|
166 | var el = contextmenuRef.value;
|
167 | if (!el) return;
|
168 | var width = el.clientWidth;
|
169 | var height = el.clientHeight;
|
170 |
|
171 | if (height + targetPosition.top >= window.innerHeight + window.scrollY) {
|
172 | var targetTop = targetPosition.top - height;
|
173 |
|
174 | if (targetTop > window.scrollY) {
|
175 | targetPosition.top = targetTop;
|
176 | }
|
177 | }
|
178 |
|
179 | if (width + targetPosition.left >= window.innerWidth + window.scrollX) {
|
180 | var targetWidth = targetPosition.left - width;
|
181 |
|
182 | if (targetWidth > window.scrollX) {
|
183 | targetPosition.left = targetWidth;
|
184 | }
|
185 | }
|
186 | }
|
187 |
|
188 | position.value = targetPosition;
|
189 |
|
190 | emit("show");
|
191 | });
|
192 | };
|
193 |
|
194 | var hide = function hide() {
|
195 | currentOptions.value = null;
|
196 | toggle(false);
|
197 |
|
198 | emit("hide");
|
199 | };
|
200 |
|
201 | var references = vue.reactive(new Map());
|
202 | var currentReference = vue.ref();
|
203 | var currentReferenceOptions = vue.computed(function () {
|
204 | return currentReference.value && references.get(currentReference.value);
|
205 | });
|
206 |
|
207 | var addReference = function addReference(el, options) {
|
208 | var triggers = function () {
|
209 | if (options !== null && options !== void 0 && options.trigger) {
|
210 | return Array.isArray(options.trigger) ? options.trigger : [options.trigger];
|
211 | }
|
212 |
|
213 | return DEFAULT_REFERENCE_OPTIONS.trigger;
|
214 | }();
|
215 |
|
216 | var handler = function handler(evt) {
|
217 | if (props.disabled) return;
|
218 | currentReference.value = el;
|
219 | show(evt, {});
|
220 | };
|
221 |
|
222 | triggers.forEach(function (eventType) {
|
223 | el.addEventListener(eventType, handler);
|
224 | });
|
225 | references.set(el, {
|
226 | triggers: triggers,
|
227 | handler: handler
|
228 | });
|
229 | };
|
230 |
|
231 | var removeReference = function removeReference(el) {
|
232 | var options = references.get(el);
|
233 | if (!options) return;
|
234 | options.triggers.forEach(function (eventType) {
|
235 | el.removeEventListener(eventType, options.handler);
|
236 | });
|
237 | references.delete(el);
|
238 | };
|
239 |
|
240 | var onBodyClick = function onBodyClick(evt) {
|
241 | if (!evt.target || !contextmenuRef.value || !currentReference.value) return;
|
242 | var notOutside = contextmenuRef.value.contains(evt.target) || currentReferenceOptions.value && currentReferenceOptions.value.triggers.includes("click") && currentReference.value.contains(evt.target);
|
243 |
|
244 | if (!notOutside) {
|
245 | toggle(false);
|
246 | }
|
247 | };
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 | vue.watch(visible, function (value) {
|
255 | if (value) {
|
256 | document.addEventListener("click", onBodyClick);
|
257 | } else {
|
258 | document.removeEventListener("click", onBodyClick);
|
259 | }
|
260 | });
|
261 | vue.onBeforeUnmount(function () {
|
262 | document.removeEventListener("click", onBodyClick);
|
263 | });
|
264 | vue.provide("visible", visible);
|
265 | vue.provide("autoAjustPlacement", props.autoAjustPlacement);
|
266 | vue.provide("show", show);
|
267 | vue.provide("hide", hide);
|
268 | return {
|
269 | visible: visible,
|
270 | style: style,
|
271 | currentReferenceOptions: currentReferenceOptions,
|
272 | currentOptions: currentOptions,
|
273 | contextmenuRef: contextmenuRef,
|
274 | addReference: addReference,
|
275 | removeReference: removeReference,
|
276 | toggle: toggle,
|
277 | show: show,
|
278 | hide: hide
|
279 | };
|
280 | },
|
281 | methods: {
|
282 | renderContent: function renderContent() {
|
283 | var _this$$slots$default, _this$$slots;
|
284 |
|
285 | return vue.withDirectives(vue.createVNode("div", {
|
286 | "class": CLASSES.contextmenu,
|
287 | "ref": "contextmenuRef",
|
288 | "style": this.style
|
289 | }, [vue.createVNode("ul", {
|
290 | "class": CLASSES.contextmenuInner
|
291 | }, [(_this$$slots$default = (_this$$slots = this.$slots).default) === null || _this$$slots$default === void 0 ? void 0 : _this$$slots$default.call(_this$$slots, {
|
292 | triggerOptions: "currentReferenceOptions",
|
293 | options: "currentOptions"
|
294 | })])]), [[vue.vShow, "visible"]]);
|
295 | }
|
296 | },
|
297 | render: function render() {
|
298 | var _slot;
|
299 |
|
300 | if (!this.visible) return null;
|
301 | return this.teleport ? vue.createVNode(vue.Teleport, {
|
302 | "to": this.teleport
|
303 | }, _isSlot(_slot = this.renderContent()) ? _slot : {
|
304 | default: function _default() {
|
305 | return [_slot];
|
306 | }
|
307 | }) : this.renderContent();
|
308 | }
|
309 | });
|
310 |
|
311 | function _defineProperty(obj, key, value) {
|
312 | if (key in obj) {
|
313 | Object.defineProperty(obj, key, {
|
314 | value: value,
|
315 | enumerable: true,
|
316 | configurable: true,
|
317 | writable: true
|
318 | });
|
319 | } else {
|
320 | obj[key] = value;
|
321 | }
|
322 |
|
323 | return obj;
|
324 | }
|
325 |
|
326 | var ContextmenuItem = vue.defineComponent({
|
327 | name: "VContextmenuItem",
|
328 | props: {
|
329 | disabled: {
|
330 | type: Boolean,
|
331 | default: false
|
332 | },
|
333 | hideOnClick: {
|
334 | type: Boolean,
|
335 | default: true
|
336 | }
|
337 | },
|
338 | emits: ["click", "mouseenter", "mouseleave"],
|
339 | setup: function setup(props, _ref) {
|
340 | var emit = _ref.emit;
|
341 | var rootHide = vue.inject("hide");
|
342 | var hover = vue.ref(false);
|
343 | var classes = vue.computed(function () {
|
344 | var _ref2;
|
345 |
|
346 | return _ref2 = {}, _defineProperty(_ref2, CLASSES.contextmenuItem, true), _defineProperty(_ref2, CLASSES.contextmenuItemDisabled, props.disabled), _defineProperty(_ref2, CLASSES.contextmenuItemHover, hover.value), _ref2;
|
347 | });
|
348 |
|
349 | var handleClick = function handleClick(evt) {
|
350 | if (props.disabled) return;
|
351 | emit("click", evt);
|
352 | props.hideOnClick && (rootHide === null || rootHide === void 0 ? void 0 : rootHide());
|
353 | };
|
354 |
|
355 | var handleMouseenter = function handleMouseenter(evt) {
|
356 | if (props.disabled) return;
|
357 | hover.value = true;
|
358 | emit("mouseenter", evt);
|
359 | };
|
360 |
|
361 | var handleMouseleave = function handleMouseleave(evt) {
|
362 | if (props.disabled) return;
|
363 | hover.value = false;
|
364 | emit("mouseleave", evt);
|
365 | };
|
366 |
|
367 | return {
|
368 | classes: classes,
|
369 | handleClick: handleClick,
|
370 | handleMouseenter: handleMouseenter,
|
371 | handleMouseleave: handleMouseleave
|
372 | };
|
373 | },
|
374 | render: function render() {
|
375 | var _this$$slots$default, _this$$slots;
|
376 |
|
377 | return vue.createVNode("li", {
|
378 | "class": this.classes,
|
379 | "onClick": this.handleClick,
|
380 | "onMouseenter": this.handleMouseenter,
|
381 | "onMouseleave": this.handleMouseleave
|
382 | }, [(_this$$slots$default = (_this$$slots = this.$slots).default) === null || _this$$slots$default === void 0 ? void 0 : _this$$slots$default.call(_this$$slots)]);
|
383 | }
|
384 | });
|
385 |
|
386 | var ContextmenuDivider = vue.defineComponent({
|
387 | name: "VContextmenuDivider",
|
388 | render: function render() {
|
389 | return vue.createVNode("li", {
|
390 | "class": CLASSES.contextmenuDivider
|
391 | }, null);
|
392 | }
|
393 | });
|
394 |
|
395 | var ContextmenuIcon = vue.defineComponent({
|
396 | name: "VContextmenuIcon",
|
397 | props: {
|
398 | name: {
|
399 | type: String,
|
400 | required: true
|
401 | }
|
402 | },
|
403 | render: function render() {
|
404 | return vue.createVNode("i", {
|
405 | "class": [CLASSES.contextmenuIcon, "".concat(CLASSES.contextmenuIcon, "-").concat(this.name)]
|
406 | }, null);
|
407 | }
|
408 | });
|
409 |
|
410 | var ContextmenuSubmenu = vue.defineComponent({
|
411 | name: "VContextmenuSubmenu",
|
412 | props: {
|
413 | title: {
|
414 | type: String,
|
415 | required: true
|
416 | },
|
417 | disabled: {
|
418 | type: Boolean,
|
419 | default: false
|
420 | }
|
421 | },
|
422 | emits: ["mouseenter", "mouseleave"],
|
423 | setup: function setup(props, _ref) {
|
424 | var emit = _ref.emit;
|
425 | var submenuRef = vue.ref(null);
|
426 | var autoAjustPlacement = vue.inject("autoAjustPlacement");
|
427 | var placements = vue.ref(["top", "right"]);
|
428 | var hover = vue.ref(false);
|
429 |
|
430 | var handleMouseenter = function handleMouseenter(evt) {
|
431 | if (props.disabled) return;
|
432 | hover.value = true;
|
433 | emit("mouseenter", evt);
|
434 | vue.nextTick(function () {
|
435 | var targetPlacements = [];
|
436 |
|
437 | if (autoAjustPlacement) {
|
438 | var target = evt.target;
|
439 | var targetDimension = target.getBoundingClientRect();
|
440 | if (!submenuRef.value) return;
|
441 | var submenuWidth = submenuRef.value.clientWidth;
|
442 | var submenuHeight = submenuRef.value.clientHeight;
|
443 |
|
444 | if (targetDimension.right + submenuWidth >= window.innerWidth) {
|
445 | targetPlacements.push("left");
|
446 | } else {
|
447 | targetPlacements.push("right");
|
448 | }
|
449 |
|
450 | if (targetDimension.bottom + submenuHeight >= window.innerHeight) {
|
451 | targetPlacements.push("bottom");
|
452 | } else {
|
453 | targetPlacements.push("top");
|
454 | }
|
455 | }
|
456 |
|
457 | placements.value = targetPlacements;
|
458 | });
|
459 | };
|
460 |
|
461 | var handleMouseleave = function handleMouseleave(evt) {
|
462 | if (props.disabled) return;
|
463 | hover.value = false;
|
464 | emit("mouseleave", evt);
|
465 | };
|
466 |
|
467 | var titleClasses = vue.computed(function () {
|
468 | var _ref2;
|
469 |
|
470 | return _ref2 = {}, _defineProperty(_ref2, CLASSES.contextmenuItem, true), _defineProperty(_ref2, CLASSES.contextmenuSubmenuTitle, true), _defineProperty(_ref2, CLASSES.contextmenuItemHover, hover.value), _defineProperty(_ref2, CLASSES.contextmenuItemDisabled, props.disabled), _ref2;
|
471 | });
|
472 | var menusClasses = vue.computed(function () {
|
473 | var _ref3;
|
474 |
|
475 | return _ref3 = {}, _defineProperty(_ref3, CLASSES.contextmenu, true), _defineProperty(_ref3, CLASSES.contextmenuSubmenuMenus, true), _defineProperty(_ref3, CLASSES.contextmenuSubmenuMenusTop, placements.value.includes("top")), _defineProperty(_ref3, CLASSES.contextmenuSubmenuMenusRight, placements.value.includes("right")), _defineProperty(_ref3, CLASSES.contextmenuSubmenuMenusBottom, placements.value.includes("bottom")), _defineProperty(_ref3, CLASSES.contextmenuSubmenuMenusLeft, placements.value.includes("left")), _ref3;
|
476 | });
|
477 | return {
|
478 | hover: hover,
|
479 | submenuRef: submenuRef,
|
480 | titleClasses: titleClasses,
|
481 | menusClasses: menusClasses,
|
482 | handleMouseenter: handleMouseenter,
|
483 | handleMouseleave: handleMouseleave
|
484 | };
|
485 | },
|
486 | render: function render() {
|
487 | var _this$$slots$title, _this$$slots, _this$$slots$default, _this$$slots2;
|
488 |
|
489 | return vue.createVNode("li", {
|
490 | "class": CLASSES.contextmenuSubmenu,
|
491 | "onMouseenter": this.handleMouseenter,
|
492 | "onMouseleave": this.handleMouseleave
|
493 | }, [vue.createVNode("div", {
|
494 | "class": this.titleClasses
|
495 | }, [((_this$$slots$title = (_this$$slots = this.$slots).title) === null || _this$$slots$title === void 0 ? void 0 : _this$$slots$title.call(_this$$slots)) || this.title, vue.createVNode("span", {
|
496 | "class": CLASSES.contextmenuSubmenuArrow
|
497 | }, [vue.createVNode(ContextmenuIcon, {
|
498 | "name": "right-arrow"
|
499 | }, null)])]), this.hover ? vue.createVNode("div", {
|
500 | "ref": "submenuRef",
|
501 | "class": this.menusClasses
|
502 | }, [vue.createVNode("ul", {
|
503 | "class": CLASSES.contextmenuInner
|
504 | }, [(_this$$slots$default = (_this$$slots2 = this.$slots).default) === null || _this$$slots$default === void 0 ? void 0 : _this$$slots$default.call(_this$$slots2)])]) : null]);
|
505 | }
|
506 | });
|
507 |
|
508 | var ContextmenuGroup = vue.defineComponent({
|
509 | name: "VContextmenuGroup",
|
510 | props: {
|
511 | title: {
|
512 | type: String,
|
513 | default: undefined
|
514 | },
|
515 | maxWidth: {
|
516 | type: [Number, String],
|
517 | default: undefined
|
518 | }
|
519 | },
|
520 | setup: function setup(props) {
|
521 | var style = vue.computed(function () {
|
522 | if (!props.maxWidth) return;
|
523 | return {
|
524 | "max-width": typeof props.maxWidth === "number" ? "".concat(props.maxWidth, "px") : props.maxWidth,
|
525 | "overflow-x": "auto"
|
526 | };
|
527 | });
|
528 | return {
|
529 | style: style
|
530 | };
|
531 | },
|
532 | methods: {
|
533 | renderTitle: function renderTitle() {
|
534 | var _this$$slots$title, _this$$slots;
|
535 |
|
536 | var content = ((_this$$slots$title = (_this$$slots = this.$slots).title) === null || _this$$slots$title === void 0 ? void 0 : _this$$slots$title.call(_this$$slots)) || this.title;
|
537 | return content ? vue.createVNode("div", {
|
538 | "class": CLASSES.contextmenuGroupTitle
|
539 | }, [content]) : null;
|
540 | }
|
541 | },
|
542 | render: function render() {
|
543 | var _this$$slots$default, _this$$slots2;
|
544 |
|
545 | return vue.createVNode("li", {
|
546 | "class": CLASSES.contextmenuGroup
|
547 | }, [this.renderTitle(), vue.createVNode("ul", {
|
548 | "style": this.style,
|
549 | "class": CLASSES.contextmenuGroupMenus
|
550 | }, [(_this$$slots$default = (_this$$slots2 = this.$slots).default) === null || _this$$slots$default === void 0 ? void 0 : _this$$slots$default.call(_this$$slots2)])]);
|
551 | }
|
552 | });
|
553 |
|
554 | var version = "3.0.0";
|
555 |
|
556 | var install = function install(app) {
|
557 | app.directive("contextmenu", contextmenuDirective);
|
558 | app.component(Contextmenu.name, Contextmenu);
|
559 | app.component(ContextmenuItem.name, ContextmenuItem);
|
560 | app.component(ContextmenuDivider.name, ContextmenuDivider);
|
561 | app.component(ContextmenuSubmenu.name, ContextmenuSubmenu);
|
562 | app.component(ContextmenuGroup.name, ContextmenuGroup);
|
563 | };
|
564 | var VContextmenu = {
|
565 | install: install,
|
566 | version: version
|
567 | };
|
568 |
|
569 | exports.Contextmenu = Contextmenu;
|
570 | exports.ContextmenuDivider = ContextmenuDivider;
|
571 | exports.ContextmenuGroup = ContextmenuGroup;
|
572 | exports.ContextmenuItem = ContextmenuItem;
|
573 | exports.ContextmenuSubmenu = ContextmenuSubmenu;
|
574 | exports.default = VContextmenu;
|
575 | exports.directive = contextmenuDirective;
|
576 | exports.install = install;
|
577 | exports.version = version;
|