From cd4bc8087571d8f46f124138fcc5a38d391823d1 Mon Sep 17 00:00:00 2001 From: Augustine Kim Date: Wed, 30 Aug 2023 17:22:29 -0700 Subject: [PATCH] Convert async task example to use labs/task --- .../samples/examples/async-task/index.html | 12 +- .../samples/examples/async-task/index.js | 27 ----- .../samples/examples/async-task/npm-info.js | 87 -------------- .../samples/examples/async-task/npm-info.ts | 109 ++++++++++++++++++ .../samples/examples/async-task/project.json | 7 +- .../site/_data/playground_examples.js | 1 + 6 files changed, 119 insertions(+), 124 deletions(-) delete mode 100644 packages/lit-dev-content/samples/examples/async-task/index.js delete mode 100644 packages/lit-dev-content/samples/examples/async-task/npm-info.js create mode 100644 packages/lit-dev-content/samples/examples/async-task/npm-info.ts diff --git a/packages/lit-dev-content/samples/examples/async-task/index.html b/packages/lit-dev-content/samples/examples/async-task/index.html index c23eb4db4..8099c92be 100644 --- a/packages/lit-dev-content/samples/examples/async-task/index.html +++ b/packages/lit-dev-content/samples/examples/async-task/index.html @@ -1,7 +1,9 @@ - - - - + + + + - + diff --git a/packages/lit-dev-content/samples/examples/async-task/index.js b/packages/lit-dev-content/samples/examples/async-task/index.js deleted file mode 100644 index 1c645e83a..000000000 --- a/packages/lit-dev-content/samples/examples/async-task/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import { LitElement, css, html } from 'lit'; -import './npm-info.js'; - -export class DemoElement extends LitElement { - static properties = { - package: String, - }; - - constructor() { - super(); - this.package = 'lit-element'; - } - - render() { - return html` - - - `; - } - - _onChange(e) { - this.package = e.target.value; - } -} -customElements.define('demo-element', DemoElement); diff --git a/packages/lit-dev-content/samples/examples/async-task/npm-info.js b/packages/lit-dev-content/samples/examples/async-task/npm-info.js deleted file mode 100644 index 3dc38991a..000000000 --- a/packages/lit-dev-content/samples/examples/async-task/npm-info.js +++ /dev/null @@ -1,87 +0,0 @@ -import { LitElement, css, html } from 'lit-element'; -import { Task } from './task.js'; - -export class NpmInfoElement extends LitElement { - - static styles = css` - :host { - display: block; - min-width: 480px; - border-radius: 5px; - border: solid 1px #aaa; - padding: 20px; - } - header { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - } - #logo { - height: 38px; - width: auto; - } - `; - - static properties = { - package: String, - }; - - /** - * This is the task that fetches from npm. - * - * It's given: - * - `this`: A reference to the host so it can trigger updates - * - An async compute function - * - A dependencies provider function - */ - _fetchNpmInfoTask = new Task(this, async (pkg) => { - if (pkg === undefined || pkg === '') { - // InitialStateError indicates that we haven't started a Task - // It's neither pending, complete, or in error - throw new InitialStateError(); - } - const response = await fetch(getPackageUrl(pkg)); - if (response.status === 200) { - return response.json(); - } else { - throw response.text(); - } - }, () => [this.package]); - - render() { - return html` -
-

${this.package}

- ${npmLogo} -
-
- ${this._fetchNpmInfoTask.render({ - complete: (pkg) => html` -

${pkg.description}

-

dist-tags:

- - `, - error: (e) => `Error ${e.message}`, - pending: () => 'Loading...', - initial: () => 'Enter a Package Name', - })} -
- `; - } -} -customElements.define('npm-info', NpmInfoElement); - -const getPackageUrl = (name) => `https://cors-anywhere.herokuapp.com/registry.npmjs.org/${name}`; - -const npmLogo = html` - -`; diff --git a/packages/lit-dev-content/samples/examples/async-task/npm-info.ts b/packages/lit-dev-content/samples/examples/async-task/npm-info.ts new file mode 100644 index 000000000..67ad9f146 --- /dev/null +++ b/packages/lit-dev-content/samples/examples/async-task/npm-info.ts @@ -0,0 +1,109 @@ +import {LitElement, css, html} from 'lit'; +import {customElement, state} from 'lit/decorators.js'; +import {Task} from '@lit-labs/task'; + +@customElement('npm-info') +export class NpmInfo extends LitElement { + @state() + _package = 'lit'; + + _fetchNpmInfoTask = new Task(this, { + task: async ([pkgName], {signal}) => { + if (pkgName === undefined || pkgName === '') { + throw new Error('Empty package name'); + } + // Artifical delay for demo purposes + await new Promise((r) => setTimeout(r, 1000)); + const response = await fetch(getPackageUrl(pkgName), {signal}); + if (response.status === 200) { + return response.json() as Promise; + } else { + throw response.text(); + } + }, + args: () => [this._package], + }); + + _onChange(e: Event) { + this._package = (e.target as HTMLInputElement).value; + } + + render() { + return html` +
+

${this._package}

+ ${npmLogo} +
+ +
+ ${this._fetchNpmInfoTask.render({ + pending: () => 'Loading...', + complete: (pkg) => html` +

${pkg.description}

+

dist-tags:

+
    + ${Array.from(Object.entries(pkg['dist-tags'])).map( + ([tag, version]) => html`
  • ${tag}: ${version}
  • ` + )} +
+ `, + error: (e) => `Error ${(e as Error).message}`, + })} +
+ `; + } + + static styles = css` + :host { + display: block; + min-width: 300px; + border-radius: 5px; + border: solid 1px #aaa; + padding: 20px; + } + header { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + } + #logo { + height: 38px; + width: auto; + } + `; +} + +const getPackageUrl = (name: string) => `https://registry.npmjs.org/${name}`; + +const npmLogo = html` + +`; + +interface NpmPackage { + description: string; + ['dist-tags']: {[tag: string]: string}; +} diff --git a/packages/lit-dev-content/samples/examples/async-task/project.json b/packages/lit-dev-content/samples/examples/async-task/project.json index cacc82429..c6ff8da0e 100644 --- a/packages/lit-dev-content/samples/examples/async-task/project.json +++ b/packages/lit-dev-content/samples/examples/async-task/project.json @@ -1,13 +1,10 @@ { "extends": "/samples/base.json", - "hide": true, "title": "Async Task / NPM Info element", "description": "Shows an example of an async Task controller. This one fetches npm package info and renders based on the state of the fetch.", - "section": "Specific Solutions", + "section": "Managing Data", "files": { - "index.js": {}, - "npm-info.js": {}, - "task.js": {}, + "npm-info.ts": {}, "index.html": {} } } diff --git a/packages/lit-dev-content/site/_data/playground_examples.js b/packages/lit-dev-content/site/_data/playground_examples.js index 18a087333..bafdc724d 100644 --- a/packages/lit-dev-content/site/_data/playground_examples.js +++ b/packages/lit-dev-content/site/_data/playground_examples.js @@ -12,6 +12,7 @@ const topSectionOrder = [ 'Reactive properties', 'Template concepts', 'Directives', + 'Managing Data', '@lit-labs/react', '@lit-labs/motion' ];