import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { get, publish, subscribe, } from "@supersoniks/concorde/decorators"; import type { APIConfiguration, ApiGetResult, } from "@supersoniks/concorde/core/utils/api"; import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey"; import { sub } from "@supersoniks/concorde/directives"; import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy"; import { tailwind } from "../tailwind"; import "./decorators-demo-init"; import { docsDemoDynApiConfKeyTemplate, docsDemoGeoApiConfigurationKey, geoCommunesApiGetEndpoint, geoCommunesApiGetEndpointDynamic, geoCommunesApiGetPublishKey, type GeoCommuneRow, } from "./decorators-demo-geo"; type PublishDemoData = { email: string; message: string; }; const publishDemoKey = new DataProviderKey("publishDemo"); @customElement("demo-publish") export class DemoPublish extends LitElement { static styles = [tailwind]; @publish(publishDemoKey.email) @state() email = ""; @publish(publishDemoKey.message) @state() message = ""; connectedCallback() { super.connectedCallback(); PublisherManager.get("publishDemo").set({ email: "", message: "" }); } render() { return html`

Les champs publient vers le publisher ; les valeurs ci-dessous passent par sub().

(this.email = (e.target as HTMLInputElement).value)} label="Email" placeholder="your@email.com" > (this.message = (e.target as HTMLInputElement).value)} label="Message" placeholder="Type a message..." >

Published values (from sub):

Email: ${sub("publishDemo.email") || "—"}

Message: ${sub("publishDemo.message") || "—"}

`; } } @customElement("demo-api-get") export class DemoApiGet extends LitElement { static styles = [tailwind]; @get(geoCommunesApiGetEndpoint, docsDemoGeoApiConfigurationKey) @state() geoApiPayload?: ApiGetResult; render() { const rows = this.geoApiPayload?.result; const status = this.geoApiPayload?.response?.status; return html`

@get — même service que sonic-queue (https://geo.api.gouv.fr/). Propriété typée ApiGetResult<T>.

${status != null ? html`

HTTP ${status}

` : ""} ${this.geoApiPayload === null ? html`

Chargement…

` : !rows || rows.length === 0 ? html`

Aucune commune

` : html`
    ${rows.map( (c) => html`
  • ${c.nom} — ${c.code}
  • `, )}
`}
`; } } @customElement("demo-api-get-configuration-key") export class DemoApiGetConfigurationKey extends LitElement { static styles = [tailwind]; @property({ type: String }) configSlot: "A" | "B" = "A"; @property({ type: Number }) communeLimit = 5; @get(geoCommunesApiGetEndpointDynamic, docsDemoDynApiConfKeyTemplate) @state() geoApiPayloadDyn?: ApiGetResult; private touchCurrentConfigPublisher() { const id = `docsDemoDynApiConf${this.configSlot}`; const pub = PublisherManager.get(id); const cur = pub.get() as APIConfiguration; pub.set({ ...cur, blockUntilDone: !cur.blockUntilDone, }); } render() { const rows = this.geoApiPayloadDyn?.result; const status = this.geoApiPayloadDyn?.response?.status; return html`

Config dynamique (docsDemoDynApiConf\${configSlot}) + path d’endpoint avec communeLimit. « Toucher la config » déclenche un nouveau GET.

Limite API : ${[3, 5, 10].map( (n) => html` { this.communeLimit = n; }} >${n} `, )}
Publisher config : { this.configSlot = "A"; }} >docsDemoDynApiConfA { this.configSlot = "B"; }} >docsDemoDynApiConfB this.touchCurrentConfigPublisher()} >Toucher la config
${status != null ? html`

HTTP ${status} · limit=${this.communeLimit} · conf= docsDemoDynApiConf${this.configSlot}

` : ""} ${this.geoApiPayloadDyn === null ? html`

Chargement…

` : !rows || rows.length === 0 ? html`

Aucune commune

` : html`
    ${rows.map( (c) => html`
  • ${c.nom} — ${c.code}
  • `, )}
`}
`; } } @customElement("demo-api-get-publish-subscribe") export class DemoApiGetPublishSubscribe extends LitElement { static styles = [tailwind]; @get(geoCommunesApiGetEndpoint) @publish(geoCommunesApiGetPublishKey) @state() geoApiPayloadPublished: ApiGetResult | null = null; @state() @subscribe(geoCommunesApiGetPublishKey.result) geoCommunesFromSubscribe: GeoCommuneRow[] | null = null; render() { const rows = this.geoCommunesFromSubscribe ?? this.geoApiPayloadPublished?.result; const status = this.geoApiPayloadPublished?.response?.status; return html`

@get (scoped) + @publish sur la clé du payload + @subscribe sur .result — même rendu que <demo-api-get> (doc @get).

${status != null ? html`

HTTP ${status}

` : ""} ${this.geoApiPayloadPublished === null ? html`

Chargement…

` : !rows || rows.length === 0 ? html`

Aucune commune

` : html`
    ${rows.map( (c) => html`
  • ${c.nom} — ${c.code}
  • `, )}
`}
`; } } type User = { firstName: string; lastName: string; email: string }; @customElement("demo-subscribe-dynamic") export class DemoSubscribeDynamic extends LitElement { static styles = [tailwind]; @property({ type: Number }) userIndex = 0; @subscribe(new DataProviderKey("demoUsers.${userIndex}")) @state() user: User | null = null; render() { return html`

@subscribe avec chemin dynamique demoUsers.\${userIndex}

(this.userIndex = parseInt((e.target as HTMLInputElement).value))} min="0" max="9" label="User index" > ${this.user ? html`

${this.user.firstName} ${this.user.lastName}

${this.user.email}

` : html`

No user at index ${this.userIndex}

`}
`; } }