Last active
March 28, 2025 20:18
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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> | |
`; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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> | |
`; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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