Skip to content

Instantly share code, notes, and snippets.

@adamjohnson
Last active March 28, 2025 20:18
Show Gist options
  • Save adamjohnson/b42615a53d36a236c3512a8a4f6f8e2b to your computer and use it in GitHub Desktop.
Save adamjohnson/b42615a53d36a236c3512a8a4f6f8e2b to your computer and use it in GitHub Desktop.
Simple lit.dev Context example. AKA how to make a parent's component's attributes pierce the shadowDom of a child component (and do stuff).
/**
* In this simple example, we're going to have 1) a parent component that wraps 2) a child component.
* The parent component will have a `size="sm"` or `size="lg"` attribute.
* Using Lit Context, we're going to add a class to the child component based on if the parent has this attribute.
* First, we must create this file and create a context.
* NB: Github Gist orders files alphabetically. To organize this mini-turorial, I have prefixed file names with numbers.
* If you implement this (say on lit.dev/playground), remove the prefixed numbers from each file name. 🤷‍♂️
*/
import { createContext } from '@lit/context';
export const sizeContext = createContext<'sm' | 'lg' | undefined>('size');
/**
* Next, we'll create the parent component, `<context-provider>`.
* Note: This component has the `size` attribute/property that we're going to use for Context.
*/
import { LitElement, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { provide } from '@lit/context';
import { sizeContext } from './context-key.js';
@customElement('context-provider')
export class ContextProvider extends LitElement {
/**
* Provides a size context, either "sm" or "lg"
*/
@provide({ context: sizeContext })
@property({ reflect: true })
size?: 'sm' | 'lg';
render() {
return html`
<h2>This content is rendered by the provider</h2>
<slot></slot>
`;
}
}
/**
* Next, we create the child component, `<context-consumer>`.
* Note line ~33 where we use `@consume` and then implement it with the `size` property in the `render()` method.
*/
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { consume } from '@lit/context';
import { classMap } from 'lit/directives/class-map.js';
import { sizeContext } from './context-key.js';
@customElement('context-consumer')
export class ContextConsumer extends LitElement {
// Some optional styles to drive the point home
static styles = css`
.size-lg {
color: green;
font-weight: bold;
font-size: 2.5rem;
}
.size-sm {
color: darkslateblue;
font-weight: bold;
font-size: .8rem;
}
`;
/**
* Consumes the size context from `context-provider`
*/
@consume({ context: sizeContext })
@property({ reflect: true })
size?: 'sm' | 'lg';
render() {
return html`
<p>This content is rendered by the consumer. Below is the context, rendered by the consumer, but the context is provided via the provider:</p>
<div class=${classMap({ [`size-${this.size}`]: !!this.size })}>
Context Size: ${this.size ?? 'none'}
</div>
`;
}
}
<!DOCTYPE html>
<head>
<!-- Finally, here we import our components and render them to the page! -->
<script type="module" src="./context-provider.js"></script>
<script type="module" src="./context-consumer.js"></script>
</head>
<body>
<context-provider size="lg">
<context-consumer></context-consumer>
</context-provider>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment