@veltra/desktop 1.2.3 → 1.2.5
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 +3 -3
- package/dist/components/action/action.vue.d.ts +2 -2
- package/dist/components/auto-complete/auto-complete.js +25 -13
- package/dist/components/auto-complete/auto-complete.js.map +1 -1
- package/dist/components/auto-complete/auto-complete.vue.d.ts +3 -2
- package/dist/components/batch-edit/batch-edit-form.js +33 -26
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-list.js +4 -1
- package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js +29 -50
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -3
- package/dist/components/batch-edit/di.js.map +1 -1
- package/dist/components/batch-edit/style2.css +3 -0
- package/dist/components/batch-edit/use-edit.js +39 -71
- package/dist/components/batch-edit/use-edit.js.map +1 -1
- package/dist/components/batch-edit/use-features.js +38 -0
- package/dist/components/batch-edit/use-features.js.map +1 -0
- package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
- package/dist/components/contextmenu/style2.css +7 -7
- 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/dual-nav/dual-nav-app.js +49 -0
- package/dist/components/dual-nav/dual-nav-app.js.map +1 -0
- package/dist/components/dual-nav/dual-nav.js +125 -0
- package/dist/components/dual-nav/dual-nav.js.map +1 -0
- package/dist/components/dual-nav/dual-nav.vue.d.ts +13 -0
- package/dist/components/dual-nav/helper.js +21 -0
- package/dist/components/dual-nav/helper.js.map +1 -0
- package/dist/components/dual-nav/index.d.ts +1 -0
- package/dist/components/dual-nav/style.js +4 -0
- package/dist/components/dual-nav/style2.css +145 -0
- package/dist/components/empty/empty.vue.d.ts +1 -1
- package/dist/components/index.d.ts +23 -22
- package/dist/components/index.js +28 -26
- package/dist/components/index.js.map +1 -1
- package/dist/components/nav/di.js +7 -0
- package/dist/components/nav/di.js.map +1 -0
- package/dist/components/nav/helper.js +18 -0
- package/dist/components/nav/helper.js.map +1 -0
- package/dist/components/nav/index.d.ts +3 -0
- package/dist/components/{menu/menu-icon.js → nav/nav-icon.js} +4 -4
- package/dist/components/nav/nav-icon.js.map +1 -0
- package/dist/components/{menu/menu-item-collapsed.js → nav/nav-item-collapsed.js} +23 -23
- package/dist/components/nav/nav-item-collapsed.js.map +1 -0
- package/dist/components/{menu/menu-item.js → nav/nav-item.js} +13 -13
- package/dist/components/nav/nav-item.js.map +1 -0
- package/dist/components/{menu/menu-item.vue.d.ts → nav/nav-item.vue.d.ts} +4 -4
- package/dist/components/{menu/menu-sub-collapsed.js → nav/nav-sub-collapsed.js} +19 -19
- package/dist/components/nav/nav-sub-collapsed.js.map +1 -0
- package/dist/components/{menu/menu-sub.js → nav/nav-sub.js} +24 -24
- package/dist/components/nav/nav-sub.js.map +1 -0
- package/dist/components/{menu/menu-sub.vue.d.ts → nav/nav-sub.vue.d.ts} +4 -4
- package/dist/components/{menu/menu.js → nav/nav.js} +45 -36
- package/dist/components/nav/nav.js.map +1 -0
- package/dist/components/nav/nav.vue.d.ts +18 -0
- package/dist/components/nav/style.d.ts +1 -0
- package/dist/components/{menu → nav}/style2.css +105 -105
- package/dist/components/{menu/use-menu-item.js → nav/use-nav-item.js} +11 -11
- package/dist/components/nav/use-nav-item.js.map +1 -0
- package/dist/components/{menu/walk-menu-path.js → nav/walk-nav-path.js} +5 -5
- package/dist/components/nav/walk-nav-path.js.map +1 -0
- package/dist/components/number/number.vue.d.ts +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/select/style2.css +4 -4
- package/dist/components/table/use-columns.js +14 -12
- package/dist/components/table/use-columns.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/watermark/watermark.vue.d.ts +1 -1
- package/dist/index.d.ts +63 -61
- package/dist/index.js +56 -55
- package/dist/style.js +2 -1
- package/dist/types/auto-complete.d.ts +6 -1
- package/dist/types/batch-edit.d.ts +15 -2
- package/dist/types/dual-nav.d.ts +27 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/nav.d.ts +48 -0
- package/package.json +6 -6
- package/src/components/auto-complete/auto-complete.vue +24 -13
- package/src/components/batch-edit/batch-edit-form.vue +29 -18
- package/src/components/batch-edit/batch-edit-list.vue +6 -1
- package/src/components/batch-edit/batch-edit.vue +36 -73
- package/src/components/batch-edit/di.ts +3 -1
- package/src/components/batch-edit/style.scss +5 -0
- package/src/components/batch-edit/use-edit.ts +63 -116
- package/src/components/batch-edit/use-features.ts +58 -0
- package/src/components/contextmenu/style.scss +5 -5
- package/src/components/dual-nav/dual-nav-app.vue +33 -0
- package/src/components/dual-nav/dual-nav.vue +150 -0
- package/src/components/dual-nav/helper.ts +25 -0
- package/src/components/dual-nav/index.ts +1 -0
- package/src/components/dual-nav/style.scss +153 -0
- package/src/components/dual-nav/style.ts +4 -0
- package/src/components/index.ts +3 -1
- package/src/components/nav/di.ts +17 -0
- package/src/components/nav/helper.ts +22 -0
- package/src/components/nav/index.ts +3 -0
- package/src/components/{menu/menu-icon.vue → nav/nav-icon.vue} +1 -1
- package/src/components/nav/nav-item-collapsed.vue +66 -0
- package/src/components/nav/nav-item.vue +36 -0
- package/src/components/{menu/menu-sub-collapsed.vue → nav/nav-sub-collapsed.vue} +15 -15
- package/src/components/{menu/menu-sub.vue → nav/nav-sub.vue} +19 -19
- package/src/components/{menu/menu.vue → nav/nav.vue} +42 -42
- package/src/components/{menu → nav}/style.scss +16 -14
- package/src/components/{menu/use-menu-item.ts → nav/use-nav-item.ts} +14 -14
- package/src/components/{menu/walk-menu-path.ts → nav/walk-nav-path.ts} +2 -2
- package/src/components/select/style.scss +4 -4
- package/src/components/table/use-columns.ts +23 -20
- package/src/style.ts +2 -1
- package/src/types/auto-complete.ts +6 -1
- package/src/types/batch-edit.ts +18 -1
- package/src/types/dual-nav.ts +28 -0
- package/src/types/index.ts +2 -1
- package/src/types/nav.ts +49 -0
- package/dist/components/menu/di.js +0 -7
- package/dist/components/menu/di.js.map +0 -1
- package/dist/components/menu/helper.js +0 -8
- package/dist/components/menu/helper.js.map +0 -1
- package/dist/components/menu/index.d.ts +0 -3
- package/dist/components/menu/menu-icon.js.map +0 -1
- package/dist/components/menu/menu-item-collapsed.js.map +0 -1
- package/dist/components/menu/menu-item.js.map +0 -1
- package/dist/components/menu/menu-sub-collapsed.js.map +0 -1
- package/dist/components/menu/menu-sub.js.map +0 -1
- package/dist/components/menu/menu.js.map +0 -1
- package/dist/components/menu/menu.vue.d.ts +0 -14
- package/dist/components/menu/use-menu-item.js.map +0 -1
- package/dist/components/menu/walk-menu-path.js.map +0 -1
- package/dist/types/menu.d.ts +0 -40
- package/src/components/menu/di.ts +0 -17
- package/src/components/menu/helper.ts +0 -3
- package/src/components/menu/index.ts +0 -3
- package/src/components/menu/menu-item-collapsed.vue +0 -66
- package/src/components/menu/menu-item.vue +0 -36
- package/src/components/menu/menu-node.ts +0 -6
- package/src/types/menu.ts +0 -41
- /package/dist/components/{menu → dual-nav}/style.d.ts +0 -0
- /package/dist/components/{menu → nav}/style.js +0 -0
- /package/src/components/{menu → nav}/style.ts +0 -0
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
@use 'pkg:@veltra/styles/vars';
|
|
4
4
|
|
|
5
5
|
// 方便拼接
|
|
6
|
-
$root-name:
|
|
7
|
-
$collapsed-
|
|
6
|
+
$root-name: nav;
|
|
7
|
+
$collapsed-nav: collapsed-nav;
|
|
8
8
|
|
|
9
|
-
@include m.b($root-name, $collapsed-
|
|
9
|
+
@include m.b($root-name, $collapsed-nav) {
|
|
10
10
|
user-select: none;
|
|
11
|
-
color: var(--u-
|
|
11
|
+
color: var(--u-nav-color);
|
|
12
12
|
|
|
13
13
|
@include m.e(item, sub, sub-list) {
|
|
14
14
|
list-style: none;
|
|
@@ -28,8 +28,8 @@ $collapsed-menu: collapsed-menu;
|
|
|
28
28
|
@include m.flex;
|
|
29
29
|
|
|
30
30
|
&:hover {
|
|
31
|
-
background-color: var(--u-
|
|
32
|
-
color: var(--u-
|
|
31
|
+
background-color: var(--u-nav-hover-bg);
|
|
32
|
+
color: var(--u-nav-hover-color);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
@include m.is(expanded, branch-active) {
|
|
@@ -38,8 +38,8 @@ $collapsed-menu: collapsed-menu;
|
|
|
38
38
|
|
|
39
39
|
@include m.is(active) {
|
|
40
40
|
position: relative;
|
|
41
|
-
background-color: var(--u-
|
|
42
|
-
color: var(--u-
|
|
41
|
+
background-color: var(--u-nav-active-bg);
|
|
42
|
+
color: var(--u-nav-active-color);
|
|
43
43
|
|
|
44
44
|
&::before {
|
|
45
45
|
content: '';
|
|
@@ -55,7 +55,9 @@ $collapsed-menu: collapsed-menu;
|
|
|
55
55
|
pointer-events: none;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
}
|
|
58
59
|
|
|
60
|
+
@include m.e(item) {
|
|
59
61
|
@include m.is(disabled) {
|
|
60
62
|
opacity: 0.55;
|
|
61
63
|
cursor: not-allowed;
|
|
@@ -84,7 +86,7 @@ $collapsed-menu: collapsed-menu;
|
|
|
84
86
|
|
|
85
87
|
#{$b}__item,
|
|
86
88
|
#{$b}__sub-content {
|
|
87
|
-
min-height: var(--u-
|
|
89
|
+
min-height: var(--u-nav-height-#{$size});
|
|
88
90
|
border-radius: calc(fn.use-var(radius, $size) + 4px);
|
|
89
91
|
}
|
|
90
92
|
|
|
@@ -104,10 +106,10 @@ $collapsed-menu: collapsed-menu;
|
|
|
104
106
|
@include m.b($root-name) {
|
|
105
107
|
margin: 0;
|
|
106
108
|
padding: 0;
|
|
107
|
-
background-color: var(--u-
|
|
109
|
+
background-color: var(--u-nav-bg-color);
|
|
108
110
|
backdrop-filter: fn.use-var(bg-filter);
|
|
109
111
|
-webkit-backdrop-filter: fn.use-var(bg-filter);
|
|
110
|
-
background-image: var(--u-
|
|
112
|
+
background-image: var(--u-nav-bg-image);
|
|
111
113
|
background-size: cover;
|
|
112
114
|
background-repeat: no-repeat;
|
|
113
115
|
border: 1px solid fn.use-var(border, color);
|
|
@@ -170,7 +172,7 @@ $collapsed-menu: collapsed-menu;
|
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
174
|
|
|
173
|
-
@include m.b($collapsed-
|
|
175
|
+
@include m.b($collapsed-nav) {
|
|
174
176
|
margin: 0;
|
|
175
177
|
padding: 0;
|
|
176
178
|
|
|
@@ -184,7 +186,7 @@ $collapsed-menu: collapsed-menu;
|
|
|
184
186
|
@include m.is(first-level) {
|
|
185
187
|
justify-content: center;
|
|
186
188
|
|
|
187
|
-
@include m.bem($collapsed-
|
|
189
|
+
@include m.bem($collapsed-nav, icon) {
|
|
188
190
|
margin-right: 0;
|
|
189
191
|
}
|
|
190
192
|
}
|
|
@@ -212,7 +214,7 @@ $collapsed-menu: collapsed-menu;
|
|
|
212
214
|
@include m.e(panel) {
|
|
213
215
|
min-width: 240px;
|
|
214
216
|
padding: 8px !important;
|
|
215
|
-
background-color: var(--u-
|
|
217
|
+
background-color: var(--u-nav-bg-color);
|
|
216
218
|
backdrop-filter: fn.use-var(bg-filter);
|
|
217
219
|
-webkit-backdrop-filter: fn.use-var(bg-filter);
|
|
218
220
|
border: 1px solid fn.use-var(border, color);
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { scrollIntoContainerView, type BEM } from '@veltra/utils'
|
|
2
2
|
import { computed, inject, watch, type ShallowRef, type ComputedRef } from 'vue'
|
|
3
3
|
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
4
|
+
import type { NavItem } from '../../types'
|
|
5
|
+
import { NavDIKey } from './di'
|
|
6
6
|
|
|
7
7
|
interface Options {
|
|
8
|
-
itemProps: {
|
|
8
|
+
itemProps: { item: NavItem; depth: number }
|
|
9
9
|
itemRef: ShallowRef<HTMLElement | null>
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
interface
|
|
13
|
-
cls: BEM<'
|
|
14
|
-
collapsedCls: BEM<'collapsed-
|
|
12
|
+
interface UseNavItemReturned {
|
|
13
|
+
cls: BEM<'nav'>
|
|
14
|
+
collapsedCls: BEM<'collapsed-nav'>
|
|
15
15
|
|
|
16
16
|
active: ComputedRef<boolean>
|
|
17
|
-
|
|
17
|
+
handleClickItem: () => void
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export function
|
|
20
|
+
export function useNavItem(options: Options): UseNavItemReturned {
|
|
21
21
|
const { itemProps, itemRef } = options
|
|
22
|
-
const { cls, collapsedCls,
|
|
22
|
+
const { cls, collapsedCls, navProps, navEmit } = inject(NavDIKey)!
|
|
23
23
|
|
|
24
24
|
const active = computed(() => {
|
|
25
|
-
return
|
|
25
|
+
return navProps.currentPath === itemProps.item.path
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
let changedByClick = false
|
|
@@ -35,10 +35,10 @@ export function useMenuItem(options: Options): UseMenuItemReturned {
|
|
|
35
35
|
scrollIntoContainerView(itemEl, null)
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
function
|
|
39
|
-
if (itemProps.
|
|
38
|
+
function handleClickItem() {
|
|
39
|
+
if (itemProps.item.disabled) return
|
|
40
40
|
changedByClick = true
|
|
41
|
-
|
|
41
|
+
navEmit('item-click', itemProps.item)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
return {
|
|
@@ -46,6 +46,6 @@ export function useMenuItem(options: Options): UseMenuItemReturned {
|
|
|
46
46
|
collapsedCls,
|
|
47
47
|
|
|
48
48
|
active,
|
|
49
|
-
|
|
49
|
+
handleClickItem
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 深度优先 + 路径;回调返回 `false` 时剪枝当前节点子树(不中断兄弟)。
|
|
3
3
|
* `@cat-kit/core` 的 `dfs` 在返回 `true` 时会终止整段遍历,语义不同,故保留此辅助。
|
|
4
4
|
*/
|
|
5
|
-
export function
|
|
5
|
+
export function walkNavWithPath<T extends Record<string, unknown>>(
|
|
6
6
|
data: T,
|
|
7
7
|
cb: (node: T, path: T[]) => void | false,
|
|
8
8
|
childrenKey = 'children',
|
|
@@ -13,6 +13,6 @@ export function walkMenuWithPath<T extends Record<string, unknown>>(
|
|
|
13
13
|
const raw = data[childrenKey]
|
|
14
14
|
if (!Array.isArray(raw)) return
|
|
15
15
|
for (let i = 0; i < raw.length; i++) {
|
|
16
|
-
|
|
16
|
+
walkNavWithPath(raw[i] as T, cb, childrenKey, path)
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -68,14 +68,14 @@ $root-name: select;
|
|
|
68
68
|
@include m.ellipsis;
|
|
69
69
|
|
|
70
70
|
&:hover {
|
|
71
|
-
background-color: var(--u-
|
|
72
|
-
color: var(--u-
|
|
71
|
+
background-color: var(--u-nav-hover-bg);
|
|
72
|
+
color: var(--u-nav-hover-color);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
@include m.is(selected) {
|
|
76
76
|
position: relative;
|
|
77
|
-
background-color: var(--u-
|
|
78
|
-
color: var(--u-
|
|
77
|
+
background-color: var(--u-nav-active-bg);
|
|
78
|
+
color: var(--u-nav-active-color);
|
|
79
79
|
font-weight: 600;
|
|
80
80
|
|
|
81
81
|
&::before {
|
|
@@ -134,26 +134,29 @@ export function useColumns(options: Options): ColumnConfig {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
const sortedColumns = [...fixedOnLeft, ...unfixed, ...fixedOnRight]
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
137
|
+
|
|
138
|
+
if (sortedColumns.length > 0) {
|
|
139
|
+
// 操作时避免改变原数据
|
|
140
|
+
const firstColumn = { ...sortedColumns[0] } as TableColumn
|
|
141
|
+
sortedColumns[0] = firstColumn
|
|
142
|
+
|
|
143
|
+
// 树形表格需要给第一列添加展开按钮
|
|
144
|
+
// 因此要重新设置第一列的宽度和对齐方式
|
|
145
|
+
if (tree || expandable) {
|
|
146
|
+
firstColumn.align = 'left'
|
|
147
|
+
firstColumn.width = firstColumn.width ? firstColumn.width + 60 : undefined
|
|
148
|
+
|
|
149
|
+
const oldNameRender = firstColumn.nameRender
|
|
150
|
+
|
|
151
|
+
firstColumn.nameRender = oldNameRender
|
|
152
|
+
? (ctx) => {
|
|
153
|
+
const oldNodes = oldNameRender!(ctx)
|
|
154
|
+
return [renderExpandAll(), ...(Array.isArray(oldNodes) ? oldNodes : [oldNodes])]
|
|
155
|
+
}
|
|
156
|
+
: () => {
|
|
157
|
+
return [renderExpandAll(), firstColumn.name]
|
|
158
|
+
}
|
|
159
|
+
}
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
const result = new Forest<TableColumn, any>({
|
package/src/style.ts
CHANGED
|
@@ -37,7 +37,8 @@ import './components/input/style'
|
|
|
37
37
|
import './components/layout/style'
|
|
38
38
|
import './components/list/style'
|
|
39
39
|
import './components/loading/style'
|
|
40
|
-
import './components/
|
|
40
|
+
import './components/dual-nav/style'
|
|
41
|
+
import './components/nav/style'
|
|
41
42
|
import './components/message-confirm/style'
|
|
42
43
|
import './components/message/style'
|
|
43
44
|
import './components/multi-select/style'
|
|
@@ -9,6 +9,8 @@ export interface AutoCompleteProps extends FormComponentProps {
|
|
|
9
9
|
suggestions?: string[] | (() => Promise<string[]> | string[])
|
|
10
10
|
/** 是否可清空 */
|
|
11
11
|
clearable?: boolean
|
|
12
|
+
/** 是否允许输入不在建议列表中的自定义值 */
|
|
13
|
+
allowCustom?: boolean
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/** 自动补全组件组件定义的事件 */
|
|
@@ -18,7 +20,10 @@ export interface AutoCompleteEmits {
|
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/** 自动补全组件组件暴露的属性和方法(组件内部使用) */
|
|
21
|
-
export interface _AutoCompleteExposed {
|
|
23
|
+
export interface _AutoCompleteExposed {
|
|
24
|
+
open: () => void
|
|
25
|
+
close: () => void
|
|
26
|
+
}
|
|
22
27
|
|
|
23
28
|
/** 自动补全组件组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
24
29
|
export type AutoCompleteExposed = DeconstructValue<_AutoCompleteExposed>
|
package/src/types/batch-edit.ts
CHANGED
|
@@ -18,6 +18,9 @@ export interface BatchEditColumn extends TableColumn {
|
|
|
18
18
|
|
|
19
19
|
export type BatchEditFeature = 'create' | 'update' | 'copy' | 'delete' | 'view' | 'createChild'
|
|
20
20
|
|
|
21
|
+
/** 批量编辑模式 */
|
|
22
|
+
export type BatchEditMode = 'normal' | 'quick'
|
|
23
|
+
|
|
21
24
|
/** 批量编辑组件属性 */
|
|
22
25
|
export interface BatchEditProps extends TableProps {
|
|
23
26
|
/**
|
|
@@ -33,13 +36,27 @@ export interface BatchEditProps extends TableProps {
|
|
|
33
36
|
cols?: string | [string, string]
|
|
34
37
|
/** 只读模式 */
|
|
35
38
|
readonly?: boolean
|
|
39
|
+
/**
|
|
40
|
+
* 编辑模式
|
|
41
|
+
* @default 'normal'
|
|
42
|
+
* @description `quick` 模式下编辑行时表单直接绑定 `row.data` 实时更新,且不调用 `saveMethod`
|
|
43
|
+
*/
|
|
44
|
+
mode?: BatchEditMode
|
|
45
|
+
/**
|
|
46
|
+
* 新增前的钩子
|
|
47
|
+
* @description 仅作用于 create 类操作。`normal` 模式在保存时调用;`quick` 模式在点击新增类按钮时立即调用。可直接修改传入的 draft 对象
|
|
48
|
+
*/
|
|
49
|
+
beforeCreate?: (
|
|
50
|
+
data: Record<string, any>,
|
|
51
|
+
parentData?: Record<string, any>
|
|
52
|
+
) => void | Promise<void>
|
|
36
53
|
/** label的宽度 */
|
|
37
54
|
labelWidth?: string | number
|
|
38
55
|
/** 删除方法 */
|
|
39
56
|
deleteMethod?: (data: Record<string, any>[]) => any
|
|
40
57
|
/**
|
|
41
58
|
* 保存方法
|
|
42
|
-
* @description
|
|
59
|
+
* @description 仅在 `normal` 模式下、保存时调用(create / update)
|
|
43
60
|
* @returns 如果返回一个值,那么这个值会被插入,否则插入的为表单值
|
|
44
61
|
*/
|
|
45
62
|
saveMethod?: (
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DeconstructValue } from '@veltra/utils'
|
|
2
|
+
|
|
3
|
+
import type { NavItem } from './nav'
|
|
4
|
+
|
|
5
|
+
/** 双栏导航根级应用项;`description` 仅在此层级生效,且仅在双栏导航右栏展示 */
|
|
6
|
+
export interface DualNavRootItem extends NavItem {
|
|
7
|
+
/** 子导航 */
|
|
8
|
+
children?: NavItem[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** 双栏导航组件属性 */
|
|
12
|
+
export interface DualNavProps {
|
|
13
|
+
/** 当前路径 */
|
|
14
|
+
currentPath?: string
|
|
15
|
+
/** 根级应用导航列表 */
|
|
16
|
+
menus?: DualNavRootItem[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 双栏导航组件定义的事件 */
|
|
20
|
+
export interface DualNavEmits {
|
|
21
|
+
(e: 'item-click', item: NavItem): void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 双栏导航组件暴露的属性和方法(组件内部使用) */
|
|
25
|
+
export interface _DualNavExposed {}
|
|
26
|
+
|
|
27
|
+
/** 双栏导航组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
28
|
+
export type DualNavExposed = DeconstructValue<_DualNavExposed>
|
package/src/types/index.ts
CHANGED
|
@@ -47,7 +47,8 @@ export * from './text'
|
|
|
47
47
|
export * from './checkbox-group'
|
|
48
48
|
export * from './table-editor'
|
|
49
49
|
export * from './table'
|
|
50
|
-
export * from './
|
|
50
|
+
export * from './nav'
|
|
51
|
+
export * from './dual-nav'
|
|
51
52
|
export * from './password-input'
|
|
52
53
|
export * from './date-picker'
|
|
53
54
|
export * from './dropdown'
|
package/src/types/nav.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { DeconstructValue } from '@veltra/utils'
|
|
2
|
+
import type { DefineComponent } from 'vue'
|
|
3
|
+
|
|
4
|
+
/** 导航项 */
|
|
5
|
+
export interface NavItem {
|
|
6
|
+
/** 图标 */
|
|
7
|
+
icon?: string | DefineComponent
|
|
8
|
+
/** 导航标题 */
|
|
9
|
+
title: string
|
|
10
|
+
/** 导航路径 */
|
|
11
|
+
path: string
|
|
12
|
+
/**
|
|
13
|
+
* 应用描述;仅根级导航项有效,且仅 UDualNav 右栏顶部展示
|
|
14
|
+
* @see DualNavRootItem
|
|
15
|
+
*/
|
|
16
|
+
description?: string
|
|
17
|
+
/** 是否禁用 */
|
|
18
|
+
disabled?: boolean
|
|
19
|
+
/** 子导航 */
|
|
20
|
+
children?: NavItem[]
|
|
21
|
+
|
|
22
|
+
[key: string]: any
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 导航组件属性 */
|
|
26
|
+
export interface NavProps {
|
|
27
|
+
/** 当前路径 */
|
|
28
|
+
currentPath?: string
|
|
29
|
+
/** 是否折叠 */
|
|
30
|
+
collapsed?: boolean
|
|
31
|
+
/** 导航列表 */
|
|
32
|
+
menus?: NavItem[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 导航组件定义的事件 */
|
|
36
|
+
export interface NavEmits {
|
|
37
|
+
(e: 'item-click', item: NavItem): void
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 导航组件暴露的属性和方法(组件内部使用) */
|
|
41
|
+
export interface _NavExposed {
|
|
42
|
+
/** 展开所有含子级的导航项 */
|
|
43
|
+
expandAll: () => void
|
|
44
|
+
/** 折叠所有导航项 */
|
|
45
|
+
collapseAll: () => void
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 导航组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
49
|
+
export type NavExposed = DeconstructValue<_NavExposed>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/menu/di.ts"],"sourcesContent":["import { type BEM, ExpandTransition } from '@veltra/utils'\nimport type { ComputedRef, InjectionKey } from 'vue'\n\nimport type { MenuProps, MenuEmits } from '../../types'\nimport type { ComponentSize } from '../../types'\n\nexport interface MenuContext {\n cls: BEM<'menu', 'u-'>\n collapsedCls: BEM<'collapsed-menu', 'u-'>\n menuProps: MenuProps\n menuEmit: MenuEmits\n expandedPath: Set<string>\n size: ComputedRef<ComponentSize>\n expandTransition: ExpandTransition\n}\n\nexport const MenuDIKey: InjectionKey<MenuContext> = Symbol('MenuDIKey')\n"],"mappings":";;AAgBA,MAAa,YAAuC,OAAO,WAAW"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/menu/helper.ts"],"sourcesContent":["export function getKey(index: number, parentKey: string): string {\n return `${parentKey}-${index}`\n}\n"],"mappings":";AAAA,SAAgB,OAAO,OAAe,WAA2B;CAC/D,OAAO,GAAG,UAAU,GAAG;AACzB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu-icon.js","names":[],"sources":["../../../src/components/menu/menu-icon.vue"],"sourcesContent":["<template>\n <u-icon v-if=\"typeof icon !== 'string'\">\n <component :is=\"icon\" />\n </u-icon>\n\n <img :src=\"icon\" v-else alt=\"icon\" />\n</template>\n\n<script lang=\"ts\" setup>\nimport type { DefineComponent } from 'vue'\n\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'MenuIcon' })\n\ndefineProps<{ icon: string | DefineComponent }>()\n</script>\n"],"mappings":";;;;;;;;;;iBACuB,QAAA,SAAI,YAAA,UAAA,GAAzB,YAES,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;2BADiB,EAAA,UAAA,GAAxB,YAAwB,wBAAR,QAAA,IAAI,CAAA,EAAA,CAAA;;uBAGtB,mBAAqC,OAAA;;IAA/B,KAAK,QAAA;IAAa,KAAI"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu-item-collapsed.js","names":[],"sources":["../../../src/components/menu/menu-item-collapsed.vue"],"sourcesContent":["<template>\n <!-- 一级菜单 -->\n <u-tip v-if=\"depth === 0\" direction=\"right\" hide-arrow>\n <li\n :class=\"[\n collapsedCls.e('item'),\n bem.is('active', active),\n bem.is('first-level'),\n bem.is('disabled', menu.disabled ?? false)\n ]\"\n ref=\"item\"\n @click=\"handleClickMenu\"\n >\n <UMenuIcon v-if=\"menu.icon\" :icon=\"menu.icon\" :class=\"collapsedCls.e('icon')\" />\n <span v-else>{{ menu.title[0] }}</span>\n </li>\n\n <template #content>\n {{ menu.title }}\n </template>\n </u-tip>\n\n <!-- 二级以及二级以下菜单 -->\n <li\n v-else\n :class=\"[\n collapsedCls.e('item'),\n bem.is('active', active),\n bem.is('disabled', menu.disabled ?? false)\n ]\"\n ref=\"item\"\n @click=\"_handleClickMenu\"\n >\n <UMenuIcon v-if=\"menu.icon\" :icon=\"menu.icon\" :class=\"collapsedCls.e('icon')\" />\n\n <!-- 文本 -->\n <span :class=\"collapsedCls.e('item-title')\">\n {{ menu.title }}\n </span>\n </li>\n</template>\n\n<script setup lang=\"ts\">\nimport { bem } from '@veltra/utils'\nimport { useTemplateRef } from 'vue'\n\nimport type { MenuItem } from '../../types'\nimport { UTip } from '../tip'\nimport UMenuIcon from './menu-icon.vue'\nimport { useMenuItem } from './use-menu-item'\n\ndefineOptions({ name: 'MenuItemCollapsed' })\n\nconst props = defineProps<{ menu: MenuItem; depth: number }>()\n\nconst itemRef = useTemplateRef('item')\n\nconst emit = defineEmits(['click'])\n\nconst { collapsedCls, active, handleClickMenu } = useMenuItem({ itemProps: props, itemRef })\n\nfunction _handleClickMenu() {\n handleClickMenu()\n emit('click')\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAqDA,MAAM,QAAQ;EAEd,MAAM,UAAU,eAAe,MAAM;EAErC,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,QAAQ,oBAAoB,YAAY;GAAE,WAAW;GAAO;EAAQ,CAAC;EAE3F,SAAS,mBAAmB;GAC1B,gBAAgB;GAChB,KAAK,OAAO;EACd;;2DA/DE,mBAAA,QAAA,GACa,QAAA,UAAK,KAAA,UAAA,GAAlB,YAkBQ,MAAA,WAAA,GAAA;;IAlBkB,WAAU;IAAQ,cAAA;;IAe/B,SAAO,cACA,CAAA,gBAAA,gBAAb,QAAA,KAAK,KAAK,GAAA,CAAA,CAAA,CAAA;2BAHV,CAZL,mBAYK,MAAA;KAXF,OAAK,eAAA;MAAY,MAAA,YAAA,EAAa,EAAC,MAAA;MAAkB,MAAA,GAAA,EAAI,GAAE,UAAW,MAAA,MAAA,CAAM;MAAW,MAAA,GAAA,EAAI,GAAE,aAAA;MAAyB,MAAA,GAAA,EAAI,GAAE,YAAa,QAAA,KAAK,YAAQ,KAAA;;KAMnJ,KAAI;KACH,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,MAAA,eAAA,KAAA,MAAA,eAAA,EAAA,GAAA,IAAA;QAES,QAAA,KAAK,QAAA,UAAA,GAAtB,YAAgF,aAAA;;KAAnD,MAAM,QAAA,KAAK;KAAO,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,MAAA,CAAA;oDACpE,mBAAuC,QAAA,YAAA,gBAAvB,QAAA,KAAK,MAAK,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,CAAA,CAAA;;uBAS9B,mBAgBK,UAAA,EAAA,KAAA,EAAA,GAAA,CAjBL,mBAAA,cAAA,GACA,mBAgBK,MAAA;IAdF,OAAK,eAAA;KAAU,MAAA,YAAA,EAAa,EAAC,MAAA;KAAgB,MAAA,GAAA,EAAI,GAAE,UAAW,MAAA,MAAA,CAAM;KAAS,MAAA,GAAA,EAAI,GAAE,YAAa,QAAA,KAAK,YAAQ,KAAA;;IAK9G,KAAI;IACH,SAAO;;IAES,QAAA,KAAK,QAAA,UAAA,GAAtB,YAAgF,aAAA;;KAAnD,MAAM,QAAA,KAAK;KAAO,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,MAAA,CAAA;;IAEpE,mBAAA,MAAA;IACA,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,YAAA,CAAA,EAAA,GAAA,gBACvB,QAAA,KAAK,KAAK,GAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu-item.js","names":[],"sources":["../../../src/components/menu/menu-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[\n cls.e('item'),\n bem.is('first-level', depth === 0),\n bem.is('active', active),\n bem.is('disabled', menu.disabled ?? false)\n ]\"\n ref=\"item\"\n @click=\"handleClickMenu\"\n >\n <MenuIcon v-if=\"menu.icon\" :icon=\"menu.icon\" :class=\"cls.e('icon')\" />\n\n <!-- 文本 -->\n <span :class=\"cls.e('item-title')\">\n {{ menu.title }}\n </span>\n </li>\n</template>\n\n<script setup lang=\"ts\">\nimport { bem } from '@veltra/utils'\nimport { useTemplateRef } from 'vue'\n\nimport type { MenuItem } from '../../types'\nimport MenuIcon from './menu-icon.vue'\nimport { useMenuItem } from './use-menu-item'\n\ndefineOptions({ name: 'MenuItem' })\n\nconst props = defineProps<{ menu: MenuItem; depth: number }>()\n\nconst itemRef = useTemplateRef('item')\n\nconst { cls, active, handleClickMenu } = useMenuItem({ itemProps: props, itemRef })\n</script>\n"],"mappings":";;;;;;;;;;;;;EAkCA,MAAM,EAAE,KAAK,QAAQ,oBAAoB,YAAY;GAAE,WAAW;GAAO,SAFzD,eAAe,MAE0C;EAAQ,CAAC;;uBAjChF,mBAgBK,MAAA;IAfF,OAAK,eAAA;KAAU,MAAA,GAAA,EAAI,EAAC,MAAA;KAAgB,MAAA,GAAA,EAAI,GAAE,eAAgB,QAAA,UAAK,CAAA;KAAe,MAAA,GAAA,EAAI,GAAE,UAAW,MAAA,MAAA,CAAM;KAAS,MAAA,GAAA,EAAI,GAAE,YAAa,QAAA,KAAK,YAAQ,KAAA;;IAM/I,KAAI;IACH,SAAK,OAAA,OAAA,OAAA,MAAA,GAAA,SAAE,MAAA,eAAA,KAAA,MAAA,eAAA,EAAA,GAAA,IAAA;;IAEQ,QAAA,KAAK,QAAA,UAAA,GAArB,YAAsE,aAAA;;KAA1C,MAAM,QAAA,KAAK;KAAO,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,MAAA,CAAA;;IAE1D,mBAAA,MAAA;IACA,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,YAAA,CAAA,EAAA,GAAA,gBACd,QAAA,KAAK,KAAK,GAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu-sub-collapsed.js","names":[],"sources":["../../../src/components/menu/menu-sub-collapsed.vue"],"sourcesContent":["<template>\n <u-tip\n hide-arrow\n direction=\"right\"\n alignment=\"start\"\n :class=\"[collapsedCls.m(size), collapsedCls.e('panel')]\"\n style=\"padding: 0\"\n v-model:visible=\"visible\"\n >\n <li :class=\"[collapsedCls.e('sub-content'), bem.is('first-level', depth === 0)]\">\n <MenuIcon v-if=\"menu.icon\" :icon=\"menu.icon\" :class=\"collapsedCls.e('icon')\" />\n\n <span v-else>{{ menu.title[0] }}</span>\n\n <template v-if=\"depth !== 0\">\n <span :class=\"collapsedCls.e('sub-title')\">\n {{ menu.title }}\n </span>\n\n <!-- 展开图标 -->\n <u-icon :class=\"[collapsedCls.e('sub-expand')]\">\n <ArrowRight />\n </u-icon>\n </template>\n </li>\n\n <template #content>\n <u-scroll tag=\"ul\" :class=\"collapsedCls.e('sub-list')\">\n <template v-for=\"(child, index) of menu.children!\" :key=\"getKey(index, parentKey)\">\n <UMenuItemCollapsed\n v-if=\"!child.children?.length\"\n :menu=\"child\"\n :depth=\"depth + 1\"\n @click=\"closeSubMenu\"\n />\n\n <MenuSubCollapsed\n v-else\n :menu=\"child\"\n :parent-key=\"getKey(index, parentKey)\"\n :depth=\"depth + 1\"\n />\n </template>\n </u-scroll>\n </template>\n </u-tip>\n</template>\n\n<script setup lang=\"ts\">\nimport { ArrowRight } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { inject, ref } from 'vue'\n\nimport type { MenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { UScroll } from '../scroll'\nimport { UTip } from '../tip'\nimport { MenuDIKey } from './di'\nimport { getKey } from './helper'\nimport MenuIcon from './menu-icon.vue'\nimport UMenuItemCollapsed from './menu-item-collapsed.vue'\n\ndefineOptions({ name: 'MenuSubCollapsed' })\n\ndefineProps<{ menu: MenuItem; parentKey: string; depth: number }>()\n\nconst visible = ref(false)\n\nfunction closeSubMenu() {\n visible.value = false\n}\n\nconst { collapsedCls, size } = inject(MenuDIKey)!\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAkEA,MAAM,UAAU,IAAI,KAAK;EAEzB,SAAS,eAAe;GACtB,QAAQ,QAAQ;EAClB;EAEA,MAAM,EAAE,cAAc,SAAS,OAAO,SAAS;;;uBAvE7C,YA4CQ,MAAA,WAAA,GAAA;IA3CN,cAAA;IACA,WAAU;IACV,WAAU;IACT,OAAK,eAAA,CAAG,MAAA,YAAA,EAAa,EAAE,MAAA,IAAA,CAAI,GAAG,MAAA,YAAA,EAAa,EAAC,OAAA,CAAA,CAAA;IAC7C,OAAA,EAAA,WAAA,IAAA;IACQ,SAAS,QAAA;8DAAA,QAAO,QAAA;;IAmBb,SAAO,cAiBL,CAhBX,YAgBW,MAAA,WAAA,GAAA;KAhBD,KAAI;KAAM,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,UAAA,CAAA;;4BACW,EAAA,UAAA,IAAA,GAAlD,mBAcW,UAAA,MAAA,WAdwB,QAAA,KAAK,WAAtB,OAAO,UAAK;8DAA2B,MAAA,MAAA,EAAO,OAAO,QAAA,SAAS,EAAA,GAAA,CAAA,CAErE,MAAM,UAAU,UAAA,UAAA,GADzB,YAKE,aAAA;;OAHC,MAAM;OACN,OAAO,QAAA,QAAK;OACZ,SAAO;sDAGV,YAKE,6BAAA;;OAHC,MAAM;OACN,cAAY,MAAA,MAAA,EAAO,OAAO,QAAA,SAAS;OACnC,OAAO,QAAA,QAAK;;;;;;;;;2BAhBhB,CAfL,mBAeK,MAAA,EAfA,OAAK,eAAA,CAAG,MAAA,YAAA,EAAa,EAAC,aAAA,GAAiB,MAAA,GAAA,EAAI,GAAE,eAAgB,QAAA,UAAK,CAAA,CAAA,CAAA,EAAA,GAAA,CACrD,QAAA,KAAK,QAAA,UAAA,GAArB,YAA+E,aAAA;;KAAnD,MAAM,QAAA,KAAK;KAAO,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,MAAA,CAAA;oDAEnE,mBAAuC,QAAA,YAAA,gBAAvB,QAAA,KAAK,MAAK,EAAA,GAAA,CAAA,IAEV,QAAA,UAAK,KAAA,UAAA,GAArB,mBASW,UAAA,EAAA,KAAA,EAAA,GAAA;KART,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,YAAA,EAAa,EAAC,WAAA,CAAA,EAAA,GAAA,gBACvB,QAAA,KAAK,KAAK,GAAA,CAAA;KAGf,mBAAA,QAAA;KACA,YAES,MAAA,WAAA,GAAA,EAFA,OAAK,eAAA,CAAG,MAAA,YAAA,EAAa,EAAC,YAAA,CAAA,CAAA,EAAA,GAAA;6BACf,CAAd,YAAc,MAAA,UAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu-sub.js","names":[],"sources":["../../../src/components/menu/menu-sub.vue"],"sourcesContent":["<template>\n <li :class=\"[cls.e('sub'), bem.is('expanded', expanded)]\">\n <div\n :class=\"[\n cls.e('sub-content'),\n bem.is('first-level', depth === 0),\n bem.is('expanded', expanded),\n bem.is('branch-active', branchActive)\n ]\"\n @click=\"handleToggleExpand\"\n >\n <UMenuIcon v-if=\"menu.icon\" :icon=\"menu.icon\" :class=\"cls.e('icon')\" />\n\n <!-- 文本 -->\n <span :class=\"cls.e('sub-title')\">\n {{ menu.title }}\n </span>\n\n <!-- 展开图标 -->\n <u-icon :class=\"[cls.e('sub-expand'), bem.is('expanded', expanded)]\">\n <ArrowRight />\n </u-icon>\n </div>\n\n <!-- @vue-ignore -->\n <transition\n @enter=\"(el: Element) => expandTransition.enter(el as HTMLElement)\"\n @after-enter=\"(el: Element) => expandTransition.afterEnter(el as HTMLElement)\"\n @before-leave=\"(el: Element) => expandTransition.beforeLeave(el as HTMLElement)\"\n @leave=\"(el: Element) => expandTransition.leave(el as HTMLElement)\"\n @after-leave=\"(el: Element) => expandTransition.afterLeave(el as HTMLElement)\"\n >\n <ul :class=\"cls.e('sub-list')\" v-show=\"expanded\">\n <template v-for=\"(child, index) of menu.children!\" :key=\"getKey(index, parentKey)\">\n <UMenuItem v-if=\"!child.children?.length\" :menu=\"child\" :depth=\"depth + 1\" />\n <MenuSub v-else :menu=\"child\" :parent-key=\"getKey(index, parentKey)\" :depth=\"depth + 1\" />\n </template>\n </ul>\n </transition>\n </li>\n</template>\n\n<script setup lang=\"ts\">\nimport { ArrowRight } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject } from 'vue'\n\nimport type { MenuItem } from '../../types'\nimport { UIcon } from '../icon'\nimport { MenuDIKey } from './di'\nimport { getKey } from './helper'\nimport UMenuIcon from './menu-icon.vue'\nimport UMenuItem from './menu-item.vue'\n\ndefineOptions({ name: 'MenuSub' })\n\nconst props = defineProps<{ menu: MenuItem; parentKey: string; depth: number }>()\n\nconst { cls, expandedPath, menuProps, expandTransition } = inject(MenuDIKey)!\n\nconst expanded = computed(() => expandedPath.has(props.menu.path))\n\nconst branchActive = computed(() => {\n const currentPath = menuProps.currentPath\n if (!currentPath) return false\n\n const check = (items?: MenuItem[]) => {\n return items?.some((item) => item.path === currentPath || check(item.children)) ?? false\n }\n\n return check(props.menu.children)\n})\n\nfunction handleToggleExpand() {\n const { menu } = props\n expandedPath.has(menu.path) ? expandedPath.delete(menu.path) : expandedPath.add(menu.path)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAwDA,MAAM,QAAQ;EAEd,MAAM,EAAE,KAAK,cAAc,WAAW,qBAAqB,OAAO,SAAS;EAE3E,MAAM,WAAW,eAAe,aAAa,IAAI,MAAM,KAAK,IAAI,CAAC;EAEjE,MAAM,eAAe,eAAe;GAClC,MAAM,cAAc,UAAU;GAC9B,IAAI,CAAC,aAAa,OAAO;GAEzB,MAAM,SAAS,UAAuB;IACpC,OAAO,OAAO,MAAM,SAAS,KAAK,SAAS,eAAe,MAAM,KAAK,QAAQ,CAAC,KAAK;GACrF;GAEA,OAAO,MAAM,MAAM,KAAK,QAAQ;EAClC,CAAC;EAED,SAAS,qBAAqB;GAC5B,MAAM,EAAE,SAAS;GACjB,aAAa,IAAI,KAAK,IAAI,IAAI,aAAa,OAAO,KAAK,IAAI,IAAI,aAAa,IAAI,KAAK,IAAI;EAC3F;;;uBA3EE,mBAsCK,MAAA,EAtCA,OAAK,eAAA,CAAG,MAAA,GAAA,EAAI,EAAC,KAAA,GAAS,MAAA,GAAA,EAAI,GAAE,YAAa,SAAA,KAAQ,CAAA,CAAA,EAAA,GAAA;IACpD,mBAoBM,OAAA;KAnBH,OAAK,eAAA;MAAY,MAAA,GAAA,EAAI,EAAC,aAAA;MAAyB,MAAA,GAAA,EAAI,GAAE,eAAgB,QAAA,UAAK,CAAA;MAAiB,MAAA,GAAA,EAAI,GAAE,YAAa,SAAA,KAAQ;MAAW,MAAA,GAAA,EAAI,GAAE,iBAAkB,aAAA,KAAY;;KAMrK,SAAO;;KAES,QAAA,KAAK,QAAA,UAAA,GAAtB,YAAuE,aAAA;;MAA1C,MAAM,QAAA,KAAK;MAAO,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,MAAA,CAAA;;KAE3D,mBAAA,MAAA;KACA,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,WAAA,CAAA,EAAA,GAAA,gBACd,QAAA,KAAK,KAAK,GAAA,CAAA;KAGf,mBAAA,QAAA;KACA,YAES,MAAA,WAAA,GAAA,EAFA,OAAK,eAAA,CAAG,MAAA,GAAA,EAAI,EAAC,YAAA,GAAgB,MAAA,GAAA,EAAI,GAAE,YAAa,SAAA,KAAQ,CAAA,CAAA,EAAA,GAAA;6BACjD,CAAd,YAAc,MAAA,UAAA,CAAA,CAAA,CAAA;;;;IAIlB,mBAAA,eAAA;IACA,YAaa,YAAA;KAZV,SAAK,OAAA,OAAA,OAAA,MAAG,OAAgB,MAAA,gBAAA,EAAiB,MAAM,EAAE;KACjD,cAAW,OAAA,OAAA,OAAA,MAAG,OAAgB,MAAA,gBAAA,EAAiB,WAAW,EAAE;KAC5D,eAAY,OAAA,OAAA,OAAA,MAAG,OAAgB,MAAA,gBAAA,EAAiB,YAAY,EAAE;KAC9D,SAAK,OAAA,OAAA,OAAA,MAAG,OAAgB,MAAA,gBAAA,EAAiB,MAAM,EAAE;KACjD,cAAW,OAAA,OAAA,OAAA,MAAG,OAAgB,MAAA,gBAAA,EAAiB,WAAW,EAAE;KAL/D,WAAA;;4BAYO,CAAA,eALL,mBAKK,MAAA,EALA,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,UAAA,CAAA,EAAA,GAAA,EAAA,UAAA,IAAA,GACf,mBAGW,UAAA,MAAA,WAHwB,QAAA,KAAK,WAAtB,OAAO,UAAK;8DAA2B,MAAA,MAAA,EAAO,OAAO,QAAA,SAAS,EAAA,GAAA,CAAA,CAC5D,MAAM,UAAU,UAAA,UAAA,GAAlC,YAA6E,aAAA;;OAAlC,MAAM;OAAQ,OAAO,QAAA,QAAK;sDACrE,YAA0F,oBAAA;;OAAzE,MAAM;OAAQ,cAAY,MAAA,MAAA,EAAO,OAAO,QAAA,SAAS;OAAI,OAAO,QAAA,QAAK;;;;;;8BAH/C,SAAA,KAAQ,CAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","names":[],"sources":["../../../src/components/menu/menu.vue"],"sourcesContent":["<template>\n <u-scroll\n tag=\"ul\"\n :class=\"[menuCls.b, menuCls.m(size)]\"\n :container-class=\"menuCls.e('container')\"\n >\n <!-- 常规 -->\n <template v-if=\"!collapsed\">\n <template v-for=\"(menu, index) of menus\" :key=\"index\">\n <UMenuSub\n v-if=\"menu.children?.length\"\n :menu=\"menu\"\n :parent-key=\"String(index)\"\n :depth=\"0\"\n />\n <UMenuItem v-else :menu=\"menu\" :key=\"index\" :depth=\"0\" />\n </template>\n </template>\n\n <!-- 折叠 -->\n <template v-else>\n <template v-for=\"(menu, index) of menus\" :key=\"index\">\n <UMenuSubCollapsed\n v-if=\"menu.children?.length\"\n :menu=\"menu\"\n :parent-key=\"String(index)\"\n :depth=\"0\"\n />\n <UMenuItemCollapsed v-else :menu=\"menu\" :key=\"index\" :depth=\"0\" />\n </template>\n </template>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem, ExpandTransition } from '@veltra/utils'\nimport { computed, provide, shallowReactive, watch } from 'vue'\n\nimport type { MenuEmits, MenuProps, ComponentSize } from '../../types'\nimport { UScroll } from '../scroll'\nimport { MenuDIKey } from './di'\nimport UMenuItemCollapsed from './menu-item-collapsed.vue'\nimport UMenuItem from './menu-item.vue'\nimport UMenuSubCollapsed from './menu-sub-collapsed.vue'\nimport UMenuSub from './menu-sub.vue'\nimport { walkMenuWithPath } from './walk-menu-path'\n\ndefineOptions({ name: 'Menu' })\n\nconst props = withDefaults(defineProps<MenuProps>(), {\n expand: false,\n activeIndex: '',\n collapsed: false,\n uniqueOpened: false\n})\n\nconst emit = defineEmits<MenuEmits>()\n\nconst cls = bem('menu')\nconst collapsedCls = bem('collapsed-menu')\n\nconst menuCls = computed(() => {\n return props.collapsed ? collapsedCls : cls\n})\n\nconst expandTransition = new ExpandTransition({\n enterTransition:\n 'height 0.25s cubic-bezier(0.4, 0, 0.2, 1), padding-top 0.25s cubic-bezier(0.4, 0, 0.2, 1), padding-bottom 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.18s cubic-bezier(0.4, 0, 0.2, 1)',\n leaveTransition:\n 'height 0.2s cubic-bezier(0.4, 0, 1, 1), padding-top 0.2s cubic-bezier(0.4, 0, 1, 1), padding-bottom 0.2s cubic-bezier(0.4, 0, 1, 1), opacity 0.12s cubic-bezier(0.4, 0, 1, 1)',\n opacity: true\n})\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst expandedPath = shallowReactive(new Set<string>())\n\nwatch(\n [() => props.currentPath, () => props.menus],\n ([currentPath, menus]) => {\n if (!currentPath || !menus) return\n menus.forEach((menu) => {\n walkMenuWithPath(menu, (node, nodePath) => {\n if (node.path === currentPath) {\n nodePath.slice(0, -1).forEach((path) => {\n expandedPath.add(path.path)\n })\n return false\n }\n })\n })\n },\n { immediate: true }\n)\n\nprovide(MenuDIKey, {\n cls,\n collapsedCls,\n menuProps: props,\n menuEmit: emit,\n expandedPath,\n size,\n expandTransition\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDA,MAAM,QAAQ;EAOd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,MAAM;EACtB,MAAM,eAAe,IAAI,gBAAgB;EAEzC,MAAM,UAAU,eAAe;GAC7B,OAAO,MAAM,YAAY,eAAe;EAC1C,CAAC;EAED,MAAM,mBAAmB,IAAI,iBAAiB;GAC5C,iBACE;GACF,iBACE;GACF,SAAS;EACX,CAAC;EAED,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,eAAe,gCAAgB,IAAI,IAAY,CAAC;EAEtD,MACE,OAAO,MAAM,mBAAmB,MAAM,KAAK,IAC1C,CAAC,aAAa,WAAW;GACxB,IAAI,CAAC,eAAe,CAAC,OAAO;GAC5B,MAAM,SAAS,SAAS;IACtB,iBAAiB,OAAO,MAAM,aAAa;KACzC,IAAI,KAAK,SAAS,aAAa;MAC7B,SAAS,MAAM,GAAG,EAAE,EAAE,SAAS,SAAS;OACtC,aAAa,IAAI,KAAK,IAAI;MAC5B,CAAC;MACD,OAAO;KACT;IACF,CAAC;GACH,CAAC;EACH,GACA,EAAE,WAAW,KAAK,CACpB;EAEA,QAAQ,WAAW;GACjB;GACA;GACA,WAAW;GACX,UAAU;GACV;GACA;GACA;EACF,CAAC;;uBAvGC,YA8BW,MAAA,WAAA,GAAA;IA7BT,KAAI;IACH,OAAK,eAAA,CAAG,QAAA,MAAQ,GAAG,QAAA,MAAQ,EAAE,MAAA,IAAA,CAAI,CAAA,CAAA;IACjC,mBAAiB,QAAA,MAAQ,EAAC,WAAA;;2BAEhB,CAAX,mBAAA,MAAA,GAAA,CACiB,QAAA,aAAA,UAAA,IAAA,GACf,mBAQW,UAAA,EAAA,KAAA,EAAA,GAAA,WARuB,QAAA,QAAhB,MAAM,UAAK;6DAAkB,MAAK,GAAA,CAE1C,KAAK,UAAU,UAAA,UAAA,GADvB,YAKE,aAAA;;MAHO;MACN,cAAY,OAAO,KAAK;MACxB,OAAO;0DAEV,YAAyD,aAAA;MAAhC;MAAO,KAAK;MAAQ,OAAO;;8BAKxD,mBAUW,UAAA,EAAA,KAAA,EAAA,GAAA,CAXX,mBAAA,MAAA,IAAA,UAAA,IAAA,GAEE,mBAQW,UAAA,MAAA,WARuB,QAAA,QAAhB,MAAM,UAAK;6DAAkB,MAAK,GAAA,CAE1C,KAAK,UAAU,UAAA,UAAA,GADvB,YAKE,aAAA;;MAHO;MACN,cAAY,OAAO,KAAK;MACxB,OAAO;0DAEV,YAAkE,aAAA;MAAhC;MAAO,KAAK;MAAQ,OAAO"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { MenuItem, MenuProps } from "../../types/menu.js";
|
|
2
|
-
//#region src/components/menu/menu.vue.d.ts
|
|
3
|
-
declare const __VLS_export: import("vue").DefineComponent<MenuProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
4
|
-
"item-click": (item: MenuItem) => any;
|
|
5
|
-
}, string, import("vue").PublicProps, Readonly<MenuProps> & Readonly<{
|
|
6
|
-
"onItem-click"?: ((item: MenuItem) => any) | undefined;
|
|
7
|
-
}>, {
|
|
8
|
-
collapsed: boolean;
|
|
9
|
-
uniqueOpened: boolean;
|
|
10
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
-
declare const _default: typeof __VLS_export;
|
|
12
|
-
//#endregion
|
|
13
|
-
export { _default };
|
|
14
|
-
//# sourceMappingURL=menu.vue.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-menu-item.js","names":[],"sources":["../../../src/components/menu/use-menu-item.ts"],"sourcesContent":["import { scrollIntoContainerView, type BEM } from '@veltra/utils'\nimport { computed, inject, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { MenuItem } from '../../types'\nimport { MenuDIKey } from './di'\n\ninterface Options {\n itemProps: { menu: MenuItem; depth: number }\n itemRef: ShallowRef<HTMLElement | null>\n}\n\ninterface UseMenuItemReturned {\n cls: BEM<'menu'>\n collapsedCls: BEM<'collapsed-menu'>\n\n active: ComputedRef<boolean>\n handleClickMenu: () => void\n}\n\nexport function useMenuItem(options: Options): UseMenuItemReturned {\n const { itemProps, itemRef } = options\n const { cls, collapsedCls, menuProps, menuEmit } = inject(MenuDIKey)!\n\n const active = computed(() => {\n return menuProps.currentPath === itemProps.menu.path\n })\n\n let changedByClick = false\n watch([active, itemRef], ([active, itemEl]) => {\n if (changedByClick) {\n changedByClick = false\n return\n }\n if (!active || !itemEl) return\n scrollIntoContainerView(itemEl, null)\n })\n\n function handleClickMenu() {\n if (itemProps.menu.disabled) return\n changedByClick = true\n menuEmit('item-click', itemProps.menu)\n }\n\n return {\n cls,\n collapsedCls,\n\n active,\n handleClickMenu\n }\n}\n"],"mappings":";;;;AAmBA,SAAgB,YAAY,SAAuC;CACjE,MAAM,EAAE,WAAW,YAAY;CAC/B,MAAM,EAAE,KAAK,cAAc,WAAW,aAAa,OAAO,SAAS;CAEnE,MAAM,SAAS,eAAe;EAC5B,OAAO,UAAU,gBAAgB,UAAU,KAAK;CAClD,CAAC;CAED,IAAI,iBAAiB;CACrB,MAAM,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,YAAY;EAC7C,IAAI,gBAAgB;GAClB,iBAAiB;GACjB;EACF;EACA,IAAI,CAAC,UAAU,CAAC,QAAQ;EACxB,wBAAwB,QAAQ,IAAI;CACtC,CAAC;CAED,SAAS,kBAAkB;EACzB,IAAI,UAAU,KAAK,UAAU;EAC7B,iBAAiB;EACjB,SAAS,cAAc,UAAU,IAAI;CACvC;CAEA,OAAO;EACL;EACA;EAEA;EACA;CACF;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"walk-menu-path.js","names":[],"sources":["../../../src/components/menu/walk-menu-path.ts"],"sourcesContent":["/**\n * 深度优先 + 路径;回调返回 `false` 时剪枝当前节点子树(不中断兄弟)。\n * `@cat-kit/core` 的 `dfs` 在返回 `true` 时会终止整段遍历,语义不同,故保留此辅助。\n */\nexport function walkMenuWithPath<T extends Record<string, unknown>>(\n data: T,\n cb: (node: T, path: T[]) => void | false,\n childrenKey = 'children',\n prefix: T[] = []\n): void {\n const path = [...prefix, data]\n if (cb(data, path) === false) return\n const raw = data[childrenKey]\n if (!Array.isArray(raw)) return\n for (let i = 0; i < raw.length; i++) {\n walkMenuWithPath(raw[i] as T, cb, childrenKey, path)\n }\n}\n"],"mappings":";;;;;AAIA,SAAgB,iBACd,MACA,IACA,cAAc,YACd,SAAc,CAAC,GACT;CACN,MAAM,OAAO,CAAC,GAAG,QAAQ,IAAI;CAC7B,IAAI,GAAG,MAAM,IAAI,MAAM,OAAO;CAC9B,MAAM,MAAM,KAAK;CACjB,IAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAC9B,iBAAiB,IAAI,IAAS,IAAI,aAAa,IAAI;AAEvD"}
|
package/dist/types/menu.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { DefineComponent } from "vue";
|
|
2
|
-
import { DeconstructValue } from "@veltra/utils";
|
|
3
|
-
|
|
4
|
-
//#region src/types/menu.d.ts
|
|
5
|
-
/** 菜单项 */
|
|
6
|
-
interface MenuItem {
|
|
7
|
-
/** 图标 */
|
|
8
|
-
icon?: string | DefineComponent;
|
|
9
|
-
/** 菜单标题 */
|
|
10
|
-
title: string;
|
|
11
|
-
/** 菜单路径 */
|
|
12
|
-
path: string;
|
|
13
|
-
/** 是否禁用 */
|
|
14
|
-
disabled?: boolean;
|
|
15
|
-
/** 子菜单 */
|
|
16
|
-
children?: MenuItem[];
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}
|
|
19
|
-
/** 菜单组件组件属性 */
|
|
20
|
-
interface MenuProps {
|
|
21
|
-
/** 当前路径 */
|
|
22
|
-
currentPath?: string;
|
|
23
|
-
/** 是否折叠 */
|
|
24
|
-
collapsed?: boolean;
|
|
25
|
-
/** 仅允许一个菜单可以打开 */
|
|
26
|
-
uniqueOpened?: boolean;
|
|
27
|
-
/** 菜单列表 */
|
|
28
|
-
menus?: MenuItem[];
|
|
29
|
-
}
|
|
30
|
-
/** 菜单组件组件定义的事件 */
|
|
31
|
-
interface MenuEmits {
|
|
32
|
-
(e: 'item-click', item: MenuItem): void;
|
|
33
|
-
}
|
|
34
|
-
/** 菜单组件组件暴露的属性和方法(组件内部使用) */
|
|
35
|
-
interface _MenuExposed {}
|
|
36
|
-
/** 菜单组件组件暴露的属性和方法(组件外部使用, 引用的值会被自动解构) */
|
|
37
|
-
type MenuExposed = DeconstructValue<_MenuExposed>;
|
|
38
|
-
//#endregion
|
|
39
|
-
export { MenuEmits, MenuExposed, MenuItem, MenuProps, _MenuExposed };
|
|
40
|
-
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type BEM, ExpandTransition } from '@veltra/utils'
|
|
2
|
-
import type { ComputedRef, InjectionKey } from 'vue'
|
|
3
|
-
|
|
4
|
-
import type { MenuProps, MenuEmits } from '../../types'
|
|
5
|
-
import type { ComponentSize } from '../../types'
|
|
6
|
-
|
|
7
|
-
export interface MenuContext {
|
|
8
|
-
cls: BEM<'menu', 'u-'>
|
|
9
|
-
collapsedCls: BEM<'collapsed-menu', 'u-'>
|
|
10
|
-
menuProps: MenuProps
|
|
11
|
-
menuEmit: MenuEmits
|
|
12
|
-
expandedPath: Set<string>
|
|
13
|
-
size: ComputedRef<ComponentSize>
|
|
14
|
-
expandTransition: ExpandTransition
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const MenuDIKey: InjectionKey<MenuContext> = Symbol('MenuDIKey')
|