From 4035bd6892c1ebca30a4e7d5f3145fcb478f7949 Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Fri, 15 Mar 2024 16:28:22 -0700 Subject: [PATCH] [playground] New context example with element that both consumes and provides (#1315) --- package-lock.json | 46 ++---------- packages/lit-dev-content/package.json | 2 +- .../context-consume-provide/index.html | 15 ++++ .../context-consume-provide/level-context.ts | 5 ++ .../context-consume-provide/my-app.ts | 72 +++++++++++++++++++ .../context-consume-provide/my-heading.js | 28 ++++++++ .../context-consume-provide/my-heading.ts | 29 ++++++++ .../context-consume-provide/my-section.ts | 40 +++++++++++ .../context-consume-provide/project.json | 13 ++++ 9 files changed, 208 insertions(+), 42 deletions(-) create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/index.html create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/level-context.ts create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/my-app.ts create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.js create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.ts create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/my-section.ts create mode 100644 packages/lit-dev-content/samples/examples/context-consume-provide/project.json diff --git a/package-lock.json b/package-lock.json index fb1ce78fc..dab105cb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -654,47 +654,11 @@ } }, "node_modules/@lit/context": { - "version": "1.0.0-pre.0", - "license": "BSD-3-Clause", - "dependencies": { - "@lit/reactive-element": "^2.0.0-pre.1", - "lit": "^3.0.0-pre.1" - } - }, - "node_modules/@lit/context/node_modules/@lit/reactive-element": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.2.tgz", - "integrity": "sha512-SVOwLAWUQg3Ji1egtOt1UiFe4zdDpnWHyc5qctSceJ5XIu0Uc76YmGpIjZgx9YJ0XtdW0Jm507sDvjOu+HnB8w==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.2" - } - }, - "node_modules/@lit/context/node_modules/lit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.0.tgz", - "integrity": "sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w==", - "dependencies": { - "@lit/reactive-element": "^2.0.0", - "lit-element": "^4.0.0", - "lit-html": "^3.1.0" - } - }, - "node_modules/@lit/context/node_modules/lit-element": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.2.tgz", - "integrity": "sha512-/W6WQZUa5VEXwC7H9tbtDMdSs9aWil3Ou8hU6z2cOKWbsm/tXPAcsoaHVEtrDo0zcOIE5GF6QgU55tlGL2Nihg==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.2", - "@lit/reactive-element": "^2.0.0", - "lit-html": "^3.1.0" - } - }, - "node_modules/@lit/context/node_modules/lit-html": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.0.tgz", - "integrity": "sha512-FwAjq3iNsaO6SOZXEIpeROlJLUlrbyMkn4iuv4f4u1H40Jw8wkeR/OUXZUHUoiYabGk8Y4Y0F/rgq+R4MrOLmA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lit/context/-/context-1.1.0.tgz", + "integrity": "sha512-fCyv4dsH05wCNm3AKbB+PdYbXGJd/XT8OOwo4hVmD4COq5wOWJlQreGAMDvmHZ7osqxuu06Y4nmP6ooXpN7ErA==", "dependencies": { - "@types/trusted-types": "^2.0.2" + "@lit/reactive-element": "^1.6.2 || ^2.0.0" } }, "node_modules/@lit/localize": { @@ -8380,7 +8344,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", diff --git a/packages/lit-dev-content/package.json b/packages/lit-dev-content/package.json index 74f4007e1..7cea903be 100644 --- a/packages/lit-dev-content/package.json +++ b/packages/lit-dev-content/package.json @@ -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", diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/index.html b/packages/lit-dev-content/samples/examples/context-consume-provide/index.html new file mode 100644 index 000000000..cd3e926c5 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/index.html @@ -0,0 +1,15 @@ + + +

+ Example inspired by: + https://react.dev/learn/passing-data-deeply-with-context +

+ diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/level-context.ts b/packages/lit-dev-content/samples/examples/context-consume-provide/level-context.ts new file mode 100644 index 000000000..21eb0c6d2 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/level-context.ts @@ -0,0 +1,5 @@ +import {createContext} from '@lit/context'; + +export type Level = {level: number; color: string}; + +export const levelContext = createContext(Symbol('level')); diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/my-app.ts b/packages/lit-dev-content/samples/examples/context-consume-provide/my-app.ts new file mode 100644 index 000000000..d140bdcd7 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/my-app.ts @@ -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() { + // 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 to provide a different value based on its depth. + + // adjusts what heading tag to use and the color based on the + // level context. + return html` + + Heading level 1 + + Heading level 2 + + + Heading level 2 + + Heading level 3 + + + Heading level 3 + + Heading level 4 + + + + + Heading level 2 + + Heading level 3 + + Heading level 4 + + + Heading level 4 + + + + + + Heading level 1 + + Heading level 2 + + Heading level 3 + + Heading level 4 + + Heading level 5 + + + + + + Heading level 2 + + Heading level 3 + + Heading level 4 + + + + + `; + } +} diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.js b/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.js new file mode 100644 index 000000000..6e1fb2fe3 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.js @@ -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})} + > + + `; + } +} +customElements.define('my-heading', MyHeading); diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.ts b/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.ts new file mode 100644 index 000000000..92bb5b7e2 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/my-heading.ts @@ -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})}> + + `; + } +} diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/my-section.ts b/packages/lit-dev-content/samples/examples/context-consume-provide/my-section.ts new file mode 100644 index 000000000..9ed9d3b6a --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/my-section.ts @@ -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`
`; + } + + static styles = css` + :host { + display: block; + text-align: center; + } + `; +} diff --git a/packages/lit-dev-content/samples/examples/context-consume-provide/project.json b/packages/lit-dev-content/samples/examples/context-consume-provide/project.json new file mode 100644 index 000000000..2f44284be --- /dev/null +++ b/packages/lit-dev-content/samples/examples/context-consume-provide/project.json @@ -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": {} + } +}