From 4f9c2e1df19a914d66565f32ce8584e034968e2b Mon Sep 17 00:00:00 2001 From: zdhxiong Date: Mon, 27 Nov 2023 15:05:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=B1=BB=E5=9E=8B=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mdui/src/components/avatar/index.ts | 7 ++- packages/mdui/src/components/badge/index.ts | 7 ++- .../src/components/bottom-app-bar/index.ts | 22 +++++--- .../mdui/src/components/button-icon/index.ts | 12 +++- .../mdui/src/components/button/button-base.ts | 16 +++--- packages/mdui/src/components/button/index.ts | 8 ++- packages/mdui/src/components/card/index.ts | 12 +++- .../mdui/src/components/checkbox/index.ts | 22 +++++--- packages/mdui/src/components/chip/index.ts | 17 ++++-- .../src/components/circular-progress/index.ts | 7 ++- .../src/components/collapse/collapse-item.ts | 17 ++++-- .../mdui/src/components/collapse/collapse.ts | 12 ++-- packages/mdui/src/components/dialog/index.ts | 32 ++++++----- packages/mdui/src/components/divider/index.ts | 7 ++- .../mdui/src/components/dropdown/index.ts | 29 +++++----- packages/mdui/src/components/fab/index.ts | 8 ++- packages/mdui/src/components/icon/index.ts | 7 ++- .../src/components/layout/layout-item-base.ts | 5 +- .../mdui/src/components/layout/layout-item.ts | 8 ++- .../mdui/src/components/layout/layout-main.ts | 7 ++- packages/mdui/src/components/layout/layout.ts | 7 ++- .../src/components/linear-progress/index.ts | 7 ++- .../mdui/src/components/list/list-item.ts | 12 +++- .../src/components/list/list-subheader.ts | 7 ++- packages/mdui/src/components/list/list.ts | 7 ++- .../mdui/src/components/menu/menu-item.ts | 33 ++++++----- packages/mdui/src/components/menu/menu.ts | 12 ++-- .../navigation-bar/navigation-bar-item.ts | 12 +++- .../navigation-bar/navigation-bar.ts | 25 ++++++--- .../src/components/navigation-drawer/index.ts | 25 ++++++--- .../navigation-rail/navigation-rail-item.ts | 12 +++- .../navigation-rail/navigation-rail.ts | 9 ++- .../mdui/src/components/radio/radio-group.ts | 28 ++++++---- packages/mdui/src/components/radio/radio.ts | 16 ++++-- .../mdui/src/components/range-slider/index.ts | 17 +++++- packages/mdui/src/components/ripple/index.ts | 7 ++- .../src/components/ripple/ripple-mixin.ts | 5 +- .../segmented-button-group.ts | 24 +++++--- .../segmented-button/segmented-button.ts | 8 ++- packages/mdui/src/components/select/index.ts | 21 +++++-- packages/mdui/src/components/slider/index.ts | 10 +++- .../mdui/src/components/slider/slider-base.ts | 19 ++++--- .../mdui/src/components/snackbar/index.ts | 28 ++++++---- packages/mdui/src/components/switch/index.ts | 22 +++++--- .../mdui/src/components/tabs/tab-panel.ts | 7 ++- packages/mdui/src/components/tabs/tab.ts | 10 +++- packages/mdui/src/components/tabs/tabs.ts | 12 ++-- .../mdui/src/components/text-field/index.ts | 33 +++++++---- packages/mdui/src/components/tooltip/index.ts | 29 +++++----- .../top-app-bar/top-app-bar-title.ts | 7 ++- .../src/components/top-app-bar/top-app-bar.ts | 22 +++++--- packages/shared/package.json | 1 + packages/shared/src/base/mdui-element.ts | 55 +++++++++++++++++++ packages/shared/src/helpers/event.ts | 22 -------- packages/shared/src/mixins/anchor.ts | 5 +- packages/shared/src/mixins/focusable.ts | 16 +++--- packages/shared/src/mixins/scrollBehavior.ts | 6 +- 57 files changed, 579 insertions(+), 281 deletions(-) create mode 100644 packages/shared/src/base/mdui-element.ts delete mode 100644 packages/shared/src/helpers/event.ts diff --git a/packages/mdui/src/components/avatar/index.ts b/packages/mdui/src/components/avatar/index.ts index f7ee63c6..c3873f9f 100644 --- a/packages/mdui/src/components/avatar/index.ts +++ b/packages/mdui/src/components/avatar/index.ts @@ -1,7 +1,8 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { styleMap } from 'lit/directives/style-map.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -24,7 +25,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-avatar') -export class Avatar extends LitElement { +export class Avatar extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -80,6 +81,8 @@ export class Avatar extends LitElement { } } +export interface AvatarEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-avatar': Avatar; diff --git a/packages/mdui/src/components/badge/index.ts b/packages/mdui/src/components/badge/index.ts index d548b7ba..5309c110 100644 --- a/packages/mdui/src/components/badge/index.ts +++ b/packages/mdui/src/components/badge/index.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; @@ -17,7 +18,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-badge') -export class Badge extends LitElement { +export class Badge extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -39,6 +40,8 @@ export class Badge extends LitElement { } } +export interface BadgeEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-badge': Badge; diff --git a/packages/mdui/src/components/bottom-app-bar/index.ts b/packages/mdui/src/components/bottom-app-bar/index.ts index f541a892..fd98f6d7 100644 --- a/packages/mdui/src/components/bottom-app-bar/index.ts +++ b/packages/mdui/src/components/bottom-app-bar/index.ts @@ -1,7 +1,6 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { ScrollBehaviorMixin } from '@mdui/shared/mixins/scrollBehavior.js'; import { LayoutItemBase } from '../layout/layout-item-base.js'; @@ -35,7 +34,9 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-bottom-app-bar') -export class BottomAppBar extends ScrollBehaviorMixin(LayoutItemBase) { +export class BottomAppBar extends ScrollBehaviorMixin( + LayoutItemBase, +) { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -79,7 +80,7 @@ export class BottomAppBar extends ScrollBehaviorMixin(LayoutItemBase) { this.addEventListener('transitionend', (event: TransitionEvent) => { if (event.target === this) { - emit(this, this.hide ? 'hidden' : 'shown'); + this.emit(this.hide ? 'hidden' : 'shown'); } }); } @@ -95,22 +96,29 @@ export class BottomAppBar extends ScrollBehaviorMixin(LayoutItemBase) { protected runScrollThreshold(isScrollingUp: boolean) { // 向下滚动 if (!isScrollingUp && !this.hide) { - const requestHide = emit(this, 'hide'); - if (!requestHide.defaultPrevented) { + const eventProceeded = this.emit('hide', { cancelable: true }); + if (eventProceeded) { this.hide = true; } } // 向上滚动 if (isScrollingUp && this.hide) { - const requestShow = emit(this, 'show'); - if (!requestShow.defaultPrevented) { + const eventProceeded = this.emit('show', { cancelable: true }); + if (eventProceeded) { this.hide = false; } } } } +export interface BottomAppBarEventMap { + show: CustomEvent; + shown: CustomEvent; + hide: CustomEvent; + hidden: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-bottom-app-bar': BottomAppBar; diff --git a/packages/mdui/src/components/button-icon/index.ts b/packages/mdui/src/components/button-icon/index.ts index 7f188b0f..b1664e7b 100644 --- a/packages/mdui/src/components/button-icon/index.ts +++ b/packages/mdui/src/components/button-icon/index.ts @@ -4,7 +4,6 @@ import { createRef, ref } from 'lit/directives/ref.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import { ButtonBase } from '../button/button-base.js'; import '../icon.js'; @@ -36,7 +35,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-button-icon') -export class ButtonIcon extends ButtonBase { +export class ButtonIcon extends ButtonBase { public static override styles: CSSResultGroup = [ButtonBase.styles, style]; /** @@ -99,7 +98,7 @@ export class ButtonIcon extends ButtonBase { @watch('selected', true) private onSelectedChange() { - emit(this, 'change'); + this.emit('change'); } protected override firstUpdated(changedProperties: PropertyValues): void { @@ -164,6 +163,13 @@ export class ButtonIcon extends ButtonBase { } } +export interface ButtonIconEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-button-icon': ButtonIcon; diff --git a/packages/mdui/src/components/button/button-base.ts b/packages/mdui/src/components/button/button-base.ts index 5f4dda46..c60481fc 100644 --- a/packages/mdui/src/components/button/button-base.ts +++ b/packages/mdui/src/components/button/button-base.ts @@ -1,10 +1,10 @@ -import { LitElement, html } from 'lit'; +import { html } from 'lit'; import { property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import cc from 'classcat'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { FormController } from '@mdui/shared/controllers/form.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { AnchorMixin } from '@mdui/shared/mixins/anchor.js'; @@ -22,9 +22,9 @@ type RenderButtonOptions = { tabindex?: number; }; -export class ButtonBase extends AnchorMixin( - RippleMixin(FocusableMixin(LitElement)), -) { +export class ButtonBase extends AnchorMixin( + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [ componentStyle, buttonBaseStyle, @@ -212,7 +212,8 @@ export class ButtonBase extends AnchorMixin( const valid = (this.focusElement as HTMLButtonElement).checkValidity(); if (!valid) { - emit(this, 'invalid', { + // @ts-ignore + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -237,7 +238,8 @@ export class ButtonBase extends AnchorMixin( ).reportValidity(); if (invalid) { - emit(this, 'invalid', { + // @ts-ignore + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, diff --git a/packages/mdui/src/components/button/index.ts b/packages/mdui/src/components/button/index.ts index ea407f9c..9365b9fc 100644 --- a/packages/mdui/src/components/button/index.ts +++ b/packages/mdui/src/components/button/index.ts @@ -34,7 +34,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-button') -export class Button extends ButtonBase { +export class Button extends ButtonBase { public static override styles: CSSResultGroup = [ButtonBase.styles, style]; /** @@ -134,6 +134,12 @@ export class Button extends ButtonBase { } } +export interface ButtonEventMap { + focus: FocusEvent; + blur: FocusEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-button': Button; diff --git a/packages/mdui/src/components/card/index.ts b/packages/mdui/src/components/card/index.ts index f5c1d655..ee979b7b 100644 --- a/packages/mdui/src/components/card/index.ts +++ b/packages/mdui/src/components/card/index.ts @@ -1,6 +1,7 @@ -import { LitElement, html } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { createRef, ref } from 'lit/directives/ref.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { AnchorMixin } from '@mdui/shared/mixins/anchor.js'; @@ -26,7 +27,9 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-card') -export class Card extends AnchorMixin(RippleMixin(FocusableMixin(LitElement))) { +export class Card extends AnchorMixin( + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -96,6 +99,11 @@ export class Card extends AnchorMixin(RippleMixin(FocusableMixin(LitElement))) { } } +export interface CardEventMap { + focus: FocusEvent; + blur: FocusEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-card': Card; diff --git a/packages/mdui/src/components/checkbox/index.ts b/packages/mdui/src/components/checkbox/index.ts index 5442251f..18025978 100644 --- a/packages/mdui/src/components/checkbox/index.ts +++ b/packages/mdui/src/components/checkbox/index.ts @@ -1,14 +1,14 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { live } from 'lit/directives/live.js'; import { createRef, ref } from 'lit/directives/ref.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import '@mdui/shared/icons/check-box-outline-blank.js'; import '@mdui/shared/icons/check-box.js'; import '@mdui/shared/icons/indeterminate-check-box.js'; @@ -48,7 +48,7 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-checkbox') export class Checkbox - extends RippleMixin(FocusableMixin(LitElement)) + extends RippleMixin(FocusableMixin(MduiElement)) implements FormControl { public static override styles: CSSResultGroup = [componentStyle, style]; @@ -210,7 +210,7 @@ export class Checkbox const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -229,14 +229,14 @@ export class Checkbox this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - const requestInvalid = emit(this, 'invalid', { + const eventProceeded = this.emit('invalid', { bubbles: false, cancelable: true, composed: false, }); // 调用了 preventDefault() 时,隐藏默认的表单错误提示 - if (requestInvalid.defaultPrevented) { + if (!eventProceeded) { this.blur(); this.focus(); } @@ -314,10 +314,18 @@ export class Checkbox private onChange() { this.checked = this.inputRef.value!.checked; this.indeterminate = false; - emit(this, 'change'); + this.emit('change'); } } +export interface CheckboxEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + input: Event; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-checkbox': Checkbox; diff --git a/packages/mdui/src/components/chip/index.ts b/packages/mdui/src/components/chip/index.ts index a5cd0ff2..fbf595f1 100644 --- a/packages/mdui/src/components/chip/index.ts +++ b/packages/mdui/src/components/chip/index.ts @@ -5,7 +5,6 @@ import cc from 'classcat'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import '@mdui/shared/icons/check.js'; import '@mdui/shared/icons/clear.js'; @@ -46,7 +45,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-chip') -export class Chip extends ButtonBase { +export class Chip extends ButtonBase { public static override styles: CSSResultGroup = [ButtonBase.styles, style]; /** @@ -150,7 +149,7 @@ export class Chip extends ButtonBase { @watch('selected', true) private onSelectedChange() { - emit(this, 'change'); + this.emit('change'); } protected override firstUpdated(changedProperties: PropertyValues): void { @@ -223,7 +222,7 @@ export class Chip extends ButtonBase { // 按下 Delete 或 BackSpace 键时,触发 delete 事件 if (this.deletable && ['Delete', 'Backspace'].includes(event.key)) { - emit(this, 'delete'); + this.emit('delete'); } } @@ -232,7 +231,7 @@ export class Chip extends ButtonBase { */ private onDelete(event: MouseEvent) { event.stopPropagation(); - emit(this, 'delete'); + this.emit('delete'); } private renderIcon(): TemplateResult { @@ -311,6 +310,14 @@ export class Chip extends ButtonBase { } } +export interface ChipEventMap { + focus: FocusEvent; + blur: FocusEvent; + invalid: CustomEvent; + change: CustomEvent; + delete: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-chip': Chip; diff --git a/packages/mdui/src/components/circular-progress/index.ts b/packages/mdui/src/components/circular-progress/index.ts index ba60a687..8c505af4 100644 --- a/packages/mdui/src/components/circular-progress/index.ts +++ b/packages/mdui/src/components/circular-progress/index.ts @@ -1,7 +1,8 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { isUndefined } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; import type { CSSResultGroup, TemplateResult } from 'lit'; @@ -14,7 +15,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * ``` */ @customElement('mdui-circular-progress') -export class CircularProgress extends LitElement { +export class CircularProgress extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -100,6 +101,8 @@ export class CircularProgress extends LitElement { } } +export interface CircularProgressEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-circular-progress': CircularProgress; diff --git a/packages/mdui/src/components/collapse/collapse-item.ts b/packages/mdui/src/components/collapse/collapse-item.ts index 14863e82..d6756343 100644 --- a/packages/mdui/src/components/collapse/collapse-item.ts +++ b/packages/mdui/src/components/collapse/collapse-item.ts @@ -1,12 +1,12 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { $ } from '@mdui/jq/$.js'; import '@mdui/jq/methods/height.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { uniqueId } from '@mdui/shared/helpers/uniqueId.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { collapseItemStyle } from './collapse-item-style.js'; @@ -36,7 +36,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart body - 折叠面板的正文内容 */ @customElement('mdui-collapse-item') -export class CollapseItem extends LitElement { +export class CollapseItem extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, collapseItemStyle, @@ -95,7 +95,7 @@ export class CollapseItem extends LitElement { } } else { this.state = this.active ? 'open' : 'close'; - emit(this, this.state); + this.emit(this.state); this.updateBodyHeight(); } } @@ -124,7 +124,7 @@ export class CollapseItem extends LitElement { private onTransitionEnd(event: TransitionEvent) { if (event.target === this.bodyRef.value) { this.state = this.active ? 'opened' : 'closed'; - emit(this, this.state); + this.emit(this.state); this.updateBodyHeight(); } } @@ -148,6 +148,13 @@ export class CollapseItem extends LitElement { } } +export interface CollapseItemEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-collapse-item': CollapseItem; diff --git a/packages/mdui/src/components/collapse/collapse.ts b/packages/mdui/src/components/collapse/collapse.ts index a2806daf..7654abc8 100644 --- a/packages/mdui/src/components/collapse/collapse.ts +++ b/packages/mdui/src/components/collapse/collapse.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -8,11 +8,11 @@ import { import { $ } from '@mdui/jq/$.js'; import '@mdui/jq/methods/is.js'; import { isElement, isUndefined } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { arraysEqualIgnoreOrder } from '@mdui/shared/helpers/array.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { collapseStyle } from './collapse-style.js'; import type { CollapseItem as CollapseItemOriginal } from './collapse-item.js'; @@ -39,7 +39,7 @@ type CollapseItem = CollapseItemOriginal & { * @slot - `` 组件 */ @customElement('mdui-collapse') -export class Collapse extends LitElement { +export class Collapse extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, collapseStyle, @@ -104,7 +104,7 @@ export class Collapse extends LitElement { this.setValue(value); if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -235,6 +235,10 @@ export class Collapse extends LitElement { } } +export interface CollapseEventMap { + change: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-collapse': Collapse; diff --git a/packages/mdui/src/components/dialog/index.ts b/packages/mdui/src/components/dialog/index.ts index 6db7762c..e43317a2 100644 --- a/packages/mdui/src/components/dialog/index.ts +++ b/packages/mdui/src/components/dialog/index.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -7,12 +7,12 @@ import { import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { Modal } from '@mdui/shared/helpers/modal.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { lockScreen, unlockScreen } from '@mdui/shared/helpers/scroll.js'; @@ -57,7 +57,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-dialog') -export class Dialog extends LitElement { +export class Dialog extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -220,10 +220,8 @@ export class Dialog extends LitElement { // 要区分是否首次渲染,首次渲染不触发事件,不执行动画;非首次渲染,触发事件,执行动画 if (this.open) { if (hasUpdated) { - const requestOpen = emit(this, 'open', { - cancelable: true, - }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -310,13 +308,11 @@ export class Dialog extends LitElement { ]); if (hasUpdated) { - emit(this, 'opened'); + this.emit('opened'); } } else { - const requestClose = emit(this, 'close', { - cancelable: true, - }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -361,7 +357,7 @@ export class Dialog extends LitElement { setTimeout(() => trigger.focus()); } - emit(this, 'closed'); + this.emit('closed'); } } @@ -437,7 +433,7 @@ export class Dialog extends LitElement { } private onOverlayClick() { - emit(this, 'overlay-click'); + this.emit('overlay-click'); if (!this.closeOnOverlayClick) { return; } @@ -466,6 +462,14 @@ export class Dialog extends LitElement { } } +export interface DialogEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; + 'overlay-click': CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-dialog': Dialog; diff --git a/packages/mdui/src/components/divider/index.ts b/packages/mdui/src/components/divider/index.ts index cffec050..f1d763df 100644 --- a/packages/mdui/src/components/divider/index.ts +++ b/packages/mdui/src/components/divider/index.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; @@ -13,7 +14,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * ``` */ @customElement('mdui-divider') -export class Divider extends LitElement { +export class Divider extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -51,6 +52,8 @@ export class Divider extends LitElement { } } +export interface DividerEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-divider': Divider; diff --git a/packages/mdui/src/components/dropdown/index.ts b/packages/mdui/src/components/dropdown/index.ts index 7a6c1e84..0d0fbdb2 100644 --- a/packages/mdui/src/components/dropdown/index.ts +++ b/packages/mdui/src/components/dropdown/index.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -10,11 +10,11 @@ import '@mdui/jq/methods/height.js'; import '@mdui/jq/methods/is.js'; import '@mdui/jq/methods/width.js'; import { isFunction } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -50,7 +50,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-dropdown') -export class Dropdown extends LitElement { +export class Dropdown extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -234,10 +234,8 @@ export class Dropdown extends LitElement { // 要区分是否首次渲染,首次渲染时不触发事件,不执行动画;非首次渲染,触发事件,执行动画 if (this.open) { if (hasUpdated) { - const requestOpen = emit(this, 'open', { - cancelable: true, - }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -278,13 +276,11 @@ export class Dropdown extends LitElement { ]); if (hasUpdated) { - emit(this, 'opened'); + this.emit('opened'); } } else { - const requestClose = emit(this, 'close', { - cancelable: true, - }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -322,7 +318,7 @@ export class Dropdown extends LitElement { this.panelRef.value.hidden = true; } - emit(this, 'closed'); + this.emit('closed'); } } @@ -703,6 +699,13 @@ export class Dropdown extends LitElement { } } +export interface DropdownEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-dropdown': Dropdown; diff --git a/packages/mdui/src/components/fab/index.ts b/packages/mdui/src/components/fab/index.ts index ca3e5c7e..cfa91a6a 100644 --- a/packages/mdui/src/components/fab/index.ts +++ b/packages/mdui/src/components/fab/index.ts @@ -39,7 +39,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --shape-corner-large - `size="large"` 时,组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-fab') -export class Fab extends ButtonBase { +export class Fab extends ButtonBase { public static override styles: CSSResultGroup = [ButtonBase.styles, style]; /** @@ -170,6 +170,12 @@ export class Fab extends ButtonBase { } } +export interface FabEventMap { + focus: FocusEvent; + blur: FocusEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-fab': Fab; diff --git a/packages/mdui/src/components/icon/index.ts b/packages/mdui/src/components/icon/index.ts index d3ee381d..207d9253 100644 --- a/packages/mdui/src/components/icon/index.ts +++ b/packages/mdui/src/components/icon/index.ts @@ -1,9 +1,10 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { styleMap } from 'lit/directives/style-map.js'; import { unsafeSVG } from 'lit/directives/unsafe-svg.js'; import { until } from 'lit/directives/until.js'; import { ajax } from '@mdui/jq/functions/ajax.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; @@ -19,7 +20,7 @@ import type { TemplateResult, CSSResultGroup } from 'lit'; * @slot - `svg` 图标的内容 */ @customElement('mdui-icon') -export class Icon extends LitElement { +export class Icon extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -68,6 +69,8 @@ export class Icon extends LitElement { } } +export interface IconEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-icon': Icon; diff --git a/packages/mdui/src/components/layout/layout-item-base.ts b/packages/mdui/src/components/layout/layout-item-base.ts index 3a10bbb1..716f9512 100644 --- a/packages/mdui/src/components/layout/layout-item-base.ts +++ b/packages/mdui/src/components/layout/layout-item-base.ts @@ -1,12 +1,13 @@ -import { LitElement } from 'lit'; import { property } from 'lit/decorators.js'; import { isNodeName } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { getLayout } from './helper.js'; import type { LayoutManager, LayoutPlacement } from './helper.js'; import type { Layout } from './layout.js'; +import type { PlainObject } from '@mdui/jq/shared/helper.js'; -export class LayoutItemBase extends LitElement { +export class LayoutItemBase extends MduiElement { /** * 该组件在 [``](/docs/2/components/layout) 中的布局顺序,按从小到大排序。默认为 `0` */ diff --git a/packages/mdui/src/components/layout/layout-item.ts b/packages/mdui/src/components/layout/layout-item.ts index bdc6ef7a..3d07a48d 100644 --- a/packages/mdui/src/components/layout/layout-item.ts +++ b/packages/mdui/src/components/layout/layout-item.ts @@ -1,11 +1,11 @@ -import { CSSResultGroup, html } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { LayoutItemBase } from './layout-item-base.js'; import { layoutItemStyle } from './layout-item-style.js'; import type { LayoutPlacement } from './helper.js'; -import type { TemplateResult } from 'lit'; +import type { CSSResultGroup, TemplateResult } from 'lit'; /** * @summary 布局项组件 @@ -21,7 +21,7 @@ import type { TemplateResult } from 'lit'; * @slot - 可以是任意内容 */ @customElement('mdui-layout-item') -export class LayoutItem extends LayoutItemBase { +export class LayoutItem extends LayoutItemBase { public static override styles: CSSResultGroup = [ componentStyle, layoutItemStyle, @@ -57,6 +57,8 @@ export class LayoutItem extends LayoutItemBase { } } +export interface LayoutItemEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-layout-item': LayoutItem; diff --git a/packages/mdui/src/components/layout/layout-main.ts b/packages/mdui/src/components/layout/layout-main.ts index 6363ce23..5f5fa507 100644 --- a/packages/mdui/src/components/layout/layout-main.ts +++ b/packages/mdui/src/components/layout/layout-main.ts @@ -1,6 +1,7 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement } from 'lit/decorators.js'; import { isNodeName } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { getLayout, LayoutManager } from './helper.js'; import { layoutMainStyle } from './layout-main-style.js'; @@ -21,7 +22,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @slot - 可以是任意内容 */ @customElement('mdui-layout-main') -export class LayoutMain extends LitElement { +export class LayoutMain extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, layoutMainStyle, @@ -52,6 +53,8 @@ export class LayoutMain extends LitElement { } } +export interface LayoutMainEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-layout-main': LayoutMain; diff --git a/packages/mdui/src/components/layout/layout.ts b/packages/mdui/src/components/layout/layout.ts index 7dc88fbe..2edb296c 100644 --- a/packages/mdui/src/components/layout/layout.ts +++ b/packages/mdui/src/components/layout/layout.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { layoutStyle } from './layout-style.js'; @@ -19,7 +20,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @slot - 可以是 [``](/docs/2/components/top-app-bar)、[``](/docs/2/components/bottom-app-bar)、[``](/docs/2/components/navigation-bar)、[``](/docs/2/components/navigation-drawer)、[``](/docs/2/components/navigation-rail)、``、`` 元素 */ @customElement('mdui-layout') -export class Layout extends LitElement { +export class Layout extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, layoutStyle]; /** @@ -38,6 +39,8 @@ export class Layout extends LitElement { } } +export interface LayoutEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-layout': Layout; diff --git a/packages/mdui/src/components/linear-progress/index.ts b/packages/mdui/src/components/linear-progress/index.ts index ac4eb2bd..60b3ddf9 100644 --- a/packages/mdui/src/components/linear-progress/index.ts +++ b/packages/mdui/src/components/linear-progress/index.ts @@ -1,7 +1,8 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { styleMap } from 'lit/directives/style-map.js'; import { isUndefined } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; import type { CSSResultGroup, TemplateResult } from 'lit'; @@ -18,7 +19,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-linear-progress') -export class LinearProgress extends LitElement { +export class LinearProgress extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -52,6 +53,8 @@ export class LinearProgress extends LitElement { } } +export interface LinearProgressEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-linear-progress': LinearProgress; diff --git a/packages/mdui/src/components/list/list-item.ts b/packages/mdui/src/components/list/list-item.ts index 1c0e169d..e4c71b45 100644 --- a/packages/mdui/src/components/list/list-item.ts +++ b/packages/mdui/src/components/list/list-item.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -7,6 +7,7 @@ import { import { createRef, ref } from 'lit/directives/ref.js'; import cc from 'classcat'; import { isNodeName, getNodeName } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; @@ -52,8 +53,8 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-list-item') export class ListItem extends AnchorMixin( - RippleMixin(FocusableMixin(LitElement)), -) { + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [ componentStyle, listItemStyle, @@ -255,6 +256,11 @@ export class ListItem extends AnchorMixin( } } +export interface ListItemEventMap { + focus: FocusEvent; + blur: FocusEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-list-item': ListItem; diff --git a/packages/mdui/src/components/list/list-subheader.ts b/packages/mdui/src/components/list/list-subheader.ts index 4bf68ecc..d1463e31 100644 --- a/packages/mdui/src/components/list/list-subheader.ts +++ b/packages/mdui/src/components/list/list-subheader.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { listSubheaderStyle } from './list-subheader-style.js'; import type { CSSResultGroup, TemplateResult } from 'lit'; @@ -18,7 +19,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @slot - 文本 */ @customElement('mdui-list-subheader') -export class ListSubheader extends LitElement { +export class ListSubheader extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, listSubheaderStyle, @@ -29,6 +30,8 @@ export class ListSubheader extends LitElement { } } +export interface ListSubheaderEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-list-subheader': ListSubheader; diff --git a/packages/mdui/src/components/list/list.ts b/packages/mdui/src/components/list/list.ts index 13b2cbdf..798a09fe 100644 --- a/packages/mdui/src/components/list/list.ts +++ b/packages/mdui/src/components/list/list.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { listStyle } from './list-style.js'; import type { CSSResultGroup, TemplateResult } from 'lit'; @@ -18,7 +19,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @slot - `` 元素 */ @customElement('mdui-list') -export class List extends LitElement { +export class List extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, listStyle]; protected override render(): TemplateResult { @@ -26,6 +27,8 @@ export class List extends LitElement { } } +export interface ListEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-list': List; diff --git a/packages/mdui/src/components/menu/menu-item.ts b/packages/mdui/src/components/menu/menu-item.ts index 891e220b..8a2dd598 100644 --- a/packages/mdui/src/components/menu/menu-item.ts +++ b/packages/mdui/src/components/menu/menu-item.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; @@ -11,12 +11,12 @@ import '@mdui/jq/methods/innerWidth.js'; import '@mdui/jq/methods/width.js'; import { isUndefined } from '@mdui/jq/shared/helper.js'; import '@mdui/jq/static/contains.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import { uniqueId } from '@mdui/shared/helpers/uniqueId.js'; @@ -67,8 +67,8 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-menu-item') export class MenuItem extends AnchorMixin( - RippleMixin(FocusableMixin(LitElement)), -) { + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [ componentStyle, menuItemStyle, @@ -235,10 +235,8 @@ export class MenuItem extends AnchorMixin( // 要区分是否首次渲染,首次渲染时不触发事件,不执行动画;非首次渲染,触发事件,执行动画 if (this.submenuOpen) { if (hasUpdated) { - const requestOpen = emit(this, 'submenu-open', { - cancelable: true, - }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('submenu-open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -268,13 +266,11 @@ export class MenuItem extends AnchorMixin( ]); if (hasUpdated) { - emit(this, 'submenu-opened'); + this.emit('submenu-opened'); } } else { - const requestClose = emit(this, 'submenu-close', { - cancelable: true, - }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('submenu-close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -298,7 +294,7 @@ export class MenuItem extends AnchorMixin( this.submenuRef.value.hidden = true; } - emit(this, 'submenu-closed'); + this.emit('submenu-closed'); } } @@ -585,6 +581,15 @@ export class MenuItem extends AnchorMixin( } } +export interface MenuItemEventMap { + focus: FocusEvent; + blur: FocusEvent; + 'submenu-open': CustomEvent; + 'submenu-opened': CustomEvent; + 'submenu-close': CustomEvent; + 'submenu-closed': CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-menu-item': MenuItem; diff --git a/packages/mdui/src/components/menu/menu.ts b/packages/mdui/src/components/menu/menu.ts index f3b4c4af..185696fd 100644 --- a/packages/mdui/src/components/menu/menu.ts +++ b/packages/mdui/src/components/menu/menu.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -14,12 +14,12 @@ import '@mdui/jq/methods/is.js'; import '@mdui/jq/methods/parent.js'; import '@mdui/jq/methods/parents.js'; import { isString, isUndefined } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { arraysEqualIgnoreOrder } from '@mdui/shared/helpers/array.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { delay } from '@mdui/shared/helpers/delay.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { menuStyle } from './menu-style.js'; import type { MenuItem as MenuItemOriginal } from './menu-item.js'; @@ -60,7 +60,7 @@ type MenuItem = MenuItemOriginal & { * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-menu') -export class Menu extends LitElement { +export class Menu extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, menuStyle]; /** @@ -232,7 +232,7 @@ export class Menu extends LitElement { this.setValue(value); if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -540,6 +540,10 @@ export class Menu extends LitElement { } } +export interface MenuEventMap { + change: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-menu': Menu; diff --git a/packages/mdui/src/components/navigation-bar/navigation-bar-item.ts b/packages/mdui/src/components/navigation-bar/navigation-bar-item.ts index 598c24e5..b1dfdb2e 100644 --- a/packages/mdui/src/components/navigation-bar/navigation-bar-item.ts +++ b/packages/mdui/src/components/navigation-bar/navigation-bar-item.ts @@ -1,7 +1,8 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { createRef, ref } from 'lit/directives/ref.js'; import cc from 'classcat'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; @@ -46,8 +47,8 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-navigation-bar-item') export class NavigationBarItem extends AnchorMixin( - RippleMixin(FocusableMixin(LitElement)), -) { + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [ componentStyle, navigationBarItemStyle, @@ -173,6 +174,11 @@ export class NavigationBarItem extends AnchorMixin( } } +export interface NavigationBarItemEventMap { + focus: FocusEvent; + blur: FocusEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-navigation-bar-item': NavigationBarItem; diff --git a/packages/mdui/src/components/navigation-bar/navigation-bar.ts b/packages/mdui/src/components/navigation-bar/navigation-bar.ts index a320a22f..c3fa0bdd 100644 --- a/packages/mdui/src/components/navigation-bar/navigation-bar.ts +++ b/packages/mdui/src/components/navigation-bar/navigation-bar.ts @@ -8,7 +8,6 @@ import { import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { ScrollBehaviorMixin } from '@mdui/shared/mixins/scrollBehavior.js'; import { LayoutItemBase } from '../layout/layout-item-base.js'; @@ -48,7 +47,9 @@ type NavigationBarItem = NavigationBarItemOriginal & { * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-navigation-bar') -export class NavigationBar extends ScrollBehaviorMixin(LayoutItemBase) { +export class NavigationBar extends ScrollBehaviorMixin( + LayoutItemBase, +) { public static override styles: CSSResultGroup = [ componentStyle, navigationBarStyle, @@ -127,7 +128,7 @@ export class NavigationBar extends ScrollBehaviorMixin(LayoutItemBase) { this.value = item?.value; if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -153,7 +154,7 @@ export class NavigationBar extends ScrollBehaviorMixin(LayoutItemBase) { this.addEventListener('transitionend', (event: TransitionEvent) => { if (event.target === this) { - emit(this, this.hide ? 'hidden' : 'shown'); + this.emit(this.hide ? 'hidden' : 'shown'); } }); } @@ -172,16 +173,16 @@ export class NavigationBar extends ScrollBehaviorMixin(LayoutItemBase) { protected runScrollThreshold(isScrollingUp: boolean) { // 向下滚动 if (!isScrollingUp && !this.hide) { - const requestHide = emit(this, 'hide'); - if (!requestHide.defaultPrevented) { + const eventProceeded = this.emit('hide', { cancelable: true }); + if (eventProceeded) { this.hide = true; } } // 向上滚动 if (isScrollingUp && this.hide) { - const requestShow = emit(this, 'show'); - if (!requestShow.defaultPrevented) { + const eventProceeded = this.emit('show', { cancelable: true }); + if (eventProceeded) { this.hide = false; } } @@ -233,6 +234,14 @@ export class NavigationBar extends ScrollBehaviorMixin(LayoutItemBase) { } } +export interface NavigationBarEventMap { + change: CustomEvent; + show: CustomEvent; + shown: CustomEvent; + hide: CustomEvent; + hidden: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-navigation-bar': NavigationBar; diff --git a/packages/mdui/src/components/navigation-drawer/index.ts b/packages/mdui/src/components/navigation-drawer/index.ts index f3cc0fd3..227fcd60 100644 --- a/packages/mdui/src/components/navigation-drawer/index.ts +++ b/packages/mdui/src/components/navigation-drawer/index.ts @@ -11,7 +11,6 @@ import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { breakpoint } from '@mdui/shared/helpers/breakpoint.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { Modal } from '@mdui/shared/helpers/modal.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; @@ -48,7 +47,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-navigation-drawer') -export class NavigationDrawer extends LayoutItemBase { +export class NavigationDrawer extends LayoutItemBase { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -240,8 +239,8 @@ export class NavigationDrawer extends LayoutItemBase { } if (hasUpdated) { - const requestOpen = emit(this, 'open', { cancelable: true }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -323,12 +322,12 @@ export class NavigationDrawer extends LayoutItemBase { } if (hasUpdated) { - emit(this, 'opened'); + this.emit('opened'); } } else if (this.hasUpdated) { // 关闭 - const requestClose = emit(this, 'close', { cancelable: true }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -398,7 +397,7 @@ export class NavigationDrawer extends LayoutItemBase { setTimeout(() => trigger.focus()); } - emit(this, 'closed'); + this.emit('closed'); } } @@ -450,7 +449,7 @@ export class NavigationDrawer extends LayoutItemBase { } private onOverlayClick() { - emit(this, 'overlay-click'); + this.emit('overlay-click'); if (this.closeOnOverlayClick) { this.open = false; @@ -477,6 +476,14 @@ export class NavigationDrawer extends LayoutItemBase { } } +export interface NavigationDrawerEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; + 'overlay-click': CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-navigation-drawer': NavigationDrawer; diff --git a/packages/mdui/src/components/navigation-rail/navigation-rail-item.ts b/packages/mdui/src/components/navigation-rail/navigation-rail-item.ts index f05f874d..c86056c5 100644 --- a/packages/mdui/src/components/navigation-rail/navigation-rail-item.ts +++ b/packages/mdui/src/components/navigation-rail/navigation-rail-item.ts @@ -1,8 +1,9 @@ -import { html, LitElement, nothing } from 'lit'; +import { html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; import cc from 'classcat'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; @@ -47,8 +48,8 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-navigation-rail-item') export class NavigationRailItem extends AnchorMixin( - RippleMixin(FocusableMixin(LitElement)), -) { + RippleMixin(FocusableMixin(MduiElement)), +) { public static override styles: CSSResultGroup = [ componentStyle, navigationRailItemStyle, @@ -176,6 +177,11 @@ export class NavigationRailItem extends AnchorMixin( } } +export interface NavigationRailItemEventMap { + focus: FocusEvent; + blur: FocusEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-navigation-rail-item': NavigationRailItem; diff --git a/packages/mdui/src/components/navigation-rail/navigation-rail.ts b/packages/mdui/src/components/navigation-rail/navigation-rail.ts index 34ba3ca2..b6aab49c 100644 --- a/packages/mdui/src/components/navigation-rail/navigation-rail.ts +++ b/packages/mdui/src/components/navigation-rail/navigation-rail.ts @@ -13,7 +13,6 @@ import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { LayoutItemBase } from '../layout/layout-item-base.js'; import { navigationRailStyle } from './navigation-rail-style.js'; @@ -53,7 +52,7 @@ type NavigationRailItem = NavigationRailItemOriginal & { * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-navigation-rail') -export class NavigationRail extends LayoutItemBase { +export class NavigationRail extends LayoutItemBase { public static override styles: CSSResultGroup = [ componentStyle, navigationRailStyle, @@ -164,7 +163,7 @@ export class NavigationRail extends LayoutItemBase { this.value = item?.value; if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -296,6 +295,10 @@ export class NavigationRail extends LayoutItemBase { } } +export interface NavigationRailEventMap { + change: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-navigation-rail': NavigationRail; diff --git a/packages/mdui/src/components/radio/radio-group.ts b/packages/mdui/src/components/radio/radio-group.ts index 00698c72..bd8f7b69 100644 --- a/packages/mdui/src/components/radio/radio-group.ts +++ b/packages/mdui/src/components/radio/radio-group.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { createRef, ref } from 'lit/directives/ref.js'; @@ -6,13 +6,12 @@ import { $ } from '@mdui/jq/$.js'; import '@mdui/jq/methods/closest.js'; import '@mdui/jq/methods/find.js'; import '@mdui/jq/methods/get.js'; -import { isNodeName } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { radioGroupStyle } from './radio-group-style.js'; import type { Radio as RadioOriginal } from './radio.js'; @@ -44,7 +43,10 @@ type Radio = RadioOriginal & { * @slot - `` 元素 */ @customElement('mdui-radio-group') -export class RadioGroup extends LitElement implements FormControl { +export class RadioGroup + extends MduiElement + implements FormControl +{ public static override styles: CSSResultGroup = [ componentStyle, radioGroupStyle, @@ -141,8 +143,8 @@ export class RadioGroup extends LitElement implements FormControl { this.isInitial = false; await this.definedController.whenDefined(); - emit(this, 'input'); - emit(this, 'change'); + this.emit('input'); + this.emit('change'); this.updateItems(); this.updateRadioFocusable(); @@ -173,7 +175,7 @@ export class RadioGroup extends LitElement implements FormControl { const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -192,14 +194,14 @@ export class RadioGroup extends LitElement implements FormControl { this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - const requestInvalid = emit(this, 'invalid', { + const eventProceeded = this.emit('invalid', { bubbles: false, cancelable: true, composed: false, }); - // 调用了 preventDefault() 时,隐藏默认的表单错误提示 - if (requestInvalid.defaultPrevented) { + if (!eventProceeded) { + // 调用了 preventDefault() 时,隐藏默认的表单错误提示 this.inputRef.value!.blur(); this.inputRef.value!.focus(); } @@ -337,6 +339,12 @@ export class RadioGroup extends LitElement implements FormControl { } } +export interface RadioGroupEventMap { + change: CustomEvent; + input: CustomEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-radio-group': RadioGroup; diff --git a/packages/mdui/src/components/radio/radio.ts b/packages/mdui/src/components/radio/radio.ts index c7aed4bc..a6eee9d7 100644 --- a/packages/mdui/src/components/radio/radio.ts +++ b/packages/mdui/src/components/radio/radio.ts @@ -1,10 +1,10 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import '@mdui/shared/icons/circle.js'; import '@mdui/shared/icons/radio-button-unchecked.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -40,7 +40,9 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart label - 文本 */ @customElement('mdui-radio') -export class Radio extends RippleMixin(FocusableMixin(LitElement)) { +export class Radio extends RippleMixin( + FocusableMixin(MduiElement), +) { public static override styles: CSSResultGroup = [componentStyle, radioStyle]; /** @@ -124,7 +126,7 @@ export class Radio extends RippleMixin(FocusableMixin(LitElement)) { @watch('checked', true) private onCheckedChange() { - emit(this, 'change'); + this.emit('change'); } protected override firstUpdated(_changedProperties: PropertyValues) { @@ -173,6 +175,12 @@ export class Radio extends RippleMixin(FocusableMixin(LitElement)) { } } +export interface RadioEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-radio': Radio; diff --git a/packages/mdui/src/components/range-slider/index.ts b/packages/mdui/src/components/range-slider/index.ts index 8757e5e3..f8ad45b1 100644 --- a/packages/mdui/src/components/range-slider/index.ts +++ b/packages/mdui/src/components/range-slider/index.ts @@ -1,4 +1,4 @@ -import { html, PropertyValues } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { map } from 'lit/directives/map.js'; @@ -12,7 +12,7 @@ import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { SliderBase } from '../slider/slider-base.js'; import type { Ripple } from '../ripple/index.js'; import type { FormControl } from '@mdui/jq/shared/form.js'; -import type { CSSResultGroup, TemplateResult } from 'lit'; +import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit'; import type { Ref } from 'lit/directives/ref.js'; /** @@ -35,7 +35,10 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart tickmark - 刻度标记 */ @customElement('mdui-range-slider') -export class RangeSlider extends SliderBase implements FormControl { +export class RangeSlider + extends SliderBase + implements FormControl +{ public static override styles: CSSResultGroup = [SliderBase.styles]; /** @@ -289,6 +292,14 @@ export class RangeSlider extends SliderBase implements FormControl { } } +export interface RangeSliderEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + input: Event; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-range-slider': RangeSlider; diff --git a/packages/mdui/src/components/ripple/index.ts b/packages/mdui/src/components/ripple/index.ts index 5f263196..80a6bc8c 100644 --- a/packages/mdui/src/components/ripple/index.ts +++ b/packages/mdui/src/components/ripple/index.ts @@ -1,4 +1,4 @@ -import { LitElement, html } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; @@ -15,6 +15,7 @@ import '@mdui/jq/methods/offset.js'; import '@mdui/jq/methods/on.js'; import '@mdui/jq/methods/prependTo.js'; import '@mdui/jq/methods/remove.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { style } from './style.js'; @@ -28,7 +29,7 @@ import type { Ref } from 'lit/directives/ref.js'; * 阴影在 ripple-mixin 中处理,通过在 :host 元素上添加 attribute 供 CSS 选择器添加样式 */ @customElement('mdui-ripple') -export class Ripple extends LitElement { +export class Ripple extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -196,6 +197,8 @@ export class Ripple extends LitElement { } } +export interface RippleEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-ripple': Ripple; diff --git a/packages/mdui/src/components/ripple/ripple-mixin.ts b/packages/mdui/src/components/ripple/ripple-mixin.ts index 89ae7063..15859bf5 100644 --- a/packages/mdui/src/components/ripple/ripple-mixin.ts +++ b/packages/mdui/src/components/ripple/ripple-mixin.ts @@ -8,7 +8,7 @@ import type { Ripple } from './index.js'; import type { Constructor } from '@open-wc/dedupe-mixin'; import type { PropertyValues, LitElement } from 'lit'; -export declare class RippleMixinInterface extends LitElement { +export declare class RippleMixinInterface { public noRipple: boolean; protected getRippleIndex: () => number | undefined; protected get rippleElement(): Ripple | Ripple[] | NodeListOf; @@ -324,6 +324,5 @@ export const RippleMixin = >( } } - // @ts-ignore - return Mixin; + return Mixin as unknown as Constructor & T; }; diff --git a/packages/mdui/src/components/segmented-button/segmented-button-group.ts b/packages/mdui/src/components/segmented-button/segmented-button-group.ts index c22b70d9..e7ce28e7 100644 --- a/packages/mdui/src/components/segmented-button/segmented-button-group.ts +++ b/packages/mdui/src/components/segmented-button/segmented-button-group.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { map } from 'lit/directives/map.js'; @@ -8,13 +8,13 @@ import { $ } from '@mdui/jq/$.js'; import '@mdui/jq/methods/find.js'; import '@mdui/jq/methods/get.js'; import { isString } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { arraysEqualIgnoreOrder } from '@mdui/shared/helpers/array.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { segmentedButtonGroupStyle } from './segmented-button-group-style.js'; import type { SegmentedButton as SegmentedButtonOriginal } from './segmented-button.js'; @@ -48,7 +48,10 @@ type SegmentedButton = SegmentedButtonOriginal & { * @cssprop --shape-corner - 组件的圆角大小。可以指定一个具体的像素值;但更推荐[引用设计令牌](/docs/2/styles/design-tokens#shape-corner) */ @customElement('mdui-segmented-button-group') -export class SegmentedButtonGroup extends LitElement implements FormControl { +export class SegmentedButtonGroup + extends MduiElement + implements FormControl +{ public static override styles: CSSResultGroup = [ componentStyle, segmentedButtonGroupStyle, @@ -216,7 +219,7 @@ export class SegmentedButtonGroup extends LitElement implements FormControl { this.setValue(value); if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -296,7 +299,7 @@ export class SegmentedButtonGroup extends LitElement implements FormControl { const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -315,14 +318,14 @@ export class SegmentedButtonGroup extends LitElement implements FormControl { this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - const requestInvalid = emit(this, 'invalid', { + const eventProceeded = this.emit('invalid', { bubbles: false, cancelable: true, composed: false, }); - // 调用了 preventDefault() 时,隐藏默认的表单错误提示 - if (requestInvalid.defaultPrevented) { + if (!eventProceeded) { + // 调用了 preventDefault() 时,隐藏默认的表单错误提示 this.inputRef.value!.blur(); this.inputRef.value!.focus(); } @@ -490,6 +493,11 @@ export class SegmentedButtonGroup extends LitElement implements FormControl { } } +export interface SegmentedButtonGroupEventMap { + change: CustomEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-segmented-button-group': SegmentedButtonGroup; diff --git a/packages/mdui/src/components/segmented-button/segmented-button.ts b/packages/mdui/src/components/segmented-button/segmented-button.ts index 894ad23b..20e860c4 100644 --- a/packages/mdui/src/components/segmented-button/segmented-button.ts +++ b/packages/mdui/src/components/segmented-button/segmented-button.ts @@ -42,7 +42,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart loading - 加载中状态的 `` 元素 */ @customElement('mdui-segmented-button') -export class SegmentedButton extends ButtonBase { +export class SegmentedButton extends ButtonBase { public static override styles: CSSResultGroup = [ ButtonBase.styles, segmentedButtonStyle, @@ -201,6 +201,12 @@ export class SegmentedButton extends ButtonBase { } } +export interface SegmentedButtonEventMap { + focus: FocusEvent; + blur: FocusEvent; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-segmented-button': SegmentedButton; diff --git a/packages/mdui/src/components/select/index.ts b/packages/mdui/src/components/select/index.ts index a9722f4a..c7cb62f8 100644 --- a/packages/mdui/src/components/select/index.ts +++ b/packages/mdui/src/components/select/index.ts @@ -1,4 +1,4 @@ -import { html, LitElement, nothing, PropertyValues } from 'lit'; +import { html, nothing, PropertyValues } from 'lit'; import { customElement, property, @@ -10,12 +10,12 @@ import { map } from 'lit/directives/map.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; import { isString } from '@mdui/jq/shared/helper.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { FocusableMixin } from '@mdui/shared/mixins/focusable.js'; @@ -62,7 +62,10 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart menu - 下拉菜单,即 [``](/docs/2/components/menu) 元素 */ @customElement('mdui-select') -export class Select extends FocusableMixin(LitElement) implements FormControl { +export class Select + extends FocusableMixin(MduiElement) + implements FormControl +{ public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -316,7 +319,7 @@ export class Select extends FocusableMixin(LitElement) implements FormControl { const valid = this.hiddenInputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -335,7 +338,7 @@ export class Select extends FocusableMixin(LitElement) implements FormControl { this.invalid = !this.hiddenInputRef.value!.reportValidity(); if (this.invalid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -571,6 +574,14 @@ export class Select extends FocusableMixin(LitElement) implements FormControl { } } +export interface SelectEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + invalid: CustomEvent; + clear: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-select': Select; diff --git a/packages/mdui/src/components/slider/index.ts b/packages/mdui/src/components/slider/index.ts index 2e01111d..e76cdaff 100644 --- a/packages/mdui/src/components/slider/index.ts +++ b/packages/mdui/src/components/slider/index.ts @@ -36,7 +36,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart tickmark - 刻度标记 */ @customElement('mdui-slider') -export class Slider extends SliderBase implements FormControl { +export class Slider extends SliderBase implements FormControl { public static override styles: CSSResultGroup = [SliderBase.styles, style]; /** @@ -167,6 +167,14 @@ export class Slider extends SliderBase implements FormControl { } } +export interface SliderEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + input: Event; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-slider': Slider; diff --git a/packages/mdui/src/components/slider/slider-base.ts b/packages/mdui/src/components/slider/slider-base.ts index 02ae39ac..04df5700 100644 --- a/packages/mdui/src/components/slider/slider-base.ts +++ b/packages/mdui/src/components/slider/slider-base.ts @@ -1,11 +1,11 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { FocusableMixin } from '@mdui/shared/mixins/focusable.js'; import { RippleMixin } from '../ripple/ripple-mixin.js'; @@ -13,7 +13,7 @@ import { sliderBaseStyle } from './slider-base-style.js'; import type { CSSResultGroup, TemplateResult } from 'lit'; import type { Ref } from 'lit/directives/ref.js'; -export class SliderBase extends RippleMixin(FocusableMixin(LitElement)) { +export class SliderBase extends RippleMixin(FocusableMixin(MduiElement)) { public static override styles: CSSResultGroup = [ componentStyle, sliderBaseStyle, @@ -141,7 +141,8 @@ export class SliderBase extends RippleMixin(FocusableMixin(LitElement)) { const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + // @ts-ignore + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -160,14 +161,15 @@ export class SliderBase extends RippleMixin(FocusableMixin(LitElement)) { this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - const requestInvalid = emit(this, 'invalid', { + // @ts-ignore + const eventProceeded = this.emit('invalid', { bubbles: false, cancelable: true, composed: false, }); - // 调用了 preventDefault() 时,隐藏默认的表单错误提示 - if (requestInvalid.defaultPrevented) { + if (!eventProceeded) { + // 调用了 preventDefault() 时,隐藏默认的表单错误提示 this.blur(); this.focus(); } @@ -234,6 +236,7 @@ export class SliderBase extends RippleMixin(FocusableMixin(LitElement)) { } protected onChange() { - emit(this, 'change'); + // @ts-ignore + this.emit('change'); } } diff --git a/packages/mdui/src/components/snackbar/index.ts b/packages/mdui/src/components/snackbar/index.ts index 9c48004a..9eedbeaf 100644 --- a/packages/mdui/src/components/snackbar/index.ts +++ b/packages/mdui/src/components/snackbar/index.ts @@ -1,11 +1,11 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { when } from 'lit/directives/when.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { breakpoint } from '@mdui/shared/helpers/breakpoint.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import '@mdui/shared/icons/clear.js'; @@ -43,7 +43,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-snackbar') -export class Snackbar extends LitElement { +export class Snackbar extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -173,8 +173,8 @@ export class Snackbar extends LitElement { } if (hasUpdated) { - const requestOpen = emit(this, 'open', { cancelable: true }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -251,7 +251,7 @@ export class Snackbar extends LitElement { ]); if (hasUpdated) { - emit(this, 'opened'); + this.emit('opened'); } return; @@ -259,8 +259,8 @@ export class Snackbar extends LitElement { // 关闭 if (!this.open && this.hasUpdated) { - const requestClose = emit(this, 'close', { cancelable: true }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -307,7 +307,7 @@ export class Snackbar extends LitElement { ]); this.style.display = 'none'; - emit(this, 'closed'); + this.emit('closed'); return; } } @@ -380,7 +380,7 @@ export class Snackbar extends LitElement { private onActionClick(event: MouseEvent) { event.stopPropagation(); - emit(this, 'action-click'); + this.emit('action-click'); } private onCloseClick() { @@ -388,6 +388,14 @@ export class Snackbar extends LitElement { } } +export interface SnackbarEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; + 'action-click': CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-snackbar': Snackbar; diff --git a/packages/mdui/src/components/switch/index.ts b/packages/mdui/src/components/switch/index.ts index 2725d636..2ca144e2 100644 --- a/packages/mdui/src/components/switch/index.ts +++ b/packages/mdui/src/components/switch/index.ts @@ -1,15 +1,15 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { live } from 'lit/directives/live.js'; import { createRef, ref } from 'lit/directives/ref.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; import '@mdui/shared/icons/check.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -48,7 +48,7 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-switch') export class Switch - extends RippleMixin(FocusableMixin(LitElement)) + extends RippleMixin(FocusableMixin(MduiElement)) implements FormControl { public static override styles: CSSResultGroup = [componentStyle, style]; @@ -199,7 +199,7 @@ export class Switch const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -218,14 +218,14 @@ export class Switch this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - const requestInvalid = emit(this, 'invalid', { + const eventProceeded = this.emit('invalid', { bubbles: false, cancelable: true, composed: false, }); // 调用了 preventDefault() 时,隐藏默认的表单错误提示 - if (requestInvalid.defaultPrevented) { + if (!eventProceeded) { this.blur(); this.focus(); } @@ -297,10 +297,18 @@ export class Switch */ private onChange() { this.checked = this.inputRef.value!.checked; - emit(this, 'change'); + this.emit('change'); } } +export interface SwitchEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + input: Event; + invalid: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-switch': Switch; diff --git a/packages/mdui/src/components/tabs/tab-panel.ts b/packages/mdui/src/components/tabs/tab-panel.ts index 62045cba..23920e01 100644 --- a/packages/mdui/src/components/tabs/tab-panel.ts +++ b/packages/mdui/src/components/tabs/tab-panel.ts @@ -1,5 +1,6 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { tabPanelStyle } from './tab-panel-style.js'; @@ -23,7 +24,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit'; * @slot - 选项卡面板内容 */ @customElement('mdui-tab-panel') -export class TabPanel extends LitElement { +export class TabPanel extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, tabPanelStyle, @@ -50,6 +51,8 @@ export class TabPanel extends LitElement { } } +export interface TabPanelEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-tab-panel': TabPanel; diff --git a/packages/mdui/src/components/tabs/tab.ts b/packages/mdui/src/components/tabs/tab.ts index 700e08ba..562bbca7 100644 --- a/packages/mdui/src/components/tabs/tab.ts +++ b/packages/mdui/src/components/tabs/tab.ts @@ -1,8 +1,9 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; @@ -44,7 +45,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart label - 导航项的文本 */ @customElement('mdui-tab') -export class Tab extends RippleMixin(FocusableMixin(LitElement)) { +export class Tab extends RippleMixin(FocusableMixin(MduiElement)) { public static override styles: CSSResultGroup = [componentStyle, tabStyle]; /** @@ -147,6 +148,11 @@ export class Tab extends RippleMixin(FocusableMixin(LitElement)) { } } +export interface TabEventMap { + focus: FocusEvent; + blur: FocusEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-tab': Tab; diff --git a/packages/mdui/src/components/tabs/tabs.ts b/packages/mdui/src/components/tabs/tabs.ts index 59a1c47b..fd5e0ebe 100644 --- a/packages/mdui/src/components/tabs/tabs.ts +++ b/packages/mdui/src/components/tabs/tabs.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, @@ -12,10 +12,10 @@ import '@mdui/jq/methods/children.js'; import '@mdui/jq/methods/css.js'; import '@mdui/jq/methods/find.js'; import '@mdui/jq/methods/get.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { tabsStyle } from './tabs-style.js'; @@ -59,7 +59,7 @@ type TabPanel = TabPanelOriginal & { * @csspart indicator - 激活状态指示器 */ @customElement('mdui-tabs') -export class Tabs extends LitElement { +export class Tabs extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, tabsStyle]; /** @@ -158,7 +158,7 @@ export class Tabs extends LitElement { this.updateActive(); if (!this.isInitial) { - emit(this, 'change'); + this.emit('change'); } } @@ -313,6 +313,10 @@ export class Tabs extends LitElement { } } +export interface TabsEventMap { + change: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-tabs': Tabs; diff --git a/packages/mdui/src/components/text-field/index.ts b/packages/mdui/src/components/text-field/index.ts index 8a6d965f..2d64fd23 100644 --- a/packages/mdui/src/components/text-field/index.ts +++ b/packages/mdui/src/components/text-field/index.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; @@ -8,12 +8,12 @@ import { when } from 'lit/directives/when.js'; import { animate } from '@lit-labs/motion'; import { $ } from '@mdui/jq/$.js'; import '@mdui/jq/methods/css.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { FormController, formResets } from '@mdui/shared/controllers/form.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { defaultValue } from '@mdui/shared/decorators/default-value.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; import { nothingTemplate } from '@mdui/shared/helpers/template.js'; @@ -77,7 +77,7 @@ import type { Ref } from 'lit/directives/ref.js'; */ @customElement('mdui-text-field') export class TextField - extends FocusableMixin(LitElement) + extends FocusableMixin(MduiElement) implements FormControl { public static override styles: CSSResultGroup = [componentStyle, style]; @@ -678,8 +678,8 @@ export class TextField if (this.value !== this.inputRef.value!.value) { this.value = this.inputRef.value!.value; this.setTextareaHeight(); - emit(this, 'input'); - emit(this, 'change'); + this.emit('input'); + this.emit('change'); } } @@ -690,7 +690,7 @@ export class TextField const valid = this.inputRef.value!.checkValidity(); if (!valid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -709,7 +709,7 @@ export class TextField this.invalid = !this.inputRef.value!.reportValidity(); if (this.invalid) { - emit(this, 'invalid', { + this.emit('invalid', { bubbles: false, cancelable: true, composed: false, @@ -800,14 +800,14 @@ export class TextField if (this.isTextarea) { this.setTextareaHeight(); } - emit(this, 'change'); + this.emit('change'); } private onClear(event: MouseEvent) { this.value = ''; - emit(this, 'clear'); - emit(this, 'input'); - emit(this, 'change'); + this.emit('clear'); + this.emit('input'); + this.emit('change'); this.focus(); event.stopPropagation(); } @@ -817,7 +817,7 @@ export class TextField if (this.isTextarea) { this.setTextareaHeight(); } - emit(this, 'input'); + this.emit('input'); } private onInvalid(event: Event) { @@ -1082,6 +1082,15 @@ export class TextField } } +export interface TextFieldEventMap { + focus: FocusEvent; + blur: FocusEvent; + change: CustomEvent; + input: CustomEvent; + invalid: CustomEvent; + clear: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-text-field': TextField; diff --git a/packages/mdui/src/components/tooltip/index.ts b/packages/mdui/src/components/tooltip/index.ts index 416a6722..87a2a3a4 100644 --- a/packages/mdui/src/components/tooltip/index.ts +++ b/packages/mdui/src/components/tooltip/index.ts @@ -1,4 +1,4 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { createRef, ref } from 'lit/directives/ref.js'; import { when } from 'lit/directives/when.js'; @@ -8,13 +8,13 @@ import '@mdui/jq/methods/filter.js'; import '@mdui/jq/methods/height.js'; import '@mdui/jq/methods/prop.js'; import '@mdui/jq/methods/width.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { DefinedController } from '@mdui/shared/controllers/defined.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { HoverController } from '@mdui/shared/controllers/hover.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { animateTo, stopAnimations } from '@mdui/shared/helpers/animate.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { getDuration, getEasing } from '@mdui/shared/helpers/motion.js'; import { observeResize } from '@mdui/shared/helpers/observeResize.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -52,7 +52,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-tooltip') -export class Tooltip extends LitElement { +export class Tooltip extends MduiElement { public static override styles: CSSResultGroup = [componentStyle, style]; /** @@ -235,10 +235,8 @@ export class Tooltip extends LitElement { } if (hasUpdated) { - const requestOpen = emit(this, 'open', { - cancelable: true, - }); - if (requestOpen.defaultPrevented) { + const eventProceeded = this.emit('open', { cancelable: true }); + if (!eventProceeded) { return; } } @@ -256,7 +254,7 @@ export class Tooltip extends LitElement { ); if (hasUpdated) { - emit(this, 'opened'); + this.emit('opened'); } return; @@ -264,10 +262,8 @@ export class Tooltip extends LitElement { // 关闭 if (!this.open && hasUpdated) { - const requestClose = emit(this, 'close', { - cancelable: true, - }); - if (requestClose.defaultPrevented) { + const eventProceeded = this.emit('close', { cancelable: true }); + if (!eventProceeded) { return; } @@ -278,7 +274,7 @@ export class Tooltip extends LitElement { { duration, easing }, ); this.popupRef.value!.hidden = true; - emit(this, 'closed'); + this.emit('closed'); } } @@ -610,6 +606,13 @@ export class Tooltip extends LitElement { } } +export interface TooltipEventMap { + open: CustomEvent; + opened: CustomEvent; + close: CustomEvent; + closed: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-tooltip': Tooltip; diff --git a/packages/mdui/src/components/top-app-bar/top-app-bar-title.ts b/packages/mdui/src/components/top-app-bar/top-app-bar-title.ts index 856e9fcb..dc54a6f1 100644 --- a/packages/mdui/src/components/top-app-bar/top-app-bar-title.ts +++ b/packages/mdui/src/components/top-app-bar/top-app-bar-title.ts @@ -1,7 +1,8 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { createRef, ref } from 'lit/directives/ref.js'; +import { MduiElement } from '@mdui/shared/base/mdui-element.js'; import { HasSlotController } from '@mdui/shared/controllers/has-slot.js'; import { getInnerHtmlFromSlot } from '@mdui/shared/helpers/slot.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; @@ -28,7 +29,7 @@ import type { Ref } from 'lit/directives/ref.js'; * @csspart label-large 展开状态的文本内容 */ @customElement('mdui-top-app-bar-title') -export class TopAppBarTitle extends LitElement { +export class TopAppBarTitle extends MduiElement { public static override styles: CSSResultGroup = [ componentStyle, topAppBarTitleStyle, @@ -101,6 +102,8 @@ export class TopAppBarTitle extends LitElement { } } +export interface TopAppBarTitleEventMap {} + declare global { interface HTMLElementTagNameMap { 'mdui-top-app-bar-title': TopAppBarTitle; diff --git a/packages/mdui/src/components/top-app-bar/top-app-bar.ts b/packages/mdui/src/components/top-app-bar/top-app-bar.ts index 4599ab58..ba82685b 100644 --- a/packages/mdui/src/components/top-app-bar/top-app-bar.ts +++ b/packages/mdui/src/components/top-app-bar/top-app-bar.ts @@ -6,7 +6,6 @@ import { } from 'lit/decorators.js'; import { watch } from '@mdui/shared/decorators/watch.js'; import { booleanConverter } from '@mdui/shared/helpers/decorator.js'; -import { emit } from '@mdui/shared/helpers/event.js'; import { componentStyle } from '@mdui/shared/lit-styles/component-style.js'; import { ScrollBehaviorMixin } from '@mdui/shared/mixins/scrollBehavior.js'; import { LayoutItemBase } from '../layout/layout-item-base.js'; @@ -43,7 +42,9 @@ type TopAppBarTitle = { * @cssprop --z-index - 组件的 CSS 的 `z-index` 值 */ @customElement('mdui-top-app-bar') -export class TopAppBar extends ScrollBehaviorMixin(LayoutItemBase) { +export class TopAppBar extends ScrollBehaviorMixin( + LayoutItemBase, +) { public static override styles: CSSResultGroup = [ componentStyle, topAppBarStyle, @@ -154,7 +155,7 @@ export class TopAppBar extends ScrollBehaviorMixin(LayoutItemBase) { this.addEventListener('transitionend', (e: TransitionEvent) => { if (e.target === this) { - emit(this, this.hide ? 'hidden' : 'shown'); + this.emit(this.hide ? 'hidden' : 'shown'); } }); } @@ -190,16 +191,16 @@ export class TopAppBar extends ScrollBehaviorMixin(LayoutItemBase) { if (this.hasScrollBehavior('hide')) { // 向下滚动 if (!isScrollingUp && !this.hide) { - const requestHide = emit(this, 'hide'); - if (!requestHide.defaultPrevented) { + const eventProceeded = this.emit('hide', { cancelable: true }); + if (eventProceeded) { this.hide = true; } } // 向上滚动 if (isScrollingUp && this.hide) { - const requestShow = emit(this, 'show'); - if (!requestShow.defaultPrevented) { + const eventProceeded = this.emit('show', { cancelable: true }); + if (eventProceeded) { this.hide = false; } } @@ -207,6 +208,13 @@ export class TopAppBar extends ScrollBehaviorMixin(LayoutItemBase) { } } +export interface TopAppBarEventMap { + show: CustomEvent; + shown: CustomEvent; + hide: CustomEvent; + hidden: CustomEvent; +} + declare global { interface HTMLElementTagNameMap { 'mdui-top-app-bar': TopAppBar; diff --git a/packages/shared/package.json b/packages/shared/package.json index 0bc93c04..3c919872 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -4,6 +4,7 @@ "description": "mdui 项目的公共部分", "type": "module", "files": [ + "base", "controllers", "decorators", "helpers", diff --git a/packages/shared/src/base/mdui-element.ts b/packages/shared/src/base/mdui-element.ts new file mode 100644 index 00000000..f9398c9e --- /dev/null +++ b/packages/shared/src/base/mdui-element.ts @@ -0,0 +1,55 @@ +import { LitElement } from 'lit'; + +export type UnpackCustomEvent = T extends CustomEvent ? U : never; + +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging +export class MduiElement extends LitElement { + /** + * 触发自定义事件。若返回 false,表示事件被取消 + * @param type + * @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用 + */ + protected emit>( + type: K, + options?: CustomEventInit, + ): boolean { + const event = new CustomEvent( + type as string, + Object.assign( + { + bubbles: true, + cancelable: false, + composed: true, + detail: {}, + }, + options, + ), + ); + + return this.dispatchEvent(event); + } +} + +export interface MduiElement { + addEventListener( + type: K, + listener: (this: this, ev: M[K]) => unknown, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; + + removeEventListener( + type: K, + listener: (this: this, ev: M[K]) => unknown, + options?: boolean | EventListenerOptions, + ): void; + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions, + ): void; +} diff --git a/packages/shared/src/helpers/event.ts b/packages/shared/src/helpers/event.ts deleted file mode 100644 index 83b62a6d..00000000 --- a/packages/shared/src/helpers/event.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 触发自定义事件 - * @param element - * @param type - * @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用 - */ -export const emit = ( - element: HTMLElement, - type: string, - options?: CustomEventInit, -): CustomEvent => { - const event = new CustomEvent(type, { - bubbles: true, - cancelable: false, - composed: true, - detail: {}, - ...options, - }); - element.dispatchEvent(event); - - return event; -}; diff --git a/packages/shared/src/mixins/anchor.ts b/packages/shared/src/mixins/anchor.ts index a6d99250..f79a14af 100644 --- a/packages/shared/src/mixins/anchor.ts +++ b/packages/shared/src/mixins/anchor.ts @@ -18,7 +18,7 @@ type RenderAnchorOptions = { refDirective?: DirectiveResult; }; -export declare class AnchorMixinInterface extends LitElement { +export declare class AnchorMixinInterface { public href?: string; public download?: string; public target?: '_blank' | '_parent' | '_self' | '_top'; @@ -138,6 +138,5 @@ export const AnchorMixin = >( } } - // @ts-ignore - return AnchorMixinClass; + return AnchorMixinClass as unknown as Constructor & T; }; diff --git a/packages/shared/src/mixins/focusable.ts b/packages/shared/src/mixins/focusable.ts index bf92cc87..6c9468b9 100644 --- a/packages/shared/src/mixins/focusable.ts +++ b/packages/shared/src/mixins/focusable.ts @@ -20,14 +20,14 @@ document.addEventListener('keydown', () => { isClick = false; }); -export declare class FocusableMixinInterface extends LitElement { - public override autofocus: boolean; - public override tabIndex: number; +export declare class FocusableMixinInterface { + public autofocus: boolean; + public tabIndex: number; protected get focusDisabled(): boolean; protected get focusElement(): HTMLElement | null | undefined; - public override focus(options?: FocusOptions): void; - public override blur(): void; - public override click(): void; + public focus(options?: FocusOptions): void; + public blur(): void; + public click(): void; } /** @@ -292,6 +292,6 @@ export const FocusableMixin = >( } } - // @ts-ignore - return FocusableMixinClass; + return FocusableMixinClass as unknown as Constructor & + T; }; diff --git a/packages/shared/src/mixins/scrollBehavior.ts b/packages/shared/src/mixins/scrollBehavior.ts index 645ade75..89ee4c14 100644 --- a/packages/shared/src/mixins/scrollBehavior.ts +++ b/packages/shared/src/mixins/scrollBehavior.ts @@ -12,7 +12,7 @@ type ScrollBehavior = 'hide' | 'shrink' | 'elevate'; export type ScrollPaddingPosition = 'top' | 'bottom'; -export declare class ScrollBehaviorMixinInterface extends LitElement { +export declare class ScrollBehaviorMixinInterface { public scrollTarget?: string | HTMLElement | JQ; public scrollBehavior?: ScrollBehavior; public scrollThreshold?: number; @@ -290,6 +290,6 @@ export const ScrollBehaviorMixin = >( } } - // @ts-ignore - return ScrollBehaviorMixinClass; + return ScrollBehaviorMixinClass as unknown as Constructor & + T; };