@greypan/web-ui 2.1.5 → 2.1.8
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/README.CN.md +52 -36
- package/README.md +55 -36
- package/dist/assets/glass.js.map +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/back-top/index.js +1 -1
- package/dist/components/back-top/index.js.map +1 -1
- package/dist/components/button/index.d.ts +6 -1
- package/dist/components/button/index.js +35 -14
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +1 -1
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +0 -3
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +4 -3
- package/dist/components/context-menu/index.js +47 -50
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/dialog/index.d.ts +1 -1
- package/dist/components/dialog/index.js +20 -19
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +1 -1
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +2 -3
- package/dist/components/drawer/index.js +41 -31
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +1 -1
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +2 -9
- package/dist/components/dropdown/index.js +55 -51
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown-item/index.d.ts +0 -1
- package/dist/components/dropdown-item/index.js.map +1 -1
- package/dist/components/dropdown-item/style.js +1 -1
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/input/index.d.ts +1 -0
- package/dist/components/input/index.js +27 -14
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +1 -1
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +3 -0
- package/dist/components/input-number/index.js +11 -3
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +1 -1
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/option/index.js +1 -1
- package/dist/components/option/index.js.map +1 -1
- package/dist/components/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +1 -5
- package/dist/components/popover/index.js +41 -36
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/radio/index.d.ts +0 -3
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/segmented/index.js +6 -2
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.js +1 -1
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +1 -0
- package/dist/components/select/index.js +11 -6
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/slider/index.d.ts +0 -2
- package/dist/components/slider/index.js +1 -1
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/spinner/index.d.ts +0 -2
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/svg-draw-lines/index.d.ts +0 -2
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +0 -1
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +1 -1
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +1 -0
- package/dist/components/textarea/index.js +47 -33
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.d.ts +0 -2
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +1 -1
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/manager.js.map +1 -1
- package/dist/components/toast/style.js +1 -1
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/toast/toast.d.ts +0 -4
- package/dist/components/toast/toast.js +14 -6
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/types.d.ts +0 -3
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/index.js +31 -30
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/shared/events/user-change.js +17 -0
- package/dist/shared/events/user-change.js.map +1 -0
- package/dist/shared/normalize/index.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js +8 -3
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/portal.js +3 -1
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/presence.js.map +1 -1
- package/package.json +9 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/dialog/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{transform:scale(var(--wui-scale-enter,.97));box-sizing:border-box;max-width:min(90vw, var(--wui-dialog-max-width,360px));max-height:90vh;color:var(--wui-color-text,#1b1b1b);opacity:0;transition:opacity var(--wui-duration-overlay-enter,.18s) var(--wui-ease-
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{transform:scale(var(--wui-scale-enter,.97));box-sizing:border-box;max-width:min(90vw, var(--wui-dialog-max-width,360px));max-height:90vh;color:var(--wui-color-text,#1b1b1b);opacity:0;transition:opacity var(--wui-duration-overlay-enter,.18s) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1)), transform var(--wui-duration-overlay-enter,.18s) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1));background:0 0;border:none;padding:0;font-family:inherit;overflow:visible}dialog::backdrop{opacity:0;background:var(--wui-dialog-overlay-bg,var(--wui-color-backdrop,#0000001a));transition:opacity var(--wui-duration-overlay-enter,.18s) ease}dialog[open].is-visible{opacity:1;transform:scale(1)}dialog.is-closing{pointer-events:none;transition-duration:var(--wui-duration-overlay-exit,.14s)}dialog.is-closing::backdrop{transition-duration:var(--wui-duration-overlay-exit,.14s)}dialog[open].is-visible::backdrop{opacity:1}@media (prefers-reduced-motion:reduce){dialog,dialog[open].is-visible{transition-duration:var(--wui-duration-feedback,.1s);transform:none}}.wui-dialog-body{--wui-glass-shadow:var(--wui-shadow-overlay,2px 16px 40px #0006);background-color:var(--wui-color-surface-overlay,#f6f6f6e0);border-radius:32px;padding:32px 24px 24px}.title{color:var(--wui-color-text,#1b1b1b);margin:0 0 16px;padding:0;font-size:18px;font-weight:600;line-height:1.4}.desc{color:var(--wui-color-text,#1b1b1b);margin:0 0 24px;padding:0;font-size:14px;line-height:1.5}.wui-dialog-footer{flex-direction:column;gap:10px;display:flex}.wui-dialog-footer ::slotted(web-ui-button){width:100%;display:flex}:host([horizontal]) .wui-dialog-footer{flex-direction:row;justify-content:center;gap:12px}:host([horizontal]) .wui-dialog-footer ::slotted(web-ui-button:not([full])){width:auto}:host([horizontal]) .wui-dialog-footer ::slotted(web-ui-button[full]){flex:1;min-width:0}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/dialog/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\ndialog {\n transform: scale(var(--wui-scale-enter, 0.97));\n\n overflow: visible;\n\n box-sizing: border-box;\n max-width: min(90vw, var(--wui-dialog-max-width, 360px));\n max-height: 90vh;\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n opacity: 0;\n background: transparent;\n\n transition:\n opacity var(--wui-duration-overlay-enter, 180ms) var(--wui-ease-
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/dialog/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\ndialog {\n transform: scale(var(--wui-scale-enter, 0.97));\n\n overflow: visible;\n\n box-sizing: border-box;\n max-width: min(90vw, var(--wui-dialog-max-width, 360px));\n max-height: 90vh;\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n opacity: 0;\n background: transparent;\n\n transition:\n opacity var(--wui-duration-overlay-enter, 180ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1)),\n transform var(--wui-duration-overlay-enter, 180ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n\n &::backdrop {\n opacity: 0;\n background: var(--wui-dialog-overlay-bg, var(--wui-color-backdrop, rgb(0 0 0 / 0.1)));\n transition: opacity var(--wui-duration-overlay-enter, 180ms) ease;\n }\n}\n\ndialog[open].is-visible {\n transform: scale(1);\n opacity: 1;\n}\n\ndialog.is-closing {\n pointer-events: none;\n transition-duration: var(--wui-duration-overlay-exit, 140ms);\n}\n\ndialog.is-closing::backdrop {\n transition-duration: var(--wui-duration-overlay-exit, 140ms);\n}\n\ndialog[open].is-visible::backdrop {\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog,\n dialog[open].is-visible {\n transform: none;\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n}\n\n/* ===== 玻璃卡片主体(样式由 glass.css 提供) ===== */\n\n.wui-dialog-body {\n --wui-glass-shadow: var(--wui-shadow-overlay, 2px 16px 40px rgb(0 0 0 / 0.4));\n padding: 32px 24px 24px;\n border-radius: 32px;\n background-color: var(--wui-color-surface-overlay, rgb(246 246 246 / 0.88));\n}\n\n/* ===== 标题 ===== */\n\n.title {\n margin: 0 0 16px;\n padding: 0;\n\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--wui-color-text, #1b1b1b);\n}\n\n/* ===== 描述 ===== */\n\n.desc {\n margin: 0 0 24px;\n padding: 0;\n\n font-size: 14px;\n line-height: 1.5;\n color: var(--wui-color-text, #1b1b1b);\n}\n\n/* ===== 按钮区域 ===== */\n\n.wui-dialog-footer {\n display: flex;\n flex-direction: column;\n gap: 10px;\n\n /* ===== 按钮全宽(默认垂直排列) ===== */\n\n & ::slotted(web-ui-button) {\n display: flex;\n width: 100%;\n }\n}\n\n/* ===== horizontal 模式 ===== */\n\n:host([horizontal]) .wui-dialog-footer {\n flex-direction: row;\n gap: 12px;\n justify-content: center;\n\n /* 非 full 按钮:居中,不拉伸 */\n\n & ::slotted(web-ui-button:not([full])) {\n width: auto;\n }\n\n /* full 按钮:平分剩余空间 */\n\n & ::slotted(web-ui-button[full]) {\n flex: 1;\n min-width: 0;\n }\n}\n"],"mappings":""}
|
|
@@ -9,12 +9,12 @@ export declare class WebUiDrawer extends LitElement {
|
|
|
9
9
|
get placement(): DrawerPlacement;
|
|
10
10
|
set placement(v: string);
|
|
11
11
|
private _placement;
|
|
12
|
-
/** 标题文字(未传 header slot 时显示默认 header) */
|
|
13
12
|
heading: string;
|
|
14
13
|
closable: boolean;
|
|
15
14
|
private get dialog();
|
|
16
15
|
private _hasHeaderSlot;
|
|
17
16
|
private _hasFooterSlot;
|
|
17
|
+
private readonly _userOpenChange;
|
|
18
18
|
private readonly _scrollLock;
|
|
19
19
|
private readonly _presence;
|
|
20
20
|
connectedCallback(): void;
|
|
@@ -26,10 +26,9 @@ export declare class WebUiDrawer extends LitElement {
|
|
|
26
26
|
protected updated(props: PropertyValues): void;
|
|
27
27
|
private handleTransitionEnd;
|
|
28
28
|
private handleKeydown;
|
|
29
|
-
/** 打开抽屉(命令式) */
|
|
30
29
|
show(): void;
|
|
31
|
-
/** 关闭抽屉(带动画) */
|
|
32
30
|
close(): void;
|
|
31
|
+
private readonly _closeFromUser;
|
|
33
32
|
private handleCancel;
|
|
34
33
|
private handleNativeClose;
|
|
35
34
|
private handleBackdropClick;
|
|
@@ -4,34 +4,37 @@ import t from "../../assets/glass.js";
|
|
|
4
4
|
import n from "../../icons/generated/ooui-close.js";
|
|
5
5
|
import { normalizeLiteral as r } from "../../shared/normalize/index.js";
|
|
6
6
|
import "../button/index.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import o from "
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
7
|
+
import { UserChangeController as i } from "../../shared/events/user-change.js";
|
|
8
|
+
import { createScrollLockLease as a } from "../../shared/scroll-lock/scroll-lock.js";
|
|
9
|
+
import { defineNativeDialogPresence as o } from "../../shared/overlay/native-dialog-presence.js";
|
|
10
|
+
import s from "./style.js";
|
|
11
|
+
import { LitElement as c, html as l, nothing as u, unsafeCSS as d } from "lit";
|
|
12
|
+
import { customElement as f, property as p } from "lit/decorators.js";
|
|
12
13
|
//#region src/components/drawer/index.ts
|
|
13
|
-
var
|
|
14
|
+
var m = [
|
|
14
15
|
"right",
|
|
15
16
|
"left",
|
|
16
17
|
"top",
|
|
17
18
|
"bottom"
|
|
18
|
-
],
|
|
19
|
+
], h = class extends c {
|
|
19
20
|
constructor(...e) {
|
|
20
|
-
super(...e), this.open = !1, this.noScrollLock = !1, this.noBackdropClose = !1, this._placement = "right", this.heading = "", this.closable = !1, this._hasHeaderSlot = !1, this._hasFooterSlot = !1, this.
|
|
21
|
+
super(...e), this.open = !1, this.noScrollLock = !1, this.noBackdropClose = !1, this._placement = "right", this.heading = "", this.closable = !1, this._hasHeaderSlot = !1, this._hasFooterSlot = !1, this._userOpenChange = new i(), this._scrollLock = a(), this._presence = o().make({
|
|
21
22
|
getDialog: () => this.dialog,
|
|
22
23
|
isConnected: () => this.isConnected,
|
|
23
24
|
isOpen: () => this.open
|
|
24
|
-
})
|
|
25
|
+
}), this._closeFromUser = () => {
|
|
26
|
+
this.open && (this._userOpenChange.mark(), this.close());
|
|
27
|
+
};
|
|
25
28
|
}
|
|
26
29
|
static {
|
|
27
|
-
this.styles = [
|
|
30
|
+
this.styles = [d(t), d(s)];
|
|
28
31
|
}
|
|
29
32
|
get placement() {
|
|
30
33
|
return this._placement;
|
|
31
34
|
}
|
|
32
35
|
set placement(e) {
|
|
33
36
|
let t = this._placement;
|
|
34
|
-
this._placement = r(e,
|
|
37
|
+
this._placement = r(e, m, "right"), this.requestUpdate("placement", t);
|
|
35
38
|
}
|
|
36
39
|
get dialog() {
|
|
37
40
|
return this.shadowRoot?.querySelector("dialog") ?? null;
|
|
@@ -60,13 +63,13 @@ var p = [
|
|
|
60
63
|
t !== this._hasFooterSlot && (this._hasFooterSlot = t, this.requestUpdate());
|
|
61
64
|
}
|
|
62
65
|
updated(e) {
|
|
63
|
-
super.updated(e), this.isConnected && (e.has("open") && (this.emitOpenChange(), this._presence.sync(this.open)), (e.has("open") || e.has("noScrollLock")) && this._syncScrollLock());
|
|
66
|
+
super.updated(e), this.isConnected && (e.has("open") && (this._userOpenChange.consume() && this.emitOpenChange(), this._presence.sync(this.open)), (e.has("open") || e.has("noScrollLock")) && this._syncScrollLock());
|
|
64
67
|
}
|
|
65
68
|
handleTransitionEnd(e) {
|
|
66
69
|
this._presence.handleTransitionEnd(e);
|
|
67
70
|
}
|
|
68
71
|
handleKeydown(e) {
|
|
69
|
-
e.key === "Escape" && (e.preventDefault(), this.
|
|
72
|
+
e.key === "Escape" && (e.preventDefault(), this._closeFromUser());
|
|
70
73
|
}
|
|
71
74
|
show() {
|
|
72
75
|
this.open ||= !0;
|
|
@@ -75,13 +78,13 @@ var p = [
|
|
|
75
78
|
this.open &&= !1;
|
|
76
79
|
}
|
|
77
80
|
handleCancel(e) {
|
|
78
|
-
e.preventDefault(), this.
|
|
81
|
+
e.preventDefault(), this._closeFromUser();
|
|
79
82
|
}
|
|
80
83
|
handleNativeClose() {
|
|
81
|
-
this.open &&= (this._presence.handleNativeClose(), !1);
|
|
84
|
+
this.open &&= (this._presence.handleNativeClose(), this._userOpenChange.mark(), !1);
|
|
82
85
|
}
|
|
83
86
|
handleBackdropClick(e) {
|
|
84
|
-
e.target === e.currentTarget && (this.noBackdropClose || this.
|
|
87
|
+
e.target === e.currentTarget && (this.noBackdropClose || this._closeFromUser());
|
|
85
88
|
}
|
|
86
89
|
emitOpenChange() {
|
|
87
90
|
this.dispatchEvent(new CustomEvent("open-change", {
|
|
@@ -95,7 +98,7 @@ var p = [
|
|
|
95
98
|
}
|
|
96
99
|
render() {
|
|
97
100
|
let e = this._hasHeaderSlot || !!this.heading;
|
|
98
|
-
return
|
|
101
|
+
return l`
|
|
99
102
|
<dialog
|
|
100
103
|
@cancel=${this.handleCancel}
|
|
101
104
|
@close=${this.handleNativeClose}
|
|
@@ -104,13 +107,13 @@ var p = [
|
|
|
104
107
|
@transitionend=${this.handleTransitionEnd}
|
|
105
108
|
>
|
|
106
109
|
<div class="wui-drawer-body wui-glass">
|
|
107
|
-
${e ?
|
|
110
|
+
${e ? l`
|
|
108
111
|
<div class="wui-drawer-header">
|
|
109
112
|
<slot name="header" @slotchange=${this.handleHeaderSlotChange}>
|
|
110
|
-
${this.heading ?
|
|
113
|
+
${this.heading ? l`<span class="wui-drawer-heading">${this.heading}</span>` : u}
|
|
111
114
|
</slot>
|
|
112
115
|
</div>
|
|
113
|
-
` :
|
|
116
|
+
` : u}
|
|
114
117
|
<div class="wui-drawer-content">
|
|
115
118
|
<slot></slot>
|
|
116
119
|
</div>
|
|
@@ -118,34 +121,41 @@ var p = [
|
|
|
118
121
|
<slot name="footer" @slotchange=${this.handleFooterSlotChange}></slot>
|
|
119
122
|
</div>
|
|
120
123
|
</div>
|
|
121
|
-
${this.closable ?
|
|
122
|
-
<web-ui-button
|
|
123
|
-
|
|
124
|
+
${this.closable ? l`
|
|
125
|
+
<web-ui-button
|
|
126
|
+
class="wui-drawer-close"
|
|
127
|
+
@click=${this._closeFromUser}
|
|
128
|
+
aria-label="关闭"
|
|
129
|
+
variant="secondary"
|
|
130
|
+
icon
|
|
131
|
+
size="26"
|
|
132
|
+
>
|
|
133
|
+
<web-ui-icon .icon=${n} size="16"></web-ui-icon>
|
|
124
134
|
</web-ui-button>
|
|
125
|
-
` :
|
|
135
|
+
` : u}
|
|
126
136
|
</dialog>
|
|
127
137
|
`;
|
|
128
138
|
}
|
|
129
139
|
};
|
|
130
|
-
e([
|
|
140
|
+
e([p({
|
|
131
141
|
type: Boolean,
|
|
132
142
|
reflect: !0
|
|
133
|
-
})],
|
|
143
|
+
})], h.prototype, "open", void 0), e([p({
|
|
134
144
|
type: Boolean,
|
|
135
145
|
reflect: !0,
|
|
136
146
|
attribute: "no-scroll-lock"
|
|
137
|
-
})],
|
|
147
|
+
})], h.prototype, "noScrollLock", void 0), e([p({
|
|
138
148
|
type: Boolean,
|
|
139
149
|
reflect: !0,
|
|
140
150
|
attribute: "no-backdrop-close"
|
|
141
|
-
})],
|
|
151
|
+
})], h.prototype, "noBackdropClose", void 0), e([p({
|
|
142
152
|
type: String,
|
|
143
153
|
reflect: !0
|
|
144
|
-
})],
|
|
154
|
+
})], h.prototype, "placement", null), e([p({ type: String })], h.prototype, "heading", void 0), e([p({
|
|
145
155
|
type: Boolean,
|
|
146
156
|
reflect: !0
|
|
147
|
-
})],
|
|
157
|
+
})], h.prototype, "closable", void 0), h = e([f("web-ui-drawer")], h);
|
|
148
158
|
//#endregion
|
|
149
|
-
export {
|
|
159
|
+
export { h as WebUiDrawer };
|
|
150
160
|
|
|
151
161
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/drawer/index.ts"],"sourcesContent":["import { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport '@/components/icon'\nimport '@/components/button'\nimport glass from '@/assets/glass.css?inline'\nimport { oouiClose } from '@/icons'\nimport { normalizeLiteral } from '@/shared/normalize'\nimport { defineNativeDialogPresence } from '@/shared/overlay/native-dialog-presence'\nimport { createScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_PLACEMENTS = ['right', 'left', 'top', 'bottom'] as const\n\nexport type DrawerPlacement = (typeof ALLOWED_PLACEMENTS)[number]\n\n@customElement('web-ui-drawer')\nexport class WebUiDrawer extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ type: Boolean, reflect: true, attribute: 'no-backdrop-close' }) noBackdropClose = false\n @property({ type: String, reflect: true })\n get placement(): DrawerPlacement {\n return this._placement\n }\n set placement(v: string) {\n const old = this._placement\n this._placement = normalizeLiteral(v, ALLOWED_PLACEMENTS, 'right')\n this.requestUpdate('placement', old)\n }\n private _placement: DrawerPlacement = 'right'\n\n /** 标题文字(未传 header slot 时显示默认 header) */\n @property({ type: String }) heading = ''\n\n @property({ type: Boolean, reflect: true }) closable = false\n\n private get dialog() {\n return this.shadowRoot?.querySelector('dialog') ?? null\n }\n\n private _hasHeaderSlot = false\n private _hasFooterSlot = false\n private readonly _scrollLock = createScrollLockLease()\n private readonly _presence = defineNativeDialogPresence().make({\n getDialog: () => this.dialog,\n isConnected: () => this.isConnected,\n isOpen: () => this.open\n })\n\n override connectedCallback() {\n super.connectedCallback()\n this._hasHeaderSlot = Array.from(this.children).some(child => child.getAttribute?.('slot') === 'header')\n this._hasFooterSlot = Array.from(this.children).some(child => child.getAttribute?.('slot') === 'footer')\n }\n\n override firstUpdated() {\n this._checkSlotContent('footer')\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._presence.dispose()\n this._scrollLock.release()\n }\n\n private _checkSlotContent(name: string) {\n const slot = this.shadowRoot?.querySelector(`slot[name=\"${name}\"]`) as HTMLSlotElement | null\n if (!slot) return\n const has = slot.assignedNodes().length > 0\n if (name === 'footer' && has !== this._hasFooterSlot) {\n this._hasFooterSlot = has\n this.requestUpdate()\n }\n }\n\n private handleHeaderSlotChange(e: Event) {\n const has = (e.target as HTMLSlotElement).assignedNodes().length > 0\n if (has !== this._hasHeaderSlot) {\n this._hasHeaderSlot = has\n this.requestUpdate()\n }\n }\n\n private handleFooterSlotChange(e: Event) {\n const has = (e.target as HTMLSlotElement).assignedNodes().length > 0\n if (has !== this._hasFooterSlot) {\n this._hasFooterSlot = has\n this.requestUpdate()\n }\n }\n\n protected override updated(props: PropertyValues) {\n super.updated(props)\n if (!this.isConnected) return\n\n if (props.has('open')) {\n this.emitOpenChange()\n this._presence.sync(this.open)\n }\n if (props.has('open') || props.has('noScrollLock')) this._syncScrollLock()\n }\n\n private handleTransitionEnd(e: TransitionEvent) {\n this._presence.handleTransitionEnd(e)\n }\n\n private handleKeydown(e: KeyboardEvent) {\n if (e.key !== 'Escape') return\n e.preventDefault()\n this.close()\n }\n\n /** 打开抽屉(命令式) */\n show() {\n if (this.open) return\n this.open = true\n }\n\n /** 关闭抽屉(带动画) */\n close() {\n if (!this.open) return\n this.open = false\n }\n\n private handleCancel(e: Event) {\n // 保留 top layer 直到 CSS 过渡结束,避免原生关闭跳过退出动画。\n e.preventDefault()\n this.close()\n }\n\n private handleNativeClose() {\n if (!this.open) return\n\n // 原生关闭可绕过 cancel;同步受控状态,避免 show() 误判为已打开。\n this._presence.handleNativeClose()\n this.open = false\n }\n\n private handleBackdropClick(e: MouseEvent) {\n if (e.target !== (e.currentTarget as HTMLDialogElement)) return\n if (this.noBackdropClose) return\n this.close()\n }\n\n private emitOpenChange() {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open: this.open },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _syncScrollLock(isOpen = this.open) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n override render() {\n const showHeader = this._hasHeaderSlot || !!this.heading\n\n return html`\n <dialog\n @cancel=${this.handleCancel}\n @close=${this.handleNativeClose}\n @click=${this.handleBackdropClick}\n @keydown=${this.handleKeydown}\n @transitionend=${this.handleTransitionEnd}\n >\n <div class=\"wui-drawer-body wui-glass\">\n ${showHeader\n ? html`\n <div class=\"wui-drawer-header\">\n <slot name=\"header\" @slotchange=${this.handleHeaderSlotChange}>\n ${this.heading ? html`<span class=\"wui-drawer-heading\">${this.heading}</span>` : nothing}\n </slot>\n </div>\n `\n : nothing}\n <div class=\"wui-drawer-content\">\n <slot></slot>\n </div>\n <div class=\"wui-drawer-footer\" ?hidden=${!this._hasFooterSlot}>\n <slot name=\"footer\" @slotchange=${this.handleFooterSlotChange}></slot>\n </div>\n </div>\n ${this.closable\n ? html`\n <web-ui-button class=\"wui-drawer-close\" @click=${this.close} aria-label=\"关闭\" variant=\"secondary\" icon>\n <web-ui-icon .icon=${oouiClose}></web-ui-icon>\n </web-ui-button>\n `\n : nothing}\n </dialog>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-drawer': WebUiDrawer\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/drawer/index.ts"],"sourcesContent":["import { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport '@/components/icon'\nimport '@/components/button'\nimport glass from '@/assets/glass.css?inline'\nimport { oouiClose } from '@/icons'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { normalizeLiteral } from '@/shared/normalize'\nimport { defineNativeDialogPresence } from '@/shared/overlay/native-dialog-presence'\nimport { createScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_PLACEMENTS = ['right', 'left', 'top', 'bottom'] as const\n\nexport type DrawerPlacement = (typeof ALLOWED_PLACEMENTS)[number]\n\n@customElement('web-ui-drawer')\nexport class WebUiDrawer extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ type: Boolean, reflect: true, attribute: 'no-backdrop-close' }) noBackdropClose = false\n @property({ type: String, reflect: true })\n get placement(): DrawerPlacement {\n return this._placement\n }\n set placement(v: string) {\n const old = this._placement\n this._placement = normalizeLiteral(v, ALLOWED_PLACEMENTS, 'right')\n this.requestUpdate('placement', old)\n }\n private _placement: DrawerPlacement = 'right'\n\n // 标题文字(未传 header slot 时显示默认 header)\n @property({ type: String }) heading = ''\n\n @property({ type: Boolean, reflect: true }) closable = false\n\n private get dialog() {\n return this.shadowRoot?.querySelector('dialog') ?? null\n }\n\n private _hasHeaderSlot = false\n private _hasFooterSlot = false\n private readonly _userOpenChange = new UserChangeController()\n private readonly _scrollLock = createScrollLockLease()\n private readonly _presence = defineNativeDialogPresence().make({\n getDialog: () => this.dialog,\n isConnected: () => this.isConnected,\n isOpen: () => this.open\n })\n\n override connectedCallback() {\n super.connectedCallback()\n this._hasHeaderSlot = Array.from(this.children).some(child => child.getAttribute?.('slot') === 'header')\n this._hasFooterSlot = Array.from(this.children).some(child => child.getAttribute?.('slot') === 'footer')\n }\n\n override firstUpdated() {\n this._checkSlotContent('footer')\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._presence.dispose()\n this._scrollLock.release()\n }\n\n private _checkSlotContent(name: string) {\n const slot = this.shadowRoot?.querySelector(`slot[name=\"${name}\"]`) as HTMLSlotElement | null\n if (!slot) return\n const has = slot.assignedNodes().length > 0\n if (name === 'footer' && has !== this._hasFooterSlot) {\n this._hasFooterSlot = has\n this.requestUpdate()\n }\n }\n\n private handleHeaderSlotChange(e: Event) {\n const has = (e.target as HTMLSlotElement).assignedNodes().length > 0\n if (has !== this._hasHeaderSlot) {\n this._hasHeaderSlot = has\n this.requestUpdate()\n }\n }\n\n private handleFooterSlotChange(e: Event) {\n const has = (e.target as HTMLSlotElement).assignedNodes().length > 0\n if (has !== this._hasFooterSlot) {\n this._hasFooterSlot = has\n this.requestUpdate()\n }\n }\n\n protected override updated(props: PropertyValues) {\n super.updated(props)\n if (!this.isConnected) return\n\n if (props.has('open')) {\n if (this._userOpenChange.consume()) this.emitOpenChange()\n this._presence.sync(this.open)\n }\n if (props.has('open') || props.has('noScrollLock')) this._syncScrollLock()\n }\n\n private handleTransitionEnd(e: TransitionEvent) {\n this._presence.handleTransitionEnd(e)\n }\n\n private handleKeydown(e: KeyboardEvent) {\n if (e.key !== 'Escape') return\n e.preventDefault()\n this._closeFromUser()\n }\n\n // 打开抽屉(命令式)\n show() {\n if (this.open) return\n this.open = true\n }\n\n // 关闭抽屉(带动画)\n close() {\n if (!this.open) return\n this.open = false\n }\n\n private readonly _closeFromUser = () => {\n if (!this.open) return\n this._userOpenChange.mark()\n this.close()\n }\n\n private handleCancel(e: Event) {\n // 保留 top layer 直到 CSS 过渡结束,避免原生关闭跳过退出动画。\n e.preventDefault()\n this._closeFromUser()\n }\n\n private handleNativeClose() {\n if (!this.open) return\n\n // 原生关闭可绕过 cancel;同步受控状态,避免 show() 误判为已打开。\n this._presence.handleNativeClose()\n this._userOpenChange.mark()\n this.open = false\n }\n\n private handleBackdropClick(e: MouseEvent) {\n if (e.target !== (e.currentTarget as HTMLDialogElement)) return\n if (this.noBackdropClose) return\n this._closeFromUser()\n }\n\n private emitOpenChange() {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open: this.open },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _syncScrollLock(isOpen = this.open) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n override render() {\n const showHeader = this._hasHeaderSlot || !!this.heading\n\n return html`\n <dialog\n @cancel=${this.handleCancel}\n @close=${this.handleNativeClose}\n @click=${this.handleBackdropClick}\n @keydown=${this.handleKeydown}\n @transitionend=${this.handleTransitionEnd}\n >\n <div class=\"wui-drawer-body wui-glass\">\n ${showHeader\n ? html`\n <div class=\"wui-drawer-header\">\n <slot name=\"header\" @slotchange=${this.handleHeaderSlotChange}>\n ${this.heading ? html`<span class=\"wui-drawer-heading\">${this.heading}</span>` : nothing}\n </slot>\n </div>\n `\n : nothing}\n <div class=\"wui-drawer-content\">\n <slot></slot>\n </div>\n <div class=\"wui-drawer-footer\" ?hidden=${!this._hasFooterSlot}>\n <slot name=\"footer\" @slotchange=${this.handleFooterSlotChange}></slot>\n </div>\n </div>\n ${this.closable\n ? html`\n <web-ui-button\n class=\"wui-drawer-close\"\n @click=${this._closeFromUser}\n aria-label=\"关闭\"\n variant=\"secondary\"\n icon\n size=\"26\"\n >\n <web-ui-icon .icon=${oouiClose} size=\"16\"></web-ui-icon>\n </web-ui-button>\n `\n : nothing}\n </dialog>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-drawer': WebUiDrawer\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/drawer/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{box-sizing:border-box;width:var(--wui-drawer-width,320px);max-width:90vw;height:100dvh;max-height:100dvh;color:var(--wui-color-text,#1b1b1b);transition:transform var(--wui-duration-drawer,.28s) var(--wui-ease-
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{box-sizing:border-box;width:var(--wui-drawer-width,320px);max-width:90vw;height:100dvh;max-height:100dvh;color:var(--wui-color-text,#1b1b1b);transition:transform var(--wui-duration-drawer-enter,.28s) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1));background:0 0;border:none;margin:0;padding:0;font-family:inherit;inset:0 0 0 auto;overflow:visible;transform:translate(100%)}dialog::backdrop{opacity:0;background:var(--wui-drawer-overlay-bg,#0000001f);transition:opacity var(--wui-duration-drawer-enter,.28s) ease}dialog[open].is-visible,:host([placement=left]) dialog[open].is-visible,:host([placement=top]) dialog[open].is-visible,:host([placement=bottom]) dialog[open].is-visible{transform:translate(0)}dialog.is-closing{pointer-events:none;transition:transform var(--wui-duration-drawer-exit,.24s) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1))}dialog.is-closing::backdrop{transition:opacity var(--wui-duration-drawer-exit,.24s) ease}dialog[open].is-visible::backdrop{opacity:1}:host([placement=left]) dialog{left:0;right:auto;transform:translate(-100%)}:host([placement=top]) dialog,:host([placement=bottom]) dialog{width:100vw;max-width:100vw;height:var(--wui-drawer-height,300px);max-height:90dvh}:host([placement=top]) dialog{inset:0 0 auto;transform:translateY(-100%)}:host([placement=bottom]) dialog{inset:auto 0 0;transform:translateY(100%)}.wui-drawer-body{--wui-glass-shadow:var(--wui-shadow-overlay,2px 16px 40px #0006);background-color:var(--wui-color-surface-overlay,#f6f6f6e0);flex-direction:column;height:100%;display:flex}.wui-drawer-header{border-bottom:1px solid #0000000f;justify-content:space-between;align-items:center;padding:16px 20px;font-size:18px;font-weight:600;line-height:1.4;display:flex}.wui-drawer-content{overscroll-behavior:contain;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);flex:1;padding:20px;line-height:1.5;overflow-y:auto}.wui-drawer-footer{border-top:1px solid #0000000f;flex-shrink:0;padding:16px 20px}@media (prefers-reduced-motion:reduce){dialog{transition:opacity var(--wui-duration-feedback,.1s) ease}dialog::backdrop{transition-duration:var(--wui-duration-feedback,.1s)}dialog[open].is-visible{transform:none}}.wui-drawer-footer[hidden]{display:none}.wui-drawer-close{z-index:3;position:absolute;top:16px;right:16px}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/drawer/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\n/* ===== Dialog 容器 ===== */\ndialog {\n /* 默认:右侧滑出 — 需显式 left:auto 覆盖 UA dialog:modal 的 left:0 */\n top: 0;\n right: 0;\n bottom: 0;\n left: auto;\n transform: translateX(100%);\n\n /* 阴影属于抽屉主体,不能由同尺寸的原生 dialog 裁剪。内容滚动由 .wui-drawer-content 管理。 */\n overflow: visible;\n\n box-sizing: border-box;\n width: var(--wui-drawer-width, 320px);\n max-width: 90vw;\n height: 100dvh;\n max-height: 100dvh;\n margin: 0;\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n background: transparent;\n\n transition: transform var(--wui-duration-drawer, 280ms) var(--wui-ease-
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/drawer/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\n/* ===== Dialog 容器 ===== */\ndialog {\n /* 默认:右侧滑出 — 需显式 left:auto 覆盖 UA dialog:modal 的 left:0 */\n top: 0;\n right: 0;\n bottom: 0;\n left: auto;\n transform: translateX(100%);\n\n /* 阴影属于抽屉主体,不能由同尺寸的原生 dialog 裁剪。内容滚动由 .wui-drawer-content 管理。 */\n overflow: visible;\n\n box-sizing: border-box;\n width: var(--wui-drawer-width, 320px);\n max-width: 90vw;\n height: 100vh;\n height: 100dvh;\n max-height: 100vh;\n max-height: 100dvh;\n margin: 0;\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n background: transparent;\n\n transition: transform var(--wui-duration-drawer-enter, 280ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n\n &::backdrop {\n opacity: 0;\n background: var(--wui-drawer-overlay-bg, rgb(0 0 0 / 0.12));\n transition: opacity var(--wui-duration-drawer-enter, 280ms) ease;\n }\n}\n\ndialog[open].is-visible {\n transform: translate(0, 0);\n}\n\n:host([placement='left']) dialog[open].is-visible,\n:host([placement='top']) dialog[open].is-visible,\n:host([placement='bottom']) dialog[open].is-visible {\n transform: translate(0, 0);\n}\n\ndialog.is-closing {\n pointer-events: none;\n transition: transform var(--wui-duration-drawer-exit, 240ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n}\n\ndialog.is-closing::backdrop {\n transition: opacity var(--wui-duration-drawer-exit, 240ms) ease;\n}\n\ndialog[open].is-visible::backdrop {\n opacity: 1;\n}\n\n/* ===== Placement 变体 ===== */\n\n:host([placement='left']) dialog {\n right: auto;\n left: 0;\n transform: translateX(-100%);\n}\n\n:host([placement='top']) dialog,\n:host([placement='bottom']) dialog {\n width: 100vw;\n max-width: 100vw;\n height: var(--wui-drawer-height, 300px);\n max-height: 90dvh;\n}\n\n:host([placement='top']) dialog {\n top: 0;\n right: 0;\n bottom: auto;\n left: 0;\n transform: translateY(-100%);\n}\n\n:host([placement='bottom']) dialog {\n top: auto;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateY(100%);\n}\n\n/* ===== 抽屉主体 ===== */\n\n.wui-drawer-body {\n --wui-glass-shadow: var(--wui-shadow-overlay, 2px 16px 40px rgb(0 0 0 / 0.4));\n display: flex;\n flex-direction: column;\n height: 100%;\n background-color: var(--wui-color-surface-overlay, rgb(246 246 246 / 0.88));\n}\n\n/* ===== Header ===== */\n\n.wui-drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 16px 20px;\n border-bottom: 1px solid rgb(0 0 0 / 0.06);\n\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n/* ===== 内容区 ===== */\n\n.wui-drawer-content {\n overflow-y: auto;\n overscroll-behavior: contain;\n flex: 1;\n\n padding: 20px;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1.5;\n color: var(--wui-color-text, #1b1b1b);\n}\n\n/* ===== Footer ===== */\n\n.wui-drawer-footer {\n flex-shrink: 0;\n padding: 16px 20px;\n border-top: 1px solid rgb(0 0 0 / 0.06);\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog {\n transition: opacity var(--wui-duration-feedback, 100ms) ease;\n }\n\n dialog::backdrop {\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n\n dialog[open].is-visible {\n transform: none;\n }\n}\n\n.wui-drawer-footer[hidden] {\n display: none;\n}\n\n/* ===== 关闭按钮(独立定位,与 header 解耦) ===== */\n\n.wui-drawer-close {\n position: absolute;\n z-index: 3;\n top: 16px;\n right: 16px;\n}\n"],"mappings":""}
|
|
@@ -21,24 +21,17 @@ export declare class WebUiDropdown extends LitElement {
|
|
|
21
21
|
private _ignoreOutsideClickTimer?;
|
|
22
22
|
private _hoverCleanupFns;
|
|
23
23
|
private readonly _scrollLock;
|
|
24
|
+
private readonly _userOpenChange;
|
|
24
25
|
private _restoreFocusTarget?;
|
|
25
26
|
private _shouldOpenInstantly;
|
|
26
27
|
get isOpen(): boolean;
|
|
27
28
|
connectedCallback(): void;
|
|
28
29
|
disconnectedCallback(): void;
|
|
29
30
|
protected updated(changed: Map<string, unknown>): void;
|
|
30
|
-
/**
|
|
31
|
-
* 打开菜单。
|
|
32
|
-
* @returns 无返回值;打开后派发 `open-change` 事件。
|
|
33
|
-
*/
|
|
34
31
|
openMenu(): void;
|
|
35
32
|
private _openMenu;
|
|
36
|
-
/**
|
|
37
|
-
* 关闭所有层级。
|
|
38
|
-
* @returns 无返回值;关闭后派发 `open-change` 事件。
|
|
39
|
-
*/
|
|
40
33
|
closeAll(): void;
|
|
41
|
-
|
|
34
|
+
private _closeAll;
|
|
42
35
|
private _closeAllSubmenus;
|
|
43
36
|
private _cleanupClosedMenu;
|
|
44
37
|
private _closeRootAfterPresence;
|
|
@@ -3,16 +3,17 @@ import { normalizeLiteral as t, normalizeNumber as n } from "../../shared/normal
|
|
|
3
3
|
import "../dropdown-divider/index.js";
|
|
4
4
|
import "../dropdown-header/index.js";
|
|
5
5
|
import "../dropdown-item/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import h from "
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
6
|
+
import { UserChangeController as r } from "../../shared/events/user-change.js";
|
|
7
|
+
import { createMenuPortalOverlay as i } from "../../shared/menu-portal/menu-portal.js";
|
|
8
|
+
import { findFocusedMenuItem as a, focusMenuItem as o, getEnabledMenuItems as s, getMenuChildren as c, getMenuItemFromEvent as l, hideNestedMenuChildren as u, moveMenuChildren as d } from "../../shared/menu-portal/menu-tree.js";
|
|
9
|
+
import { hideOverlayPresence as f, showOverlayPresence as p } from "../../shared/overlay/presence.js";
|
|
10
|
+
import { createScrollLockLease as m } from "../../shared/scroll-lock/scroll-lock.js";
|
|
11
|
+
import { defineOverlay as h } from "../../shared/overlay/overlay.js";
|
|
12
|
+
import g from "./style.js";
|
|
13
|
+
import { LitElement as _, html as v, unsafeCSS as y } from "lit";
|
|
14
|
+
import { customElement as b, property as x, state as S } from "lit/decorators.js";
|
|
14
15
|
//#region src/components/dropdown/index.ts
|
|
15
|
-
var
|
|
16
|
+
var C = "web-ui-menu-level-", w = [
|
|
16
17
|
"top",
|
|
17
18
|
"top-start",
|
|
18
19
|
"top-end",
|
|
@@ -25,14 +26,14 @@ var S = "web-ui-menu-level-", C = [
|
|
|
25
26
|
"left",
|
|
26
27
|
"left-start",
|
|
27
28
|
"left-end"
|
|
28
|
-
],
|
|
29
|
+
], T = class extends _ {
|
|
29
30
|
constructor(...e) {
|
|
30
|
-
super(...e), this.open = !1, this.disabled = !1, this.matchWidth = !1, this.noScrollLock = !1, this._placement = "bottom-start", this._offset = 4, this._activePath = [], this._overlays = /* @__PURE__ */ new Map(), this._closingSubmenuOverlays = /* @__PURE__ */ new Map(), this._ignoreOutsideClick = !1, this._hoverCleanupFns = [], this._scrollLock =
|
|
31
|
-
this.disabled || (this.open ? this.
|
|
31
|
+
super(...e), this.open = !1, this.disabled = !1, this.matchWidth = !1, this.noScrollLock = !1, this._placement = "bottom-start", this._offset = 4, this._activePath = [], this._overlays = /* @__PURE__ */ new Map(), this._closingSubmenuOverlays = /* @__PURE__ */ new Map(), this._ignoreOutsideClick = !1, this._hoverCleanupFns = [], this._scrollLock = m(), this._userOpenChange = new r(), this._shouldOpenInstantly = !0, this._onTriggerClick = (e) => {
|
|
32
|
+
this.disabled || (this.open ? this._closeAll(!0) : this._openMenu(e.detail === 0, !0));
|
|
32
33
|
}, this._onClickOutside = (e) => {
|
|
33
|
-
!this.isOpen || this._ignoreOutsideClick || this._isInsideShadowRoot(e) || this.
|
|
34
|
+
!this.isOpen || this._ignoreOutsideClick || this._isInsideShadowRoot(e) || this._closeAll(!0);
|
|
34
35
|
}, this._onMenuClick = (e) => {
|
|
35
|
-
let t =
|
|
36
|
+
let t = l(e);
|
|
36
37
|
if (!t || t.hasAttribute("disabled") || !t.hasAttribute("submenu")) return;
|
|
37
38
|
let n = this._getFocusedLevel(t);
|
|
38
39
|
if (n === void 0) return;
|
|
@@ -40,8 +41,8 @@ var S = "web-ui-menu-level-", C = [
|
|
|
40
41
|
r >= 0 && this._toggleSubmenu(n, r, e.detail === 0);
|
|
41
42
|
}, this._onKeydown = (e) => {
|
|
42
43
|
if (this.disabled || !this.open) return;
|
|
43
|
-
if (e.key === "Escape"
|
|
44
|
-
this._activePath.length > 0 ? this._closeSubmenuFrom(this._activePath.length) : this.
|
|
44
|
+
if (e.key === "Escape") {
|
|
45
|
+
this._activePath.length > 0 ? this._closeSubmenuFrom(this._activePath.length) : this._closeAll(!0), e.preventDefault();
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
let t = this._getFocusedItem(e), n = this._getFocusedLevel(t);
|
|
@@ -74,7 +75,7 @@ var S = "web-ui-menu-level-", C = [
|
|
|
74
75
|
t?.click();
|
|
75
76
|
break;
|
|
76
77
|
case "Escape":
|
|
77
|
-
this._activePath.length > 0 ? this._closeSubmenuFrom(this._activePath.length) : this.
|
|
78
|
+
this._activePath.length > 0 ? this._closeSubmenuFrom(this._activePath.length) : this._closeAll(!0);
|
|
78
79
|
break;
|
|
79
80
|
default: return;
|
|
80
81
|
}
|
|
@@ -82,13 +83,13 @@ var S = "web-ui-menu-level-", C = [
|
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
85
|
static {
|
|
85
|
-
this.styles =
|
|
86
|
+
this.styles = y(g);
|
|
86
87
|
}
|
|
87
88
|
get placement() {
|
|
88
89
|
return this._placement;
|
|
89
90
|
}
|
|
90
91
|
set placement(e) {
|
|
91
|
-
this._placement = t(e,
|
|
92
|
+
this._placement = t(e, w, "bottom-start");
|
|
92
93
|
}
|
|
93
94
|
get offset() {
|
|
94
95
|
return this._offset;
|
|
@@ -108,7 +109,7 @@ var S = "web-ui-menu-level-", C = [
|
|
|
108
109
|
updated(e) {
|
|
109
110
|
e.has("open") && (this.open ? (this._restoreFocusTarget ??= document.activeElement instanceof HTMLElement ? document.activeElement : void 0, this._ignoreCurrentOutsideClick(), this._syncScrollLock(), this._hideAllSubmenuChildren(), requestAnimationFrame(() => {
|
|
110
111
|
this.open && (this._ensureOverlay(0, this._shouldOpenInstantly), this._shouldOpenInstantly = !0, this._focusMenuItem(this._getEnabledLevelItems(0)[0]));
|
|
111
|
-
}), this._bindHoversAfterUpdate()) : (this._syncScrollLock(), this._closeRootAfterPresence()), this.dispatchEvent(new CustomEvent("open-change", {
|
|
112
|
+
}), this._bindHoversAfterUpdate()) : (this._syncScrollLock(), this._closeRootAfterPresence()), this._userOpenChange.consume() && this.dispatchEvent(new CustomEvent("open-change", {
|
|
112
113
|
detail: { open: this.open },
|
|
113
114
|
bubbles: !0,
|
|
114
115
|
composed: !0
|
|
@@ -119,13 +120,16 @@ var S = "web-ui-menu-level-", C = [
|
|
|
119
120
|
}), this._bindLevelHovers();
|
|
120
121
|
}
|
|
121
122
|
openMenu() {
|
|
122
|
-
this._openMenu(!0);
|
|
123
|
+
this._openMenu(!0, !1);
|
|
123
124
|
}
|
|
124
|
-
_openMenu(e) {
|
|
125
|
-
this.disabled || this.open || (this._ignoreCurrentOutsideClick(), this._shouldOpenInstantly = e, this.open = !0);
|
|
125
|
+
_openMenu(e, t) {
|
|
126
|
+
this.disabled || this.open || (this._ignoreCurrentOutsideClick(), this._shouldOpenInstantly = e, t && this._userOpenChange.mark(), this.open = !0);
|
|
126
127
|
}
|
|
127
128
|
closeAll() {
|
|
128
|
-
this.
|
|
129
|
+
this._closeAll(!1);
|
|
130
|
+
}
|
|
131
|
+
_closeAll(e) {
|
|
132
|
+
this.open &&= (e && this._userOpenChange.mark(), !1);
|
|
129
133
|
}
|
|
130
134
|
_closeAllSubmenus() {
|
|
131
135
|
this._closeSubmenuFrom(1, !0), this._disposeClosingSubmenuOverlays(), this._syncActiveAttrs();
|
|
@@ -135,10 +139,10 @@ var S = "web-ui-menu-level-", C = [
|
|
|
135
139
|
}
|
|
136
140
|
async _closeRootAfterPresence() {
|
|
137
141
|
let e = this._overlays.get(0)?.overlay;
|
|
138
|
-
e && !await
|
|
142
|
+
e && !await f(e) || this.open || !this.isConnected || (this._cleanupClosedMenu(), this._restoreFocusTarget?.focus(), this._restoreFocusTarget = void 0);
|
|
139
143
|
}
|
|
140
144
|
_hideAllSubmenuChildren() {
|
|
141
|
-
|
|
145
|
+
u(this, `${C}-hidden`);
|
|
142
146
|
}
|
|
143
147
|
_toggleSubmenu(e, t, n = !1) {
|
|
144
148
|
if (this._activePath[e] === t) return;
|
|
@@ -168,38 +172,38 @@ var S = "web-ui-menu-level-", C = [
|
|
|
168
172
|
}
|
|
169
173
|
_getLevelItems(e) {
|
|
170
174
|
let t = this._overlays.get(e)?.content;
|
|
171
|
-
return t ?
|
|
175
|
+
return t ? c(t) : [];
|
|
172
176
|
}
|
|
173
177
|
_populateLevel0() {
|
|
174
178
|
let e = this._overlays.get(0)?.content;
|
|
175
|
-
e &&
|
|
179
|
+
e && d(this, e);
|
|
176
180
|
}
|
|
177
181
|
_returnLevel0Items() {
|
|
178
182
|
let e = this._overlays.get(0)?.content;
|
|
179
|
-
e &&
|
|
183
|
+
e && d(e, this);
|
|
180
184
|
}
|
|
181
185
|
_populateOverlay(e, t) {
|
|
182
186
|
let n = this._overlays.get(e)?.content;
|
|
183
|
-
n &&
|
|
187
|
+
n && d(t, n);
|
|
184
188
|
}
|
|
185
189
|
_depopulateOverlay(e, t) {
|
|
186
190
|
let n = this._overlays.get(e)?.content;
|
|
187
191
|
if (!n) return;
|
|
188
192
|
let r = e - 1, i = t ?? this._getLevelItems(r)[this._activePath[r]];
|
|
189
|
-
i &&
|
|
193
|
+
i && d(n, i);
|
|
190
194
|
}
|
|
191
195
|
_ensureOverlay(e, t = !1, n) {
|
|
192
196
|
let r = n ? this._closingSubmenuOverlays.get(n) : void 0;
|
|
193
|
-
if (r) return this._closingSubmenuOverlays.delete(n), this._overlays.set(e, r), r.api.open(),
|
|
197
|
+
if (r) return this._closingSubmenuOverlays.delete(n), this._overlays.set(e, r), r.api.open(), p(r.overlay, { isInstant: t }), !0;
|
|
194
198
|
let i = this._overlays.get(e);
|
|
195
|
-
return i ? (i.api.open(),
|
|
199
|
+
return i ? (i.api.open(), p(i.overlay, { isInstant: t }), !1) : (this._buildOverlay(e, t), !1);
|
|
196
200
|
}
|
|
197
201
|
_buildOverlay(e, t = !1) {
|
|
198
|
-
let { panel: n, content:
|
|
202
|
+
let { panel: n, content: r } = i("dropdown-overlay");
|
|
199
203
|
n.setAttribute("role", "menu"), n.dataset.level = String(e), n.addEventListener("click", this._onMenuClick), n.addEventListener("keydown", this._onKeydown);
|
|
200
204
|
let a = e === 0 ? this._queryTriggerAnchor() : this._getSubmenuTriggerAnchor(e - 1);
|
|
201
205
|
if (a) {
|
|
202
|
-
let
|
|
206
|
+
let i = h().make({
|
|
203
207
|
anchor: a,
|
|
204
208
|
overlay: n,
|
|
205
209
|
placement: e === 0 ? this.placement : "right-start",
|
|
@@ -208,10 +212,10 @@ var S = "web-ui-menu-level-", C = [
|
|
|
208
212
|
strategy: "fixed"
|
|
209
213
|
});
|
|
210
214
|
this._overlays.set(e, {
|
|
211
|
-
api:
|
|
215
|
+
api: i,
|
|
212
216
|
overlay: n,
|
|
213
|
-
content:
|
|
214
|
-
}), e === 0 && this._populateLevel0(),
|
|
217
|
+
content: r
|
|
218
|
+
}), e === 0 && this._populateLevel0(), i.open(), p(n, { isInstant: t });
|
|
215
219
|
}
|
|
216
220
|
}
|
|
217
221
|
_disposeOverlay(e) {
|
|
@@ -222,7 +226,7 @@ var S = "web-ui-menu-level-", C = [
|
|
|
222
226
|
for (let e of this._overlays.keys()) this._disposeOverlay(e);
|
|
223
227
|
}
|
|
224
228
|
async _closeSubmenuAfterPresence(e, t) {
|
|
225
|
-
await
|
|
229
|
+
await f(e.overlay) && this._closingSubmenuOverlays.get(t) === e && (this._closingSubmenuOverlays.delete(t), this._restoreSubmenuItems(e, t), e.api.dispose(), e.overlay.remove());
|
|
226
230
|
}
|
|
227
231
|
_disposeClosingSubmenuOverlays() {
|
|
228
232
|
this._closingSubmenuOverlays.forEach((e, t) => {
|
|
@@ -230,7 +234,7 @@ var S = "web-ui-menu-level-", C = [
|
|
|
230
234
|
}), this._closingSubmenuOverlays.clear();
|
|
231
235
|
}
|
|
232
236
|
_restoreSubmenuItems(e, t) {
|
|
233
|
-
|
|
237
|
+
d(e.content, t);
|
|
234
238
|
}
|
|
235
239
|
_syncScrollLock(e = this.open) {
|
|
236
240
|
this._scrollLock.sync(e && !this.noScrollLock);
|
|
@@ -247,16 +251,16 @@ var S = "web-ui-menu-level-", C = [
|
|
|
247
251
|
}
|
|
248
252
|
_getEnabledLevelItems(e) {
|
|
249
253
|
let t = this._overlays.get(e)?.content;
|
|
250
|
-
return t ?
|
|
254
|
+
return t ? s(t) : [];
|
|
251
255
|
}
|
|
252
256
|
_getFocusedItem(e) {
|
|
253
|
-
return e?.composedPath().find((e) => e instanceof HTMLElement && e.matches("web-ui-dropdown-item")) ||
|
|
257
|
+
return e?.composedPath().find((e) => e instanceof HTMLElement && e.matches("web-ui-dropdown-item")) || a([...this._overlays.values()].map(({ overlay: e }) => e));
|
|
254
258
|
}
|
|
255
259
|
_getFocusedLevel(e = this._getFocusedItem()) {
|
|
256
260
|
if (e) return [...this._overlays.entries()].find(([, t]) => t.overlay.contains(e))?.[0];
|
|
257
261
|
}
|
|
258
262
|
_focusMenuItem(e) {
|
|
259
|
-
|
|
263
|
+
o(e);
|
|
260
264
|
}
|
|
261
265
|
_isInsideShadowRoot(e) {
|
|
262
266
|
for (let t of e.composedPath()) if (t === this || t === this.shadowRoot || t instanceof Node && t.getRootNode() === this.shadowRoot || t instanceof Node && [...this._overlays.values()].some(({ overlay: e }) => e.contains(t))) return !0;
|
|
@@ -285,32 +289,32 @@ var S = "web-ui-menu-level-", C = [
|
|
|
285
289
|
requestAnimationFrame(() => this._bindLevelHovers());
|
|
286
290
|
}
|
|
287
291
|
render() {
|
|
288
|
-
return
|
|
292
|
+
return v`
|
|
289
293
|
<div class="dropdown-trigger" @click=${this._onTriggerClick}>
|
|
290
294
|
<slot name="trigger"></slot>
|
|
291
295
|
</div>
|
|
292
296
|
`;
|
|
293
297
|
}
|
|
294
298
|
};
|
|
295
|
-
e([
|
|
299
|
+
e([x({
|
|
296
300
|
type: Boolean,
|
|
297
301
|
reflect: !0
|
|
298
|
-
})],
|
|
302
|
+
})], T.prototype, "open", void 0), e([x({
|
|
299
303
|
type: Boolean,
|
|
300
304
|
reflect: !0
|
|
301
|
-
})],
|
|
305
|
+
})], T.prototype, "disabled", void 0), e([x({
|
|
302
306
|
type: Boolean,
|
|
303
307
|
reflect: !0,
|
|
304
308
|
attribute: "match-width"
|
|
305
|
-
})],
|
|
309
|
+
})], T.prototype, "matchWidth", void 0), e([x({
|
|
306
310
|
type: Boolean,
|
|
307
311
|
reflect: !0,
|
|
308
312
|
attribute: "no-scroll-lock"
|
|
309
|
-
})],
|
|
313
|
+
})], T.prototype, "noScrollLock", void 0), e([x({
|
|
310
314
|
type: String,
|
|
311
315
|
reflect: !0
|
|
312
|
-
})],
|
|
316
|
+
})], T.prototype, "placement", null), e([x({ type: Number })], T.prototype, "offset", null), e([S()], T.prototype, "_activePath", void 0), T = e([b("web-ui-dropdown")], T);
|
|
313
317
|
//#endregion
|
|
314
|
-
export {
|
|
318
|
+
export { T as WebUiDropdown };
|
|
315
319
|
|
|
316
320
|
//# sourceMappingURL=index.js.map
|