@veltra/desktop 1.1.31 → 1.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/action/action-group.vue.d.ts +1 -1
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +1 -1
- package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
- package/dist/components/contextmenu/api.d.ts +8 -0
- package/dist/components/{context-menu → contextmenu}/api.js +2 -2
- package/dist/components/contextmenu/api.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-item.js +64 -0
- package/dist/components/contextmenu/contextmenu-item.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-panel.js +33 -0
- package/dist/components/contextmenu/contextmenu-panel.js.map +1 -0
- package/dist/components/contextmenu/contextmenu-sub.js +83 -0
- package/dist/components/contextmenu/contextmenu-sub.js.map +1 -0
- package/dist/components/contextmenu/contextmenu.js +79 -0
- package/dist/components/contextmenu/contextmenu.js.map +1 -0
- package/dist/components/{context-menu/context-menu.vue.d.ts → contextmenu/contextmenu.vue.d.ts} +5 -5
- package/dist/components/contextmenu/di.js +7 -0
- package/dist/components/contextmenu/di.js.map +1 -0
- package/dist/components/contextmenu/helper.js +8 -0
- package/dist/components/contextmenu/helper.js.map +1 -0
- package/dist/components/contextmenu/index.d.ts +2 -0
- package/dist/components/contextmenu/style2.css +154 -0
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
- package/dist/components/file-viewer/previewers/sheet-previewer.js +33 -93
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
- package/dist/components/file-viewer/sheet-parser.js +46 -0
- package/dist/components/file-viewer/sheet-parser.js.map +1 -0
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/number/number.vue.d.ts +1 -1
- package/dist/components/table/node/col.d.ts +5 -0
- package/dist/components/table/node/col.js +6 -0
- package/dist/components/table/node/col.js.map +1 -1
- package/dist/components/table/use-col-resize.js +10 -10
- package/dist/components/table/use-col-resize.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/style.js +1 -1
- package/dist/types/{context-menu.d.ts → contextmenu.d.ts} +12 -10
- package/dist/types/index.d.ts +2 -2
- package/package.json +6 -6
- package/src/components/{context-menu → contextmenu}/api.ts +4 -4
- package/src/components/contextmenu/contextmenu-item.vue +63 -0
- package/src/components/contextmenu/contextmenu-panel.vue +28 -0
- package/src/components/contextmenu/contextmenu-sub.vue +88 -0
- package/src/components/contextmenu/contextmenu.vue +77 -0
- package/src/components/contextmenu/di.ts +13 -0
- package/src/components/contextmenu/helper.ts +5 -0
- package/src/components/contextmenu/index.ts +3 -0
- package/src/components/contextmenu/style.scss +135 -0
- package/src/components/file-viewer/previewers/sheet-previewer.vue +35 -131
- package/src/components/file-viewer/sheet-parser.ts +52 -0
- package/src/components/index.ts +1 -1
- package/src/components/table/node/col.ts +7 -0
- package/src/components/table/use-col-resize.ts +18 -16
- package/src/style.ts +1 -1
- package/src/types/{context-menu.ts → contextmenu.ts} +9 -7
- package/src/types/index.ts +1 -1
- package/dist/components/context-menu/api.d.ts +0 -8
- package/dist/components/context-menu/api.js.map +0 -1
- package/dist/components/context-menu/context-menu-item.js +0 -60
- package/dist/components/context-menu/context-menu-item.js.map +0 -1
- package/dist/components/context-menu/context-menu.js +0 -95
- package/dist/components/context-menu/context-menu.js.map +0 -1
- package/dist/components/context-menu/di.js +0 -6
- package/dist/components/context-menu/di.js.map +0 -1
- package/dist/components/context-menu/index.d.ts +0 -2
- package/dist/components/context-menu/style2.css +0 -52
- package/src/components/context-menu/context-menu-item.vue +0 -67
- package/src/components/context-menu/context-menu.vue +0 -119
- package/src/components/context-menu/di.ts +0 -5
- package/src/components/context-menu/index.ts +0 -3
- package/src/components/context-menu/style.scss +0 -51
- /package/dist/components/{context-menu → contextmenu}/style.d.ts +0 -0
- /package/dist/components/{context-menu → contextmenu}/style.js +0 -0
- /package/src/components/{context-menu → contextmenu}/style.ts +0 -0
package/dist/style.js
CHANGED
|
@@ -30,7 +30,7 @@ import "./components/collapse/style.js";
|
|
|
30
30
|
import "./components/select/style.js";
|
|
31
31
|
import "./components/expression-editor/style.js";
|
|
32
32
|
import "./components/condition-editor/style.js";
|
|
33
|
-
import "./components/
|
|
33
|
+
import "./components/contextmenu/style.js";
|
|
34
34
|
import "./components/date-panel/style.js";
|
|
35
35
|
import "./components/date-picker/style.js";
|
|
36
36
|
import "./components/date-range-picker/style.js";
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import { Component } from "vue";
|
|
2
2
|
import { ComponentProps, DeconstructValue } from "@veltra/utils";
|
|
3
3
|
|
|
4
|
-
//#region src/types/
|
|
4
|
+
//#region src/types/contextmenu.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* 右键菜单项
|
|
7
7
|
*/
|
|
8
|
-
interface
|
|
8
|
+
interface ContextmenuItem {
|
|
9
9
|
/** 菜单名称 */
|
|
10
10
|
label: string;
|
|
11
11
|
/** 菜单描述 */
|
|
12
12
|
description?: string;
|
|
13
13
|
/** 菜单图标 */
|
|
14
14
|
icon?: Component;
|
|
15
|
+
/** 子菜单 */
|
|
16
|
+
children?: ContextmenuItem[];
|
|
15
17
|
/** 菜单点击时的回调 */
|
|
16
|
-
callback?: () =>
|
|
18
|
+
callback?: () => any;
|
|
17
19
|
/** 是否禁用 */
|
|
18
20
|
disabled?: boolean | (() => boolean);
|
|
19
21
|
}
|
|
20
22
|
/** 鼠标右键菜单组件属性 */
|
|
21
|
-
interface
|
|
23
|
+
interface ContextmenuProps extends ComponentProps {
|
|
22
24
|
/** 鼠标位置 */
|
|
23
25
|
mousePosition: {
|
|
24
26
|
x: number;
|
|
@@ -30,16 +32,16 @@ interface ContextMenuProps extends ComponentProps {
|
|
|
30
32
|
*/
|
|
31
33
|
width?: number | string;
|
|
32
34
|
/** 菜单项 */
|
|
33
|
-
menus:
|
|
35
|
+
menus: ContextmenuItem[] | (() => ContextmenuItem[]);
|
|
34
36
|
}
|
|
35
37
|
/** 鼠标右键菜单组件定义的事件 */
|
|
36
|
-
interface
|
|
38
|
+
interface ContextmenuEmits {
|
|
37
39
|
(e: 'destroy'): void;
|
|
38
40
|
}
|
|
39
41
|
/** 鼠标右键菜单组件暴露的属性和方法(组件内部使用) */
|
|
40
|
-
interface
|
|
42
|
+
interface _ContextmenuExposed {}
|
|
41
43
|
/** 鼠标右键菜单组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
42
|
-
type
|
|
44
|
+
type ContextmenuExposed = DeconstructValue<_ContextmenuExposed>;
|
|
43
45
|
//#endregion
|
|
44
|
-
export {
|
|
45
|
-
//# sourceMappingURL=
|
|
46
|
+
export { ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, _ContextmenuExposed };
|
|
47
|
+
//# sourceMappingURL=contextmenu.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ import { MenuEmits, MenuExposed, MenuItem, MenuProps, _MenuExposed } from "./men
|
|
|
50
50
|
import { PasswordInputEmits, PasswordInputExposed, PasswordInputProps, _PasswordInputExposed } from "./password-input.js";
|
|
51
51
|
import { DatePickerEmits, DatePickerExposed, DatePickerProps, _DatePickerExposed } from "./date-picker.js";
|
|
52
52
|
import { DropdownEmits, DropdownExposed, DropdownProps, _DropdownExposed } from "./dropdown.js";
|
|
53
|
-
import {
|
|
53
|
+
import { ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, _ContextmenuExposed } from "./contextmenu.js";
|
|
54
54
|
import { SelectEmits, SelectExposed, SelectProps, _SelectExposed } from "./select.js";
|
|
55
55
|
import { RadioEmits, RadioExposed, RadioProps, _RadioExposed } from "./radio.js";
|
|
56
56
|
import { CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxProps } from "./checkbox.js";
|
|
@@ -81,7 +81,7 @@ export type * from "@veltra/utils";
|
|
|
81
81
|
|
|
82
82
|
//#region src/types/index.d.ts
|
|
83
83
|
declare namespace index_d_exports {
|
|
84
|
-
export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AllKeys, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditProps, BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, BreakCols, Breakpoint, ButtonEmits, ButtonExposed, ButtonProps, ButtonType, CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, CardActionProps, CardContentProps, CardCoverProps, CardEmits, CardExposed, CardProps, CascadeEmits, CascadeExposed, CascadeNode, CascadeProps, CheckTagEmits, CheckTagExposed, CheckTagProps, CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxGroupEmits, CheckboxGroupExposed, CheckboxGroupProps, CheckboxProps, CodeEditorEmits, CodeEditorExposed, CodeEditorLang, CodeEditorProps, CollapseEmits, CollapseItemProps, CollapseModelValue, CollapseProps, CollapseValue, ConditionConnector, ConditionEditorEmits, ConditionEditorExposed, ConditionEditorProps, ConditionExpression, ConditionField, ConditionGroup, ConditionLeaf, ConditionNode, ConditionValue,
|
|
84
|
+
export { ActionEmits, ActionExposed, ActionGroupExposed, ActionGroupProps, ActionProps, AllKeys, AnimationEmits, AnimationExposed, AnimationProps, AutoCompleteEmits, AutoCompleteExposed, AutoCompleteProps, BadgeEmits, BadgeExposed, BadgeProps, BarType, BatchEditColumn, BatchEditEmits, BatchEditExposed, BatchEditFeature, BatchEditProps, BreadcrumbEmits, BreadcrumbExposed, BreadcrumbItem, BreadcrumbProps, BreadcrumbSlotScope, BreakCols, Breakpoint, ButtonEmits, ButtonExposed, ButtonProps, ButtonType, CalendarDay, CalendarEmits, CalendarExposed, CalendarMonth, CalendarProps, CalendarYear, CardActionProps, CardContentProps, CardCoverProps, CardEmits, CardExposed, CardProps, CascadeEmits, CascadeExposed, CascadeNode, CascadeProps, CheckTagEmits, CheckTagExposed, CheckTagProps, CheckboxButtonEmits, CheckboxButtonProps, CheckboxEmits, CheckboxExposed, CheckboxGroupEmits, CheckboxGroupExposed, CheckboxGroupProps, CheckboxProps, CodeEditorEmits, CodeEditorExposed, CodeEditorLang, CodeEditorProps, CollapseEmits, CollapseItemProps, CollapseModelValue, CollapseProps, CollapseValue, ConditionConnector, ConditionEditorEmits, ConditionEditorExposed, ConditionEditorProps, ConditionExpression, ConditionField, ConditionGroup, ConditionLeaf, ConditionNode, ConditionValue, ContextmenuEmits, ContextmenuExposed, ContextmenuItem, ContextmenuProps, CssTransitionEmits, CssTransitionExposed, CssTransitionProps, DataSettingConfig, DatePanelEmits, DatePanelProps, DatePickerEmits, DatePickerExposed, DatePickerProps, DateRangePickerEmits, DateRangePickerExposed, DateRangePickerProps, DialogEmits, DialogExposed, DialogProps, DrawerDirection, DrawerEmits, DrawerExposed, DrawerMode, DrawerProps, DropdownEmits, DropdownExposed, DropdownProps, EmptyEmits, EmptyExposed, EmptyProps, ExpressionEditorEmits, ExpressionEditorExposed, ExpressionEditorProps, ExpressionSelectableLevels, FileViewerEmits, FileViewerExposed, FileViewerItem, FileViewerKind, FileViewerProps, FloatButtonEmits, FloatButtonExposed, FloatButtonItem, FloatButtonProps, FormExposed, FormItemEmits, FormItemExposed, FormItemProps, FormModelField, FormModelItem, FormProps, GanttChartEmits, GanttChartExposed, GanttChartProps, GridEmits, GridExposed, GridInputEmits, GridInputExposed, GridInputProps, GridItemProps, GridProps, GroupInputEmits, GroupInputExposed, GroupInputProps, IFormModel, IconEmits, IconExposed, IconProps, InputEmits, InputExposed, InputProps, LayoutEmits, LayoutExposed, LayoutProps, ListEmits, ListExposed, ListProps, LoadingEmits, LoadingExposed, LoadingProps, LoadingType, MenuEmits, MenuExposed, MenuItem, MenuProps, Message, MessageConfirmEmits, MessageConfirmExposed, MessageConfirmProps, MessageEmits, MessageExposed, MessageInstance, MessageOptions, MessageProps, MessageType, ModelData, ModelRules, MultiAutoCompleteEmits, MultiAutoCompleteExposed, MultiAutoCompleteProps, MultiSelectEmits, MultiSelectExposed, MultiSelectProps, MultiTreeSelectEmits, MultiTreeSelectExposed, MultiTreeSelectProps, NodeRenderExposed, NodeRenderProps, NotificationEmits, NotificationExposed, NotificationProps, NumberEmits, NumberExposed, NumberInputEmits, NumberInputExposed, NumberInputProps, NumberProps, NumberRangeInputEmits, NumberRangeInputExposed, NumberRangeInputProps, NumberRangeTuple, PaginatorEmits, PaginatorExposed, PaginatorProps, PaletteColorType, PaletteEmits, PaletteExposed, PaletteHSV, PaletteProps, PaletteRGB, PanelItem, PanelType, PasswordInputEmits, PasswordInputExposed, PasswordInputProps, PopConfirmEmits, PopConfirmExposed, PopConfirmProps, PopEmits, PopExposed, PopProps, ProgressEmits, ProgressExposed, ProgressNodesEmits, ProgressNodesExposed, ProgressNodesProps, ProgressProps, QuickBatchEditEmits, QuickBatchEditExposed, QuickBatchEditProps, RadioEmits, RadioExposed, RadioGroupEmits, RadioGroupExposed, RadioGroupProps, RadioProps, RichTextEditorEmits, RichTextEditorExposed, RichTextEditorProps, RichTextFormat, ScrollEmits, ScrollExposed, ScrollPosition, ScrollProps, SelectEmits, SelectExposed, SelectProps, SliderEmits, SliderExposed, SliderProps, StepsEmits, StepsExposed, StepsProps, StepsSlotScope, SwitchEmits, SwitchExposed, SwitchProps, TabItem, TableColumn, TableColumnAlign, TableColumnNode, TableColumnRenderContext, TableColumnSlotsScope, TableEditorEmits, TableEditorExposed, TableEditorProps, TableEmits, TableExposed, TableProps, TableRow, TableRowSlotsScope, TableSummaryContext, TabsEmits, TabsExposed, TabsHorizontalEmits, TabsHorizontalExposed, TabsHorizontalProps, TabsProps, TabsVerticalEmits, TabsVerticalExposed, TabsVerticalProps, TagEmits, TagExposed, TagProps, TextEditorEmits, TextEditorExposed, TextEditorProps, TextEmits, TextExposed, TextProps, TextareaEmits, TextareaExposed, TextareaProps, ThemeExposed, ThemeProps, TipAlign, TipDirection, TipEmits, TipExposed, TipProps, ToolbarItem, TreeEmit, TreeExposed, TreeNode, TreeNodeProps, TreeProps, TreeSelectEmits, TreeSelectExposed, TreeSelectProps, UploaderEmits, UploaderExposed, UploaderProps, VariableItem, WatermarkEmits, WatermarkExposed, WatermarkProps, _ActionExposed, _ActionGroupExposed, _AnimationExposed, _AutoCompleteExposed, _BadgeExposed, _BatchEditExposed, _BreadcrumbExposed, _ButtonExposed, _CalendarExposed, _CardExposed, _CascadeExposed, _CheckTagExposed, _CodeEditorExposed, _ConditionEditorExposed, _ContextmenuExposed, _CssTransitionExposed, _DatePickerExposed, _DateRangePickerExposed, _DialogExposed, _DrawerExposed, _DropdownExposed, _EmptyExposed, _ExpressionEditorExposed, _FileViewerExposed, _FloatButtonExposed, _FormExposed, _GanttChartExposed, _GridExposed, _GridInputExposed, _GroupInputExposed, _InputExposed, _LayoutExposed, _ListExposed, _LoadingExposed, _MenuExposed, _MessageConfirmExposed, _MessageExposed, _MultiAutoCompleteExposed, _MultiSelectExposed, _MultiTreeSelectExposed, _NotificationExposed, _PaginatorExposed, _PaletteExposed, _PasswordInputExposed, _PopConfirmExposed, _PopExposed, _ProgressExposed, _ProgressNodesExposed, _QuickBatchEditExposed, _RadioExposed, _RadioGroupExposed, _RichTextEditorExposed, _ScrollExposed, _SelectExposed, _SliderExposed, _StepsExposed, _SwitchExposed, _TableEditorExposed, _TableExposed, _TabsExposed, _TabsHorizontalExposed, _TabsVerticalExposed, _TextEditorExposed, _TextExposed, _TextareaExposed, _ThemeExposed, _TipExposed, _TreeExposed, _TreeSelectExposed, _UploaderExposed, _WatermarkExposed };
|
|
85
85
|
}
|
|
86
86
|
import * as import__veltra_utils from "@veltra/utils";
|
|
87
87
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veltra/desktop",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.33",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"src"
|
|
@@ -68,11 +68,11 @@
|
|
|
68
68
|
"@cat-kit/core": ">=1.1.6",
|
|
69
69
|
"@cat-kit/excel": ">=1.0.0",
|
|
70
70
|
"@cat-kit/fe": "^1.1.6",
|
|
71
|
-
"@veltra/compositions": "1.1.
|
|
72
|
-
"@veltra/directives": "1.1.
|
|
73
|
-
"@veltra/icons": "1.1.
|
|
74
|
-
"@veltra/styles": "1.1.
|
|
75
|
-
"@veltra/utils": "1.1.
|
|
71
|
+
"@veltra/compositions": "1.1.33",
|
|
72
|
+
"@veltra/directives": "1.1.33",
|
|
73
|
+
"@veltra/icons": "1.1.33",
|
|
74
|
+
"@veltra/styles": "1.1.33",
|
|
75
|
+
"@veltra/utils": "1.1.33",
|
|
76
76
|
"vue": ">=3.5.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createVNode, render, type VNode } from 'vue'
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
import
|
|
3
|
+
import type { ContextmenuProps } from '../../types'
|
|
4
|
+
import UContextmenu from './contextmenu.vue'
|
|
5
5
|
|
|
6
6
|
let node: VNode
|
|
7
7
|
|
|
8
8
|
export const contextmenu = {
|
|
9
|
-
pop(options:
|
|
9
|
+
pop(options: ContextmenuProps): void {
|
|
10
10
|
if (node) {
|
|
11
11
|
render(null, document.body)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
node = createVNode(
|
|
14
|
+
node = createVNode(UContextmenu, {
|
|
15
15
|
...options,
|
|
16
16
|
onDestroy() {
|
|
17
17
|
render(null, document.body)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li
|
|
3
|
+
:class="[cls.e('item'), bem.is('disabled', disabled), bem.is('loading', loading)]"
|
|
4
|
+
v-ripple="!disabled && !loading"
|
|
5
|
+
@click="handleClickMenu"
|
|
6
|
+
>
|
|
7
|
+
<div :class="cls.e('item-content')">
|
|
8
|
+
<template v-if="showIconColumn">
|
|
9
|
+
<u-icon v-if="loading" :class="bem.is('loading')">
|
|
10
|
+
<Loading />
|
|
11
|
+
</u-icon>
|
|
12
|
+
<u-icon v-else-if="menu.icon">
|
|
13
|
+
<component :is="menu.icon" />
|
|
14
|
+
</u-icon>
|
|
15
|
+
<i v-else :class="cls.e('icon-place')"></i>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<span :class="cls.e('label')">{{ menu.label }}</span>
|
|
19
|
+
|
|
20
|
+
<i v-if="showArrowColumn" :class="cls.e('arrow-place')"></i>
|
|
21
|
+
</div>
|
|
22
|
+
</li>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script lang="ts" setup>
|
|
26
|
+
import { vRipple } from '@veltra/directives'
|
|
27
|
+
import { Loading } from '@veltra/icons/normal'
|
|
28
|
+
import { bem } from '@veltra/utils'
|
|
29
|
+
import { computed, inject, shallowRef } from 'vue'
|
|
30
|
+
|
|
31
|
+
import type { ContextmenuItem } from '../../types'
|
|
32
|
+
import { UIcon } from '../icon'
|
|
33
|
+
import { ContextmenuPanelDIKey, ContextmenuRootDIKey } from './di'
|
|
34
|
+
import { getMenuDisabled } from './helper'
|
|
35
|
+
|
|
36
|
+
defineOptions({ name: 'ContextmenuItem' })
|
|
37
|
+
|
|
38
|
+
const { menu } = defineProps<{ menu: ContextmenuItem }>()
|
|
39
|
+
|
|
40
|
+
const { cls, onItemClickStart, onItemClickEnd } = inject(ContextmenuRootDIKey)!
|
|
41
|
+
const { showIconColumn, showArrowColumn } = inject(ContextmenuPanelDIKey)!
|
|
42
|
+
|
|
43
|
+
const loading = shallowRef(false)
|
|
44
|
+
const disabled = computed(() => getMenuDisabled(menu))
|
|
45
|
+
|
|
46
|
+
function handleClickMenu() {
|
|
47
|
+
if (disabled.value || loading.value) return
|
|
48
|
+
onItemClickStart()
|
|
49
|
+
loading.value = true
|
|
50
|
+
|
|
51
|
+
const done = () => {
|
|
52
|
+
onItemClickEnd()
|
|
53
|
+
loading.value = false
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const result = menu.callback?.()
|
|
57
|
+
if (result instanceof Promise) {
|
|
58
|
+
result.finally(done)
|
|
59
|
+
} else {
|
|
60
|
+
done()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ul v-bind="$attrs">
|
|
3
|
+
<template v-for="(menu, index) of menus" :key="index">
|
|
4
|
+
<UContextmenuSub v-if="menu.children?.length" :menu="menu" />
|
|
5
|
+
<UContextmenuItem v-else :menu="menu" />
|
|
6
|
+
</template>
|
|
7
|
+
</ul>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script lang="ts" setup>
|
|
11
|
+
import { computed, inject, provide } from 'vue'
|
|
12
|
+
|
|
13
|
+
import type { ContextmenuItem } from '../../types'
|
|
14
|
+
import UContextmenuItem from './contextmenu-item.vue'
|
|
15
|
+
import UContextmenuSub from './contextmenu-sub.vue'
|
|
16
|
+
import { ContextmenuPanelDIKey, ContextmenuRootDIKey } from './di'
|
|
17
|
+
|
|
18
|
+
defineOptions({ name: 'ContextmenuPanel', inheritAttrs: false })
|
|
19
|
+
|
|
20
|
+
const { menus } = defineProps<{ menus: ContextmenuItem[] }>()
|
|
21
|
+
|
|
22
|
+
inject(ContextmenuRootDIKey)
|
|
23
|
+
|
|
24
|
+
const showIconColumn = computed(() => menus.some((menu) => !!menu.icon))
|
|
25
|
+
const showArrowColumn = computed(() => menus.some((menu) => !!menu.children?.length))
|
|
26
|
+
|
|
27
|
+
provide(ContextmenuPanelDIKey, { showIconColumn, showArrowColumn })
|
|
28
|
+
</script>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li
|
|
3
|
+
:class="[
|
|
4
|
+
cls.e('item'),
|
|
5
|
+
bem.is('disabled', disabled),
|
|
6
|
+
bem.is('open', subVisible),
|
|
7
|
+
bem.is('flip-x', flipX)
|
|
8
|
+
]"
|
|
9
|
+
@mouseenter="handleMouseEnter"
|
|
10
|
+
@mouseleave="scheduleClose"
|
|
11
|
+
>
|
|
12
|
+
<div :class="cls.e('item-content')">
|
|
13
|
+
<template v-if="showIconColumn">
|
|
14
|
+
<u-icon v-if="menu.icon">
|
|
15
|
+
<component :is="menu.icon" />
|
|
16
|
+
</u-icon>
|
|
17
|
+
<i v-else :class="cls.e('icon-place')"></i>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<span :class="cls.e('label')">{{ menu.label }}</span>
|
|
21
|
+
|
|
22
|
+
<u-icon v-if="showArrowColumn" :class="cls.e('arrow')">
|
|
23
|
+
<ArrowRight />
|
|
24
|
+
</u-icon>
|
|
25
|
+
<i v-else :class="cls.e('arrow-place')"></i>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<UContextmenuPanel
|
|
29
|
+
v-show="subVisible"
|
|
30
|
+
:menus="menu.children!"
|
|
31
|
+
:class="[cls.e('sub'), bem.is('flip-x', flipX)]"
|
|
32
|
+
@mouseenter="cancelClose"
|
|
33
|
+
@mouseleave="scheduleClose"
|
|
34
|
+
/>
|
|
35
|
+
</li>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script lang="ts" setup>
|
|
39
|
+
import { ArrowRight } from '@veltra/icons/normal'
|
|
40
|
+
import { bem } from '@veltra/utils'
|
|
41
|
+
import { computed, inject, nextTick, onBeforeUnmount, shallowRef } from 'vue'
|
|
42
|
+
|
|
43
|
+
import type { ContextmenuItem } from '../../types'
|
|
44
|
+
import { UIcon } from '../icon'
|
|
45
|
+
import UContextmenuPanel from './contextmenu-panel.vue'
|
|
46
|
+
import { ContextmenuPanelDIKey, ContextmenuRootDIKey } from './di'
|
|
47
|
+
import { getMenuDisabled } from './helper'
|
|
48
|
+
|
|
49
|
+
defineOptions({ name: 'ContextmenuSub' })
|
|
50
|
+
|
|
51
|
+
const { menu } = defineProps<{ menu: ContextmenuItem }>()
|
|
52
|
+
|
|
53
|
+
const { cls } = inject(ContextmenuRootDIKey)!
|
|
54
|
+
const { showIconColumn, showArrowColumn } = inject(ContextmenuPanelDIKey)!
|
|
55
|
+
|
|
56
|
+
const subVisible = shallowRef(false)
|
|
57
|
+
const flipX = shallowRef(false)
|
|
58
|
+
|
|
59
|
+
let closeTimer: ReturnType<typeof setTimeout> | undefined
|
|
60
|
+
|
|
61
|
+
const disabled = computed(() => getMenuDisabled(menu))
|
|
62
|
+
|
|
63
|
+
function cancelClose() {
|
|
64
|
+
if (closeTimer !== undefined) {
|
|
65
|
+
clearTimeout(closeTimer)
|
|
66
|
+
closeTimer = undefined
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function scheduleClose() {
|
|
71
|
+
cancelClose()
|
|
72
|
+
closeTimer = setTimeout(() => {
|
|
73
|
+
subVisible.value = false
|
|
74
|
+
}, 250)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function handleMouseEnter(e: MouseEvent) {
|
|
78
|
+
if (disabled.value) return
|
|
79
|
+
cancelClose()
|
|
80
|
+
subVisible.value = true
|
|
81
|
+
nextTick(() => {
|
|
82
|
+
const panel = (e.currentTarget as HTMLElement).querySelector<HTMLElement>(`.${cls.e('sub')}`)
|
|
83
|
+
if (panel) flipX.value = panel.getBoundingClientRect().right > window.innerWidth
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onBeforeUnmount(cancelClose)
|
|
88
|
+
</script>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport to="body">
|
|
3
|
+
<transition name="zoom-in" appear @after-leave="emit('destroy')">
|
|
4
|
+
<UContextmenuPanel
|
|
5
|
+
v-if="visible"
|
|
6
|
+
:menus="menus"
|
|
7
|
+
:class="[cls.b, cls.m(size)]"
|
|
8
|
+
:style="style"
|
|
9
|
+
v-click-outside="handleClickOutside"
|
|
10
|
+
/>
|
|
11
|
+
</transition>
|
|
12
|
+
</Teleport>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
import { useFallbackProps } from '@veltra/compositions'
|
|
17
|
+
import { vClickOutside } from '@veltra/directives'
|
|
18
|
+
import { bem, withUnit, zIndex } from '@veltra/utils'
|
|
19
|
+
import { computed, provide, shallowRef, type CSSProperties } from 'vue'
|
|
20
|
+
|
|
21
|
+
import type { ContextmenuEmits, ContextmenuProps, ComponentSize } from '../../types'
|
|
22
|
+
import UContextmenuPanel from './contextmenu-panel.vue'
|
|
23
|
+
import { ContextmenuRootDIKey } from './di'
|
|
24
|
+
|
|
25
|
+
defineOptions({ name: 'Contextmenu' })
|
|
26
|
+
|
|
27
|
+
const props = withDefaults(defineProps<ContextmenuProps>(), { width: 150 })
|
|
28
|
+
|
|
29
|
+
const emit = defineEmits<ContextmenuEmits>()
|
|
30
|
+
|
|
31
|
+
const { size } = useFallbackProps([props], { size: 'default' as ComponentSize })
|
|
32
|
+
|
|
33
|
+
const cls = bem('contextmenu')
|
|
34
|
+
|
|
35
|
+
const visible = shallowRef(true)
|
|
36
|
+
|
|
37
|
+
const style = computed<CSSProperties>(() => {
|
|
38
|
+
const { x, y } = props.mousePosition
|
|
39
|
+
const flipX = x > window.innerWidth / 2
|
|
40
|
+
const flipY = y > window.innerHeight / 2
|
|
41
|
+
return {
|
|
42
|
+
width: withUnit(props.width, 'px'),
|
|
43
|
+
zIndex: zIndex(),
|
|
44
|
+
...(flipX
|
|
45
|
+
? { right: withUnit(window.innerWidth - x - 1, 'px') }
|
|
46
|
+
: { left: withUnit(x + 1, 'px') }),
|
|
47
|
+
...(flipY
|
|
48
|
+
? { bottom: withUnit(window.innerHeight - y - 1, 'px') }
|
|
49
|
+
: { top: withUnit(y + 1, 'px') }),
|
|
50
|
+
transformOrigin: `${flipY ? 'bottom' : 'top'} ${flipX ? 'right' : 'left'}`
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const menus = computed(() => (typeof props.menus === 'function' ? props.menus() : props.menus))
|
|
55
|
+
|
|
56
|
+
function close() {
|
|
57
|
+
visible.value = false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let loading = false
|
|
61
|
+
|
|
62
|
+
provide(ContextmenuRootDIKey, {
|
|
63
|
+
cls,
|
|
64
|
+
onItemClickStart: () => {
|
|
65
|
+
loading = true
|
|
66
|
+
},
|
|
67
|
+
onItemClickEnd: () => {
|
|
68
|
+
loading = false
|
|
69
|
+
close()
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
function handleClickOutside() {
|
|
74
|
+
if (loading) return
|
|
75
|
+
close()
|
|
76
|
+
}
|
|
77
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BEM } from '@veltra/utils'
|
|
2
|
+
import type { ComputedRef, InjectionKey } from 'vue'
|
|
3
|
+
|
|
4
|
+
export const ContextmenuRootDIKey: InjectionKey<{
|
|
5
|
+
cls: BEM<'contextmenu'>
|
|
6
|
+
onItemClickStart: () => void
|
|
7
|
+
onItemClickEnd: () => void
|
|
8
|
+
}> = Symbol('ContextmenuRootDIKey')
|
|
9
|
+
|
|
10
|
+
export const ContextmenuPanelDIKey: InjectionKey<{
|
|
11
|
+
showIconColumn: ComputedRef<boolean>
|
|
12
|
+
showArrowColumn: ComputedRef<boolean>
|
|
13
|
+
}> = Symbol('ContextmenuPanelDIKey')
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
@use 'pkg:@veltra/styles/mixins' as m;
|
|
2
|
+
@use 'pkg:@veltra/styles/functions' as fn;
|
|
3
|
+
|
|
4
|
+
$root-name: contextmenu;
|
|
5
|
+
$arrow-size: 12px;
|
|
6
|
+
|
|
7
|
+
@mixin panel-surface {
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 4px;
|
|
10
|
+
list-style: none;
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: 1px;
|
|
14
|
+
user-select: none;
|
|
15
|
+
color: fn.use-var(text-color, main);
|
|
16
|
+
background-color: fn.use-var(bg-color, top);
|
|
17
|
+
border: 1px solid fn.use-var(border, color);
|
|
18
|
+
border-radius: calc(fn.use-var(radius, default) + 2px);
|
|
19
|
+
box-shadow:
|
|
20
|
+
0 1px 2px rgba(15, 23, 42, 0.05),
|
|
21
|
+
0 8px 20px rgba(15, 23, 42, 0.08);
|
|
22
|
+
backdrop-filter: fn.use-var(bg-filter);
|
|
23
|
+
-webkit-backdrop-filter: fn.use-var(bg-filter);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@include m.b($root-name) {
|
|
27
|
+
$b: &;
|
|
28
|
+
|
|
29
|
+
position: fixed;
|
|
30
|
+
@include panel-surface;
|
|
31
|
+
|
|
32
|
+
@include m.e(label) {
|
|
33
|
+
flex: 1;
|
|
34
|
+
min-width: 0;
|
|
35
|
+
@include m.ellipsis;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@include m.e(item) {
|
|
39
|
+
position: relative;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
padding: 0;
|
|
42
|
+
|
|
43
|
+
@include m.is(disabled, loading) {
|
|
44
|
+
opacity: 0.55;
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
color: fn.use-var(text-color, disabled);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@include m.is(open) {
|
|
50
|
+
&::after {
|
|
51
|
+
content: '';
|
|
52
|
+
position: absolute;
|
|
53
|
+
top: 0;
|
|
54
|
+
left: 100%;
|
|
55
|
+
width: 6px;
|
|
56
|
+
height: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@include m.is(flip-x) {
|
|
60
|
+
&::after {
|
|
61
|
+
left: auto;
|
|
62
|
+
right: 100%;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@include m.e(item-content) {
|
|
69
|
+
gap: 8px;
|
|
70
|
+
width: 100%;
|
|
71
|
+
padding: 0 8px;
|
|
72
|
+
min-height: 28px;
|
|
73
|
+
border-radius: calc(fn.use-var(radius, default) + 1px);
|
|
74
|
+
transition:
|
|
75
|
+
background-color 0.15s ease,
|
|
76
|
+
color 0.15s ease;
|
|
77
|
+
@include m.flex($align: center);
|
|
78
|
+
|
|
79
|
+
#{$b}__item:not(.is-disabled):not(.is-loading) > & {
|
|
80
|
+
&:hover {
|
|
81
|
+
background-color: var(--u-menu-hover-bg);
|
|
82
|
+
color: var(--u-menu-hover-color);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#{$b}__item.is-open:not(.is-disabled) > #{$b}__item-content {
|
|
88
|
+
background-color: var(--u-menu-hover-bg);
|
|
89
|
+
color: var(--u-menu-hover-color);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@include m.e(icon-place) {
|
|
93
|
+
width: 1em;
|
|
94
|
+
flex-shrink: 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@include m.e(arrow) {
|
|
98
|
+
width: $arrow-size;
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
font-size: $arrow-size;
|
|
101
|
+
opacity: 0.65;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@include m.e(arrow-place) {
|
|
105
|
+
width: $arrow-size;
|
|
106
|
+
flex-shrink: 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@include m.e(sub) {
|
|
110
|
+
position: absolute;
|
|
111
|
+
top: 0;
|
|
112
|
+
left: 100%;
|
|
113
|
+
margin-left: -4px;
|
|
114
|
+
min-width: 120px;
|
|
115
|
+
width: max-content;
|
|
116
|
+
@include panel-surface;
|
|
117
|
+
|
|
118
|
+
@include m.is(flip-x) {
|
|
119
|
+
left: auto;
|
|
120
|
+
right: 100%;
|
|
121
|
+
margin-left: 0;
|
|
122
|
+
margin-right: -4px;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@include m.size using ($size) {
|
|
127
|
+
font-size: fn.use-var(font-size-main, $size);
|
|
128
|
+
|
|
129
|
+
@include m.e(item-content) {
|
|
130
|
+
padding: 0 fn.use-var(gap, $size);
|
|
131
|
+
min-height: calc(var(--u-menu-height-#{$size}) - 8px);
|
|
132
|
+
border-radius: calc(fn.use-var(radius, $size) + 1px);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|