From 46fddb1c1c148461798233af61627f5bb7cc1493 Mon Sep 17 00:00:00 2001 From: Anthony Wikkerink Date: Sun, 10 Nov 2024 17:13:10 -0500 Subject: [PATCH] Add template parameters to reset of mixins and common.d.ts --- components/paging/pageable-mixin.js | 8 ++++++-- .../paging/pageable-subscriber-mixin.js | 8 ++++++-- .../selection/selection-action-mixin.js | 8 ++++++-- components/selection/selection-mixin.js | 8 ++++++-- .../selection/selection-observer-mixin.js | 8 ++++++-- components/skeleton/skeleton-group-mixin.js | 14 +++++++++---- components/skeleton/skeleton-mixin.js | 14 +++++++++---- helpers/localize-core-element.js | 4 ++++ mixins/arrow-keys/arrow-keys-mixin.js | 8 ++++++-- .../async-container/async-container-mixin.js | 8 ++++++-- mixins/collection/collection-mixin.js | 8 ++++++-- mixins/focus/focus-mixin.js | 16 ++++++++++----- mixins/interactive/interactive-mixin.js | 8 ++++++-- mixins/labelled/labelled-mixin.js | 12 +++++++++-- .../loading-complete-mixin.js | 10 ++++++++-- mixins/localize/localize-mixin.js | 20 ++++++++++++++----- .../property-required-mixin.js | 16 ++++++++++----- mixins/provider/provider-mixin.js | 8 ++++++++ mixins/rtl/rtl-mixin.js | 15 +++++++++----- mixins/theme/theme-mixin.js | 3 +++ .../visible-on-ancestor-mixin.js | 8 ++++++-- typings/common.d.ts | 14 +++++++++++++ 22 files changed, 174 insertions(+), 52 deletions(-) create mode 100644 typings/common.d.ts diff --git a/components/paging/pageable-mixin.js b/components/paging/pageable-mixin.js index c74ead52ddf..ecc5bc9d8ae 100644 --- a/components/paging/pageable-mixin.js +++ b/components/paging/pageable-mixin.js @@ -2,6 +2,10 @@ import { CollectionMixin } from '../../mixins/collection/collection-mixin.js'; import { html } from 'lit'; import { SubscriberRegistryController } from '../../controllers/subscriber/subscriberControllers.js'; +/** + * @template {LitElementClassType} S + * @param {S} superclass + */ export const PageableMixin = superclass => class extends CollectionMixin(superclass) { static get properties() { @@ -10,8 +14,8 @@ export const PageableMixin = superclass => class extends CollectionMixin(supercl }; } - constructor() { - super(); + constructor(...args) { + super(...args); this._itemShowingCount = 0; this._pageableSubscriberRegistry = new SubscriberRegistryController(this, 'pageable', { diff --git a/components/paging/pageable-subscriber-mixin.js b/components/paging/pageable-subscriber-mixin.js index d76a12d55c6..440fc212551 100644 --- a/components/paging/pageable-subscriber-mixin.js +++ b/components/paging/pageable-subscriber-mixin.js @@ -1,5 +1,9 @@ import { EventSubscriberController, IdSubscriberController } from '../../controllers/subscriber/subscriberControllers.js'; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const PageableSubscriberMixin = superclass => class extends superclass { static get properties() { @@ -13,8 +17,8 @@ export const PageableSubscriberMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this._pageableInfo = null; this._pageableEventSubscriber = new EventSubscriberController(this, 'pageable'); diff --git a/components/selection/selection-action-mixin.js b/components/selection/selection-action-mixin.js index 7ea708c7f8e..e6c7547bd22 100644 --- a/components/selection/selection-action-mixin.js +++ b/components/selection/selection-action-mixin.js @@ -1,6 +1,10 @@ import { SelectionInfo } from './selection-mixin.js'; import { SelectionObserverMixin } from './selection-observer-mixin.js'; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const SelectionActionMixin = superclass => class extends SelectionObserverMixin(superclass) { static get properties() { @@ -13,8 +17,8 @@ export const SelectionActionMixin = superclass => class extends SelectionObserve }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.requiresSelection = false; } diff --git a/components/selection/selection-mixin.js b/components/selection/selection-mixin.js index fd626cfbda4..0631b561e5c 100644 --- a/components/selection/selection-mixin.js +++ b/components/selection/selection-mixin.js @@ -44,6 +44,10 @@ export class SelectionInfo { } +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const SelectionMixin = superclass => class extends RtlMixin(CollectionMixin(superclass)) { static get properties() { @@ -60,8 +64,8 @@ export const SelectionMixin = superclass => class extends RtlMixin(CollectionMix }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.selectionNoInputArrowKeyBehaviour = false; this.selectionSingle = false; this._selectAllPages = false; diff --git a/components/selection/selection-observer-mixin.js b/components/selection/selection-observer-mixin.js index daa7f46c501..ab7b38af9fa 100644 --- a/components/selection/selection-observer-mixin.js +++ b/components/selection/selection-observer-mixin.js @@ -1,6 +1,10 @@ import { cssEscape } from '../../helpers/dom.js'; import { SelectionInfo } from './selection-mixin.js'; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const SelectionObserverMixin = superclass => class extends superclass { static get properties() { @@ -20,8 +24,8 @@ export const SelectionObserverMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.selectionInfo = new SelectionInfo(); this._provider = null; } diff --git a/components/skeleton/skeleton-group-mixin.js b/components/skeleton/skeleton-group-mixin.js index 99621f02484..2d5e3c16b07 100644 --- a/components/skeleton/skeleton-group-mixin.js +++ b/components/skeleton/skeleton-group-mixin.js @@ -2,7 +2,11 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin'; import { SkeletonMixin } from './skeleton-mixin.js'; import { SubscriberRegistryController } from '../../controllers/subscriber/subscriberControllers.js'; -export const SkeletonGroupMixin = dedupeMixin(superclass => class extends SkeletonMixin(superclass) { +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ +const InternalSkeletonGroupMixin = superclass => class extends SkeletonMixin(superclass) { static get properties() { return { @@ -10,8 +14,8 @@ export const SkeletonGroupMixin = dedupeMixin(superclass => class extends Skelet }; } - constructor() { - super(); + constructor(...args) { + super(...args); this._anySubscribersWithSkeletonActive = false; this._skeletonSubscribers = new SubscriberRegistryController(this, 'skeleton', { onSubscribe: this.onSubscriberChange.bind(this), @@ -46,4 +50,6 @@ export const SkeletonGroupMixin = dedupeMixin(superclass => class extends Skelet this._parentSkeleton?.registry?.onSubscriberChange(); } -}); +}; + +export const SkeletonGroupMixin = dedupeMixin(InternalSkeletonGroupMixin); diff --git a/components/skeleton/skeleton-mixin.js b/components/skeleton/skeleton-mixin.js index 29c0dbf5e96..0ac5e9acd08 100644 --- a/components/skeleton/skeleton-mixin.js +++ b/components/skeleton/skeleton-mixin.js @@ -148,7 +148,11 @@ export const skeletonStyles = css` } `; -export const SkeletonMixin = dedupeMixin(superclass => class extends RtlMixin(superclass) { +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ +const InternalSkeletonMixin = superclass => class extends RtlMixin(superclass) { static get properties() { return { @@ -166,8 +170,8 @@ export const SkeletonMixin = dedupeMixin(superclass => class extends RtlMixin(su return styles; } - constructor() { - super(); + constructor(...args) { + super(...args); this._skeletonSetByParent = false; this._skeletonSetExplicitly = false; this._skeletonActive = false; @@ -217,4 +221,6 @@ export const SkeletonMixin = dedupeMixin(superclass => class extends RtlMixin(su this.requestUpdate('skeleton', this._skeletonSetExplicitly); } -}); +}; + +export const SkeletonMixin = dedupeMixin(InternalSkeletonMixin); diff --git a/helpers/localize-core-element.js b/helpers/localize-core-element.js index b349be2b7a3..936eeed1e36 100644 --- a/helpers/localize-core-element.js +++ b/helpers/localize-core-element.js @@ -1,5 +1,9 @@ import { LocalizeMixin } from '../mixins/localize/localize-mixin.js'; +/** + * @template {LitElementConstructor} S + * @param {S} superclass + */ export const LocalizeCoreElement = superclass => class extends LocalizeMixin(superclass) { static get localizeConfig() { diff --git a/mixins/arrow-keys/arrow-keys-mixin.js b/mixins/arrow-keys/arrow-keys-mixin.js index 2a8ea960e05..c40b68f3436 100644 --- a/mixins/arrow-keys/arrow-keys-mixin.js +++ b/mixins/arrow-keys/arrow-keys-mixin.js @@ -9,6 +9,10 @@ const keyCodes = Object.freeze({ DOWN: 40, }); +/** + * @template {LitElementClassType} S + * @param {S} superclass + */ export const ArrowKeysMixin = superclass => class extends superclass { static get properties() { @@ -24,8 +28,8 @@ export const ArrowKeysMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.arrowKeysDirection = 'leftright'; this.arrowKeysNoWrap = false; } diff --git a/mixins/async-container/async-container-mixin.js b/mixins/async-container/async-container-mixin.js index cd3104db9cd..01551b5fa82 100644 --- a/mixins/async-container/async-container-mixin.js +++ b/mixins/async-container/async-container-mixin.js @@ -5,6 +5,10 @@ export const asyncStates = { complete: 'complete' }; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const AsyncContainerMixin = superclass => class extends superclass { static get properties() { @@ -20,8 +24,8 @@ export const AsyncContainerMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this._initializeAsyncState(); this.asyncPendingDelay = 0; this._handleAsyncItemState = this._handleAsyncItemState.bind(this); diff --git a/mixins/collection/collection-mixin.js b/mixins/collection/collection-mixin.js index 53c722a5dc9..2d0f1471801 100644 --- a/mixins/collection/collection-mixin.js +++ b/mixins/collection/collection-mixin.js @@ -1,3 +1,7 @@ +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const CollectionMixin = superclass => class extends superclass { static get properties() { @@ -10,8 +14,8 @@ export const CollectionMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.itemCount = null; } diff --git a/mixins/focus/focus-mixin.js b/mixins/focus/focus-mixin.js index dcad09348d1..2b87115b89b 100644 --- a/mixins/focus/focus-mixin.js +++ b/mixins/focus/focus-mixin.js @@ -1,9 +1,13 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin'; -export const FocusMixin = dedupeMixin(superclass => class extends superclass { - - constructor() { - super(); +/** + * @template {ReactiveElementConstructor} S + * @param {S} superclass + */ +export const InternalFocusMixin = superclass => class extends superclass { + + constructor(...args) { + super(...args); this._focusOnFirstRender = false; } @@ -40,4 +44,6 @@ export const FocusMixin = dedupeMixin(superclass => class extends superclass { } -}); +}; + +export const FocusMixin = dedupeMixin(InternalFocusMixin); diff --git a/mixins/interactive/interactive-mixin.js b/mixins/interactive/interactive-mixin.js index b263e99a2da..3ca71d0516d 100644 --- a/mixins/interactive/interactive-mixin.js +++ b/mixins/interactive/interactive-mixin.js @@ -15,6 +15,10 @@ export function isInteractiveDescendant(node) { }); } +/** + * @template {LitElementClassType} S + * @param {S} superclass + */ export const InteractiveMixin = superclass => class extends LocalizeCoreElement(RtlMixin(superclass)) { static get properties() { @@ -35,8 +39,8 @@ export const InteractiveMixin = superclass => class extends LocalizeCoreElement( `]; } - constructor() { - super(); + constructor(...args) { + super(...args); this._dismissibleId = null; this._focusingToggle = false; this._hasInteractiveAncestor = false; diff --git a/mixins/labelled/labelled-mixin.js b/mixins/labelled/labelled-mixin.js index a84712008aa..7eb09cd0c4d 100644 --- a/mixins/labelled/labelled-mixin.js +++ b/mixins/labelled/labelled-mixin.js @@ -46,6 +46,10 @@ const waitForElement = async(contextElement, selector, timeout) => { }); }; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const LabelMixin = superclass => class extends superclass { static get properties() { @@ -75,6 +79,10 @@ export const LabelMixin = superclass => class extends superclass { }; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const LabelledMixin = superclass => class extends PropertyRequiredMixin(superclass) { static get properties() { @@ -105,8 +113,8 @@ export const LabelledMixin = superclass => class extends PropertyRequiredMixin(s }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.labelRequired = true; this._labelElem = null; this._missingLabelErrorHasBeenThrown = false; diff --git a/mixins/loading-complete/loading-complete-mixin.js b/mixins/loading-complete/loading-complete-mixin.js index 9f147dd56df..d2f6dcce6ae 100644 --- a/mixins/loading-complete/loading-complete-mixin.js +++ b/mixins/loading-complete/loading-complete-mixin.js @@ -1,6 +1,10 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin'; -export const LoadingCompleteMixin = dedupeMixin((superclass) => class extends superclass { +/** + * @template {ReactiveElementConstructor & (new (...args: any[]) => { getLoadingComplete?(): Promise })} S + * @param {S} superclass + */ +export const InternalLoadingCompleteMixin = (superclass) => class extends superclass { get loadingComplete() { return this.getLoadingComplete(); } @@ -25,4 +29,6 @@ export const LoadingCompleteMixin = dedupeMixin((superclass) => class extends su ? new Promise(resolve => this.#loadingCompleteResolve = resolve) : Promise.resolve(); -}); +}; + +export const LoadingCompleteMixin = dedupeMixin(InternalLoadingCompleteMixin); diff --git a/mixins/localize/localize-mixin.js b/mixins/localize/localize-mixin.js index fc4e5aa4aa7..3876658e749 100644 --- a/mixins/localize/localize-mixin.js +++ b/mixins/localize/localize-mixin.js @@ -3,10 +3,14 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin'; import { html } from 'lit'; import { ifDefined } from 'lit/directives/if-defined.js'; -export const _LocalizeMixinBase = dedupeMixin(superclass => class LocalizeMixinBaseClass extends getLocalizeClass(superclass) { - - constructor() { - super(); +/** + * @template {LitElementConstructor} S + * @param {S} superclass + */ +const _InternalLocalizeMixinBase = superclass => class LocalizeMixinBaseClass extends getLocalizeClass(superclass) { + + constructor(...args) { + super(...args); super.constructor.setLocalizeMarkup(localizeMarkup); } @@ -63,8 +67,14 @@ export const _LocalizeMixinBase = dedupeMixin(superclass => class LocalizeMixinB #updatedProperties = new Map(); -}); +}; + +export const _LocalizeMixinBase = dedupeMixin(_InternalLocalizeMixinBase); +/** + * @template {LitElementConstructor} S + * @param {S} superclass + */ export const LocalizeMixin = superclass => class extends _LocalizeMixinBase(superclass) { static getLocalizeResources() { diff --git a/mixins/property-required/property-required-mixin.js b/mixins/property-required/property-required-mixin.js index 18e7176d1d8..8f29d7bbb77 100644 --- a/mixins/property-required/property-required-mixin.js +++ b/mixins/property-required/property-required-mixin.js @@ -22,10 +22,14 @@ export function createInvalidPropertyTypeMessage(elem, propertyName) { ); } -export const PropertyRequiredMixin = dedupeMixin(superclass => class extends superclass { - - constructor() { - super(); +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ +const InternalPropertyRequiredMixin = superclass => class extends superclass { + + constructor(...args) { + super(...args); this._requiredProperties = new Map(); this._initProperties(Object.getPrototypeOf(this)); } @@ -115,4 +119,6 @@ export const PropertyRequiredMixin = dedupeMixin(superclass => class extends sup info.timeout = setTimeout(() => this._flushRequiredPropertyError(name), TIMEOUT_DURATION); } -}); +}; + +export const PropertyRequiredMixin = dedupeMixin(InternalPropertyRequiredMixin); diff --git a/mixins/provider/provider-mixin.js b/mixins/provider/provider-mixin.js index c748982da83..4061a7db57a 100644 --- a/mixins/provider/provider-mixin.js +++ b/mixins/provider/provider-mixin.js @@ -29,6 +29,10 @@ export function provideInstance(node, key, obj) { node._providerInstances.set(key, obj); } +/** + * @template {CustomElementConstructor} S + * @param {S} superclass + */ export const ProviderMixin = superclass => class extends superclass { provideInstance(key, obj) { provideInstance(this, key, obj); @@ -46,6 +50,10 @@ export function requestInstance(node, key) { return event.detail.instance; } +/** + * @template {CustomElementConstructor} S + * @param {S} superclass + */ export const RequesterMixin = superclass => class extends superclass { requestInstance(key) { return requestInstance(this, key); diff --git a/mixins/rtl/rtl-mixin.js b/mixins/rtl/rtl-mixin.js index eb4593c7a65..ad7ec210b77 100644 --- a/mixins/rtl/rtl-mixin.js +++ b/mixins/rtl/rtl-mixin.js @@ -1,8 +1,11 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin'; import { getDocumentLocaleSettings } from '@brightspace-ui/intl/lib/common.js'; -export const RtlMixin = dedupeMixin(superclass => class extends superclass { - +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ +const InternalRtlMixin = superclass => class extends superclass { static get properties() { return { /** @@ -13,8 +16,8 @@ export const RtlMixin = dedupeMixin(superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this._localeSettings = getDocumentLocaleSettings(); this._handleLanguageChange = this._handleLanguageChange.bind(this); this._handleLanguageChange(); @@ -38,4 +41,6 @@ export const RtlMixin = dedupeMixin(superclass => class extends superclass { } } -}); +}; + +export const RtlMixin = dedupeMixin(InternalRtlMixin); diff --git a/mixins/theme/theme-mixin.js b/mixins/theme/theme-mixin.js index 4d993740322..fbfeb22089c 100644 --- a/mixins/theme/theme-mixin.js +++ b/mixins/theme/theme-mixin.js @@ -4,6 +4,9 @@ * "theme" attribute could resolve automatically based on the user's * OS preference. For now, it's only used in menus/dropdowns by * the media player. + * + * @template {ReactiveElementClassType} S + * @param {S} superclass */ export const ThemeMixin = superclass => class extends superclass { diff --git a/mixins/visible-on-ancestor/visible-on-ancestor-mixin.js b/mixins/visible-on-ancestor/visible-on-ancestor-mixin.js index 11e3493a664..550208c11df 100644 --- a/mixins/visible-on-ancestor/visible-on-ancestor-mixin.js +++ b/mixins/visible-on-ancestor/visible-on-ancestor-mixin.js @@ -41,6 +41,10 @@ export const visibleOnAncestorStyles = css` `; +/** + * @template {ReactiveElementClassType} S + * @param {S} superclass + */ export const VisibleOnAncestorMixin = superclass => class extends superclass { static get properties() { @@ -57,8 +61,8 @@ export const VisibleOnAncestorMixin = superclass => class extends superclass { }; } - constructor() { - super(); + constructor(...args) { + super(...args); this.animationType = 'opacity-transform'; this.visibleOnAncestor = false; diff --git a/typings/common.d.ts b/typings/common.d.ts new file mode 100644 index 00000000000..9741edda0d1 --- /dev/null +++ b/typings/common.d.ts @@ -0,0 +1,14 @@ +import { Constructor } from '@open-wc/dedupe-mixin'; +import { LitElement, ReactiveElement } from 'lit'; + +declare global { + // Used for mixins that use lit-html but don't set properties or styles + type LitElementConstructor = Constructor; + // Used for mixins that use lit-html and set properties or styles + type LitElementClassType = LitElementConstructor & Pick; + + // Used for mixins that use reactive element properties (updated, willUpdate, firstUpdated, connectedCallback, etc) but don't set properties or styles + type ReactiveElementConstructor = Constructor; + // Used for mixins that use reactive element properties (updated, willUpdate, firstUpdated, connectedCallback, etc) and set properties or styles + type ReactiveElementClassType = ReactiveElementConstructor & Pick; +} \ No newline at end of file