mirror of
https://github.com/material-components/material-web.git
synced 2026-03-09 00:09:23 +08:00
- **BREAKING:BUILD** underlying Lit 1 libraries updated to Lit 2 - This may break certain builds that are transitively relying on Lit 1 - If your Lit 1 components break due to this, make sure your `package.json` explicitly includes the latest Lit 1 versions of lit-html and lit-element or deduplicate your versions of Lit 1 with your bundler PiperOrigin-RevId: 396468826
65 lines
2.4 KiB
TypeScript
65 lines
2.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2018 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
// Style preference for leading underscores.
|
|
// tslint:disable:strip-private-property-underscore
|
|
// tslint:disable:no-any
|
|
|
|
import {PropertyValues, ReactiveElement} from '@lit/reactive-element';
|
|
|
|
/**
|
|
* Observer function type.
|
|
*/
|
|
export interface Observer {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
(value: any, old: any): void;
|
|
}
|
|
|
|
type ReactiveElementClass = typeof ReactiveElement;
|
|
interface ReactiveElementClassWithObservers extends ReactiveElementClass {
|
|
// tslint:disable-next-line:enforce-name-casing
|
|
_observers: Map<PropertyKey, Observer>;
|
|
}
|
|
|
|
/**
|
|
* Specifies an observer callback that is run when the decorated property
|
|
* changes. The observer receives the current and old value as arguments.
|
|
*/
|
|
export const observer = (observer: Observer) =>
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
(proto: any, propName: PropertyKey) => {
|
|
// if we haven't wrapped `updated` in this class, do so
|
|
if (!(proto.constructor as ReactiveElementClassWithObservers)
|
|
._observers) {
|
|
proto.constructor._observers = new Map<PropertyKey, Observer>();
|
|
const userUpdated = proto.updated;
|
|
proto.updated = function(
|
|
this: ReactiveElement, changedProperties: PropertyValues) {
|
|
userUpdated.call(this, changedProperties);
|
|
changedProperties.forEach((v, k) => {
|
|
const observers =
|
|
(this.constructor as ReactiveElementClassWithObservers)
|
|
._observers;
|
|
const observer = observers.get(k);
|
|
if (observer !== undefined) {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
observer.call(this, (this as any)[k], v);
|
|
}
|
|
});
|
|
};
|
|
// clone any existing observers (superclasses)
|
|
// eslint-disable-next-line no-prototype-builtins
|
|
} else if (!proto.constructor.hasOwnProperty('_observers')) {
|
|
const observers = proto.constructor._observers;
|
|
proto.constructor._observers = new Map();
|
|
observers.forEach(
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
(v: any, k: PropertyKey) => proto.constructor._observers.set(k, v));
|
|
}
|
|
// set this method
|
|
proto.constructor._observers.set(propName, observer);
|
|
};
|