mdui 2.0.1 → 2.0.3
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/LICENSE +21 -21
- package/components/avatar/index.d.ts +4 -2
- package/components/avatar/index.js +4 -2
- package/components/badge/index.d.ts +4 -2
- package/components/badge/index.js +4 -2
- package/components/bottom-app-bar/index.d.ts +9 -3
- package/components/bottom-app-bar/index.js +9 -9
- package/components/button/button-base.d.ts +5 -5
- package/components/button/button-base.js +22 -19
- package/components/button/index.d.ts +6 -1
- package/components/button/index.js +2 -1
- package/components/button-icon/index.d.ts +7 -1
- package/components/button-icon/index.js +3 -3
- package/components/card/index.d.ts +8 -4
- package/components/card/index.js +7 -3
- package/components/checkbox/index.d.ts +10 -3
- package/components/checkbox/index.js +13 -16
- package/components/checkbox/style.js +1 -1
- package/components/chip/index.d.ts +8 -1
- package/components/chip/index.js +5 -5
- package/components/circular-progress/index.d.ts +4 -2
- package/components/circular-progress/index.js +5 -4
- package/components/collapse/collapse-item-style.js +1 -1
- package/components/collapse/collapse-item.d.ts +15 -3
- package/components/collapse/collapse-item.js +26 -23
- package/components/collapse/collapse.d.ts +16 -8
- package/components/collapse/collapse.js +61 -38
- package/components/dialog/index.d.ts +12 -4
- package/components/dialog/index.js +36 -36
- package/components/divider/index.d.ts +4 -2
- package/components/divider/index.js +4 -2
- package/components/dropdown/index.d.ts +13 -7
- package/components/dropdown/index.js +70 -63
- package/components/fab/index.d.ts +7 -1
- package/components/fab/index.js +10 -5
- package/components/icon/index.d.ts +4 -2
- package/components/icon/index.js +4 -2
- package/components/layout/helper.d.ts +5 -6
- package/components/layout/helper.js +42 -48
- package/components/layout/layout-item-base.d.ts +3 -2
- package/components/layout/layout-item-base.js +3 -4
- package/components/layout/layout-item.d.ts +4 -3
- package/components/layout/layout-item.js +3 -3
- package/components/layout/layout-main.d.ts +4 -2
- package/components/layout/layout-main.js +4 -2
- package/components/layout/layout.d.ts +4 -2
- package/components/layout/layout.js +4 -2
- package/components/linear-progress/index.d.ts +4 -2
- package/components/linear-progress/index.js +5 -4
- package/components/list/list-item-style.js +1 -1
- package/components/list/list-item.d.ts +7 -3
- package/components/list/list-item.js +5 -3
- package/components/list/list-subheader.d.ts +4 -2
- package/components/list/list-subheader.js +4 -2
- package/components/list/list.d.ts +4 -2
- package/components/list/list.js +4 -2
- package/components/menu/menu-item.d.ts +12 -3
- package/components/menu/menu-item.js +53 -40
- package/components/menu/menu.d.ts +9 -3
- package/components/menu/menu.js +85 -59
- package/components/navigation-bar/navigation-bar-item-style.js +1 -1
- package/components/navigation-bar/navigation-bar-item.d.ts +13 -5
- package/components/navigation-bar/navigation-bar-item.js +28 -11
- package/components/navigation-bar/navigation-bar.d.ts +14 -7
- package/components/navigation-bar/navigation-bar.js +58 -49
- package/components/navigation-drawer/index.d.ts +13 -2
- package/components/navigation-drawer/index.js +69 -49
- package/components/navigation-drawer/style.js +1 -1
- package/components/navigation-rail/navigation-rail-item-style.js +1 -1
- package/components/navigation-rail/navigation-rail-item.d.ts +13 -5
- package/components/navigation-rail/navigation-rail-item.js +22 -9
- package/components/navigation-rail/navigation-rail.d.ts +8 -6
- package/components/navigation-rail/navigation-rail.js +55 -46
- package/components/radio/radio-group.d.ts +13 -6
- package/components/radio/radio-group.js +69 -59
- package/components/radio/radio-style.js +1 -1
- package/components/radio/radio.d.ts +11 -5
- package/components/radio/radio.js +26 -19
- package/components/range-slider/index.d.ts +9 -3
- package/components/range-slider/index.js +13 -11
- package/components/ripple/index.d.ts +4 -2
- package/components/ripple/index.js +4 -2
- package/components/ripple/ripple-mixin.d.ts +1 -1
- package/components/ripple/ripple-mixin.js +0 -1
- package/components/segmented-button/segmented-button-group-style.js +1 -1
- package/components/segmented-button/segmented-button-group.d.ts +12 -5
- package/components/segmented-button/segmented-button-group.js +92 -77
- package/components/segmented-button/segmented-button.d.ts +8 -3
- package/components/segmented-button/segmented-button.js +5 -4
- package/components/select/index.d.ts +13 -5
- package/components/select/index.js +30 -28
- package/components/slider/index.d.ts +8 -1
- package/components/slider/index.js +11 -18
- package/components/slider/slider-base-style.js +1 -1
- package/components/slider/slider-base.d.ts +7 -3
- package/components/slider/slider-base.js +28 -13
- package/components/snackbar/index.d.ts +9 -2
- package/components/snackbar/index.js +11 -10
- package/components/switch/index.d.ts +10 -3
- package/components/switch/index.js +12 -15
- package/components/switch/style.js +1 -1
- package/components/tabs/tab-panel.d.ts +4 -2
- package/components/tabs/tab-panel.js +4 -2
- package/components/tabs/tab-style.js +1 -1
- package/components/tabs/tab.d.ts +7 -3
- package/components/tabs/tab.js +12 -6
- package/components/tabs/tabs-style.js +1 -1
- package/components/tabs/tabs.d.ts +11 -7
- package/components/tabs/tabs.js +57 -40
- package/components/text-field/index.d.ts +13 -5
- package/components/text-field/index.js +43 -65
- package/components/text-field/style.js +1 -1
- package/components/tooltip/index.d.ts +14 -7
- package/components/tooltip/index.js +45 -38
- package/components/top-app-bar/top-app-bar-title-style.js +1 -1
- package/components/top-app-bar/top-app-bar-title.d.ts +4 -2
- package/components/top-app-bar/top-app-bar-title.js +18 -13
- package/components/top-app-bar/top-app-bar.d.ts +9 -3
- package/components/top-app-bar/top-app-bar.js +11 -10
- package/custom-elements.json +904 -546
- package/functions/getTheme.js +3 -3
- package/functions/snackbar.js +1 -2
- package/functions/utils/colorScheme.js +2 -2
- package/mdui.esm.js +8 -8
- package/mdui.global.js +8 -8
- package/package.json +8 -7
- package/web-types.zh-cn.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
2
2
|
import '../icon.js';
|
|
3
|
-
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
3
|
+
import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
4
4
|
/**
|
|
5
5
|
* @summary 对话框组件
|
|
6
6
|
*
|
|
@@ -33,7 +33,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
33
33
|
* @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
34
34
|
* @cssprop --z-index - 组件的 CSS 的 `z-index` 值
|
|
35
35
|
*/
|
|
36
|
-
export declare class Dialog extends
|
|
36
|
+
export declare class Dialog extends MduiElement<DialogEventMap> {
|
|
37
37
|
static styles: CSSResultGroup;
|
|
38
38
|
/**
|
|
39
39
|
* 顶部的 Material Icons 图标名。也可以通过 `slot="icon"` 设置
|
|
@@ -83,15 +83,23 @@ export declare class Dialog extends LitElement {
|
|
|
83
83
|
private readonly panelRef;
|
|
84
84
|
private readonly bodyRef;
|
|
85
85
|
private readonly hasSlotController;
|
|
86
|
+
private readonly definedController;
|
|
86
87
|
private onOpenChange;
|
|
87
|
-
connectedCallback(): void;
|
|
88
88
|
disconnectedCallback(): void;
|
|
89
|
+
protected firstUpdated(_changedProperties: PropertyValues): void;
|
|
89
90
|
protected render(): TemplateResult;
|
|
90
91
|
private onOverlayClick;
|
|
91
92
|
private renderIcon;
|
|
92
93
|
private renderHeadline;
|
|
93
94
|
private renderDescription;
|
|
94
95
|
}
|
|
96
|
+
export interface DialogEventMap {
|
|
97
|
+
open: CustomEvent<void>;
|
|
98
|
+
opened: CustomEvent<void>;
|
|
99
|
+
close: CustomEvent<void>;
|
|
100
|
+
closed: CustomEvent<void>;
|
|
101
|
+
'overlay-click': CustomEvent<void>;
|
|
102
|
+
}
|
|
95
103
|
declare global {
|
|
96
104
|
interface HTMLElementTagNameMap {
|
|
97
105
|
'mdui-dialog': Dialog;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html
|
|
2
|
+
import { html } from 'lit';
|
|
3
3
|
import { customElement, property, queryAssignedElements, } from 'lit/decorators.js';
|
|
4
4
|
import { classMap } from 'lit/directives/class-map.js';
|
|
5
5
|
import { createRef, ref } from 'lit/directives/ref.js';
|
|
6
6
|
import { when } from 'lit/directives/when.js';
|
|
7
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
8
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
7
9
|
import { HasSlotController } from '@mdui/shared/controllers/has-slot.js';
|
|
8
10
|
import { watch } from '@mdui/shared/decorators/watch.js';
|
|
9
11
|
import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js';
|
|
10
12
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
11
|
-
import { emit } from '@mdui/shared/helpers/event.js';
|
|
12
13
|
import { Modal } from '@mdui/shared/helpers/modal.js';
|
|
13
14
|
import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js';
|
|
14
15
|
import { lockScreen, unlockScreen } from '@mdui/shared/helpers/scroll.js';
|
|
@@ -48,7 +49,7 @@ import { style } from './style.js';
|
|
|
48
49
|
* @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
49
50
|
* @cssprop --z-index - 组件的 CSS 的 `z-index` 值
|
|
50
51
|
*/
|
|
51
|
-
|
|
52
|
+
let Dialog = class Dialog extends MduiElement {
|
|
52
53
|
constructor() {
|
|
53
54
|
super(...arguments);
|
|
54
55
|
/**
|
|
@@ -75,10 +76,17 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
75
76
|
this.panelRef = createRef();
|
|
76
77
|
this.bodyRef = createRef();
|
|
77
78
|
this.hasSlotController = new HasSlotController(this, 'header', 'icon', 'headline', 'description', 'action', '[default]');
|
|
79
|
+
this.definedController = new DefinedController(this, {
|
|
80
|
+
relatedElements: ['mdui-top-app-bar'],
|
|
81
|
+
});
|
|
78
82
|
}
|
|
79
83
|
async onOpenChange() {
|
|
80
|
-
var _a;
|
|
81
84
|
const hasUpdated = this.hasUpdated;
|
|
85
|
+
// 默认为关闭状态。因此首次渲染时,且为关闭状态,不执行
|
|
86
|
+
if (!this.open && !hasUpdated) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
await this.definedController.whenDefined();
|
|
82
90
|
if (!hasUpdated) {
|
|
83
91
|
await this.updateComplete;
|
|
84
92
|
}
|
|
@@ -87,20 +95,23 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
87
95
|
const easingLinear = getEasing(this, 'linear');
|
|
88
96
|
const easingEmphasizedDecelerate = getEasing(this, 'emphasized-decelerate');
|
|
89
97
|
const easingEmphasizedAccelerate = getEasing(this, 'emphasized-accelerate');
|
|
98
|
+
const stopAnimation = () => Promise.all([
|
|
99
|
+
stopAnimations(this.overlayRef.value),
|
|
100
|
+
stopAnimations(this.panelRef.value),
|
|
101
|
+
...children.map((child) => stopAnimations(child)),
|
|
102
|
+
]);
|
|
90
103
|
// 打开
|
|
91
104
|
// 要区分是否首次渲染,首次渲染不触发事件,不执行动画;非首次渲染,触发事件,执行动画
|
|
92
105
|
if (this.open) {
|
|
93
106
|
if (hasUpdated) {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
if (requestOpen.defaultPrevented) {
|
|
107
|
+
const eventProceeded = this.emit('open', { cancelable: true });
|
|
108
|
+
if (!eventProceeded) {
|
|
98
109
|
return;
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
this.style.display = 'flex';
|
|
102
113
|
// 包含 <mdui-top-app-bar slot="header"> 时
|
|
103
|
-
const topAppBarElements =
|
|
114
|
+
const topAppBarElements = this.topAppBarElements ?? [];
|
|
104
115
|
if (topAppBarElements.length) {
|
|
105
116
|
const topAppBarElement = topAppBarElements[0];
|
|
106
117
|
// top-app-bar 未设置 scrollTarget 时,默认设置为 bodyRef
|
|
@@ -113,11 +124,7 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
113
124
|
this.originalTrigger = document.activeElement;
|
|
114
125
|
this.modalHelper.activate();
|
|
115
126
|
lockScreen(this);
|
|
116
|
-
await
|
|
117
|
-
stopAnimations(this.overlayRef.value),
|
|
118
|
-
stopAnimations(this.panelRef.value),
|
|
119
|
-
...children.map((child) => stopAnimations(child)),
|
|
120
|
-
]);
|
|
127
|
+
await stopAnimation();
|
|
121
128
|
// 设置聚焦
|
|
122
129
|
requestAnimationFrame(() => {
|
|
123
130
|
const autoFocusTarget = this.querySelector('[autofocus]');
|
|
@@ -156,23 +163,16 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
156
163
|
})),
|
|
157
164
|
]);
|
|
158
165
|
if (hasUpdated) {
|
|
159
|
-
emit(
|
|
166
|
+
this.emit('opened');
|
|
160
167
|
}
|
|
161
|
-
return;
|
|
162
168
|
}
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
if (requestClose.defaultPrevented) {
|
|
169
|
+
else {
|
|
170
|
+
const eventProceeded = this.emit('close', { cancelable: true });
|
|
171
|
+
if (!eventProceeded) {
|
|
168
172
|
return;
|
|
169
173
|
}
|
|
170
174
|
this.modalHelper.deactivate();
|
|
171
|
-
await
|
|
172
|
-
stopAnimations(this.overlayRef.value),
|
|
173
|
-
stopAnimations(this.panelRef.value),
|
|
174
|
-
...children.map((child) => stopAnimations(child)),
|
|
175
|
-
]);
|
|
175
|
+
await stopAnimation();
|
|
176
176
|
const duration = getDuration(this, 'short4');
|
|
177
177
|
await Promise.all([
|
|
178
178
|
animateTo(this.overlayRef.value, [{ opacity: 1 }, { opacity: 0 }], {
|
|
@@ -190,15 +190,18 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
190
190
|
unlockScreen(this);
|
|
191
191
|
// 对话框关闭后,恢复焦点到原有的元素上
|
|
192
192
|
const trigger = this.originalTrigger;
|
|
193
|
-
if (typeof
|
|
193
|
+
if (typeof trigger?.focus === 'function') {
|
|
194
194
|
setTimeout(() => trigger.focus());
|
|
195
195
|
}
|
|
196
|
-
emit(
|
|
197
|
-
return;
|
|
196
|
+
this.emit('closed');
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
|
-
|
|
201
|
-
super.
|
|
199
|
+
disconnectedCallback() {
|
|
200
|
+
super.disconnectedCallback();
|
|
201
|
+
unlockScreen(this);
|
|
202
|
+
}
|
|
203
|
+
firstUpdated(_changedProperties) {
|
|
204
|
+
super.firstUpdated(_changedProperties);
|
|
202
205
|
this.modalHelper = new Modal(this);
|
|
203
206
|
this.addEventListener('keydown', (event) => {
|
|
204
207
|
if (this.open && this.closeOnEsc && event.key === 'Escape') {
|
|
@@ -207,10 +210,6 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
207
210
|
}
|
|
208
211
|
});
|
|
209
212
|
}
|
|
210
|
-
disconnectedCallback() {
|
|
211
|
-
super.disconnectedCallback();
|
|
212
|
-
unlockScreen(this);
|
|
213
|
-
}
|
|
214
213
|
render() {
|
|
215
214
|
const hasActionSlot = this.hasSlotController.test('action');
|
|
216
215
|
const hasDefaultSlot = this.hasSlotController.test('[default]');
|
|
@@ -226,7 +225,7 @@ export let Dialog = class Dialog extends LitElement {
|
|
|
226
225
|
})}" tabindex="0">${when(hasHeader, () => html `<slot name="header" part="header" class="header">${when(hasIcon, () => this.renderIcon())} ${when(hasHeadline, () => this.renderHeadline())}</slot>`)} ${when(hasBody, () => html `<div ${ref(this.bodyRef)} part="body" class="body">${when(hasDescription, () => this.renderDescription())}<slot></slot></div>`)} ${when(hasActionSlot, () => html `<slot name="action" part="action" class="action"></slot>`)}</div>`;
|
|
227
226
|
}
|
|
228
227
|
onOverlayClick() {
|
|
229
|
-
emit(
|
|
228
|
+
this.emit('overlay-click');
|
|
230
229
|
if (!this.closeOnOverlayClick) {
|
|
231
230
|
return;
|
|
232
231
|
}
|
|
@@ -305,3 +304,4 @@ __decorate([
|
|
|
305
304
|
Dialog = __decorate([
|
|
306
305
|
customElement('mdui-dialog')
|
|
307
306
|
], Dialog);
|
|
307
|
+
export { Dialog };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
2
2
|
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary 分割线组件
|
|
@@ -7,7 +7,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
7
7
|
* <mdui-divider></mdui-divider>
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
export declare class Divider extends
|
|
10
|
+
export declare class Divider extends MduiElement<DividerEventMap> {
|
|
11
11
|
static styles: CSSResultGroup;
|
|
12
12
|
/**
|
|
13
13
|
* 是否显示垂直分割线
|
|
@@ -23,6 +23,8 @@ export declare class Divider extends LitElement {
|
|
|
23
23
|
middle: boolean;
|
|
24
24
|
protected render(): TemplateResult;
|
|
25
25
|
}
|
|
26
|
+
export interface DividerEventMap {
|
|
27
|
+
}
|
|
26
28
|
declare global {
|
|
27
29
|
interface HTMLElementTagNameMap {
|
|
28
30
|
'mdui-divider': Divider;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html
|
|
2
|
+
import { html } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
4
5
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
5
6
|
import { componentStyle } from '@mdui/shared/lit-styles/component-style.js';
|
|
6
7
|
import { style } from './style.js';
|
|
@@ -11,7 +12,7 @@ import { style } from './style.js';
|
|
|
11
12
|
* <mdui-divider></mdui-divider>
|
|
12
13
|
* ```
|
|
13
14
|
*/
|
|
14
|
-
|
|
15
|
+
let Divider = class Divider extends MduiElement {
|
|
15
16
|
constructor() {
|
|
16
17
|
super(...arguments);
|
|
17
18
|
/**
|
|
@@ -56,3 +57,4 @@ __decorate([
|
|
|
56
57
|
Divider = __decorate([
|
|
57
58
|
customElement('mdui-divider')
|
|
58
59
|
], Divider);
|
|
60
|
+
export { Divider };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { LitElement } from 'lit';
|
|
2
1
|
import '@mdui/jq/methods/height.js';
|
|
3
2
|
import '@mdui/jq/methods/is.js';
|
|
4
|
-
import '@mdui/jq/methods/on.js';
|
|
5
3
|
import '@mdui/jq/methods/width.js';
|
|
4
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
6
5
|
import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
7
6
|
/**
|
|
8
7
|
* @summary 下拉组件
|
|
@@ -30,7 +29,7 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
30
29
|
*
|
|
31
30
|
* @cssprop --z-index - 组件的 CSS 的 `z-index` 值
|
|
32
31
|
*/
|
|
33
|
-
export declare class Dropdown extends
|
|
32
|
+
export declare class Dropdown extends MduiElement<DropdownEventMap> {
|
|
34
33
|
static styles: CSSResultGroup;
|
|
35
34
|
/**
|
|
36
35
|
* dropdown 是否打开
|
|
@@ -84,18 +83,19 @@ export declare class Dropdown extends LitElement {
|
|
|
84
83
|
* 是否在触发 dropdown 时的光标所在的位置打开 dropdown。通常用于在打开鼠标右键菜单时使用
|
|
85
84
|
*/
|
|
86
85
|
openOnPointer: boolean;
|
|
87
|
-
private readonly
|
|
88
|
-
private readonly
|
|
86
|
+
private readonly triggerElements;
|
|
87
|
+
private readonly panelElements;
|
|
89
88
|
private pointerOffsetX;
|
|
90
89
|
private pointerOffsetY;
|
|
91
90
|
private animateDirection;
|
|
92
91
|
private openTimeout;
|
|
93
92
|
private closeTimeout;
|
|
94
93
|
private observeResize?;
|
|
94
|
+
private overflowAncestors?;
|
|
95
95
|
private readonly panelRef;
|
|
96
|
+
private readonly definedController;
|
|
96
97
|
constructor();
|
|
97
|
-
private get
|
|
98
|
-
private get panelSlot();
|
|
98
|
+
private get triggerElement();
|
|
99
99
|
private onPositionChange;
|
|
100
100
|
private onOpenChange;
|
|
101
101
|
connectedCallback(): void;
|
|
@@ -124,6 +124,12 @@ export declare class Dropdown extends LitElement {
|
|
|
124
124
|
private onMouseLeave;
|
|
125
125
|
private updatePositioner;
|
|
126
126
|
}
|
|
127
|
+
export interface DropdownEventMap {
|
|
128
|
+
open: CustomEvent<void>;
|
|
129
|
+
opened: CustomEvent<void>;
|
|
130
|
+
close: CustomEvent<void>;
|
|
131
|
+
closed: CustomEvent<void>;
|
|
132
|
+
}
|
|
127
133
|
declare global {
|
|
128
134
|
interface HTMLElementTagNameMap {
|
|
129
135
|
'mdui-dropdown': Dropdown;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html
|
|
2
|
+
import { html } from 'lit';
|
|
3
3
|
import { customElement, property, queryAssignedElements, } from 'lit/decorators.js';
|
|
4
4
|
import { createRef, ref } from 'lit/directives/ref.js';
|
|
5
|
+
import { getOverflowAncestors } from '@floating-ui/utils/dom';
|
|
5
6
|
import { $ } from '@mdui/jq/$.js';
|
|
6
7
|
import '@mdui/jq/methods/height.js';
|
|
7
8
|
import '@mdui/jq/methods/is.js';
|
|
8
|
-
import '@mdui/jq/methods/on.js';
|
|
9
9
|
import '@mdui/jq/methods/width.js';
|
|
10
|
+
import { isFunction } from '@mdui/jq/shared/helper.js';
|
|
11
|
+
import { MduiElement } from '@mdui/shared/base/mdui-element.js';
|
|
12
|
+
import { DefinedController } from '@mdui/shared/controllers/defined.js';
|
|
10
13
|
import { watch } from '@mdui/shared/decorators/watch.js';
|
|
11
14
|
import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js';
|
|
12
15
|
import { booleanConverter } from '@mdui/shared/helpers/decorator.js';
|
|
13
|
-
import { emit } from '@mdui/shared/helpers/event.js';
|
|
14
16
|
import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js';
|
|
15
17
|
import { observeResize } from '@mdui/shared/helpers/observeResize.js';
|
|
16
18
|
import { componentStyle } from '@mdui/shared/lit-styles/component-style.js';
|
|
@@ -41,7 +43,7 @@ import { style } from './style.js';
|
|
|
41
43
|
*
|
|
42
44
|
* @cssprop --z-index - 组件的 CSS 的 `z-index` 值
|
|
43
45
|
*/
|
|
44
|
-
|
|
46
|
+
let Dropdown = class Dropdown extends MduiElement {
|
|
45
47
|
constructor() {
|
|
46
48
|
super();
|
|
47
49
|
/**
|
|
@@ -97,6 +99,9 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
97
99
|
*/
|
|
98
100
|
this.openOnPointer = false;
|
|
99
101
|
this.panelRef = createRef();
|
|
102
|
+
this.definedController = new DefinedController(this, {
|
|
103
|
+
relatedElements: [''],
|
|
104
|
+
});
|
|
100
105
|
this.onDocumentClick = this.onDocumentClick.bind(this);
|
|
101
106
|
this.onDocumentKeydown = this.onDocumentKeydown.bind(this);
|
|
102
107
|
this.onWindowScroll = this.onWindowScroll.bind(this);
|
|
@@ -107,43 +112,44 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
107
112
|
this.onMouseEnter = this.onMouseEnter.bind(this);
|
|
108
113
|
this.onPanelClick = this.onPanelClick.bind(this);
|
|
109
114
|
}
|
|
110
|
-
get
|
|
111
|
-
return this.
|
|
112
|
-
}
|
|
113
|
-
get panelSlot() {
|
|
114
|
-
return this.panelSlots[0];
|
|
115
|
+
get triggerElement() {
|
|
116
|
+
return this.triggerElements[0];
|
|
115
117
|
}
|
|
116
118
|
// 这些属性变更时,需要更新样式
|
|
117
119
|
async onPositionChange() {
|
|
118
|
-
//
|
|
120
|
+
// 如果是打开状态,则更新 panel 的位置
|
|
119
121
|
if (this.open) {
|
|
122
|
+
await this.definedController.whenDefined();
|
|
120
123
|
this.updatePositioner();
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
async onOpenChange() {
|
|
124
|
-
var _a, _b, _c, _d;
|
|
125
127
|
const hasUpdated = this.hasUpdated;
|
|
128
|
+
// 默认为关闭状态。因此首次渲染时,且为关闭状态,不执行
|
|
129
|
+
if (!this.open && !hasUpdated) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
await this.definedController.whenDefined();
|
|
133
|
+
if (!hasUpdated) {
|
|
134
|
+
await this.updateComplete;
|
|
135
|
+
}
|
|
126
136
|
const easingLinear = getEasing(this, 'linear');
|
|
127
137
|
const easingEmphasizedDecelerate = getEasing(this, 'emphasized-decelerate');
|
|
128
138
|
const easingEmphasizedAccelerate = getEasing(this, 'emphasized-accelerate');
|
|
129
139
|
// 打开
|
|
130
140
|
// 要区分是否首次渲染,首次渲染时不触发事件,不执行动画;非首次渲染,触发事件,执行动画
|
|
131
141
|
if (this.open) {
|
|
132
|
-
if (!hasUpdated) {
|
|
133
|
-
await this.updateComplete;
|
|
134
|
-
}
|
|
135
142
|
if (hasUpdated) {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
});
|
|
139
|
-
if (requestOpen.defaultPrevented) {
|
|
143
|
+
const eventProceeded = this.emit('open', { cancelable: true });
|
|
144
|
+
if (!eventProceeded) {
|
|
140
145
|
return;
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
// dropdown 打开时,尝试把焦点放到 panel 中
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
const focusablePanel = this.panelElements.find((panel) => isFunction(panel.focus));
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
focusablePanel?.focus();
|
|
152
|
+
});
|
|
147
153
|
const duration = getDuration(this, 'medium4');
|
|
148
154
|
await stopAnimations(this.panelRef.value);
|
|
149
155
|
this.panelRef.value.hidden = false;
|
|
@@ -162,24 +168,20 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
162
168
|
}),
|
|
163
169
|
]);
|
|
164
170
|
if (hasUpdated) {
|
|
165
|
-
emit(
|
|
171
|
+
this.emit('opened');
|
|
166
172
|
}
|
|
167
|
-
return;
|
|
168
173
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
cancelable: true,
|
|
173
|
-
});
|
|
174
|
-
if (requestClose.defaultPrevented) {
|
|
174
|
+
else {
|
|
175
|
+
const eventProceeded = this.emit('close', { cancelable: true });
|
|
176
|
+
if (!eventProceeded) {
|
|
175
177
|
return;
|
|
176
178
|
}
|
|
177
179
|
// dropdown 关闭时,如果不支持 focus 触发,且焦点在 dropdown 内,则焦点回到 trigger 上
|
|
178
180
|
if (!this.hasTrigger('focus') &&
|
|
179
|
-
|
|
181
|
+
isFunction(this.triggerElement?.focus) &&
|
|
180
182
|
(this.contains(document.activeElement) ||
|
|
181
|
-
this.contains(
|
|
182
|
-
this.
|
|
183
|
+
this.contains(document.activeElement?.assignedSlot ?? null))) {
|
|
184
|
+
this.triggerElement.focus();
|
|
183
185
|
}
|
|
184
186
|
const duration = getDuration(this, 'short4');
|
|
185
187
|
await stopAnimations(this.panelRef.value);
|
|
@@ -194,40 +196,45 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
194
196
|
if (this.panelRef.value) {
|
|
195
197
|
this.panelRef.value.hidden = true;
|
|
196
198
|
}
|
|
197
|
-
emit(
|
|
199
|
+
this.emit('closed');
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
connectedCallback() {
|
|
201
203
|
super.connectedCallback();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
this.updatePositioner();
|
|
204
|
+
this.definedController.whenDefined().then(() => {
|
|
205
|
+
document.addEventListener('pointerdown', this.onDocumentClick);
|
|
206
|
+
document.addEventListener('keydown', this.onDocumentKeydown);
|
|
207
|
+
this.overflowAncestors = getOverflowAncestors(this.triggerElement);
|
|
208
|
+
this.overflowAncestors.forEach((ancestor) => {
|
|
209
|
+
ancestor.addEventListener('scroll', this.onWindowScroll);
|
|
209
210
|
});
|
|
210
211
|
});
|
|
211
212
|
}
|
|
212
213
|
disconnectedCallback() {
|
|
213
|
-
var _a;
|
|
214
214
|
super.disconnectedCallback();
|
|
215
215
|
document.removeEventListener('pointerdown', this.onDocumentClick);
|
|
216
216
|
document.removeEventListener('keydown', this.onDocumentKeydown);
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
this.overflowAncestors?.forEach((ancestor) => {
|
|
218
|
+
ancestor.removeEventListener('scroll', this.onWindowScroll);
|
|
219
|
+
});
|
|
220
|
+
this.observeResize?.unobserve();
|
|
219
221
|
}
|
|
220
222
|
firstUpdated(changedProperties) {
|
|
221
223
|
super.firstUpdated(changedProperties);
|
|
222
224
|
this.addEventListener('mouseleave', this.onMouseLeave);
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
this.definedController.whenDefined().then(() => {
|
|
226
|
+
this.triggerElement.addEventListener('focus', this.onFocus);
|
|
227
|
+
this.triggerElement.addEventListener('click', this.onClick);
|
|
228
|
+
this.triggerElement.addEventListener('contextmenu', this.onContextMenu);
|
|
229
|
+
this.triggerElement.addEventListener('mouseenter', this.onMouseEnter);
|
|
230
|
+
// triggerElement 的尺寸变化时,重新调整 panel 的位置
|
|
231
|
+
this.observeResize = observeResize(this.triggerElement, () => {
|
|
232
|
+
this.updatePositioner();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
228
235
|
}
|
|
229
236
|
render() {
|
|
230
|
-
return html `<slot name="trigger" part="trigger" class="trigger"></slot><slot ${ref(this.panelRef)} part="panel" class="panel" hidden></slot>`;
|
|
237
|
+
return html `<slot name="trigger" part="trigger" class="trigger"></slot><slot ${ref(this.panelRef)} part="panel" class="panel" hidden @click="${this.onPanelClick}"></slot>`;
|
|
231
238
|
}
|
|
232
239
|
/**
|
|
233
240
|
* 获取 dropdown 打开、关闭动画的 CSS scaleX 或 scaleY
|
|
@@ -250,7 +257,7 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
250
257
|
// 当包含 contextmenu 且不包含 click 时,点击 trigger,关闭
|
|
251
258
|
if (this.hasTrigger('contextmenu') &&
|
|
252
259
|
!this.hasTrigger('click') &&
|
|
253
|
-
path.includes(this.
|
|
260
|
+
path.includes(this.triggerElement)) {
|
|
254
261
|
this.open = false;
|
|
255
262
|
}
|
|
256
263
|
}
|
|
@@ -258,7 +265,6 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
258
265
|
* 在 document 上按下按键时,根据条件判断是否要关闭 dropdown
|
|
259
266
|
*/
|
|
260
267
|
onDocumentKeydown(event) {
|
|
261
|
-
var _a;
|
|
262
268
|
if (this.disabled || !this.open) {
|
|
263
269
|
return;
|
|
264
270
|
}
|
|
@@ -270,8 +276,7 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
270
276
|
// 按下 Tab 键时,关闭 dropdown
|
|
271
277
|
if (event.key === 'Tab') {
|
|
272
278
|
// 如果不支持 focus 触发,则焦点回到 trigger 上(这个会在 onOpenChange 中执行 )这里只需阻止默认的 Tab 行为
|
|
273
|
-
if (!this.hasTrigger('focus') &&
|
|
274
|
-
typeof ((_a = this.triggerSlot) === null || _a === void 0 ? void 0 : _a.focus) === 'function') {
|
|
279
|
+
if (!this.hasTrigger('focus') && isFunction(this.triggerElement?.focus)) {
|
|
275
280
|
event.preventDefault();
|
|
276
281
|
}
|
|
277
282
|
this.open = false;
|
|
@@ -304,10 +309,9 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
304
309
|
this.open = !this.open;
|
|
305
310
|
}
|
|
306
311
|
onPanelClick(e) {
|
|
307
|
-
const event = e;
|
|
308
312
|
if (!this.disabled &&
|
|
309
313
|
!this.stayOpenOnClick &&
|
|
310
|
-
$(
|
|
314
|
+
$(e.target).is('mdui-menu-item')) {
|
|
311
315
|
this.open = false;
|
|
312
316
|
}
|
|
313
317
|
}
|
|
@@ -345,17 +349,19 @@ export let Dropdown = class Dropdown extends LitElement {
|
|
|
345
349
|
this.open = false;
|
|
346
350
|
}, this.closeDelay || 50);
|
|
347
351
|
}
|
|
352
|
+
// 更新 panel 的位置
|
|
348
353
|
updatePositioner() {
|
|
349
|
-
var _a;
|
|
350
354
|
const $panel = $(this.panelRef.value);
|
|
351
355
|
const $window = $(window);
|
|
352
|
-
const
|
|
356
|
+
const panelElements = this.panelElements;
|
|
353
357
|
const panelRect = {
|
|
354
|
-
width: Math.max(...(
|
|
355
|
-
height:
|
|
358
|
+
width: Math.max(...(panelElements?.map((panel) => panel.offsetWidth) ?? [])),
|
|
359
|
+
height: panelElements
|
|
360
|
+
?.map((panel) => panel.offsetHeight)
|
|
361
|
+
.reduce((total, height) => total + height, 0),
|
|
356
362
|
};
|
|
357
|
-
// 在光标位置触发时,假设
|
|
358
|
-
const triggerClientRect = this.
|
|
363
|
+
// 在光标位置触发时,假设 triggerElement 的宽高为 0,位置位于光标位置
|
|
364
|
+
const triggerClientRect = this.triggerElement.getBoundingClientRect();
|
|
359
365
|
const triggerRect = this.openOnPointer
|
|
360
366
|
? {
|
|
361
367
|
top: this.pointerOffsetY + triggerClientRect.top,
|
|
@@ -555,10 +561,10 @@ __decorate([
|
|
|
555
561
|
], Dropdown.prototype, "openOnPointer", void 0);
|
|
556
562
|
__decorate([
|
|
557
563
|
queryAssignedElements({ slot: 'trigger', flatten: true })
|
|
558
|
-
], Dropdown.prototype, "
|
|
564
|
+
], Dropdown.prototype, "triggerElements", void 0);
|
|
559
565
|
__decorate([
|
|
560
566
|
queryAssignedElements({ flatten: true })
|
|
561
|
-
], Dropdown.prototype, "
|
|
567
|
+
], Dropdown.prototype, "panelElements", void 0);
|
|
562
568
|
__decorate([
|
|
563
569
|
watch('placement', true),
|
|
564
570
|
watch('openOnPointer', true)
|
|
@@ -569,3 +575,4 @@ __decorate([
|
|
|
569
575
|
Dropdown = __decorate([
|
|
570
576
|
customElement('mdui-dropdown')
|
|
571
577
|
], Dropdown);
|
|
578
|
+
export { Dropdown };
|
|
@@ -25,7 +25,7 @@ import type { TemplateResult, CSSResultGroup } from 'lit';
|
|
|
25
25
|
* @cssprop --shape-corner-normal - `size="normal"` 时,组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
26
26
|
* @cssprop --shape-corner-large - `size="large"` 时,组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner)
|
|
27
27
|
*/
|
|
28
|
-
export declare class Fab extends ButtonBase {
|
|
28
|
+
export declare class Fab extends ButtonBase<FabEventMap> {
|
|
29
29
|
static styles: CSSResultGroup;
|
|
30
30
|
/**
|
|
31
31
|
* FAB 形状,此组件的不同形状之间只有颜色不一样。可选值为:
|
|
@@ -53,6 +53,7 @@ export declare class Fab extends ButtonBase {
|
|
|
53
53
|
extended: boolean;
|
|
54
54
|
private readonly rippleRef;
|
|
55
55
|
private readonly hasSlotController;
|
|
56
|
+
private readonly definedController;
|
|
56
57
|
protected get rippleElement(): Ripple;
|
|
57
58
|
/**
|
|
58
59
|
* extended 变更时,设置动画
|
|
@@ -63,6 +64,11 @@ export declare class Fab extends ButtonBase {
|
|
|
63
64
|
private renderIcon;
|
|
64
65
|
private renderInner;
|
|
65
66
|
}
|
|
67
|
+
export interface FabEventMap {
|
|
68
|
+
focus: FocusEvent;
|
|
69
|
+
blur: FocusEvent;
|
|
70
|
+
invalid: CustomEvent<void>;
|
|
71
|
+
}
|
|
66
72
|
declare global {
|
|
67
73
|
interface HTMLElementTagNameMap {
|
|
68
74
|
'mdui-fab': Fab;
|