lit / lit-element

LEGACY REPO. This repository is for maintenance of the legacy LitElement library. The LitElement base class is now part of the Lit library, which is developed in the lit monorepo.
https://lit-element.polymer-project.org
BSD 3-Clause "New" or "Revised" License
4.49k stars 319 forks source link

Support for contexts? #1182

Closed mcjazzyfunky closed 2 years ago

mcjazzyfunky commented 3 years ago

Remark: I haven't found a lot of conversation about "context support in lit-element" - just https://github.com/Polymer/lit-element/issues/46 and this seems quite old.

Description

If you develop a non-trivial component suite with React, very often it's necessary that you not just export the components themselves but also the context objects that are needed for those components (at least if you do not wrap all those context objects in custom hooks and special components). Means: Those context objects are a very important part of your published component suite.

Any plans/chance that lit-element will provide out-of-the-box support for contexts in near future too? Of course, something like this is doable in userland, but then everybody has her own solution and for each solution you may need some special adapters or whatever, which would be (and actually currently is) quite annoying. A de facto standard would be much, much, much, much better.

Of course the base context API should be framework agnostic, so that the core types/interfaces of that context API could also be used outside of the lit-element world.

Frankly, I currently have no idea whether such a context API could be implemented performant for SSR.

If this topic may be of interest please find here some more details

```ts // One of many possible context APIs // framework agnostic // maybe an additional readonly property `uuid` would also be useful type Context = { readonly kind: 'context', readonly defaultValue: T } // framwork agnostic function createContext(defaultValue: T): Context { return Object.freeze({ kind: 'context', defaultValue }) } // framework agnostic function createProvider(): CustomElementConstructor { .... } // Here just for example a @context decorator to handle the // context value injections. Of course this could be also handled // in a completely different non-decorator-based way. // More infos about that decorator will follow in the example below. // Not framework agnostic! function context(...) { ... } /************************************* * Here's a little example * *************************************/ enum Theme { Light = 'light', Dark = 'dark' } const ThemeCtx = createContext(Theme.Light) const ThemeProvider = createProvider(ThemeCtx) customElements.define('theme-provider', ThemeProvider) @customElement('theme-info') class ThemeInfo extends LitElement { @context(ThemeCtx) private theme = ThemeCtx.defaultValue render() { return html`

Current theme: ${this.theme}
` } } const output = html`

Context demo

` ```

Find here some remarks on how the context API of the web component library `haunted` could be transferred to a framework agnostic API


Please find here the important parts of the context API in `haunted`: Link The most important part is this (please be aware that nothing is framework agnostic here): ```ts const contextEvent = 'haunted.context'; interface Context { Provider: ComponentConstructor<{}>; Consumer: ComponentConstructor>; defaultValue: T; } interface ContextDetail { Context: Context; callback: (value: T) => void; // These properties will not exist if a context consumer lacks a provider value: T; unsubscribe?: (this: Context) => void; } ``` A framework agnostic variant of that could for example look as follows: ```ts const contextEvent = 'component.context'; type Context = { readonly kind: 'context', readonly defaultValue: T } type ContextDetail = { readonly context: Context readonly callback: (newValue: T) => void readonly cancelled: Promise } ```

Acceptance criteria

thepassle commented 3 years ago

There's been a bunch of discussion on context here

sorvell commented 2 years ago

Closing this issue since there's an active PR where this is being developed and refined. Please feel free to kick the tires on that and post feedback. Thanks!