@holochain-open-dev/context

Helpers and controllers for using Context protocol, ported from @lit-labs/context

Usage no npm install needed!

<script type="module">
  import holochainOpenDevContext from 'https://cdn.skypack.dev/@holochain-open-dev/context';
</script>

README

@holochain-open-dev/context

NOTICE! This is a temporary port from this PR. When the PR is completed and the @lit-labs/context package is released, this package will most likely be deprecated.

Overview

Usage

There are several different usages of the Context API.

Creating a Context

First lets define a context key we can use elsewhere in our examples:

logger-context.ts

import {createContext} from '@holochain-open-dev/context';

export interface Logger {
  log: (msg: string) => void;
}

export const loggerContext = createContext<Logger>('logger');

Consuming a Context

Now we can define a consumer for this context, some component in our app needs the logger:

my-element.ts

import {ContextConsumer} from '@holochain-open-dev/context';
import {property} from 'lit/decorators.js';
import {LitElement} from 'lit';
import {Logger, loggerContext} from './logger.js';

export class MyElement extends LitElement {
  @property({attribute: false})
  public logger?: Logger;

  public constructor() {
    // add the consumer controller
    new ContextConsumer(
      this,
      loggerContext,
      (value) => {
        this.logger = value;
      },
      true // pass true to get updates if the logger changes
    );
  }
}

Another way we can use a context in a component is via the contextProvided decorator:

my-element.ts

import {ContextConsumer} from '@holochain-open-dev/context';
import {property} from 'lit/decorators.js';
import {LitElement} from 'lit';
import {Logger, loggerContext} from './logger.js';

export class MyElement extends LitElement {
  @contextProvided({context: loggerContext, multiple: true})
  @property({attribute: false})
  public logger?: Logger;
}

Providing a Context

Finally we want to be able to provide this context from somewhere higher in the DOM:

my-app.ts

import {LitElement} from 'lit';
import {provide} from '@holochain-open-dev/context';
import {loggerContext, Logger} from './my-logger.js';

const loggerContext = createContext('logger', new Logger());

export class MyApp extends LitElement {
  private logger: Logger = {
    log: (msg) => {
      console.log(`[my-app] ${msg}`);
    },
  };
  protected render(): TemplateResult {
    return html`
      <div ${provide(loggerContext, this.logger)}>
        <my-thing></my-thing>
      </div>
    `;
  }
}