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.
Files changed (127) hide show
  1. package/LICENSE +21 -21
  2. package/components/avatar/index.d.ts +4 -2
  3. package/components/avatar/index.js +4 -2
  4. package/components/badge/index.d.ts +4 -2
  5. package/components/badge/index.js +4 -2
  6. package/components/bottom-app-bar/index.d.ts +9 -3
  7. package/components/bottom-app-bar/index.js +9 -9
  8. package/components/button/button-base.d.ts +5 -5
  9. package/components/button/button-base.js +22 -19
  10. package/components/button/index.d.ts +6 -1
  11. package/components/button/index.js +2 -1
  12. package/components/button-icon/index.d.ts +7 -1
  13. package/components/button-icon/index.js +3 -3
  14. package/components/card/index.d.ts +8 -4
  15. package/components/card/index.js +7 -3
  16. package/components/checkbox/index.d.ts +10 -3
  17. package/components/checkbox/index.js +13 -16
  18. package/components/checkbox/style.js +1 -1
  19. package/components/chip/index.d.ts +8 -1
  20. package/components/chip/index.js +5 -5
  21. package/components/circular-progress/index.d.ts +4 -2
  22. package/components/circular-progress/index.js +5 -4
  23. package/components/collapse/collapse-item-style.js +1 -1
  24. package/components/collapse/collapse-item.d.ts +15 -3
  25. package/components/collapse/collapse-item.js +26 -23
  26. package/components/collapse/collapse.d.ts +16 -8
  27. package/components/collapse/collapse.js +61 -38
  28. package/components/dialog/index.d.ts +12 -4
  29. package/components/dialog/index.js +36 -36
  30. package/components/divider/index.d.ts +4 -2
  31. package/components/divider/index.js +4 -2
  32. package/components/dropdown/index.d.ts +13 -7
  33. package/components/dropdown/index.js +70 -63
  34. package/components/fab/index.d.ts +7 -1
  35. package/components/fab/index.js +10 -5
  36. package/components/icon/index.d.ts +4 -2
  37. package/components/icon/index.js +4 -2
  38. package/components/layout/helper.d.ts +5 -6
  39. package/components/layout/helper.js +42 -48
  40. package/components/layout/layout-item-base.d.ts +3 -2
  41. package/components/layout/layout-item-base.js +3 -4
  42. package/components/layout/layout-item.d.ts +4 -3
  43. package/components/layout/layout-item.js +3 -3
  44. package/components/layout/layout-main.d.ts +4 -2
  45. package/components/layout/layout-main.js +4 -2
  46. package/components/layout/layout.d.ts +4 -2
  47. package/components/layout/layout.js +4 -2
  48. package/components/linear-progress/index.d.ts +4 -2
  49. package/components/linear-progress/index.js +5 -4
  50. package/components/list/list-item-style.js +1 -1
  51. package/components/list/list-item.d.ts +7 -3
  52. package/components/list/list-item.js +5 -3
  53. package/components/list/list-subheader.d.ts +4 -2
  54. package/components/list/list-subheader.js +4 -2
  55. package/components/list/list.d.ts +4 -2
  56. package/components/list/list.js +4 -2
  57. package/components/menu/menu-item.d.ts +12 -3
  58. package/components/menu/menu-item.js +53 -40
  59. package/components/menu/menu.d.ts +9 -3
  60. package/components/menu/menu.js +85 -59
  61. package/components/navigation-bar/navigation-bar-item-style.js +1 -1
  62. package/components/navigation-bar/navigation-bar-item.d.ts +13 -5
  63. package/components/navigation-bar/navigation-bar-item.js +28 -11
  64. package/components/navigation-bar/navigation-bar.d.ts +14 -7
  65. package/components/navigation-bar/navigation-bar.js +58 -49
  66. package/components/navigation-drawer/index.d.ts +13 -2
  67. package/components/navigation-drawer/index.js +69 -49
  68. package/components/navigation-drawer/style.js +1 -1
  69. package/components/navigation-rail/navigation-rail-item-style.js +1 -1
  70. package/components/navigation-rail/navigation-rail-item.d.ts +13 -5
  71. package/components/navigation-rail/navigation-rail-item.js +22 -9
  72. package/components/navigation-rail/navigation-rail.d.ts +8 -6
  73. package/components/navigation-rail/navigation-rail.js +55 -46
  74. package/components/radio/radio-group.d.ts +13 -6
  75. package/components/radio/radio-group.js +69 -59
  76. package/components/radio/radio-style.js +1 -1
  77. package/components/radio/radio.d.ts +11 -5
  78. package/components/radio/radio.js +26 -19
  79. package/components/range-slider/index.d.ts +9 -3
  80. package/components/range-slider/index.js +13 -11
  81. package/components/ripple/index.d.ts +4 -2
  82. package/components/ripple/index.js +4 -2
  83. package/components/ripple/ripple-mixin.d.ts +1 -1
  84. package/components/ripple/ripple-mixin.js +0 -1
  85. package/components/segmented-button/segmented-button-group-style.js +1 -1
  86. package/components/segmented-button/segmented-button-group.d.ts +12 -5
  87. package/components/segmented-button/segmented-button-group.js +92 -77
  88. package/components/segmented-button/segmented-button.d.ts +8 -3
  89. package/components/segmented-button/segmented-button.js +5 -4
  90. package/components/select/index.d.ts +13 -5
  91. package/components/select/index.js +30 -28
  92. package/components/slider/index.d.ts +8 -1
  93. package/components/slider/index.js +11 -18
  94. package/components/slider/slider-base-style.js +1 -1
  95. package/components/slider/slider-base.d.ts +7 -3
  96. package/components/slider/slider-base.js +28 -13
  97. package/components/snackbar/index.d.ts +9 -2
  98. package/components/snackbar/index.js +11 -10
  99. package/components/switch/index.d.ts +10 -3
  100. package/components/switch/index.js +12 -15
  101. package/components/switch/style.js +1 -1
  102. package/components/tabs/tab-panel.d.ts +4 -2
  103. package/components/tabs/tab-panel.js +4 -2
  104. package/components/tabs/tab-style.js +1 -1
  105. package/components/tabs/tab.d.ts +7 -3
  106. package/components/tabs/tab.js +12 -6
  107. package/components/tabs/tabs-style.js +1 -1
  108. package/components/tabs/tabs.d.ts +11 -7
  109. package/components/tabs/tabs.js +57 -40
  110. package/components/text-field/index.d.ts +13 -5
  111. package/components/text-field/index.js +43 -65
  112. package/components/text-field/style.js +1 -1
  113. package/components/tooltip/index.d.ts +14 -7
  114. package/components/tooltip/index.js +45 -38
  115. package/components/top-app-bar/top-app-bar-title-style.js +1 -1
  116. package/components/top-app-bar/top-app-bar-title.d.ts +4 -2
  117. package/components/top-app-bar/top-app-bar-title.js +18 -13
  118. package/components/top-app-bar/top-app-bar.d.ts +9 -3
  119. package/components/top-app-bar/top-app-bar.js +11 -10
  120. package/custom-elements.json +904 -546
  121. package/functions/getTheme.js +3 -3
  122. package/functions/snackbar.js +1 -2
  123. package/functions/utils/colorScheme.js +2 -2
  124. package/mdui.esm.js +8 -8
  125. package/mdui.global.js +8 -8
  126. package/package.json +8 -7
  127. package/web-types.zh-cn.json +1 -1
@@ -1,6 +1,6 @@
1
- import { LitElement } from 'lit';
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 LitElement {
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, LitElement } from 'lit';
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
- export let Dialog = class Dialog extends LitElement {
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 requestOpen = emit(this, 'open', {
95
- cancelable: true,
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 = (_a = this.topAppBarElements) !== null && _a !== void 0 ? _a : [];
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 Promise.all([
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(this, 'opened');
166
+ this.emit('opened');
160
167
  }
161
- return;
162
168
  }
163
- if (!this.open && hasUpdated) {
164
- const requestClose = emit(this, 'close', {
165
- cancelable: true,
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 Promise.all([
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 (trigger === null || trigger === void 0 ? void 0 : trigger.focus) === 'function') {
193
+ if (typeof trigger?.focus === 'function') {
194
194
  setTimeout(() => trigger.focus());
195
195
  }
196
- emit(this, 'closed');
197
- return;
196
+ this.emit('closed');
198
197
  }
199
198
  }
200
- connectedCallback() {
201
- super.connectedCallback();
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(this, 'overlay-click');
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 { LitElement } from 'lit';
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 LitElement {
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, LitElement } from 'lit';
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
- export let Divider = class Divider extends LitElement {
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 LitElement {
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 triggerSlots;
88
- private readonly panelSlots;
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 triggerSlot();
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, LitElement } from 'lit';
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
- export let Dropdown = class Dropdown extends LitElement {
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 triggerSlot() {
111
- return this.triggerSlots[0];
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
- // 打开动画开始前,设置 panel 的样式
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 requestOpen = emit(this, 'open', {
137
- cancelable: true,
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
- if (typeof ((_a = this.panelSlot) === null || _a === void 0 ? void 0 : _a.focus) === 'function') {
145
- this.panelSlot.focus();
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(this, 'opened');
171
+ this.emit('opened');
166
172
  }
167
- return;
168
173
  }
169
- // 关闭
170
- if (!this.open && hasUpdated) {
171
- const requestClose = emit(this, 'close', {
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
- typeof ((_b = this.triggerSlot) === null || _b === void 0 ? void 0 : _b.focus) === 'function' &&
181
+ isFunction(this.triggerElement?.focus) &&
180
182
  (this.contains(document.activeElement) ||
181
- this.contains((_d = (_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.assignedSlot) !== null && _d !== void 0 ? _d : null))) {
182
- this.triggerSlot.focus();
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(this, 'closed');
199
+ this.emit('closed');
198
200
  }
199
201
  }
200
202
  connectedCallback() {
201
203
  super.connectedCallback();
202
- document.addEventListener('pointerdown', this.onDocumentClick);
203
- document.addEventListener('keydown', this.onDocumentKeydown);
204
- window.addEventListener('scroll', this.onWindowScroll);
205
- // triggerSlot 的尺寸变化时,重新调整 panel 的位置
206
- this.updateComplete.then(() => {
207
- this.observeResize = observeResize(this.triggerSlot, () => {
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
- window.removeEventListener('scroll', this.onWindowScroll);
218
- (_a = this.observeResize) === null || _a === void 0 ? void 0 : _a.unobserve();
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.triggerSlot.addEventListener('focus', this.onFocus);
224
- this.triggerSlot.addEventListener('click', this.onClick);
225
- this.triggerSlot.addEventListener('contextmenu', this.onContextMenu);
226
- this.triggerSlot.addEventListener('mouseenter', this.onMouseEnter);
227
- $(this.panelRef.value).on('click', this.onPanelClick);
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.triggerSlot)) {
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
- $(event.target).is('mdui-menu-item')) {
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 panelSlots = this.panelSlots;
356
+ const panelElements = this.panelElements;
353
357
  const panelRect = {
354
- width: Math.max(...((_a = panelSlots === null || panelSlots === void 0 ? void 0 : panelSlots.map((panel) => panel.offsetWidth)) !== null && _a !== void 0 ? _a : [])),
355
- height: panelSlots === null || panelSlots === void 0 ? void 0 : panelSlots.map((panel) => panel.offsetHeight).reduce((total, height) => total + 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
- // 在光标位置触发时,假设 triggerSlot 的宽高为 0,位置位于光标位置
358
- const triggerClientRect = this.triggerSlot.getBoundingClientRect();
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, "triggerSlots", void 0);
564
+ ], Dropdown.prototype, "triggerElements", void 0);
559
565
  __decorate([
560
566
  queryAssignedElements({ flatten: true })
561
- ], Dropdown.prototype, "panelSlots", void 0);
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;