@arcmantle/lit-context
    Preparing search index...

    @arcmantle/lit-context

    @arcmantle/lit-context

    A powerful and lightweight context provider and consumer system for Lit Elements, enabling efficient state sharing across component hierarchies without prop drilling.

    • 🚀 Easy to use: Simple decorators for providing and consuming context
    • 🎯 Type-safe: Full TypeScript support with proper type inference
    • âš¡ Performant: Efficient event-based communication system
    • 🔄 Reactive: Automatic updates when context values change
    • 🌳 Flexible: Works with both decorator-based and component-based approaches
    • 📦 Lightweight: Minimal bundle size with zero external dependencies (except Lit)
    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>
    `;
    }
    }

    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;
    }

    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
    }
    }

    A Lit element that provides context to its children.

    Properties:

    • context: Record<string, any> - Object containing all context values

    Methods:

    • static register(): Registers the component as a custom element

    Example:

    import { ContextProvider } from '@arcmantle/lit-context';

    ContextProvider.register();

    // Now you can use <context-provider> in your templates

    Interface for context properties in consumer components.

    interface ContextProp<T = any> {
    value: 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>
    `;
    }
    }
    • Context updates use an efficient event-based system
    • Only consumers that actually use a changed context value will re-render
    • The library automatically manages event listeners and cleanup
    • Minimal overhead with lazy controller initialization

    This library supports all modern browsers that support:

    • ES2017+ (async/await, etc.)
    • Custom Elements v1
    • ES Modules
    # 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.