import { reactive, nextTick } from 'vue' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { CreateComponentType } from '@/packages/index.d' import { renderIcon, loadingError } from '@/utils' import { icon } from '@/plugins' const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5 const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon } = icon.carbon const chartEditStore = useChartEditStore() export enum MenuEnum { DELETE = 'delete', COPY = 'copy', CUT = 'cut', PARSE = 'parse', TOP = 'top', BOTTOM = 'bottom', UP = 'up', DOWN = 'down', CLEAR = 'clear' } export interface MenuOptionsItemType { type?: string label?: string key: MenuEnum | string icon?: Function fnHandle?: Function disabled?: boolean hidden?: boolean } // * 默认选项 const defaultOptions: MenuOptionsItemType[] = [ { label: '复制', key: MenuEnum.COPY, icon: renderIcon(CopyIcon), fnHandle: chartEditStore.setCopy, }, { label: '剪切', key: MenuEnum.CUT, icon: renderIcon(CutIcon), fnHandle: chartEditStore.setCut, }, { label: '粘贴', key: MenuEnum.PARSE, icon: renderIcon(ClipboardOutlineIcon), fnHandle: chartEditStore.setParse, }, { type: 'divider', key: 'd1' }, { label: '置顶', key: MenuEnum.TOP, icon: renderIcon(UpToTopIcon), fnHandle: chartEditStore.setTop, }, { label: '置底', key: MenuEnum.BOTTOM, icon: renderIcon(DownToBottomIcon), fnHandle: chartEditStore.setBottom, }, { label: '上移一层', key: MenuEnum.UP, icon: renderIcon(ChevronUpIcon), fnHandle: chartEditStore.setUp, }, { label: '下移一层', key: MenuEnum.DOWN, icon: renderIcon(ChevronDownIcon), fnHandle: chartEditStore.setDown, }, { type: 'divider', key: 'd2' }, { label: '清空剪贴板', key: MenuEnum.CLEAR, icon: renderIcon(PaintBrushIcon), fnHandle: chartEditStore.setRecordChart, }, { label: '删除', key: MenuEnum.DELETE, icon: renderIcon(TrashIcon), fnHandle: chartEditStore.removeComponentList, } ] // * 去除隐藏选项 const clearHideOption = (options: MenuOptionsItemType[], hideList?: MenuEnum[]) => { if(!hideList) return options const a = options.filter((op: MenuOptionsItemType) => { return hideList.findIndex((e: MenuEnum) => e !== op.key) }) } // * 右键处理 const handleContextMenu = (e: MouseEvent, item?: CreateComponentType) => { e.stopPropagation() e.preventDefault() let target = e.target while (target instanceof SVGElement) { target = target.parentNode } chartEditStore.setRightMenuShow(false) nextTick().then(() => { chartEditStore.setMousePosition(e.clientX, e.clientY) chartEditStore.setRightMenuShow(true) }) } /** * * 右键hook * @param menuConfig * @returns */ export const useContextMenu = (menuConfig?: { // 自定义右键配置 selfOptions?: MenuOptionsItemType[] // 前置处理函数 optionsHandle?: Function // 隐藏列表 hideOptionsList?: MenuEnum[] }) => { const selfOptions = menuConfig?.selfOptions const optionsHandle = menuConfig?.optionsHandle const hideOptionsList = menuConfig?.hideOptionsList // * 右键选项 const menuOptions: MenuOptionsItemType[] = selfOptions || defaultOptions // * 失焦 const onClickoutside = () => { chartEditStore.setRightMenuShow(false) } // * 事件处理 const handleMenuSelect = (key: string) => { chartEditStore.setRightMenuShow(false) const targetItem: MenuOptionsItemType[] = menuOptions.filter( (e: MenuOptionsItemType) => e.key === key ) menuOptions.forEach((e: MenuOptionsItemType) => { if (e.key === key) { if (e.fnHandle) { e.fnHandle() return } if (!targetItem) loadingError() } }) } return { // todo 每次右键都执行判断功能 // menuOptions: clearHideOption ? clearHideOption(menuOptions, hideOptionsList) : menuOptions, menuOptions: menuOptions, handleContextMenu, onClickoutside, handleMenuSelect, mousePosition: chartEditStore.getMousePosition } }