From 6652b5edde278e9a8d31640473ff0e3e4a261268 Mon Sep 17 00:00:00 2001
From: schangxiang@126.com <schangxiang@126.com>
Date: 周六, 03 5月 2025 17:41:12 +0800
Subject: [PATCH] 22
---
HIAWms/web/src/components/vue3-context-menu/ContextMenuInstance.ts | 133 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/HIAWms/web/src/components/vue3-context-menu/ContextMenuInstance.ts b/HIAWms/web/src/components/vue3-context-menu/ContextMenuInstance.ts
new file mode 100644
index 0000000..2254270
--- /dev/null
+++ b/HIAWms/web/src/components/vue3-context-menu/ContextMenuInstance.ts
@@ -0,0 +1,133 @@
+import { h, ref, render } from "vue";
+import type { App, Slot } from "vue";
+import type { ContextMenuInstance } from "./ContextMenuDefine";
+import type { MenuOptions } from "./ContextMenuDefine";
+import { checkOpenedContextMenu, closeContextMenu } from "./ContextMenuMutex";
+import { genContainer, transformMenuPosition } from "./ContextMenuUtils";
+import ContextMenuConstructor from './ContextMenu.vue'
+import ContextSubMenuWrapperConstructor from './ContextSubMenuWrapper.vue'
+import ContextSubMenuConstructor from './ContextSubMenu.vue'
+import ContextMenuItemConstructor from './ContextMenuItem.vue'
+import ContextMenuGroupConstructor from './ContextMenuGroup.vue'
+import ContextMenuSeparatorConstructor from './ContextMenuSeparator.vue'
+
+function initInstance(
+ options: MenuOptions,
+ container: HTMLElement,
+ isNew: boolean,
+ customSlots?: Record<string, Slot>,
+) {
+ const show = ref(true);
+ const vnode = h(ContextSubMenuWrapperConstructor, {
+ options: options,
+ show: show,
+ container: container,
+ isFullScreenContainer: !isNew,
+ onCloseAnimFinished: () => {
+ render(null, container);
+ },
+ onClose: (item: undefined) => {
+ options.onClose?.(item);
+ show.value = false;
+ },
+ }, customSlots);
+ render(vnode, container);
+ return vnode.component;
+}
+
+//Show global contextmenu
+function $contextmenu(options : MenuOptions, customSlots?: Record<string, Slot>) {
+ const container = genContainer(options);
+ const component = initInstance(options, container.container, container.isNew, customSlots);
+ return (component as unknown as Record<string, unknown>).exposed as ContextMenuInstance;
+}
+
+export default {
+ /**
+ * For Vue install
+ * @param app
+ */
+ install(app: App<Element>) : void {
+ app.config.globalProperties.$contextmenu = $contextmenu;
+ app.component('ContextMenu', ContextMenuConstructor);
+ app.component('ContextMenuItem', ContextMenuItemConstructor);
+ app.component('ContextMenuGroup', ContextMenuGroupConstructor);
+ app.component('ContextMenuSperator', ContextMenuSeparatorConstructor);
+ app.component('ContextMenuSeparator', ContextMenuSeparatorConstructor);
+ app.component('ContextSubMenu', ContextSubMenuConstructor);
+ },
+ /**
+ * Show a ContextMenu in page, same as `this.$contextmenu`
+ *
+ * For example:
+ *
+ * ```ts
+ * onContextMenu(e : MouseEvent) {
+ * //prevent the browser's default menu
+ * e.preventDefault();
+ * //show your menu
+ * ContextMenu.showContextMenu({
+ * x: e.x,
+ * y: e.y,
+ * items: [
+ * {
+ * label: "A menu item",
+ * onClick: () => {
+ * alert("You click a menu item");
+ * }
+ * },
+ * {
+ * label: "A submenu",
+ * children: [
+ * { label: "Item1" },
+ * { label: "Item2" },
+ * { label: "Item3" },
+ * ]
+ * },
+ * ]
+ * });
+ * }
+ * ```
+ *
+ * You can pass customSlots to custom rendering this menu.
+ *
+ * For example, custom rendering #itemRender and #separatorRender:
+ * ```ts
+ * ContextMenu.showContextMenu({
+ * ...
+ * } as MenuOptions, {
+ * //Use slot in function mode
+ * itemRender: ({ disabled, label, icon, showRightArrow, onClick, onMouseEnter }) => [ h('div', {
+ * class: 'my-menu-item'+(disabled?' disabled':''),
+ * onMouseenter: onMouseEnter,
+ * onClick: onClick,
+ * }, [
+ * icon ? h('img', { src: icon }) : h('div', { class: 'icon-place-holder' }),
+ * h('span', label),
+ * showRightArrow ? h('span', { class: 'right-arraw' }, '>>') : h('div'),
+ * ]) ],
+ * separatorRender: () => [ h('div', { class: 'my-menu-sperator' }) ]
+ * })
+ * ```
+ *
+ * @param options The options of ContextMenu
+ * @param customSlots You can provide some custom slots to customize the rendering style of the menu. These slots are the same as the slots of component ContextMenu.
+ * @returns Menu instance
+ */
+ showContextMenu(options : MenuOptions, customSlots?: Record<string, Slot>) : ContextMenuInstance {
+ return $contextmenu(options, customSlots);
+ },
+ /**
+ * Get if there is a menu open now.
+ */
+ isAnyContextMenuOpen() {
+ return checkOpenedContextMenu();
+ },
+ /**
+ * Close the currently open menu
+ */
+ closeContextMenu,
+ //Tools
+ transformMenuPosition,
+}
+
--
Gitblit v1.9.3