A powerful and lightweight context provider and consumer system for Lit Elements, enabling efficient state sharing across component hierarchies without prop drilling.
npm install @arcmantle/lit-context
# or
pnpm add @arcmantle/lit-context
# or
yarn add @arcmantle/lit-context
Provider Component:
import { LitElement, html } from 'lit';
import { provide } from '@arcmantle/lit-context';
class MyProvider extends LitElement {
@provide() theme = 'dark';
@provide() user = { name: 'John', id: 1 };
render() {
return html`
<div>
<h1>My App</h1>
<slot></slot>
</div>
`;
}
}
Consumer Component:
import { LitElement, html } from 'lit';
import { consume, type ContextProp } from '@arcmantle/lit-context';
class MyConsumer extends LitElement {
@consume() theme: ContextProp<string>;
@consume() user: ContextProp<{ name: string; id: number }>;
render() {
return html`
<div class="theme-${this.theme?.value}">
<p>Hello, ${this.user?.value?.name}!</p>
<button @click=${() => this.theme.value = 'light'}>
Switch Theme
</button>
</div>
`;
}
}
import { LitElement, html } from 'lit';
import { ContextProvider } from '@arcmantle/lit-context';
// Register the context provider component
ContextProvider.register();
class MyApp extends LitElement {
private context = {
theme: 'dark',
user: { name: 'John', id: 1 }
};
render() {
return html`
<context-provider .context=${this.context}>
<my-consumer></my-consumer>
<my-other-consumer></my-other-consumer>
</context-provider>
`;
}
}
@provide(name?: string)Marks a property as a context provider. The property will be available to all child components that consume the same context.
Parameters:
name (optional): Custom name for the context. If not provided, uses the property name.Example:
class Provider extends LitElement {
@provide() myValue = 'hello';
@provide('customName') anotherValue = 42;
}
@consume(name?: string)Marks a property as a context consumer. The property will receive updates from the nearest parent provider.
Parameters:
name (optional): Custom name for the context to consume. If not provided, uses the property name.Returns: ContextProp<T> - An object with a value property for getting/setting the context value.
Example:
class Consumer extends LitElement {
@consume() myValue: ContextProp<string>;
@consume('customName') anotherValue: ContextProp<number>;
someMethod() {
console.log(this.myValue.value); // 'hello'
this.myValue.value = 'updated'; // Updates the provider
}
}
ContextProviderA Lit element that provides context to its children.
Properties:
context: Record<string, any> - Object containing all context valuesMethods:
static register(): Registers the component as a custom elementExample:
import { ContextProvider } from '@arcmantle/lit-context';
ContextProvider.register();
// Now you can use <context-provider> in your templates
ContextProp<T>Interface for context properties in consumer components.
interface ContextProp<T = any> {
value: T;
}
ConsumeContextEvent<T>Custom event type used internally for context communication.
type ConsumeContextEvent<T = any> = CustomEvent<{ prop: { value: T; }; }>;
You can use named contexts to avoid conflicts when multiple providers offer the same property name:
class ThemeProvider extends LitElement {
@provide('app-theme') theme = 'dark';
}
class ThemeConsumer extends LitElement {
@consume('app-theme') theme: ContextProp<string>;
}
Context providers can be nested, with inner providers taking precedence:
html`
<outer-provider>
<!-- theme from outer-provider -->
<consumer-one></consumer-one>
<inner-provider>
<!-- theme from inner-provider -->
<consumer-two></consumer-two>
</inner-provider>
</outer-provider>
`
Context values are reactive and will automatically trigger updates in consuming components:
class Provider extends LitElement {
@provide() counter = 0;
increment() {
this.counter++; // All consumers will update automatically
}
}
class Consumer extends LitElement {
@consume() counter: ContextProp<number>;
render() {
return html`
<p>Count: ${this.counter?.value}</p>
<button @click=${() => this.counter.value++}>
Increment from consumer
</button>
`;
}
}
This library supports all modern browsers that support:
# Install dependencies
pnpm install
# Run development server with demo
pnpm dev
# Build the library
pnpm build
Apache-2.0
Contributions are welcome! Please feel free to submit issues and pull requests.