@gzmjs/menu 0.1.1 → 0.2.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 +3 -1
- package/dist/009-menu/model.d.ts +1 -0
- package/dist/menu.es.js +20 -6
- package/dist/menu.es.js.map +1 -1
- package/package.json +1 -1
package/dist/009-menu/menu.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ declare global {
|
|
|
10
10
|
}
|
|
11
11
|
export interface MenuOptions extends ViewListModel<MiOptions, MI.MenuItem, Menu> {
|
|
12
12
|
tagName?: typeof tagName;
|
|
13
|
+
itemClick?: (this: MenuOptions, item: MiOptions, $item: MI.MenuItem, ev: MouseEvent) => void;
|
|
13
14
|
}
|
|
14
|
-
export declare function createMenu(...menuItems: MiOptions[]): Menu;
|
|
15
15
|
export declare class Menu extends ViewGroupElement<MiOptions, MI.MenuItem, MenuOptions> {
|
|
16
16
|
#private;
|
|
17
17
|
constructor();
|
|
@@ -42,3 +42,5 @@ export declare class Menu extends ViewGroupElement<MiOptions, MI.MenuItem, MenuO
|
|
|
42
42
|
protected $section: HTMLElement;
|
|
43
43
|
protected readonly groupElementTagName: string;
|
|
44
44
|
}
|
|
45
|
+
export declare function createMenu(...menuItems: MiOptions[]): Menu;
|
|
46
|
+
export declare function createMenuWithModel(vm: MenuOptions): Menu;
|
package/dist/009-menu/model.d.ts
CHANGED
package/dist/menu.es.js
CHANGED
|
@@ -268,12 +268,6 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
268
268
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
269
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
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
271
|
const styleSheet$1 = createStyleSheet({
|
|
278
272
|
":host": {
|
|
279
273
|
"display": "block",
|
|
@@ -347,6 +341,9 @@ class Menu extends (_a$1 = ViewGroupElement, _up_dec = [boolAttr], _down_dec = [
|
|
|
347
341
|
$item.parentElement?.querySelectorAll("*[tag=radio][checked]")?.forEach(($x) => $x.setModelProperty("checked", false));
|
|
348
342
|
$item.setModelProperty("checked", true);
|
|
349
343
|
}
|
|
344
|
+
if (!$item.model?.onclick) {
|
|
345
|
+
findMenuModelWithClick(this)?.itemClick?.($item.model, $item, e);
|
|
346
|
+
}
|
|
350
347
|
this.closeAll();
|
|
351
348
|
});
|
|
352
349
|
__privateAdd(this, _onwheel, (e) => {
|
|
@@ -518,6 +515,23 @@ function tryGetMenu(mi) {
|
|
|
518
515
|
const sr = mi.getRootNode();
|
|
519
516
|
return sr.host;
|
|
520
517
|
}
|
|
518
|
+
function findMenuModelWithClick($menu) {
|
|
519
|
+
if ($menu.model?.itemClick) {
|
|
520
|
+
return $menu.model;
|
|
521
|
+
}
|
|
522
|
+
if ($menu.$supMenuItem) {
|
|
523
|
+
const $m = tryGetMenu($menu.$supMenuItem);
|
|
524
|
+
if ($m) {
|
|
525
|
+
return findMenuModelWithClick($m);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
function createMenu(...menuItems) {
|
|
530
|
+
const $menu = document.createElement(tagName$1);
|
|
531
|
+
$menu.modelList = menuItems;
|
|
532
|
+
$menu.setAttribute("popover", "manual");
|
|
533
|
+
return $menu;
|
|
534
|
+
}
|
|
521
535
|
var __create = Object.create;
|
|
522
536
|
var __defProp = Object.defineProperty;
|
|
523
537
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/dist/menu.es.js.map
CHANGED
|
@@ -1 +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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,aAAA,WAAA,cAAA,aAAA,YAAA,WAAA,YAAA,UAAAA,MAAA,sBAAAC,SAAA,MAAA,QAAA,OAAA,QAAA,SAAA,UAAA,OAAA;AAKA,MAAM,oBAAoB,CAAC,OAAO,SAAS,QAAQ,SAAS,WAAW,QAAQ,QAAQ;AAChF,MAAMC,YAAU;AAEhB,MAAMC,eAAa,iBAAiB;AAAA,EACvC,CAACD,SAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,CAAC,GAAGA,SAAO,IAAI,GAAG;AAAA;AAAA;AAAA;AAAA,EAIlB,CAAC,GAAGA,SAAO,qBAAqB,GAAG;AAAA;AAAA;AAAA,EAGnC,CAAC,GAAGA,SAAO,sBAAsB,GAAG;AAAA;AAAA;AAAA,EAGpC,CAAC,GAAGA,SAAO,cAAcA,SAAO,YAAY,GAAG;AAAA,IAC3C,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,EAAA;AAAA,EAEZ,CAAC,GAAGA,SAAO,UAAU,GAAG;AAAA,IACpB,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,EAAA;AAAA;AAAA,EAGX,CAAC,GAAGA,SAAO,IAAI,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,CAAC,GAAGA,SAAO,kCAAkC,GAAG;AAAA;AAAA;AAAA;AAAA;AAKpD,CAAC;AAED,uBAAA,CAAC,cAAc,EAAA,SAACA,WAAS,kBAAA,CAAkB,CAAA;AACpC,MAAM,kBAAiBF,OAAA,aAY1B,WAAA,CAAC,UAGD,aAAA,CAAC,OAAA,GAGD,aAAC,OAAA,GAOD,aAAA,CAAC,OAAA,GAGD,cAAA,CAAC,WAGD,eAAA,CAAC,QAAA,GAGD,aAAC,OAAA,GAGD,cAAA,CAAC,UArCyBA,MAAsF;AAAA,EAA7G,cAAA;AAAA,UAAA,GAAA,SAAA;AAGHI,oBAAA,MAAA,SAAuB,CAAC,SAAS,cAAc,WAAW,GAAG,SAAS,cAAc,KAAK,GAAG,SAAS,cAAc,KAAK,GAAG,SAAS,cAAc,KAAK,CAAC,CAAA;AAUxJC,mBAAA,MAAS,MAATC,oBAAAL,SAAA,GAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,QAATC,oBAAAL,SAAA,IAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,OAATC,oBAAAL,SAAA,IAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAOAI,mBAAA,MAAS,QAATC,oBAAAL,SAAA,IAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,SAAkBC,oBAA3BL,SAAA,IAAA,MAA2B,KAAA,CAAA,GAA3BK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,UAAmBC,oBAA5BL,SAAA,IAAA,MAA4B,KAAA,CAAA,GAA5BK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,OAATC,oBAAAL,SAAA,IAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAGAI,mBAAA,MAAS,SAATC,oBAAAL,SAAA,IAAA,IAAA,CAAA,GAAAK,oBAAAL,SAAA,IAAA,IAAA;AAAA,EAAA;AAAA,EAjCA,oBAAoB;AAChB,QAAI,KAAK,sBAAsB,GAAG;AAC9B,WAAK,OAAO,GAAG,KAAK,KAAK;AAAA,IAC7B;AAAA,EACJ;AAAA,EA+BA,SAAsB,KAAyB,KAAyB;AACpE,QAAI,QAAQ,IAAK;AAGjB,QAAI,QAAQ,WAAW,QAAQ,SAAS;AAEpC,WAAK,aAAA;AAAA,IACT,WACS,QAAQ,WAAW,QAAQ,SAAS;AACzC,WAAK,UAAU,KAAK,QAAQ,IAAI;AAAA,IACpC;AAGA,QAAI,QAAQ,QAAQ;AAChB,YAAM,KAAK,KAAK,MAAM,CAAC;AACvB,YAAM,KAAK,KAAK,MAAM,CAAC,IAAI,SAAS,cAAc,GAAG;AACrD,UAAI,GAAG,aAAa;AAChB,WAAG,YAAY,EAAE;AAAA,MACrB;AACA,WAAK,WAAW,KAAK,SAAS,IAAI;AAClC,WAAK,UAAU,KAAK,QAAQ,IAAI;AAChC,WAAK,YAAY,KAAK,UAAU,QAAQ;AAAA,IAC5C,WACS,QAAQ,QAAQ;AACrB,YAAM,KAAK,KAAK,MAAM,CAAC;AACvB,YAAM,KAAK,KAAK,MAAM,CAAC,IAAI,SAAS,cAAc,KAAK;AACvD,UAAI,GAAG,aAAa;AAChB,WAAG,YAAY,EAAE;AAAA,MACrB;AACA,WAAK,WAAW,KAAK,SAAS,IAAI;AAAA,IACtC;AAKA,QAAI,QAAQ,OAAQ;AAAA,aAGX,QAAQ,QAAQ;AACrB,WAAK,MAAM,CAAC,EAAG,YAAY;AAAA,IAC/B;AAAA,EACJ;AAAA,EACA,UAAU,KAAoB;AAC1B,UAAM,OAAO,KAAK,MAAM,CAAC;AACzB,SAAK,OAAO,OAAO;AAAA,EACvB;AAAA,EACA,WAAW,KAAoB;AAC3B,UAAM,OAAO,KAAK,MAAM,CAAC;AACzB,SAAK,cAAc;AAAA,EACvB;AAAA,EACA,WAAW,KAAoB;AAC3B,UAAM,OAAO,KAAK,MAAM,CAAC;AACzB,QAAI,CAAC,KAAK;AACN,WAAK,YAAY;AACjB;AAAA,IACJ;AACA,QAAI,OAAO,KAAK;AAChB,QAAI,CAAC,MAAM;AACP,aAAO,SAAS,cAAc,YAAY;AAC1C,WAAK,OAAO,IAAI;AAAA,IACpB;AACA,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,eAAe;AACX,UAAM,MAAM,KAAK;AACjB,UAAM,UAAU,KAAK;AAGrB,QAAI,QAAQ,SAAS;AAEjB,WAAK,UAAU,UAAU,kBAAkB,iBAAiB;AAAA,IAChE,WACS,QAAQ,SAAS;AAEtB,WAAK,UAAU,UAAU,eAAe,cAAc;AAAA,IAW1D;AAAA,EACJ;AAAA,EACA,UAAU,IAAmB;AACzB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,OAAG,OAAO,MAAM;AAAA,EACpB;AAAA,EACA,YAAY,IAAmB;AAC3B,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,OAAG,SAAS,MAAM;AAAA,EACtB;AAAA;AAEJ;AAxIOA,UAAAM,mBAAAP,IAAA;AAaM,OAAA,oBAAA,QAAA;AAGA,SAAA,oBAAA,QAAA;AAGA,QAAA,oBAAA,QAAA;AAOA,SAAA,oBAAA,QAAA;AAGA,UAAA,oBAAA,QAAA;AAGA,WAAA,oBAAA,QAAA;AAGA,QAAA,oBAAA,QAAA;AAGA,UAAA,oBAAA,QAAA;AAzBTQ,oBAAAP,SAAA,GAAS,OADT,UAZS,UAaA,IAAA;AAGTO,oBAAAP,SAAA,GAAS,SADT,YAfS,UAgBA,MAAA;AAGTO,oBAAAP,SAAA,GAAS,QADT,WAlBS,UAmBA,KAAA;AAOTO,oBAAAP,SAAA,GAAS,SADT,YAzBS,UA0BA,MAAA;AAGTO,oBAAAP,SAAA,GAAS,UADT,aA5BS,UA6BA,OAAA;AAGTO,oBAAAP,SAAA,GAAS,WADT,cA/BS,UAgCA,QAAA;AAGTO,oBAAAP,SAAA,GAAS,QADT,WAlCS,UAmCA,KAAA;AAGTO,oBAAAP,SAAA,GAAS,UADT,aArCS,UAsCA,OAAA;AAtCA,WAANO,4CADP,sBACa,QAAA;AAANF,oBAAAL,SAAA,GAAM,QAAA;AA0Ib,MAAM,iBAAiB;AACvB,MAAM,eAAe;AACrB,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB;AAExB,UAAU,iBAAiB,IAC3B;AAAA;AAAA;AAAA;AAKA,UAAU,eAAe,IACzB;AAAA;AAAA;AAAA;AAKA,UAAU,cAAc,IACxB;AAAA;AAAA;AAAA;AAKA,UAAU,YAAY,IACtB;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpNA,IAAA,WAAA,SAAAD,MAAA,kBAAA,UAAA,iBAAA,gBAAA,WAAA,cAAA,kBAAA,UAAA,gBAAAC,SAAA,KAAA,OAAA,UAAA;AAKO,MAAMC,YAAU;AAWhB,SAAS,cAAc,WAA8B;AACxD,QAAM,QAAQ,SAAS,cAAcA,SAAO;AAC5C,QAAM,YAAY;AAClB,QAAM,aAAa,WAAW,QAAQ;AACtC,SAAO;AACX;AAEA,MAAMC,eAAa,iBAAiB;AAAA,EAChC,SAAS;AAAA,IACL,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA;AAAA,IAGX,OAAM;AAAA,IACN,QAAO;AAAA;AAAA,IAGP,iBAAiB;AAAA,EAAA;AAAA,EAErB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOT,KAAK;AAAA;AAAA;AAAA;AAAA,EAIL,iCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAMrC,CAAC;AACD,MAAM,mBAAmB,iBAAiB;AAAA;AAAA,EAEtC,CAACD,SAAO,GAAG;AAAA;AAAA;AAAA,QAGP;AAAA;AAAA,EAEJ,CAACA,YAAU,wBAAwB,GAAG;AAAA;AAAA;AAAA,EAGtC,CAACA,YAAU,cAAc,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5B,CAACA,YAAU,eAAe,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOjC,CAAC;AAED,mBAAA,CAAC,cAAc,EAAA,SAACA,WAAS,OAAO,kBAAiB,CAAA;AAC1C,MAAM,cAAaF,OAAA,kBAyItB,UAAA,CAAC,QAAA,GAGD,YAAA,CAAC,WA5IqBA,MAAsD;AAAA,EAC5E,cAAc;AACV,UAAA;AAFD,iBAAA,MAAA,eAAA;AAeH,iBAAA,MAAA,UAAW,CAAC,MAAa;AACrB,YAAM,KAAK,EAAE;AACb,YAAM,QAAQ,GAAG,QAAQS,SAAU;AACnC,UAAI,CAAC,MAAO;AAEZ,UAAI,MAAM,QAAQ,QAAQ;AACtB,wBAAA,MAAK,iCAAL,KAAA,MAAkB,KAAA;AAClB;AAAA,MACJ;AAEA,UAAI,MAAM,QAAQ,SAAS;AACvB,cAAM,iBAAiB,WAAW,CAAC,MAAM,OAAO;AAAA,MACpD,WACS,MAAM,QAAQ,WAAW,CAAC,MAAM,SAAS;AAC9C,cAAM,eAAe,iBAA8B,uBAAuB,GAAG,QAAQ,QAAM,GAAG,iBAAiB,WAAW,KAAK,CAAC;AAChI,cAAM,iBAAiB,WAAW,IAAI;AAAA,MAC1C;AACA,WAAK,SAAA;AAAA,IACT,CAAA;AAsEA,iBAAA,MAAA,UAAW,CAAC,MAAkB;AAE1B,YAAMC,MAAK,KAAK;AAGhB,UAAI,KAAK,MAAM,EAAE,SAAS,GAAG;AACzB,QAAAA,IAAG,aAAa,EAAE;AAClB,wBAAA,MAAK,iBAAA,cAAA,EAAL,KAAA,IAAA;AAAA,MACJ;AACA,UAAI,KAAK,QAAQ,EAAE,SAAS,GAAG;AAC3B,QAAAA,IAAG,aAAa,EAAE;AAClB,wBAAA,MAAK,iBAAA,cAAA,EAAL,KAAA,IAAA;AAAA,MACJ;AAAA,IACJ,CAAA;AAsBA,iBAAA,MAAS,KAAcJ,oBAAvBL,SAAA,GAAA,MAAuB,KAAA,CAAA,GAAvBK,oBAAAL,SAAA,IAAA,IAAA;AAGA,iBAAA,MAAS,OAAgBK,oBAAzBL,SAAA,IAAA,MAAyB,KAAA,CAAA,GAAzBK,oBAAAL,SAAA,IAAA,IAAA;AAIA,kBAAA,MAAA,cAAA;AACA,iBAAA,MAAA,QAAA;AAyEA,kBAAA,MAAU,YAAW,SAAS,cAAc,SAAS,CAAA;AACrD,kBAAA,MAAmB,uBAA8B,KAAA;AAxN7C,UAAM,KAAK,KAAK;AAChB,OAAG,iBAAiB,SAAS,aAAA,MAAK,QAAA,GAAU,IAAI;AAChD,OAAG,iBAAiB,SAAS,aAAA,MAAK,WAAU,EAAC,SAAQ,MAAK;AAE1D,UAAM,OAAO,KAAK,aAAa,EAAE,MAAM,QAAQ;AAC/C,SAAK,qBAAqB,CAAC,WAAWE,cAAYQ,YAAa;AAC/D,SAAK,YAAY,EAAE;AAAA,EACvB;AAAA;AAAA,EAyBO,KAAK,WAAwB,cAAsB,QAAiB;AACvE,QAAI,WAAW,QAAQ;AACnB,YAAM,SAAS,aAAa,YAAY;AACxC,YAAM,QAAQ,YAAY,YAAY;AACtC,eAAS,WAAW,CAAC,QAAQ,KAAK;AAAA,IACtC;AACA,oBAAA,MAAK,iBAAA,gBAAA,EAAL,KAAA,IAAA;AAEA,QAAI,aAAa,MAAM,QAAQ,WAAW,YAAY,EAAE,IAAA;AAExD,SAAK,MAAA;AACL,oBAAA,MAAK,iBAAA,cAAA,EAAL,KAAA,IAAA;AACA,SAAK,SAAS,gBAAA,MAAK,iBAAA,SAAA;AACnB,SAAK,YAAY,gBAAA,MAAK,iBAAA,YAAA;AAAA,EAC1B;AAAA,EACA,IAAW,WAAW;AAClB,UAAM,MAAM,SAAS,SAAS,iBAAiB,CAAC,CAAC,KAAK,WAAW;AACjE,YAAQ,MAAMT,WAAS,YAAY,GAAG;AACtC,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EA6GA,QAAQ;AACJ,SAAK,cAAA;AACL,SAAK,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAIA,WAAW;AACP,SAAK,MAAA;AAEL,QAAI,KAAK,cAAc;AACnB,YAAM,KAAK,WAAW,KAAK,YAAY;AACvC,UAAI,SAAA;AAAA,IACR;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,oBAAoB;AAC1B,QAAI,KAAK,UAAU;AACf,WAAK,cAAA;AACL;AAAA,IACJ;AACA,QAAI,KAAK,cAAc;AACnB,YAAM,KAAK,WAAW,KAAK,YAAY;AACvC,UAAI,kBAAA;AAAA,IACR,OACK;AACD,WAAK,MAAA;AAAA,IACT;AAAA,EACJ;AAAA,EACU,gBAAgB;AACtB,QAAI,mBAAK,QAAA,GAAU;AACf,YAAM,MAAM,mBAAK,QAAA,EAAS;AAC1B,UAAI,KAAK;AACL,YAAI,SAAS;AACb,qBAAA,MAAK,UAAS,eAAe;AAAA,MACjC;AACA,mBAAA,MAAK,UAAS,MAAA;AACd,mBAAA,MAAK,UAAW,MAAA;AAAA,IACpB;AACA,SAAK,MAAA;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,sBAA8B;AACpC,WAAOO;AAAAA,EACX;AAAA,EACA,IAAW,sBAAgD;AACvD,WAAO,KAAK;AAAA,EAChB;AAAA;AAIJ;AA9NOR,UAAAM,mBAAAP,IAAA;AAeH,WAAA,oBAAA,QAAA;AAfG,kBAAA,oBAAA,QAAA;AA2DH,iBAAY,WAAG;AACX,MAAI,KAAK,UAAU;AAMf,SAAK,MAAA;AAAA,EACT,OACK;AACD,SAAK,kBAAA;AAAA,EACT;AACJ;AACA,YAAO,WAAG;AAEN,UAAQ,MAAME,WAAS,MAAM;AAE7B,MAAI,CAAC,mBAAK,QAAA,GAAU;AAEhB,WAAO,WAAW,MAAM;AACpB,sBAAA,MAAK,iBAAA,cAAA,EAAL,KAAA,IAAA;AAAA,IACJ,GAAG,EAAE;AAAA,EACT;AACJ;AACA,eAAU,SAAC,GAAkB;AACzB,MAAI,EAAE,QAAQ,UAAU;AAEpB,QAAI,KAAK,cAAc;AACnB,YAAM,KAAK,WAAW,KAAK,YAAY;AACvC,UAAI,cAAA;AAAA,IACR,OACK;AACD,WAAK,MAAA;AAAA,IACT;AAAA,EACJ;AACJ;AACA,mBAAc,WAAG;AACb,MAAI,CAAC,KAAK,aAAa,UAAU,GAAG;AAChC,SAAK,aAAa,YAAY,GAAG;AAAA,EACrC;AACJ;AAIA,WAAA,oBAAA,QAAA;AAcA,iBAAY,WAAG;AACX,OAAK,KAAK;AACV,OAAK,OAAO;AAGZ,QAAM,KAAK,KAAK;AAChB,MAAI,GAAG,gBAAgB,GAAG,cAAc;AACpC;AAAA,EACJ;AACA,MAAI,GAAG,YAAY,GAAG;AAClB,SAAK,KAAK;AAAA,EACd;AAEA,QAAM,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG;AAEjD,MAAK,OAAO,IAAI;AACZ,SAAK,OAAO;AAAA,EAChB;AACJ;AAGS,MAAA,oBAAA,QAAA;AAGA,QAAA,oBAAA,QAAA;AAKT,WAAA,oBAAA,QAAA;AAEA,iBAAY,SAAC,KAAkB;AAC3B,QAAM,MAAO,IAAI,OAAoB;AACrC,MAAI,CAAC,IAAK;AAEV,OAAK,cAAA;AAEL,MAAI,SAAS;AAEb,QAAM,MAAM,aAAA,MAAK,UAAW,WAAW,GAAG,GAAG,CAAA;AAC7C,MAAI,eAAe;AACnB,MAAI,KAAK,IAAI,MAAM,CAAC,GAAI,GAAG,UAAU,GAAG,OAAO;AACnD;AArBAM,oBAAAP,SAAA,GAAS,MADT,SAzIS,MA0IA,GAAA;AAGTO,oBAAAP,SAAA,GAAS,QADT,WA5IS,MA6IA,KAAA;AA7IA,OAANO,wCADP,kBACa,IAAA;AAANF,oBAAAL,SAAA,GAAM,IAAA;AAgOb,SAAS,WAAW,IAAmC;AACnD,QAAM,KAAK,GAAG,YAAA;AACd,SAAO,GAAG;AACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpTA,IAAA,sBAAA,OAAA;AAMO,MAAM,UAAU;AAKvB,MAAM,aAAa,iBAAiB;AAAA,EAChC,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,KAAK;AAAA;AAAA;AAAA,EAGL,sCAAsC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtC,wDAAwD;AAAA;AAAA;AAG5D,CAAC;AAED,uBAAA,CAAC,cAAc,EAAC,QAAA,CAAQ,CAAA;AACjB,MAAM,kBAAiB,KAAA,kBAA0D;AAAA,EACpF,cAAc;AACV,UAAA;AACA,UAAM,OAAO,KAAK,aAAa,EAAE,MAAM,QAAQ;AAC/C,SAAK,qBAAqB,CAAC,WAAW,YAAYU,YAAa;AAC/D,SAAK,iBAAiB,SAAS,KAAK,UAAU,IAAI;AAClD,SAAK,YAAY,KAAK,QAAQ;AAAA,EAClC;AAAA;AAAA,EAIA,WAAW,CAAC,MAAa;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,OAAO,GAAG,QAAQF,SAAU;AAClC,QAAI,CAAC,KAAM;AAGX,SAAK,WAAW,iBAA8BA,YAAa,UAAU,EAAE,QAAQ,CAAA,OAAM,GAAG,SAAS,KAAK;AACtG,SAAK,SAAS;AAEd,QAAI,KAAK,QAAQ,QAAQ;AACrB,WAAK,aAAa,IAAI;AACtB;AAAA,IACJ;AACA,QAAI,KAAK,QAAQ,SAAS;AACtB,WAAK,iBAAiB,WAAW,CAAC,KAAK,OAAO;AAAA,IAClD,WACS,KAAK,QAAQ,WAAW,CAAC,KAAK,SAAS;AAC5C,WAAK,eAAe,iBAA8B,uBAAuB,GAAG,QAAQ,QAAM,GAAG,iBAAiB,WAAW,KAAK,CAAC;AAC/H,WAAK,iBAAiB,WAAW,IAAI;AAAA,IACzC;AACA,SAAK,cAAA;AAAA,EACT;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA,aAAa,KAAkB;AAC3B,UAAM,MAAO,IAAI,OAAoB;AACrC,QAAI,CAAC,IAAK;AAEV,SAAK,cAAA;AAEL,UAAM,MAAM,KAAK,WAAWG,WAAa,GAAG,GAAG;AAC/C,QAAI,eAAe;AACnB,QAAI,KAAK,IAAI,MAAM,CAAC,GAAI,GAAG,UAAU,GAAG,OAAO;AAAA,EACnD;AAAA,EACA,gBAAgB;AACZ,QAAI,KAAK,UAAU;AACf,YAAM,MAAM,KAAK,SAAS;AAC1B,UAAI,KAAK;AACL,YAAI,SAAS;AACb,aAAK,SAAS,eAAe;AAAA,MACjC;AACA,WAAK,SAAS,MAAA;AACd,WAAK,WAAW;AAAA,IACpB;AAAA,EACJ;AAAA,EACU,oBAAoB;AAC1B,SAAK,cAAA;AAAA,EACT;AAAA,EACA,WAAW;AACP,SAAK,cAAA;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,sBAA8B;AACpC,WAAOH;AAAAA,EACX;AAAA,EACA,IAAW,sBAAgD;AACvD,WAAO,KAAK;AAAA,EAChB;AAAA,EACmB,sBAA8B;AAAA,EACvC,WAAW,SAAS,cAAc,SAAS;AAAA;AAEzD;AA5EO,QAAA,iBAAA,EAAA;AAAM,WAAN,wCADP,sBACa,QAAA;AAAN,kBAAA,OAAA,GAAM,QAAA;"}
|
|
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 itemClick?: (this: MenuOptions, item: MiOptions, $item: MI.MenuItem, ev: MouseEvent) => void;\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: MouseEvent) => {\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 if (!$item.model?.onclick) {\r\n findMenuModelWithClick(this)?.itemClick?.($item.model!, $item, e);\r\n }\r\n this.closeAll();\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}\r\n\r\nfunction findMenuModelWithClick($menu: Menu): MenuOptions | undefined {\r\n if ($menu.model?.itemClick) {\r\n return $menu.model;\r\n }\r\n if ($menu.$supMenuItem) {\r\n const $m = tryGetMenu($menu.$supMenuItem);\r\n if ($m) {\r\n return findMenuModelWithClick($m);\r\n }\r\n }\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\nexport function createMenuWithModel(vm: MenuOptions): Menu {\r\n const $menu = document.createElement(tagName);\r\n $menu.model = vm;\r\n $menu.setAttribute('popover', 'manual');\r\n return $menu;\r\n}\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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"}
|