Skip to content

Commit

Permalink
[playground] New context example with element that both consumes and …
Browse files Browse the repository at this point in the history
…provides (#1315)
  • Loading branch information
augustjk authored Mar 15, 2024
1 parent 6c7b3f9 commit 4035bd6
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 42 deletions.
46 changes: 5 additions & 41 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/lit-dev-content/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@
"@lit-labs/motion": "^1.0.1",
"@lit-labs/react": "^1.0.8",
"@lit-labs/task": "^3.0.2",
"@lit/context": "^1.0.0 || 1.0.0-pre.0",
"@lit/context": "^1.1.0",
"@lit/localize": "^0.10.0",
"@lit/react": "^1.0.0 || 1.0.0-pre.0",
"@lit/task": "^1.0.0 || 1.0.0-pre.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script type="module" src="./my-app.js"></script>
<style>
:root {
font-family: sans-serif;
}
</style>
<p>
Example inspired by:
<a
href="https://react.dev/learn/passing-data-deeply-with-context"
target="_blank"
>https://react.dev/learn/passing-data-deeply-with-context</a
>
</p>
<my-app></my-app>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {createContext} from '@lit/context';

export type Level = {level: number; color: string};

export const levelContext = createContext<Level>(Symbol('level'));
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {html, LitElement} from 'lit';
import {customElement} from 'lit/decorators.js';
import './my-section.js';
import './my-heading.js';

@customElement('my-app')
export class MyApp extends LitElement {
render() {
// <my-section> serves as both context provider and consumer. It provides a
// level value that is 1 greater than what's provided to it. This allows
// nested <my-section> to provide a different value based on its depth.

// <my-heading> adjusts what heading tag to use and the color based on the
// level context.
return html`
<my-section>
<my-heading>Heading level 1</my-heading>
<my-section>
<my-heading>Heading level 2</my-heading>
</my-section>
<my-section>
<my-heading>Heading level 2</my-heading>
<my-section>
<my-heading>Heading level 3</my-heading>
</my-section>
<my-section>
<my-heading>Heading level 3</my-heading>
<my-section>
<my-heading>Heading level 4</my-heading>
</my-section>
</my-section>
</my-section>
<my-section>
<my-heading>Heading level 2</my-heading>
<my-section>
<my-heading>Heading level 3</my-heading>
<my-section>
<my-heading>Heading level 4</my-heading>
</my-section>
<my-section>
<my-heading>Heading level 4</my-heading>
</my-section>
</my-section>
</my-section>
</my-section>
<my-section>
<my-heading>Heading level 1</my-heading>
<my-section>
<my-heading>Heading level 2</my-heading>
<my-section>
<my-heading>Heading level 3</my-heading>
<my-section>
<my-heading>Heading level 4</my-heading>
<my-section>
<my-heading>Heading level 5</my-heading>
</my-section>
</my-section>
</my-section>
</my-section>
<my-section>
<my-heading>Heading level 2</my-heading>
<my-section>
<my-heading>Heading level 3</my-heading>
<my-section>
<my-heading>Heading level 4</my-heading>
</my-section>
</my-section>
</my-section>
</my-section>
`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {LitElement} from 'lit';
import {html, literal} from 'lit/static-html.js';
import {styleMap} from 'lit/directives/style-map.js';
import {ContextConsumer} from '@lit/context';
import {levelContext} from './level-context.js';

export class MyHeading extends LitElement {
_levelContext = new ContextConsumer(this, {context: levelContext});

get _tag() {
const level = this._levelContext.value?.level;
if (typeof level === 'number' && level >= 0 && level <= 5) {
return unsafeStatic(`h${level + 1}`);
} else {
return literal`p`;
}
}

render() {
return html`
<${this._tag}
style=${styleMap({color: this._levelContext.value?.color})}
>
<slot></slot>
</${this._tag}>`;
}
}
customElements.define('my-heading', MyHeading);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {LitElement} from 'lit';
import {html, literal, unsafeStatic} from 'lit/static-html.js';
import {customElement} from 'lit/decorators.js';
import {styleMap} from 'lit/directives/style-map.js';
import {consume} from '@lit/context';
import {levelContext, type Level} from './level-context.js';

@customElement('my-heading')
export class MyHeading extends LitElement {
// Consume the level and color from parent provider
@consume({context: levelContext})
private _level?: Level;

private get _tag() {
const level = this._level?.level;
if (typeof level === 'number' && level >= 0 && level <= 5) {
return unsafeStatic(`h${level + 1}`);
} else {
return literal`p`;
}
}

render() {
return html`
<${this._tag} style=${styleMap({color: this._level?.color})}>
<slot></slot>
</${this._tag}>`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {html, css, LitElement} from 'lit';
import {customElement} from 'lit/decorators.js';
import {ContextProvider, ContextConsumer} from '@lit/context';
import {levelContext} from './level-context.js';

const COLORS = ['blue', 'orange', 'green', 'purple'];

@customElement('my-section')
export class MySection extends LitElement {
// Serve as a context provider with an initial level 1 and the color for that
// level
private _provider = new ContextProvider(this, {
context: levelContext,
initialValue: {level: 0, color: COLORS[0]},
});

// Consumes level context from a parent provider. If a parent provider is
// found, update own provider level to be 1 greater than provided value and
// its corresponding color.
private _consumer = new ContextConsumer(this, {
context: levelContext,
callback: ({level}) => {
this._provider.setValue({
level: level + 1,
color: COLORS[(level + 1) % COLORS.length],
});
},
});

render() {
return html`<section><slot></slot></section>`;
}

static styles = css`
:host {
display: block;
text-align: center;
}
`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "/samples/base.json",
"title": "Context Consume and Provide",
"description": "Showcase an element both consuming and providing the same context.",
"section": "Managing Data",
"files": {
"my-app.ts": {},
"my-section.ts": {},
"my-heading.ts": {},
"level-context.ts": {},
"index.html": {}
}
}

0 comments on commit 4035bd6

Please sign in to comment.