lit / rfcs

RFCs for changes to Lit
BSD 3-Clause "New" or "Revised" License
15 stars 10 forks source link

[RRFC] Add first-class support for observables/signals in lit-html #12

Open willmartian opened 1 year ago

willmartian commented 1 year ago

Motivation

Given the prevalence of subscribable reactive primitives in front-end development (such as RxJS Observables and Preact Signals), it would be win for developer experience and interop if lit-html supported binding to them directly without needing to use a custom Async Directive.

Example

These examples are live here.

RxJS

import { interval } from 'rxjs';

html`<div>${inverval(1000)}</div>`

Preact Signals

import { signal } from '@preact/signals-core';

const count$ = signal(0);
html`<input type="button" value=${count$} @click=${() => count$.value += 1}>`

How

The above examples use a naive implementation found here: https://github.com/willmartian/lit-signals

It works by utilizing an ObserveDirective, identical to the example in the Async Directive docs.

Any subscribable objects are automatically wrapped in the directive:

import { html as _html } from "lit-html";
import { observe } from "./ObserveDirective";

export const html = (strings: TemplateStringsArray, ...values: unknown[]) => {
   return _html(strings, ...values.map(
       val => isSubscribable(val) ? observe(val) : val)
   );
}

const isSubscribable = (value: any): value is Subscribable<unknown> => {
   return 'subscribe' in value && typeof value.subscribe === 'function';
}

I am sure there is a more nuanced way to actually implement this, but my assumption is that this is a fairly light weight addition.

Current Behavior

The current behavior requires the developer to wrap wrap any subscribable values in a custom Async Directive.

html`<div>${observe(observable)}</div>`

Desired Behavior

html`<div>${observable}</div>`

References

JosefJezek commented 10 months ago

FYI

augustjk commented 5 months ago

The @lit-labs/preact-signals package has since been published which includes an html tag function that auto wraps signals with directives.

klauss194 commented 2 months ago

What about observables ?