@gzmjs/menu 0.1.0
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/009-menu/menu.d.ts +44 -0
- package/dist/009-menu/menuItem.d.ts +27 -0
- package/dist/009-menu/menuList.d.ts +19 -0
- package/dist/009-menu/model.d.ts +40 -0
- package/dist/index.d.ts +2 -0
- package/dist/menu.es.js +659 -0
- package/dist/menu.es.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MiOptions } from './model';
|
|
2
|
+
import { ViewListModel, ViewGroupElement } from '@gzmjs/mvvm';
|
|
3
|
+
import { Corner } from '@gzmjs/ui-basic';
|
|
4
|
+
import * as MI from './menuItem';
|
|
5
|
+
export declare const tagName = "GZM-MENU";
|
|
6
|
+
declare global {
|
|
7
|
+
interface HTMLElementTagNameMap {
|
|
8
|
+
[tagName]: Menu;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export interface MenuOptions extends ViewListModel<MiOptions, MI.MenuItem, Menu> {
|
|
12
|
+
tagName?: typeof tagName;
|
|
13
|
+
}
|
|
14
|
+
export declare function createMenu(...menuItems: MiOptions[]): Menu;
|
|
15
|
+
export declare class Menu extends ViewGroupElement<MiOptions, MI.MenuItem, MenuOptions> {
|
|
16
|
+
#private;
|
|
17
|
+
constructor();
|
|
18
|
+
readonly shadowRoot: ShadowRoot;
|
|
19
|
+
show($attachTo: HTMLElement, attachCorner: Corner, corner?: Corner): void;
|
|
20
|
+
get isActive(): boolean;
|
|
21
|
+
accessor up: boolean;
|
|
22
|
+
accessor down: boolean;
|
|
23
|
+
$supMenuItem?: MI.MenuItem;
|
|
24
|
+
/**
|
|
25
|
+
* 关闭自己以及下级菜单
|
|
26
|
+
*/
|
|
27
|
+
close(): void;
|
|
28
|
+
/**
|
|
29
|
+
* 关闭所有菜单,包括上级和上级的上级
|
|
30
|
+
*/
|
|
31
|
+
closeAll(): void;
|
|
32
|
+
/**
|
|
33
|
+
* 场景:
|
|
34
|
+
* 此菜单显示了一个子菜单,子菜单获得输入焦点。鼠标没有点击子菜单,却点击了此菜单(如另一个submenu菜单项,或者不属于菜单项的任意菜单部分)。
|
|
35
|
+
* 子菜单 blur 事件触发,这时不能关闭所有的菜单,而是从子菜单开始向上找,将未获得焦点的菜单全部关闭。
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
38
|
+
protected _closeIfNotActive(): void;
|
|
39
|
+
protected _closeSubMenu(): void;
|
|
40
|
+
protected _getViewItemTagName(): string;
|
|
41
|
+
get $viewItemsContainer(): HTMLElement | ShadowRoot;
|
|
42
|
+
protected $section: HTMLElement;
|
|
43
|
+
protected readonly groupElementTagName: string;
|
|
44
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { MiOptions } from './model.ts';
|
|
2
|
+
import { AttributeHandlers } from '@gzmjs/ui-basic';
|
|
3
|
+
import { ViewElement } from '@gzmjs/mvvm';
|
|
4
|
+
type MenuItemTag = 'click' | 'link' | 'check' | 'radio' | 'menu';
|
|
5
|
+
declare const mutableAttributes: readonly ["tag", "label", "icon", "badge", "checked", "href", "target"];
|
|
6
|
+
export declare const tagName = "GZM-MENU-ITEM";
|
|
7
|
+
export declare const styleSheet: CSSStyleSheet;
|
|
8
|
+
export declare class MenuItem extends ViewElement<MiOptions> implements AttributeHandlers<typeof mutableAttributes[number]> {
|
|
9
|
+
$divs: HTMLElement[];
|
|
10
|
+
connectedCallback(): void;
|
|
11
|
+
accessor tag: MenuItemTag | undefined;
|
|
12
|
+
accessor label: string | undefined;
|
|
13
|
+
accessor icon: string | undefined;
|
|
14
|
+
accessor badge: string | undefined;
|
|
15
|
+
accessor active: boolean;
|
|
16
|
+
accessor checked: boolean;
|
|
17
|
+
accessor href: string | undefined;
|
|
18
|
+
accessor target: string | undefined;
|
|
19
|
+
_tag_set<MenuItemTag>(tag: MenuItemTag | null, old: MenuItemTag | null): void;
|
|
20
|
+
_icon_set(icn: string | null): void;
|
|
21
|
+
_label_set(lbl: string | null): void;
|
|
22
|
+
_badge_set(bdg: string | null): void;
|
|
23
|
+
_checked_set(): void;
|
|
24
|
+
_href_set(nv: string | null): void;
|
|
25
|
+
_target_set(nv: string | null): void;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ViewListModel, ViewGroupElement } from '@gzmjs/mvvm';
|
|
2
|
+
import { MiOptions } from './model';
|
|
3
|
+
import * as MI from './menuItem';
|
|
4
|
+
export declare const tagName = "GZM-MENU-LIST";
|
|
5
|
+
export interface MenuListOptions extends ViewListModel<MiOptions, MI.MenuItem, MenuList> {
|
|
6
|
+
tagName?: typeof tagName;
|
|
7
|
+
}
|
|
8
|
+
export declare class MenuList extends ViewGroupElement<MiOptions, MI.MenuItem, MenuListOptions> {
|
|
9
|
+
#private;
|
|
10
|
+
constructor();
|
|
11
|
+
readonly shadowRoot: ShadowRoot;
|
|
12
|
+
_closeSubMenu(): void;
|
|
13
|
+
protected _closeIfNotActive(): void;
|
|
14
|
+
closeAll(): void;
|
|
15
|
+
protected _getViewItemTagName(): string;
|
|
16
|
+
get $viewItemsContainer(): HTMLElement | ShadowRoot;
|
|
17
|
+
protected readonly groupElementTagName: string;
|
|
18
|
+
protected $section: HTMLElement;
|
|
19
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ViewModel } from '@gzmjs/mvvm';
|
|
2
|
+
import { MenuItem } from './menuItem';
|
|
3
|
+
interface IMiOptions extends ViewModel<MenuItem> {
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: string;
|
|
6
|
+
group?: string;
|
|
7
|
+
badge?: string;
|
|
8
|
+
/**
|
|
9
|
+
* 本来这个属性只适用于 check 和 radio,为了在 menu 中调用 setModelProperty('check') 改到这里。
|
|
10
|
+
* 同时需要对其他菜单项添加 checked?: never。
|
|
11
|
+
*/
|
|
12
|
+
checked?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface IClick extends IMiOptions {
|
|
15
|
+
readonly tag: 'click';
|
|
16
|
+
checked?: never;
|
|
17
|
+
onclick?: (this: IClick, ev: MouseEvent, vm: IClick) => unknown;
|
|
18
|
+
}
|
|
19
|
+
interface ILink extends IMiOptions {
|
|
20
|
+
readonly tag: 'link';
|
|
21
|
+
href: string;
|
|
22
|
+
target?: string;
|
|
23
|
+
checked?: never;
|
|
24
|
+
onclick?: (this: ILink, ev: MouseEvent, vm: ILink) => unknown;
|
|
25
|
+
}
|
|
26
|
+
interface ICheck extends IMiOptions {
|
|
27
|
+
readonly tag: 'check';
|
|
28
|
+
onclick?: (this: ICheck, ev: MouseEvent, vm: ICheck) => unknown;
|
|
29
|
+
}
|
|
30
|
+
interface IRadio extends IMiOptions {
|
|
31
|
+
readonly tag: 'radio';
|
|
32
|
+
onclick?: (this: IRadio, ev: MouseEvent, vm: IRadio) => unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface ISubMenu extends IMiOptions {
|
|
35
|
+
readonly tag: 'menu';
|
|
36
|
+
checked?: never;
|
|
37
|
+
subItems: MiOptions[];
|
|
38
|
+
}
|
|
39
|
+
export type MiOptions = IClick | ILink | ICheck | IRadio | ISubMenu;
|
|
40
|
+
export {};
|
package/dist/index.d.ts
ADDED
package/dist/menu.es.js
ADDED
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import { createStyleSheet, defineElement, iconCache, strAttr, boolAttr, iconTagName, badgeTagName, gzmFrame, baseStyle, isLeftCorner, isTopCorner, makeCorner, CornerHelper, xy } from "@gzmjs/ui-basic";
|
|
2
|
+
import { ViewElement, ViewGroupElement } from "@gzmjs/mvvm";
|
|
3
|
+
var __create$2 = Object.create;
|
|
4
|
+
var __defProp$2 = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __knownSymbol$2 = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
7
|
+
var __typeError$2 = (msg) => {
|
|
8
|
+
throw TypeError(msg);
|
|
9
|
+
};
|
|
10
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __name$2 = (target, value) => __defProp$2(target, "name", { value, configurable: true });
|
|
12
|
+
var __decoratorStart$2 = (base) => [, , , __create$2(base?.[__knownSymbol$2("metadata")] ?? null)];
|
|
13
|
+
var __decoratorStrings$2 = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
14
|
+
var __expectFn$2 = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError$2("Function expected") : fn;
|
|
15
|
+
var __decoratorContext$2 = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings$2[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError$2("Already initialized") : fns.push(__expectFn$2(fn || null)) });
|
|
16
|
+
var __decoratorMetadata$2 = (array, target) => __defNormalProp$2(target, __knownSymbol$2("metadata"), array[3]);
|
|
17
|
+
var __runInitializers$2 = (array, flags, self, value) => {
|
|
18
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
var __decorateElement$2 = (array, flags, name, decorators, target, extra) => {
|
|
22
|
+
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
|
|
23
|
+
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings$2[k + 5];
|
|
24
|
+
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
|
|
25
|
+
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc$2(k < 4 ? target : { get [name]() {
|
|
26
|
+
return __privateGet$1(this, extra);
|
|
27
|
+
}, set [name](x) {
|
|
28
|
+
return __privateSet$1(this, extra, x);
|
|
29
|
+
} }, name));
|
|
30
|
+
k ? p && k < 4 && __name$2(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name$2(target, name);
|
|
31
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
32
|
+
ctx = __decoratorContext$2(k, name, done = {}, array[3], extraInitializers);
|
|
33
|
+
if (k) {
|
|
34
|
+
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn$1(target, x) : (x) => name in x };
|
|
35
|
+
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet$1 : __privateMethod$1)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
|
|
36
|
+
if (k > 2) access.set = p ? (x, y) => __privateSet$1(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
|
|
37
|
+
}
|
|
38
|
+
it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
|
|
39
|
+
if (k ^ 4 || it === void 0) __expectFn$2(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
|
|
40
|
+
else if (typeof it !== "object" || it === null) __typeError$2("Object expected");
|
|
41
|
+
else __expectFn$2(fn = it.get) && (desc.get = fn), __expectFn$2(fn = it.set) && (desc.set = fn), __expectFn$2(fn = it.init) && initializers.unshift(fn);
|
|
42
|
+
}
|
|
43
|
+
return k || __decoratorMetadata$2(array, target), desc && __defProp$2(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
44
|
+
};
|
|
45
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$2(obj, key + "", value);
|
|
46
|
+
var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
|
|
47
|
+
var __privateIn$1 = (member, obj) => Object(obj) !== obj ? __typeError$2('Cannot use the "in" operator on this value') : member.has(obj);
|
|
48
|
+
var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
49
|
+
var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
50
|
+
var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
51
|
+
var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
|
|
52
|
+
var _target_dec, _href_dec, _checked_dec, _active_dec, _badge_dec, _icon_dec, _label_dec, _tag_dec, _a$2, _MenuItem_decorators, _init$2, _tag, _label, _icon, _badge, _active, _checked, _href, _target;
|
|
53
|
+
const mutableAttributes = ["tag", "label", "icon", "badge", "checked", "href", "target"];
|
|
54
|
+
const tagName$2 = "GZM-MENU-ITEM";
|
|
55
|
+
const styleSheet$2 = createStyleSheet({
|
|
56
|
+
[tagName$2]: `
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
display: contents;
|
|
59
|
+
`,
|
|
60
|
+
//因为 display:contents,只能设置每一个grid单元的边框来实现hover效果。
|
|
61
|
+
[`${tagName$2}>*`]: `
|
|
62
|
+
border:1px solid transparent;
|
|
63
|
+
padding-inline:0.125rem;
|
|
64
|
+
`,
|
|
65
|
+
[`${tagName$2}>*:not(:last-child)`]: `
|
|
66
|
+
border-right:0;
|
|
67
|
+
`,
|
|
68
|
+
[`${tagName$2}>*:not(:first-child)`]: `
|
|
69
|
+
border-left:0;
|
|
70
|
+
`,
|
|
71
|
+
[`${tagName$2}:active>*, ${tagName$2}[active]>*`]: {
|
|
72
|
+
color: "var(--gzm-a-btn-txt-color)",
|
|
73
|
+
background: "var(--gzm-a-btn-background)",
|
|
74
|
+
border: "var(--gzm-a-btn-border)"
|
|
75
|
+
},
|
|
76
|
+
[`${tagName$2}:hover>*`]: {
|
|
77
|
+
background: "var(--gzm-h-btn-background)",
|
|
78
|
+
border: "var(--gzm-h-btn-border)",
|
|
79
|
+
color: "var(--gzm-h-btn-txt-color)"
|
|
80
|
+
},
|
|
81
|
+
//link <a> 的颜色
|
|
82
|
+
[`${tagName$2} a`]: `
|
|
83
|
+
color: inherit;
|
|
84
|
+
`,
|
|
85
|
+
//menu
|
|
86
|
+
//https://www.compart.com/en/unicode/U+2BC8
|
|
87
|
+
[`${tagName$2}[tag=menu]>div:last-child::after`]: `
|
|
88
|
+
content: '⯈';
|
|
89
|
+
font-size: 0.75rem;
|
|
90
|
+
padding-right:0.125rem;
|
|
91
|
+
`
|
|
92
|
+
});
|
|
93
|
+
_MenuItem_decorators = [defineElement({ tagName: tagName$2, mutableAttributes })];
|
|
94
|
+
class MenuItem extends (_a$2 = ViewElement, _tag_dec = [strAttr], _label_dec = [strAttr], _icon_dec = [strAttr], _badge_dec = [strAttr], _active_dec = [boolAttr], _checked_dec = [boolAttr], _href_dec = [strAttr], _target_dec = [strAttr], _a$2) {
|
|
95
|
+
constructor() {
|
|
96
|
+
super(...arguments);
|
|
97
|
+
__publicField$1(this, "$divs", [document.createElement(iconTagName), document.createElement("div"), document.createElement("div"), document.createElement("div")]);
|
|
98
|
+
__privateAdd$1(this, _tag, __runInitializers$2(_init$2, 8, this)), __runInitializers$2(_init$2, 11, this);
|
|
99
|
+
__privateAdd$1(this, _label, __runInitializers$2(_init$2, 12, this)), __runInitializers$2(_init$2, 15, this);
|
|
100
|
+
__privateAdd$1(this, _icon, __runInitializers$2(_init$2, 16, this)), __runInitializers$2(_init$2, 19, this);
|
|
101
|
+
__privateAdd$1(this, _badge, __runInitializers$2(_init$2, 20, this)), __runInitializers$2(_init$2, 23, this);
|
|
102
|
+
__privateAdd$1(this, _active, __runInitializers$2(_init$2, 24, this, false)), __runInitializers$2(_init$2, 27, this);
|
|
103
|
+
__privateAdd$1(this, _checked, __runInitializers$2(_init$2, 28, this, false)), __runInitializers$2(_init$2, 31, this);
|
|
104
|
+
__privateAdd$1(this, _href, __runInitializers$2(_init$2, 32, this)), __runInitializers$2(_init$2, 35, this);
|
|
105
|
+
__privateAdd$1(this, _target, __runInitializers$2(_init$2, 36, this)), __runInitializers$2(_init$2, 39, this);
|
|
106
|
+
}
|
|
107
|
+
connectedCallback() {
|
|
108
|
+
if (this.childElementCount === 0) {
|
|
109
|
+
this.append(...this.$divs);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
_tag_set(tag, old) {
|
|
113
|
+
if (old === tag) return;
|
|
114
|
+
if (tag === "check" || tag === "radio") {
|
|
115
|
+
this._checked_set();
|
|
116
|
+
} else if (old === "check" || old === "radio") {
|
|
117
|
+
this._icon_set(this.icon ?? null);
|
|
118
|
+
}
|
|
119
|
+
if (tag === "link") {
|
|
120
|
+
const $d = this.$divs[1];
|
|
121
|
+
const $a = this.$divs[1] = document.createElement("a");
|
|
122
|
+
if ($d.isConnected) {
|
|
123
|
+
$d.replaceWith($a);
|
|
124
|
+
}
|
|
125
|
+
this._label_set(this.label ?? null);
|
|
126
|
+
this._href_set(this.href ?? null);
|
|
127
|
+
this._target_set(this.target ?? "_blank");
|
|
128
|
+
} else if (old === "link") {
|
|
129
|
+
const $a = this.$divs[1];
|
|
130
|
+
const $d = this.$divs[1] = document.createElement("div");
|
|
131
|
+
if ($a.isConnected) {
|
|
132
|
+
$a.replaceWith($d);
|
|
133
|
+
}
|
|
134
|
+
this._label_set(this.label ?? null);
|
|
135
|
+
}
|
|
136
|
+
if (tag === "menu") ;
|
|
137
|
+
else if (old === "menu") {
|
|
138
|
+
this.$divs[3].innerHTML = "";
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
_icon_set(icn) {
|
|
142
|
+
const $icn = this.$divs[0];
|
|
143
|
+
$icn.icon = icn ?? void 0;
|
|
144
|
+
}
|
|
145
|
+
_label_set(lbl) {
|
|
146
|
+
const $div = this.$divs[1];
|
|
147
|
+
$div.textContent = lbl;
|
|
148
|
+
}
|
|
149
|
+
_badge_set(bdg) {
|
|
150
|
+
const $div = this.$divs[2];
|
|
151
|
+
if (!bdg) {
|
|
152
|
+
$div.innerHTML = "";
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let $bdg = $div.firstElementChild;
|
|
156
|
+
if (!$bdg) {
|
|
157
|
+
$bdg = document.createElement(badgeTagName);
|
|
158
|
+
$div.append($bdg);
|
|
159
|
+
}
|
|
160
|
+
$bdg.badge = bdg;
|
|
161
|
+
}
|
|
162
|
+
_checked_set() {
|
|
163
|
+
const tag = this.tag;
|
|
164
|
+
const checked = this.checked;
|
|
165
|
+
if (tag === "check") {
|
|
166
|
+
this._icon_set(checked ? checkboxChecked : checkboxUnchecked);
|
|
167
|
+
} else if (tag === "radio") {
|
|
168
|
+
this._icon_set(checked ? radioChecked : radioUnchecked);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
_href_set(nv) {
|
|
172
|
+
const $a = this.$divs[1];
|
|
173
|
+
$a.href = nv || "javascript:void(0);";
|
|
174
|
+
}
|
|
175
|
+
_target_set(nv) {
|
|
176
|
+
const $a = this.$divs[1];
|
|
177
|
+
$a.target = nv ?? "_blank";
|
|
178
|
+
}
|
|
179
|
+
// #endregion
|
|
180
|
+
}
|
|
181
|
+
_init$2 = __decoratorStart$2(_a$2);
|
|
182
|
+
_tag = /* @__PURE__ */ new WeakMap();
|
|
183
|
+
_label = /* @__PURE__ */ new WeakMap();
|
|
184
|
+
_icon = /* @__PURE__ */ new WeakMap();
|
|
185
|
+
_badge = /* @__PURE__ */ new WeakMap();
|
|
186
|
+
_active = /* @__PURE__ */ new WeakMap();
|
|
187
|
+
_checked = /* @__PURE__ */ new WeakMap();
|
|
188
|
+
_href = /* @__PURE__ */ new WeakMap();
|
|
189
|
+
_target = /* @__PURE__ */ new WeakMap();
|
|
190
|
+
__decorateElement$2(_init$2, 4, "tag", _tag_dec, MenuItem, _tag);
|
|
191
|
+
__decorateElement$2(_init$2, 4, "label", _label_dec, MenuItem, _label);
|
|
192
|
+
__decorateElement$2(_init$2, 4, "icon", _icon_dec, MenuItem, _icon);
|
|
193
|
+
__decorateElement$2(_init$2, 4, "badge", _badge_dec, MenuItem, _badge);
|
|
194
|
+
__decorateElement$2(_init$2, 4, "active", _active_dec, MenuItem, _active);
|
|
195
|
+
__decorateElement$2(_init$2, 4, "checked", _checked_dec, MenuItem, _checked);
|
|
196
|
+
__decorateElement$2(_init$2, 4, "href", _href_dec, MenuItem, _href);
|
|
197
|
+
__decorateElement$2(_init$2, 4, "target", _target_dec, MenuItem, _target);
|
|
198
|
+
MenuItem = __decorateElement$2(_init$2, 0, "MenuItem", _MenuItem_decorators, MenuItem);
|
|
199
|
+
__runInitializers$2(_init$2, 1, MenuItem);
|
|
200
|
+
const radioUnchecked = "gzm-menu-item-radio-unchecked";
|
|
201
|
+
const radioChecked = "gzm-menu-item-radio-checked";
|
|
202
|
+
const checkboxUnchecked = "gzm-menu-item-checkbox-unchecked";
|
|
203
|
+
const checkboxChecked = "gzm-menu-item-checkbox-checked";
|
|
204
|
+
iconCache[checkboxUnchecked] = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
205
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
206
|
+
<path d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z"></path>
|
|
207
|
+
</svg>`;
|
|
208
|
+
iconCache[checkboxChecked] = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
209
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
210
|
+
<path d="M18.333 2c1.96 0 3.56 1.537 3.662 3.472l.005 .195v12.666c0 1.96 -1.537 3.56 -3.472 3.662l-.195 .005h-12.666a3.667 3.667 0 0 1 -3.662 -3.472l-.005 -.195v-12.666c0 -1.96 1.537 -3.56 3.472 -3.662l.195 -.005h12.666zm-2.626 7.293a1 1 0 0 0 -1.414 0l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.32 1.497l2 2l.094 .083a1 1 0 0 0 1.32 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z" stroke-width="0" fill="currentColor"></path>
|
|
211
|
+
</svg>`;
|
|
212
|
+
iconCache[radioUnchecked] = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
213
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
214
|
+
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
|
|
215
|
+
</svg>`;
|
|
216
|
+
iconCache[radioChecked] = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
217
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
218
|
+
<path d="M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z" stroke-width="0" fill="currentColor"></path>
|
|
219
|
+
</svg>`;
|
|
220
|
+
var __create$1 = Object.create;
|
|
221
|
+
var __defProp$1 = Object.defineProperty;
|
|
222
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
223
|
+
var __knownSymbol$1 = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
224
|
+
var __typeError$1 = (msg) => {
|
|
225
|
+
throw TypeError(msg);
|
|
226
|
+
};
|
|
227
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
228
|
+
var __name$1 = (target, value) => __defProp$1(target, "name", { value, configurable: true });
|
|
229
|
+
var __decoratorStart$1 = (base) => [, , , __create$1(base?.[__knownSymbol$1("metadata")] ?? null)];
|
|
230
|
+
var __decoratorStrings$1 = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
231
|
+
var __expectFn$1 = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError$1("Function expected") : fn;
|
|
232
|
+
var __decoratorContext$1 = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings$1[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError$1("Already initialized") : fns.push(__expectFn$1(fn || null)) });
|
|
233
|
+
var __decoratorMetadata$1 = (array, target) => __defNormalProp$1(target, __knownSymbol$1("metadata"), array[3]);
|
|
234
|
+
var __runInitializers$1 = (array, flags, self, value) => {
|
|
235
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
|
|
236
|
+
return value;
|
|
237
|
+
};
|
|
238
|
+
var __decorateElement$1 = (array, flags, name, decorators, target, extra) => {
|
|
239
|
+
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
|
|
240
|
+
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings$1[k + 5];
|
|
241
|
+
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
|
|
242
|
+
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc$1(k < 4 ? target : { get [name]() {
|
|
243
|
+
return __privateGet(this, extra);
|
|
244
|
+
}, set [name](x) {
|
|
245
|
+
return __privateSet(this, extra, x);
|
|
246
|
+
} }, name));
|
|
247
|
+
k ? p && k < 4 && __name$1(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name$1(target, name);
|
|
248
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
249
|
+
ctx = __decoratorContext$1(k, name, done = {}, array[3], extraInitializers);
|
|
250
|
+
if (k) {
|
|
251
|
+
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
|
|
252
|
+
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
|
|
253
|
+
if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
|
|
254
|
+
}
|
|
255
|
+
it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
|
|
256
|
+
if (k ^ 4 || it === void 0) __expectFn$1(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
|
|
257
|
+
else if (typeof it !== "object" || it === null) __typeError$1("Object expected");
|
|
258
|
+
else __expectFn$1(fn = it.get) && (desc.get = fn), __expectFn$1(fn = it.set) && (desc.set = fn), __expectFn$1(fn = it.init) && initializers.unshift(fn);
|
|
259
|
+
}
|
|
260
|
+
return k || __decoratorMetadata$1(array, target), desc && __defProp$1(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
261
|
+
};
|
|
262
|
+
var __publicField = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
263
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
|
|
264
|
+
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError$1('Cannot use the "in" operator on this value') : member.has(obj);
|
|
265
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
266
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
267
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
268
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
269
|
+
var _down_dec, _up_dec, _a$1, _Menu_decorators, _onClick, _Menu_instances, checkActive_fn, onblur_fn, onkeydown_fn, checkTabIndex_fn, _onwheel, checkScroll_fn, _init$1, _up, _down, _subMenu, showSubMenu_fn;
|
|
270
|
+
const tagName$1 = "GZM-MENU";
|
|
271
|
+
function createMenu(...menuItems) {
|
|
272
|
+
const $menu = document.createElement(tagName$1);
|
|
273
|
+
$menu.modelList = menuItems;
|
|
274
|
+
$menu.setAttribute("popover", "manual");
|
|
275
|
+
return $menu;
|
|
276
|
+
}
|
|
277
|
+
const styleSheet$1 = createStyleSheet({
|
|
278
|
+
":host": {
|
|
279
|
+
"display": "block",
|
|
280
|
+
"opacity": "0.9",
|
|
281
|
+
"z-index": "10000",
|
|
282
|
+
//否则可能造成:网页原本没有滚动栏,appendTo(body)之后出现滚动栏,在定位后滚动栏又消失,最终出现偏差
|
|
283
|
+
"top": "0",
|
|
284
|
+
"left": "0",
|
|
285
|
+
//去掉 focus 后会显示的黑框
|
|
286
|
+
"outline-style": "none"
|
|
287
|
+
},
|
|
288
|
+
section: `
|
|
289
|
+
display:inline-grid;
|
|
290
|
+
grid-template-columns: auto auto auto auto;
|
|
291
|
+
max-height:80vh;
|
|
292
|
+
overflow-y:hidden;
|
|
293
|
+
`,
|
|
294
|
+
//group
|
|
295
|
+
nav: `
|
|
296
|
+
display:contents;
|
|
297
|
+
`,
|
|
298
|
+
//delimiter
|
|
299
|
+
"nav:not(:first-child)::before": `
|
|
300
|
+
content: '';
|
|
301
|
+
grid-column: 1 / span 4;
|
|
302
|
+
border-top: var(--gzm-btn-border);
|
|
303
|
+
margin: 0.5rem 0;
|
|
304
|
+
`
|
|
305
|
+
});
|
|
306
|
+
const scrollStyleSheet = createStyleSheet({
|
|
307
|
+
//scroll 指示器
|
|
308
|
+
[tagName$1]: `
|
|
309
|
+
max-height: 80vh;
|
|
310
|
+
scroll-behavior: smooth;
|
|
311
|
+
` + gzmFrame,
|
|
312
|
+
//不理解为什么浏览器默认样式是 overflow: auto !important。
|
|
313
|
+
[tagName$1 + "[popover]:popover-open"]: `
|
|
314
|
+
overflow-y: hidden !important;
|
|
315
|
+
`,
|
|
316
|
+
[tagName$1 + "[up]::before"]: `
|
|
317
|
+
content: '△';
|
|
318
|
+
position: absolute;
|
|
319
|
+
top: -0.5rem;
|
|
320
|
+
left: 50%;
|
|
321
|
+
transform: translateX(-50%);
|
|
322
|
+
`,
|
|
323
|
+
[tagName$1 + "[down]::after"]: `
|
|
324
|
+
content: '▽';
|
|
325
|
+
position: absolute;
|
|
326
|
+
bottom: -0.5rem;
|
|
327
|
+
left: 50%;
|
|
328
|
+
transform: translateX(-50%);
|
|
329
|
+
`
|
|
330
|
+
});
|
|
331
|
+
_Menu_decorators = [defineElement({ tagName: tagName$1, style: scrollStyleSheet })];
|
|
332
|
+
class Menu extends (_a$1 = ViewGroupElement, _up_dec = [boolAttr], _down_dec = [boolAttr], _a$1) {
|
|
333
|
+
constructor() {
|
|
334
|
+
super();
|
|
335
|
+
__privateAdd(this, _Menu_instances);
|
|
336
|
+
__privateAdd(this, _onClick, (e) => {
|
|
337
|
+
const $t = e.target;
|
|
338
|
+
const $item = $t.closest(tagName$2);
|
|
339
|
+
if (!$item) return;
|
|
340
|
+
if ($item.tag === "menu") {
|
|
341
|
+
__privateMethod(this, _Menu_instances, showSubMenu_fn).call(this, $item);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if ($item.tag === "check") {
|
|
345
|
+
$item.setModelProperty("checked", !$item.checked);
|
|
346
|
+
} else if ($item.tag === "radio" && !$item.checked) {
|
|
347
|
+
$item.parentElement?.querySelectorAll("*[tag=radio][checked]")?.forEach(($x) => $x.setModelProperty("checked", false));
|
|
348
|
+
$item.setModelProperty("checked", true);
|
|
349
|
+
}
|
|
350
|
+
this.closeAll();
|
|
351
|
+
});
|
|
352
|
+
__privateAdd(this, _onwheel, (e) => {
|
|
353
|
+
const $s2 = this.$section;
|
|
354
|
+
if (this.up && e.deltaY < 0) {
|
|
355
|
+
$s2.scrollTop += e.deltaY;
|
|
356
|
+
__privateMethod(this, _Menu_instances, checkScroll_fn).call(this);
|
|
357
|
+
}
|
|
358
|
+
if (this.down && e.deltaY > 0) {
|
|
359
|
+
$s2.scrollTop += e.deltaY;
|
|
360
|
+
__privateMethod(this, _Menu_instances, checkScroll_fn).call(this);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
__privateAdd(this, _up, __runInitializers$1(_init$1, 8, this, false)), __runInitializers$1(_init$1, 11, this);
|
|
364
|
+
__privateAdd(this, _down, __runInitializers$1(_init$1, 12, this, false)), __runInitializers$1(_init$1, 15, this);
|
|
365
|
+
__publicField(this, "$supMenuItem");
|
|
366
|
+
__privateAdd(this, _subMenu);
|
|
367
|
+
__publicField(this, "$section", document.createElement("section"));
|
|
368
|
+
__publicField(this, "groupElementTagName", "NAV");
|
|
369
|
+
const $s = this.$section;
|
|
370
|
+
$s.addEventListener("click", __privateGet(this, _onClick), true);
|
|
371
|
+
$s.addEventListener("wheel", __privateGet(this, _onwheel), { passive: true });
|
|
372
|
+
const root = this.attachShadow({ mode: "open" });
|
|
373
|
+
root.adoptedStyleSheets = [baseStyle, styleSheet$1, styleSheet$2];
|
|
374
|
+
root.appendChild($s);
|
|
375
|
+
}
|
|
376
|
+
// #region 处理显示和隐藏
|
|
377
|
+
show($attachTo, attachCorner, corner) {
|
|
378
|
+
if (corner === void 0) {
|
|
379
|
+
const isLeft = isLeftCorner(attachCorner);
|
|
380
|
+
const isTop = isTopCorner(attachCorner);
|
|
381
|
+
corner = makeCorner(!isLeft, isTop);
|
|
382
|
+
}
|
|
383
|
+
__privateMethod(this, _Menu_instances, checkTabIndex_fn).call(this);
|
|
384
|
+
new CornerHelper(this, corner, $attachTo, attachCorner).pos();
|
|
385
|
+
this.focus();
|
|
386
|
+
__privateMethod(this, _Menu_instances, checkScroll_fn).call(this);
|
|
387
|
+
this.onblur = __privateMethod(this, _Menu_instances, onblur_fn);
|
|
388
|
+
this.onkeydown = __privateMethod(this, _Menu_instances, onkeydown_fn);
|
|
389
|
+
}
|
|
390
|
+
get isActive() {
|
|
391
|
+
const ret = this === document.activeElement || !!this.shadowRoot.activeElement;
|
|
392
|
+
console.debug(tagName$1, "isActive", ret);
|
|
393
|
+
return ret;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* 关闭自己以及下级菜单
|
|
397
|
+
*/
|
|
398
|
+
close() {
|
|
399
|
+
this._closeSubMenu();
|
|
400
|
+
this.remove();
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* 关闭所有菜单,包括上级和上级的上级
|
|
404
|
+
*/
|
|
405
|
+
closeAll() {
|
|
406
|
+
this.close();
|
|
407
|
+
if (this.$supMenuItem) {
|
|
408
|
+
const $m = tryGetMenu(this.$supMenuItem);
|
|
409
|
+
$m?.closeAll();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* 场景:
|
|
414
|
+
* 此菜单显示了一个子菜单,子菜单获得输入焦点。鼠标没有点击子菜单,却点击了此菜单(如另一个submenu菜单项,或者不属于菜单项的任意菜单部分)。
|
|
415
|
+
* 子菜单 blur 事件触发,这时不能关闭所有的菜单,而是从子菜单开始向上找,将未获得焦点的菜单全部关闭。
|
|
416
|
+
* @returns
|
|
417
|
+
*/
|
|
418
|
+
_closeIfNotActive() {
|
|
419
|
+
if (this.isActive) {
|
|
420
|
+
this._closeSubMenu();
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (this.$supMenuItem) {
|
|
424
|
+
const $m = tryGetMenu(this.$supMenuItem);
|
|
425
|
+
$m?._closeIfNotActive();
|
|
426
|
+
} else {
|
|
427
|
+
this.close();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
_closeSubMenu() {
|
|
431
|
+
if (__privateGet(this, _subMenu)) {
|
|
432
|
+
const $mi = __privateGet(this, _subMenu).$supMenuItem;
|
|
433
|
+
if ($mi) {
|
|
434
|
+
$mi.active = false;
|
|
435
|
+
__privateGet(this, _subMenu).$supMenuItem = void 0;
|
|
436
|
+
}
|
|
437
|
+
__privateGet(this, _subMenu).close();
|
|
438
|
+
__privateSet(this, _subMenu, void 0);
|
|
439
|
+
}
|
|
440
|
+
this.focus();
|
|
441
|
+
}
|
|
442
|
+
// #endregion
|
|
443
|
+
// #region 重写 ViewGroupElement
|
|
444
|
+
_getViewItemTagName() {
|
|
445
|
+
return tagName$2;
|
|
446
|
+
}
|
|
447
|
+
get $viewItemsContainer() {
|
|
448
|
+
return this.$section;
|
|
449
|
+
}
|
|
450
|
+
// #endregion
|
|
451
|
+
}
|
|
452
|
+
_init$1 = __decoratorStart$1(_a$1);
|
|
453
|
+
_onClick = /* @__PURE__ */ new WeakMap();
|
|
454
|
+
_Menu_instances = /* @__PURE__ */ new WeakSet();
|
|
455
|
+
checkActive_fn = function() {
|
|
456
|
+
if (this.isActive) {
|
|
457
|
+
this.focus();
|
|
458
|
+
} else {
|
|
459
|
+
this._closeIfNotActive();
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
onblur_fn = function() {
|
|
463
|
+
console.debug(tagName$1, "blur");
|
|
464
|
+
if (!__privateGet(this, _subMenu)) {
|
|
465
|
+
window.setTimeout(() => {
|
|
466
|
+
__privateMethod(this, _Menu_instances, checkActive_fn).call(this);
|
|
467
|
+
}, 25);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
onkeydown_fn = function(e) {
|
|
471
|
+
if (e.key === "Escape") {
|
|
472
|
+
if (this.$supMenuItem) {
|
|
473
|
+
const $m = tryGetMenu(this.$supMenuItem);
|
|
474
|
+
$m?._closeSubMenu();
|
|
475
|
+
} else {
|
|
476
|
+
this.close();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
checkTabIndex_fn = function() {
|
|
481
|
+
if (!this.hasAttribute("tabindex")) {
|
|
482
|
+
this.setAttribute("tabindex", "0");
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
_onwheel = /* @__PURE__ */ new WeakMap();
|
|
486
|
+
checkScroll_fn = function() {
|
|
487
|
+
this.up = false;
|
|
488
|
+
this.down = false;
|
|
489
|
+
const $s = this.$section;
|
|
490
|
+
if ($s.scrollHeight <= $s.clientHeight) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if ($s.scrollTop > 0) {
|
|
494
|
+
this.up = true;
|
|
495
|
+
}
|
|
496
|
+
const diff = $s.scrollTop + $s.clientHeight - $s.scrollHeight;
|
|
497
|
+
if (diff < -1) {
|
|
498
|
+
this.down = true;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
_up = /* @__PURE__ */ new WeakMap();
|
|
502
|
+
_down = /* @__PURE__ */ new WeakMap();
|
|
503
|
+
_subMenu = /* @__PURE__ */ new WeakMap();
|
|
504
|
+
showSubMenu_fn = function($mi) {
|
|
505
|
+
const sis = $mi.model?.subItems;
|
|
506
|
+
if (!sis) return;
|
|
507
|
+
this._closeSubMenu();
|
|
508
|
+
$mi.active = true;
|
|
509
|
+
const $sm = __privateSet(this, _subMenu, createMenu(...sis));
|
|
510
|
+
$sm.$supMenuItem = $mi;
|
|
511
|
+
$sm.show($mi.$divs[3], xy.rightTop, xy.leftTop);
|
|
512
|
+
};
|
|
513
|
+
__decorateElement$1(_init$1, 4, "up", _up_dec, Menu, _up);
|
|
514
|
+
__decorateElement$1(_init$1, 4, "down", _down_dec, Menu, _down);
|
|
515
|
+
Menu = __decorateElement$1(_init$1, 0, "Menu", _Menu_decorators, Menu);
|
|
516
|
+
__runInitializers$1(_init$1, 1, Menu);
|
|
517
|
+
function tryGetMenu(mi) {
|
|
518
|
+
const sr = mi.getRootNode();
|
|
519
|
+
return sr.host;
|
|
520
|
+
}
|
|
521
|
+
var __create = Object.create;
|
|
522
|
+
var __defProp = Object.defineProperty;
|
|
523
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
524
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
525
|
+
var __typeError = (msg) => {
|
|
526
|
+
throw TypeError(msg);
|
|
527
|
+
};
|
|
528
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
529
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
530
|
+
var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)];
|
|
531
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
532
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
|
|
533
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
534
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
535
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
536
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self);
|
|
537
|
+
return value;
|
|
538
|
+
};
|
|
539
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
540
|
+
var it, done, ctx, k = flags & 7, p = false;
|
|
541
|
+
var j = 0;
|
|
542
|
+
var extraInitializers = array[j] || (array[j] = []);
|
|
543
|
+
var desc = k && (target = target.prototype, k < 5 && (k > 3 || !p) && __getOwnPropDesc(target, name));
|
|
544
|
+
__name(target, name);
|
|
545
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
546
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
547
|
+
it = (0, decorators[i])(target, ctx), done._ = 1;
|
|
548
|
+
__expectFn(it) && (target = it);
|
|
549
|
+
}
|
|
550
|
+
return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
551
|
+
};
|
|
552
|
+
var _MenuList_decorators, _init, _a;
|
|
553
|
+
const tagName = "GZM-MENU-LIST";
|
|
554
|
+
const styleSheet = createStyleSheet({
|
|
555
|
+
":host": `
|
|
556
|
+
display:inline-block;
|
|
557
|
+
`,
|
|
558
|
+
//菜单项太多要求出现滚动栏,如果:host出现滚动栏很难看。
|
|
559
|
+
//所以由 section 出现滚动栏,在 :host 和 section 之间要有 padding。
|
|
560
|
+
section: `
|
|
561
|
+
display:inline-grid;
|
|
562
|
+
grid-template-columns: auto auto auto auto;
|
|
563
|
+
max-height:100%;
|
|
564
|
+
overflow-y:auto;
|
|
565
|
+
`,
|
|
566
|
+
//group
|
|
567
|
+
nav: `
|
|
568
|
+
display:contents;
|
|
569
|
+
`,
|
|
570
|
+
'nav[label]:not([label=""])::before': `
|
|
571
|
+
content: attr(label);
|
|
572
|
+
font-weight: bolder;
|
|
573
|
+
grid-column: 1 / span 4;
|
|
574
|
+
padding-inline: 0.25rem;
|
|
575
|
+
padding-bottom: 0.25rem;
|
|
576
|
+
`,
|
|
577
|
+
'nav[label]:not([label=""]):not(:first-child)::before': `
|
|
578
|
+
padding-top: 1rem;
|
|
579
|
+
`
|
|
580
|
+
});
|
|
581
|
+
_MenuList_decorators = [defineElement({ tagName })];
|
|
582
|
+
class MenuList extends (_a = ViewGroupElement) {
|
|
583
|
+
constructor() {
|
|
584
|
+
super();
|
|
585
|
+
const root = this.attachShadow({ mode: "open" });
|
|
586
|
+
root.adoptedStyleSheets = [baseStyle, styleSheet, styleSheet$2];
|
|
587
|
+
root.addEventListener("click", this.#onClick, true);
|
|
588
|
+
root.appendChild(this.$section);
|
|
589
|
+
}
|
|
590
|
+
//捕获阶段在先,而 item.model.onclick 后被调用。为了让这里的 checked 属性先被修改。
|
|
591
|
+
#onClick = (e) => {
|
|
592
|
+
const $t = e.target;
|
|
593
|
+
const item = $t.closest(tagName$2);
|
|
594
|
+
if (!item) return;
|
|
595
|
+
this.shadowRoot.querySelectorAll(tagName$2 + "[active]").forEach(($x) => $x.active = false);
|
|
596
|
+
item.active = true;
|
|
597
|
+
if (item.tag === "menu") {
|
|
598
|
+
this.#showSubMenu(item);
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
if (item.tag === "check") {
|
|
602
|
+
item.setModelProperty("checked", !item.checked);
|
|
603
|
+
} else if (item.tag === "radio" && !item.checked) {
|
|
604
|
+
item.parentElement?.querySelectorAll("*[tag=radio][checked]")?.forEach(($x) => $x.setModelProperty("checked", false));
|
|
605
|
+
item.setModelProperty("checked", true);
|
|
606
|
+
}
|
|
607
|
+
this._closeSubMenu();
|
|
608
|
+
};
|
|
609
|
+
// #region 处理子菜单
|
|
610
|
+
#subMenu;
|
|
611
|
+
//当前显示的子菜单
|
|
612
|
+
#showSubMenu($mi) {
|
|
613
|
+
const sis = $mi.model?.subItems;
|
|
614
|
+
if (!sis) return;
|
|
615
|
+
this._closeSubMenu();
|
|
616
|
+
const $sm = this.#subMenu = createMenu(...sis);
|
|
617
|
+
$sm.$supMenuItem = $mi;
|
|
618
|
+
$sm.show($mi.$divs[3], xy.rightTop, xy.leftTop);
|
|
619
|
+
}
|
|
620
|
+
_closeSubMenu() {
|
|
621
|
+
if (this.#subMenu) {
|
|
622
|
+
const $mi = this.#subMenu.$supMenuItem;
|
|
623
|
+
if ($mi) {
|
|
624
|
+
$mi.active = false;
|
|
625
|
+
this.#subMenu.$supMenuItem = void 0;
|
|
626
|
+
}
|
|
627
|
+
this.#subMenu.close();
|
|
628
|
+
this.#subMenu = void 0;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
_closeIfNotActive() {
|
|
632
|
+
this._closeSubMenu();
|
|
633
|
+
}
|
|
634
|
+
closeAll() {
|
|
635
|
+
this._closeSubMenu();
|
|
636
|
+
}
|
|
637
|
+
// #endregion
|
|
638
|
+
// #region 重写 ViewGroupElement
|
|
639
|
+
_getViewItemTagName() {
|
|
640
|
+
return tagName$2;
|
|
641
|
+
}
|
|
642
|
+
get $viewItemsContainer() {
|
|
643
|
+
return this.$section;
|
|
644
|
+
}
|
|
645
|
+
groupElementTagName = "NAV";
|
|
646
|
+
$section = document.createElement("section");
|
|
647
|
+
// #endregion
|
|
648
|
+
}
|
|
649
|
+
_init = __decoratorStart(_a);
|
|
650
|
+
MenuList = __decorateElement(_init, 0, "MenuList", _MenuList_decorators, MenuList);
|
|
651
|
+
__runInitializers(_init, 1, MenuList);
|
|
652
|
+
export {
|
|
653
|
+
Menu,
|
|
654
|
+
MenuList,
|
|
655
|
+
createMenu,
|
|
656
|
+
tagName as menuListTagName,
|
|
657
|
+
tagName$1 as menuTagName
|
|
658
|
+
};
|
|
659
|
+
//# sourceMappingURL=menu.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.es.js","sources":["../src/009-menu/menuItem.ts","../src/009-menu/menu.ts","../src/009-menu/menuList.ts"],"sourcesContent":["import type {MiOptions} from './model.ts';\r\nimport {type Badge, badgeTagName, boolAttr, createStyleSheet, defineElement, type Icon, iconTagName, strAttr, iconCache, type AttributeHandlers} from '@gzmjs/ui-basic';\r\nimport {ViewElement} from '@gzmjs/mvvm';\r\n\r\ntype MenuItemTag = 'click' | 'link' | 'check' | 'radio' | 'menu';\r\nconst mutableAttributes = ['tag', 'label', 'icon', 'badge', 'checked', 'href', 'target'] as const;\r\nexport const tagName = 'GZM-MENU-ITEM';\r\n\r\nexport const styleSheet = createStyleSheet({\r\n [tagName]: `\r\n cursor: pointer;\r\n display: contents;\r\n `,\r\n\r\n //因为 display:contents,只能设置每一个grid单元的边框来实现hover效果。\r\n [`${tagName}>*`]: `\r\n border:1px solid transparent;\r\n padding-inline:0.125rem;\r\n `,\r\n [`${tagName}>*:not(:last-child)`]: `\r\n border-right:0;\r\n `,\r\n [`${tagName}>*:not(:first-child)`]: `\r\n border-left:0;\r\n `,\r\n [`${tagName}:active>*, ${tagName}[active]>*`]: {\r\n color: 'var(--gzm-a-btn-txt-color)',\r\n background: 'var(--gzm-a-btn-background)',\r\n border: 'var(--gzm-a-btn-border)',\r\n },\r\n [`${tagName}:hover>*`]: {\r\n background: 'var(--gzm-h-btn-background)',\r\n border: 'var(--gzm-h-btn-border)',\r\n color: 'var(--gzm-h-btn-txt-color)',\r\n },\r\n //link <a> 的颜色\r\n [`${tagName} a`]: `\r\n color: inherit;\r\n `,\r\n\r\n //menu\r\n //https://www.compart.com/en/unicode/U+2BC8\r\n [`${tagName}[tag=menu]>div:last-child::after`]: `\r\n content: '⯈';\r\n font-size: 0.75rem;\r\n padding-right:0.125rem;\r\n `,\r\n});\r\n\r\n@defineElement({tagName, mutableAttributes})\r\nexport class MenuItem extends ViewElement<MiOptions> implements AttributeHandlers<typeof mutableAttributes[number]> {\r\n\r\n //一共 4 个,用来放置: icon, label, badge, submenu。整个 menu 是 grid 布局,这 4 个 div 就是一行的占位符。\r\n $divs: HTMLElement[] = [document.createElement(iconTagName), document.createElement('div'), document.createElement('div'), document.createElement('div')];\r\n\r\n connectedCallback() {\r\n if (this.childElementCount === 0) {\r\n this.append(...this.$divs);\r\n }\r\n }\r\n \r\n // #region 处理所有的属性\r\n @strAttr\r\n accessor tag: MenuItemTag | undefined;\r\n\r\n @strAttr\r\n accessor label: string | undefined;\r\n\r\n @strAttr\r\n accessor icon: string | undefined;\r\n\r\n /* 不要定义 group 属性,当 group 改变时由 menu 去处理 model event。\r\n @ATR.getStrAttr\r\n public get group(): string {return '';}*/\r\n\r\n @strAttr\r\n accessor badge: string | undefined;\r\n\r\n @boolAttr\r\n accessor active: boolean = false;\r\n\r\n @boolAttr\r\n accessor checked: boolean = false;\r\n\r\n @strAttr\r\n accessor href: string | undefined;\r\n\r\n @strAttr\r\n accessor target: string | undefined;\r\n\r\n _tag_set<MenuItemTag>(tag: MenuItemTag | null, old: MenuItemTag | null) {\r\n if (old === tag) return;\r\n\r\n //处理图标\r\n if (tag === 'check' || tag === 'radio') {\r\n //现在无论是 check 还是 radio,都必须重新设置 icon,而且是根据 checked 来设置。\r\n this._checked_set();\r\n }\r\n else if (old === 'check' || old === 'radio') {\r\n this._icon_set(this.icon ?? null);\r\n }\r\n\r\n //处理文本\r\n if (tag === 'link') {\r\n const $d = this.$divs[1]!;\r\n const $a = this.$divs[1] = document.createElement('a');\r\n if ($d.isConnected) {\r\n $d.replaceWith($a);\r\n }\r\n this._label_set(this.label ?? null);\r\n this._href_set(this.href ?? null);\r\n this._target_set(this.target ?? '_blank');\r\n }\r\n else if (old === 'link') {\r\n const $a = this.$divs[1]!;\r\n const $d = this.$divs[1] = document.createElement('div');\r\n if ($a.isConnected) {\r\n $a.replaceWith($d);\r\n }\r\n this._label_set(this.label ?? null);\r\n }\r\n\r\n //badge 对所有的都一样,无需处理\r\n\r\n //处理 submenu\r\n if (tag === 'menu') {\r\n //什么都不需要做\r\n }\r\n else if (old === 'menu') {\r\n this.$divs[3]!.innerHTML = '';\r\n }\r\n } \r\n _icon_set(icn: string | null) {\r\n const $icn = this.$divs[0] as Icon;\r\n $icn.icon = icn ?? void 0;\r\n }\r\n _label_set(lbl: string | null) {\r\n const $div = this.$divs[1]!;\r\n $div.textContent = lbl;\r\n }\r\n _badge_set(bdg: string | null) {\r\n const $div = this.$divs[2]!;\r\n if (!bdg) {\r\n $div.innerHTML = '';\r\n return;\r\n }\r\n let $bdg = $div.firstElementChild as Badge;\r\n if (!$bdg) {\r\n $bdg = document.createElement(badgeTagName);\r\n $div.append($bdg);\r\n }\r\n $bdg.badge = bdg;\r\n }\r\n _checked_set() {\r\n const tag = this.tag;\r\n const checked = this.checked;\r\n\r\n //https://old.unicode-table.com/en/sets/check/\r\n if (tag === 'check') {\r\n //this._icon_set(icn, checked ? '▣' : '▢');\r\n this._icon_set(checked ? checkboxChecked : checkboxUnchecked);\r\n }\r\n else if (tag === 'radio') {\r\n //this._icon_set(icn, checked ? '◉' : '◯');\r\n this._icon_set(checked ? radioChecked : radioUnchecked);\r\n /*\r\n if (this.checked && this.inputName) {\r\n //相同 input-name 的其他项要\r\n const ra = this.parentElement.querySelectorAll(`${menuItemTagName}[input-name='${this.inputName}'][type='radio']`);\r\n for (const r of ra) {\r\n if (r !== this && r.checked) {\r\n r.checked = false;\r\n }\r\n }\r\n }*/\r\n }\r\n }\r\n _href_set(nv: string | null) {\r\n const $a = this.$divs[1] as HTMLAnchorElement;\r\n $a.href = nv || 'javascript:void(0);';\r\n }\r\n _target_set(nv: string | null) {\r\n const $a = this.$divs[1] as HTMLAnchorElement;\r\n $a.target = nv ?? '_blank';\r\n }\r\n // #endregion\r\n}\r\n\r\nconst radioUnchecked = 'gzm-menu-item-radio-unchecked';\r\nconst radioChecked = 'gzm-menu-item-radio-checked';\r\nconst checkboxUnchecked = 'gzm-menu-item-checkbox-unchecked';\r\nconst checkboxChecked = 'gzm-menu-item-checkbox-checked';\r\n\r\niconCache[checkboxUnchecked] =\r\n`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n <path d=\"M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z\"></path>\r\n</svg>`;\r\n\r\niconCache[checkboxChecked] =\r\n`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n <path d=\"M18.333 2c1.96 0 3.56 1.537 3.662 3.472l.005 .195v12.666c0 1.96 -1.537 3.56 -3.472 3.662l-.195 .005h-12.666a3.667 3.667 0 0 1 -3.662 -3.472l-.005 -.195v-12.666c0 -1.96 1.537 -3.56 3.472 -3.662l.195 -.005h12.666zm-2.626 7.293a1 1 0 0 0 -1.414 0l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.32 1.497l2 2l.094 .083a1 1 0 0 0 1.32 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\" stroke-width=\"0\" fill=\"currentColor\"></path>\r\n</svg>`;\r\n\r\niconCache[radioUnchecked] =\r\n`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n <path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"></path>\r\n</svg>`;\r\n\r\niconCache[radioChecked] =\r\n`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n <path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\" stroke-width=\"0\" fill=\"currentColor\"></path>\r\n</svg>`;","import type {MiOptions, ISubMenu} from './model';\r\nimport * as MI from './menuItem';\r\nimport {type ViewListModel, ViewGroupElement} from '@gzmjs/mvvm';\r\nimport {baseStyle, createStyleSheet, defineElement, type Corner, CornerHelper, isLeftCorner, isTopCorner, makeCorner, boolAttr, xy, gzmFrame} from '@gzmjs/ui-basic';\r\n\r\nexport const tagName = 'GZM-MENU';//弹出式菜单\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n [tagName]: Menu;\r\n }\r\n}\r\n\r\nexport interface MenuOptions extends ViewListModel<MiOptions, MI.MenuItem, Menu> {\r\n tagName?: typeof tagName;\r\n}\r\n\r\nexport function createMenu(...menuItems: MiOptions[]): Menu {\r\n const $menu = document.createElement(tagName);\r\n $menu.modelList = menuItems;\r\n $menu.setAttribute('popover', 'manual');\r\n return $menu;\r\n}\r\n\r\nconst styleSheet = createStyleSheet({\r\n ':host': {\r\n 'display': 'block',\r\n 'opacity': '0.9',\r\n 'z-index': '10000',\r\n\r\n //否则可能造成:网页原本没有滚动栏,appendTo(body)之后出现滚动栏,在定位后滚动栏又消失,最终出现偏差\r\n 'top':'0',\r\n 'left':'0',\r\n\r\n //去掉 focus 后会显示的黑框\r\n 'outline-style': 'none',\r\n },\r\n section: `\r\n display:inline-grid;\r\n grid-template-columns: auto auto auto auto;\r\n max-height:80vh;\r\n overflow-y:hidden;\r\n `,\r\n //group\r\n nav: `\r\n display:contents;\r\n `,\r\n //delimiter\r\n 'nav:not(:first-child)::before': `\r\n content: '';\r\n grid-column: 1 / span 4;\r\n border-top: var(--gzm-btn-border);\r\n margin: 0.5rem 0;\r\n `\r\n});\r\nconst scrollStyleSheet = createStyleSheet({\r\n //scroll 指示器\r\n [tagName]: `\r\n max-height: 80vh;\r\n scroll-behavior: smooth;\r\n ` + gzmFrame,\r\n //不理解为什么浏览器默认样式是 overflow: auto !important。\r\n [tagName + '[popover]:popover-open']: `\r\n overflow-y: hidden !important;\r\n `,\r\n [tagName + '[up]::before']: `\r\n content: '△';\r\n position: absolute;\r\n top: -0.5rem;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n `,\r\n [tagName + '[down]::after']: `\r\n content: '▽';\r\n position: absolute;\r\n bottom: -0.5rem;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n `,\r\n});\r\n\r\n@defineElement({tagName, style: scrollStyleSheet})\r\nexport class Menu extends ViewGroupElement<MiOptions, MI.MenuItem, MenuOptions> {\r\n constructor() {\r\n super();\r\n\r\n const $s = this.$section;\r\n $s.addEventListener('click', this.#onClick, true);//捕获阶段\r\n $s.addEventListener('wheel', this.#onwheel, {passive:true});//否则浏览器警告\r\n\r\n const root = this.attachShadow({ mode: 'open' });\r\n root.adoptedStyleSheets = [baseStyle, styleSheet, MI.styleSheet];\r\n root.appendChild($s);\r\n }\r\n declare readonly shadowRoot: ShadowRoot;\r\n\r\n //捕获阶段在先,而 $item.model.onclick 后被调用。为了让这里的 checked 属性先被修改。\r\n #onClick = (e: Event) => {\r\n const $t = e.target as Element;\r\n const $item = $t.closest(MI.tagName) as MI.MenuItem;\r\n if (!$item) return;\r\n\r\n if ($item.tag === 'menu') {\r\n this.#showSubMenu($item);\r\n return;\r\n }\r\n \r\n if ($item.tag === 'check') {\r\n $item.setModelProperty('checked', !$item.checked);\r\n }\r\n else if ($item.tag === 'radio' && !$item.checked) {\r\n $item.parentElement?.querySelectorAll<MI.MenuItem>('*[tag=radio][checked]')?.forEach($x => $x.setModelProperty('checked', false));\r\n $item.setModelProperty('checked', true);\r\n }\r\n this.closeAll();\r\n }\r\n\r\n // #region 处理显示和隐藏\r\n public show($attachTo: HTMLElement, attachCorner: Corner, corner?: Corner) {\r\n if (corner === void 0) {\r\n const isLeft = isLeftCorner(attachCorner);\r\n const isTop = isTopCorner(attachCorner);\r\n corner = makeCorner(!isLeft, isTop);\r\n }\r\n this.#checkTabIndex();\r\n \r\n new CornerHelper(this, corner, $attachTo, attachCorner).pos();\r\n\r\n this.focus();\r\n this.#checkScroll();\r\n this.onblur = this.#onblur;\r\n this.onkeydown = this.#onkeydown;\r\n }\r\n public get isActive() {\r\n const ret = this === document.activeElement || !!this.shadowRoot.activeElement;\r\n console.debug(tagName, 'isActive', ret);\r\n return ret;\r\n }\r\n /**\r\n * 当失去焦点,则判断当前获得焦点的元素是否是container的子元素,如果不是则关闭\r\n */\r\n #checkActive() {\r\n if (this.isActive) {\r\n /**\r\n * 当前焦点元素是子元素,则使容器再次获得焦点,否则下次就不会触发onblur事件。\r\n * 举例:datepicker控件,弹出的日历中点击选择月份,会触发onblur事件。\r\n * 如果不将焦点重新设置到容器,则鼠标点击 body 不会关闭 popup。\r\n */\r\n this.focus();\r\n }\r\n else {\r\n this._closeIfNotActive();\r\n }\r\n }\r\n #onblur() {\r\n //https://devdocs.io/dom/element/blur_event\r\n console.debug(tagName, 'blur');\r\n\r\n if (!this.#subMenu) {\r\n //当不存在子菜单的时候,就需要关闭当前菜单。\r\n window.setTimeout(() => {\r\n this.#checkActive();\r\n }, 25);\r\n }\r\n }\r\n #onkeydown(e: KeyboardEvent) {\r\n if (e.key === 'Escape') {\r\n //esc,如果是子菜单则只关闭自己这一级\r\n if (this.$supMenuItem) {\r\n const $m = tryGetMenu(this.$supMenuItem);\r\n $m?._closeSubMenu(); \r\n }\r\n else {\r\n this.close();\r\n }\r\n }\r\n }\r\n #checkTabIndex() {\r\n if (!this.hasAttribute('tabindex')) {\r\n this.setAttribute('tabindex', '0');\r\n }\r\n }\r\n // #endregion\r\n\r\n // #region 处理滚动\r\n #onwheel = (e: WheelEvent) => {\r\n //https://devdocs.io/dom/element/wheel_event\r\n const $s = this.$section;\r\n //console.debug(tagName, 'scroll', `${$s.scrollHeight}, ${$s.scrollTop}, ${$s.clientHeight}`, `${e.deltaMode} ${e.deltaY}`);\r\n \r\n if (this.up && e.deltaY < 0) {\r\n $s.scrollTop += e.deltaY;\r\n this.#checkScroll();\r\n }\r\n if (this.down && e.deltaY > 0) {\r\n $s.scrollTop += e.deltaY;\r\n this.#checkScroll();\r\n }\r\n }\r\n #checkScroll() {\r\n this.up = false;\r\n this.down = false;\r\n //console.debug(`${this.scrollTop} ${this.clientHeight} ${this.scrollHeight}`);\r\n\r\n const $s = this.$section;\r\n if ($s.scrollHeight <= $s.clientHeight) {\r\n return;\r\n }\r\n if ($s.scrollTop > 0) {\r\n this.up = true;\r\n }\r\n\r\n const diff = $s.scrollTop + $s.clientHeight - $s.scrollHeight;\r\n //console.debug(tagName, 'checkScroll', diff);\r\n if ( diff < -1) { //浮点数计算有误差,逻辑上应该是 < 0。\r\n this.down = true;\r\n }\r\n }\r\n\r\n @boolAttr\r\n accessor up: boolean = false;\r\n\r\n @boolAttr\r\n accessor down: boolean = false;\r\n // #endregion\r\n\r\n // #region 处理子菜单\r\n $supMenuItem?: MI.MenuItem; //作为子菜单存在的时候,这个值指向上级菜单的菜单项\r\n #subMenu?: Menu; //当前显示的子菜单\r\n\r\n #showSubMenu($mi: MI.MenuItem) {\r\n const sis = ($mi.model as ISubMenu)?.subItems;\r\n if (!sis) return;\r\n \r\n this._closeSubMenu();\r\n\r\n $mi.active = true; //显示子菜单的时候可以明显看出上一级的菜单项\r\n\r\n const $sm = this.#subMenu = createMenu(...sis);\r\n $sm.$supMenuItem = $mi;\r\n $sm.show($mi.$divs[3]!, xy.rightTop, xy.leftTop);\r\n }\r\n \r\n /**\r\n * 关闭自己以及下级菜单\r\n */\r\n close() {\r\n this._closeSubMenu();\r\n this.remove();\r\n }\r\n /**\r\n * 关闭所有菜单,包括上级和上级的上级\r\n */\r\n closeAll() {\r\n this.close();\r\n\r\n if (this.$supMenuItem) {\r\n const $m = tryGetMenu(this.$supMenuItem);\r\n $m?.closeAll();\r\n }\r\n }\r\n /**\r\n * 场景:\r\n * 此菜单显示了一个子菜单,子菜单获得输入焦点。鼠标没有点击子菜单,却点击了此菜单(如另一个submenu菜单项,或者不属于菜单项的任意菜单部分)。\r\n * 子菜单 blur 事件触发,这时不能关闭所有的菜单,而是从子菜单开始向上找,将未获得焦点的菜单全部关闭。\r\n * @returns \r\n */\r\n protected _closeIfNotActive() {\r\n if (this.isActive) {\r\n this._closeSubMenu();\r\n return;\r\n }\r\n if (this.$supMenuItem) {\r\n const $m = tryGetMenu(this.$supMenuItem);\r\n $m?._closeIfNotActive();\r\n }\r\n else {\r\n this.close();\r\n }\r\n }\r\n protected _closeSubMenu() {\r\n if (this.#subMenu) {\r\n const $mi = this.#subMenu.$supMenuItem;\r\n if ($mi) {\r\n $mi.active = false;\r\n this.#subMenu.$supMenuItem = void 0;\r\n }\r\n this.#subMenu.close();\r\n this.#subMenu = void 0;\r\n }\r\n this.focus();\r\n }\r\n // #endregion\r\n\r\n // #region 重写 ViewGroupElement\r\n protected _getViewItemTagName(): string {\r\n return MI.tagName;\r\n }\r\n public get $viewItemsContainer(): HTMLElement | ShadowRoot {\r\n return this.$section;\r\n }\r\n protected $section = document.createElement('section');\r\n protected readonly groupElementTagName: string = 'NAV';\r\n // #endregion\r\n}\r\n\r\nfunction tryGetMenu(mi: MI.MenuItem): Menu | undefined {\r\n const sr = mi.getRootNode() as ShadowRoot;\r\n return sr.host as Menu;\r\n}","import {type ViewListModel, ViewGroupElement} from '@gzmjs/mvvm';\r\nimport {baseStyle, createStyleSheet, defineElement, xy} from '@gzmjs/ui-basic';\r\nimport type {MiOptions, ISubMenu} from './model';\r\nimport * as MI from './menuItem';\r\nimport * as M from './menu';\r\n\r\nexport const tagName = 'GZM-MENU-LIST';//非弹出式菜单\r\nexport interface MenuListOptions extends ViewListModel<MiOptions, MI.MenuItem, MenuList> {\r\n tagName?: typeof tagName;\r\n}\r\n\r\nconst styleSheet = createStyleSheet({\r\n ':host': `\r\n display:inline-block;\r\n `,\r\n \r\n //菜单项太多要求出现滚动栏,如果:host出现滚动栏很难看。\r\n //所以由 section 出现滚动栏,在 :host 和 section 之间要有 padding。\r\n section: `\r\n display:inline-grid;\r\n grid-template-columns: auto auto auto auto;\r\n max-height:100%;\r\n overflow-y:auto;\r\n `,\r\n\r\n //group\r\n nav: `\r\n display:contents;\r\n `,\r\n 'nav[label]:not([label=\"\"])::before': `\r\n content: attr(label);\r\n font-weight: bolder;\r\n grid-column: 1 / span 4;\r\n padding-inline: 0.25rem;\r\n padding-bottom: 0.25rem;\r\n `,\r\n 'nav[label]:not([label=\"\"]):not(:first-child)::before': `\r\n padding-top: 1rem;\r\n `,\r\n});\r\n\r\n@defineElement({tagName})\r\nexport class MenuList extends ViewGroupElement<MiOptions, MI.MenuItem, MenuListOptions> {\r\n constructor() {\r\n super();\r\n const root = this.attachShadow({ mode: 'open' });\r\n root.adoptedStyleSheets = [baseStyle, styleSheet, MI.styleSheet];\r\n root.addEventListener('click', this.#onClick, true);//捕获阶段\r\n root.appendChild(this.$section);\r\n }\r\n declare readonly shadowRoot: ShadowRoot;\r\n\r\n //捕获阶段在先,而 item.model.onclick 后被调用。为了让这里的 checked 属性先被修改。\r\n #onClick = (e: Event) => {\r\n const $t = e.target as Element;\r\n const item = $t.closest(MI.tagName) as MI.MenuItem;\r\n if (!item) return;\r\n\r\n //清除其他选中项\r\n this.shadowRoot.querySelectorAll<MI.MenuItem>(MI.tagName + '[active]').forEach($x => $x.active = false);\r\n item.active = true; //选中点击项。\r\n\r\n if (item.tag === 'menu') {\r\n this.#showSubMenu(item);\r\n return;\r\n }\r\n if (item.tag === 'check') {\r\n item.setModelProperty('checked', !item.checked);\r\n }\r\n else if (item.tag === 'radio' && !item.checked) {\r\n item.parentElement?.querySelectorAll<MI.MenuItem>('*[tag=radio][checked]')?.forEach($x => $x.setModelProperty('checked', false));\r\n item.setModelProperty('checked', true);\r\n }\r\n this._closeSubMenu();\r\n };\r\n\r\n // #region 处理子菜单\r\n #subMenu?: M.Menu; //当前显示的子菜单\r\n\r\n #showSubMenu($mi: MI.MenuItem) {\r\n const sis = ($mi.model as ISubMenu)?.subItems;\r\n if (!sis) return;\r\n\r\n this._closeSubMenu();\r\n\r\n const $sm = this.#subMenu = M.createMenu(...sis);\r\n $sm.$supMenuItem = $mi;\r\n $sm.show($mi.$divs[3]!, xy.rightTop, xy.leftTop);\r\n }\r\n _closeSubMenu() {\r\n if (this.#subMenu) {\r\n const $mi = this.#subMenu.$supMenuItem;\r\n if ($mi) {\r\n $mi.active = false;\r\n this.#subMenu.$supMenuItem = void 0;\r\n }\r\n this.#subMenu.close();\r\n this.#subMenu = void 0;\r\n }\r\n }\r\n protected _closeIfNotActive() {\r\n this._closeSubMenu();\r\n }\r\n closeAll() {\r\n this._closeSubMenu();\r\n }\r\n // #endregion\r\n\r\n // #region 重写 ViewGroupElement\r\n protected _getViewItemTagName(): string {\r\n return MI.tagName;\r\n }\r\n public get $viewItemsContainer(): HTMLElement | ShadowRoot {\r\n return this.$section;\r\n }\r\n protected readonly groupElementTagName: string = 'NAV';\r\n protected $section = document.createElement('section');\r\n // #endregion\r\n}\r\n"],"names":["_a","_init","tagName","styleSheet","__publicField","__privateAdd","__runInitializers","__decoratorStart","__decorateElement","MI.tagName","$s","MI.styleSheet","M.createMenu"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gzmjs/menu",
|
|
3
|
+
"description": "GZMJS UI Menu Component",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"module": "dist/menu.es.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "tsc && vite build",
|
|
14
|
+
"preview": "vite preview",
|
|
15
|
+
"analyzer": "vite-bundle-visualizer"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^25.1.0",
|
|
19
|
+
"eslint": "^9.39.2",
|
|
20
|
+
"typescript": "~5.9.3",
|
|
21
|
+
"typescript-eslint": "^8.54.0",
|
|
22
|
+
"vite": "^7.2.4",
|
|
23
|
+
"vite-bundle-visualizer": "^1.2.1",
|
|
24
|
+
"vite-plugin-dts": "^4.5.4"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@gzmjs/mvvm": "^0.1.0",
|
|
28
|
+
"@gzmjs/ui-basic": "^0.3.0"
|
|
29
|
+
}
|
|
30
|
+
}
|