Skip to content

Instantly share code, notes, and snippets.

@dliebner
Created November 10, 2023 16:56
Show Gist options
  • Save dliebner/5d3a85b00744c28d3efb2912a228ec18 to your computer and use it in GitHub Desktop.
Save dliebner/5d3a85b00744c28d3efb2912a228ec18 to your computer and use it in GitHub Desktop.
preact signal reactivity mixin for Lit elements
/** Credit to @justinfagnani for the original implementation */
import type {ReactiveElement} from 'lit';
import {signal, effect} from '@preact/signals-core';
type ReactiveElementConstructor = new (...args: any[]) => ReactiveElement;
export function SignalWatcher<T extends ReactiveElementConstructor>(
Base: T
): T {
// Return Base class if it's already a SignalWatcher
if( 'isSignalWatcherClass' in Base && Base.isSignalWatcherClass ) return Base;
// Return extended Base class
return class SignalWatcher extends Base {
private __disposeEffect?: () => void;
static isSignalWatcherClass = true;
performUpdate() {
if (!this.isUpdatePending) {
return;
}
this.__disposeEffect?.();
this.__disposeEffect = effect(() => {
this.isUpdatePending = true;
super.performUpdate();
});
}
disconnectedCallback() {
this.__disposeEffect?.();
this.__disposeEffect = undefined;
super.disconnectedCallback();
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment