diff --git a/renderers/lit/CHANGELOG.md b/renderers/lit/CHANGELOG.md index 9e86306a2..56bf693e4 100644 --- a/renderers/lit/CHANGELOG.md +++ b/renderers/lit/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.9.0 + +- \[v0_9\] Modify Text widget from the basic catalog to support markdown. +- \[v0_9\] Add `Context.markdown` to the public API +- \[CI\] Fix post-build script. This pins the dependency on `@a2ui/web_core` to + the latest available in the repo when publishing. + ## 0.8.4 - Add a `v0_9` renderer. Import from `@a2ui/lit/v0_9`. diff --git a/renderers/lit/package-lock.json b/renderers/lit/package-lock.json index 36ecf5807..658abd36e 100644 --- a/renderers/lit/package-lock.json +++ b/renderers/lit/package-lock.json @@ -1,12 +1,12 @@ { "name": "@a2ui/lit", - "version": "0.8.4", + "version": "0.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@a2ui/lit", - "version": "0.8.4", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "@a2ui/web_core": "file:../web_core", @@ -27,7 +27,7 @@ }, "../web_core": { "name": "@a2ui/web_core", - "version": "0.8.8", + "version": "0.9.1", "license": "Apache-2.0", "dependencies": { "@preact/signals-core": "^1.13.0", @@ -39,6 +39,7 @@ "@angular/core": "^21.2.5", "@types/node": "^24.11.0", "c8": "^11.0.0", + "google-artifactregistry-auth": "^3.5.0", "gts": "^7.0.0", "rxjs": "^7.8.2", "typescript": "^5.8.3", diff --git a/renderers/lit/src/v0_9/catalogs/basic/components/Text.ts b/renderers/lit/src/v0_9/catalogs/basic/components/Text.ts index 70b8b76fb..73ea577b9 100644 --- a/renderers/lit/src/v0_9/catalogs/basic/components/Text.ts +++ b/renderers/lit/src/v0_9/catalogs/basic/components/Text.ts @@ -16,11 +16,20 @@ import { html, nothing } from "lit"; import { customElement } from "lit/decorators.js"; +import { consume } from "@lit/context"; import { TextApi } from "@a2ui/web_core/v0_9/basic_catalog"; -import { A2uiLitElement, A2uiController } from "@a2ui/lit/v0_9"; +import { A2uiLitElement, A2uiController, Context } from "@a2ui/lit/v0_9"; +import * as Types from "@a2ui/web_core/types/types"; + +import { markdown } from "../../../directives/directives.js"; @customElement("a2ui-basic-text") export class A2uiBasicTextElement extends A2uiLitElement { + + // Retrieve a MarkdownRenderer provided by the application. + @consume({ context: Context.markdown, subscribe: true }) + accessor markdownRenderer: Types.MarkdownRenderer | undefined; + protected createController() { return new A2uiController(this, TextApi); } @@ -29,23 +38,35 @@ export class A2uiBasicTextElement extends A2uiLitElement { const props = this.controller.props; if (!props) return nothing; - const variant = props.variant ?? "body"; - switch (variant) { + // Use props.variant to convert props.text to markdown + let markdownText = props.text; + switch (props.variant) { case "h1": - return html`

${props.text}

`; + markdownText = `# ${markdownText}`; + break; case "h2": - return html`

${props.text}

`; + markdownText = `## ${markdownText}`; + break; case "h3": - return html`

${props.text}

`; + markdownText = `### ${markdownText}`; + break; case "h4": - return html`

${props.text}

`; + markdownText = `#### ${markdownText}`; + break; case "h5": - return html`
${props.text}
`; - case "caption": - return html`${props.text}`; + markdownText = `##### ${markdownText}`; + break; default: - return html`

${props.text}

`; + break; // body and caption. + } + + const renderedMarkdown = markdown(markdownText, this.markdownRenderer); + // There's not a good way to handle the caption variant in markdown, so we + // tag it with a class so it can be tweaked via CSS. + if (props.variant === "caption") { + return html`${renderedMarkdown}`; } + return html`${renderedMarkdown}`; } } diff --git a/renderers/lit/src/v0_9/context/context.ts b/renderers/lit/src/v0_9/context/context.ts new file mode 100644 index 000000000..d0ab62d8f --- /dev/null +++ b/renderers/lit/src/v0_9/context/context.ts @@ -0,0 +1,24 @@ +/** + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { markdown } from "./markdown.js"; + +/** + * Contexts used to inject dependencies into the Lit renderer. + */ +export const Context = { + markdown, +}; diff --git a/renderers/lit/src/v0_9/context/markdown.ts b/renderers/lit/src/v0_9/context/markdown.ts new file mode 100644 index 000000000..0b3e152a5 --- /dev/null +++ b/renderers/lit/src/v0_9/context/markdown.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createContext } from "@lit/context"; +import * as Types from "@a2ui/web_core/types/types"; + +/** + * The markdown renderer context. + * + * This is used by the Text widget to render markdown content. + */ +export const markdown = createContext(Symbol("A2UIMarkdown")); diff --git a/renderers/lit/src/v0_9/directives/directives.ts b/renderers/lit/src/v0_9/directives/directives.ts new file mode 100644 index 000000000..92713e9d7 --- /dev/null +++ b/renderers/lit/src/v0_9/directives/directives.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { markdown } from "./markdown.js"; diff --git a/renderers/lit/src/v0_9/directives/markdown.ts b/renderers/lit/src/v0_9/directives/markdown.ts new file mode 100644 index 000000000..3151ed52d --- /dev/null +++ b/renderers/lit/src/v0_9/directives/markdown.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { html, noChange } from "lit"; +import { + Directive, + DirectiveParameters, + Part, + directive, +} from "lit/directive.js"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import { until } from "lit/directives/until.js"; +import * as Types from "@a2ui/web_core/types/types"; + +class MarkdownDirective extends Directive { + private lastValue: string | null = null; + private lastTagClassMap: string | null = null; + + update(_part: Part, [value, markdownRenderer, markdownOptions]: DirectiveParameters) { + const jsonTagClassMap = JSON.stringify(markdownOptions?.tagClassMap); + if ( + this.lastValue === value && + jsonTagClassMap === this.lastTagClassMap + ) { + return noChange; + } + + this.lastValue = value; + this.lastTagClassMap = jsonTagClassMap; + return this.render(value, markdownRenderer, markdownOptions); + } + + private static defaultMarkdownWarningLogged = false; + /** + * Renders the markdown string to HTML using the injected markdown renderer, + * if present. Otherwise, it returns the value wrapped in a span. + */ + render(value: string, markdownRenderer?: Types.MarkdownRenderer, markdownOptions?: Types.MarkdownRendererOptions) { + if (markdownRenderer) { + const rendered = markdownRenderer(value, markdownOptions).then((value) => { + // `value` is a plain string, which we need to convert to a template + // with the `unsafeHTML` directive. + // It is the responsibility of the markdown renderer to sanitize the HTML. + return unsafeHTML(value); + }) + // The until directive lets us render a placeholder *until* the rendered + // content resolves. + return until(rendered, html`${value}`); + } + + if (!MarkdownDirective.defaultMarkdownWarningLogged) { + console.warn("[MarkdownDirective]", + "can't render markdown because no markdown renderer is configured.\n", + "Use `@a2ui/markdown-it`, or your own markdown renderer."); + MarkdownDirective.defaultMarkdownWarningLogged = true; + } + return html`${value}`; + } +} + +export const markdown = directive(MarkdownDirective); diff --git a/renderers/lit/src/v0_9/index.ts b/renderers/lit/src/v0_9/index.ts index de2c57d62..3cf805a71 100644 --- a/renderers/lit/src/v0_9/index.ts +++ b/renderers/lit/src/v0_9/index.ts @@ -18,5 +18,6 @@ export type { LitComponentApi } from "./types.js"; export { A2uiController } from "./a2ui-controller.js"; export { A2uiSurface } from "./surface/a2ui-surface.js"; export { A2uiLitElement } from "./a2ui-lit-element.js"; +export { Context } from "./context/context.js"; export { minimalCatalog } from "./catalogs/minimal/index.js"; export { basicCatalog } from "./catalogs/basic/index.js"; diff --git a/renderers/lit/src/v0_9/tests/markdown.test.ts b/renderers/lit/src/v0_9/tests/markdown.test.ts new file mode 100644 index 000000000..6c65992ed --- /dev/null +++ b/renderers/lit/src/v0_9/tests/markdown.test.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { setupTestDom, teardownTestDom, asyncUpdate } from "./dom-setup.js"; +import assert from "node:assert"; +import { describe, it, before, after } from "node:test"; +import * as Types from "@a2ui/web_core/types/types"; + +describe("Markdown Directive", () => { + before(() => { + // Set up the DOM before any lit imports in the tests + setupTestDom(); + }); + + after(() => { + teardownTestDom(); + }); + + it("should render fallback when no renderer is provided", async () => { + const { html, render } = await import("lit"); + const { markdown } = await import("../directives/markdown.js"); + + const container = document.createElement("div"); + + // Render the directive directly into our container + render(html`
${markdown("Hello world")}
`, container); + + const htmlContent = container.innerHTML; + assert.ok( + htmlContent.includes("no-markdown-renderer"), + "Should render fallback span class", + ); + assert.ok( + container.textContent?.includes("Hello world"), + "Should render fallback text properly", + ); + }); + + it("should render parsed markdown when renderer is provided", async () => { + const { html, render } = await import("lit"); + const { markdown } = await import("../directives/markdown.js"); + + const container = document.createElement("div"); + + let resolveRenderer: (value: string) => void; + // Leak the `resolve` function of this promise to the `resolveRenderer` + // variable, so we can call it later in the test. + const renderPromise = new Promise((resolve) => { + resolveRenderer = resolve; + }); + // Mock a markdown renderer that resolves by calling `resolveRenderer` + const mockRenderer: Types.MarkdownRenderer = async () => renderPromise; + + // Render the directive with our mock renderer + render( + html`
${markdown("Hello markdown", mockRenderer)}
`, + container, + ); + + // Before resolution, should show the placeholder (until directive) + assert.ok(container.innerHTML.includes("no-markdown-renderer")); + + // Resolve the promise via asyncUpdate so it yields to the macro-task queue + await asyncUpdate(container, () => { + resolveRenderer!("Rendered HTML"); + }); + + const htmlContent = container.innerHTML; + assert.ok( + htmlContent.includes("Rendered HTML"), + "Should render the HTML from the renderer", + ); + assert.ok( + !htmlContent.includes("no-markdown-renderer"), + "Placeholder should be gone", + ); + }); +}); diff --git a/renderers/markdown/markdown-it/package-lock.json b/renderers/markdown/markdown-it/package-lock.json index a670bb61f..02fde5bf0 100644 --- a/renderers/markdown/markdown-it/package-lock.json +++ b/renderers/markdown/markdown-it/package-lock.json @@ -29,7 +29,7 @@ }, "../../web_core": { "name": "@a2ui/web_core", - "version": "0.8.1", + "version": "0.9.1", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/renderers/web_core/package-lock.json b/renderers/web_core/package-lock.json index 17869ecb4..479d99962 100644 --- a/renderers/web_core/package-lock.json +++ b/renderers/web_core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@a2ui/web_core", - "version": "0.8.8", + "version": "0.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@a2ui/web_core", - "version": "0.8.8", + "version": "0.9.1", "license": "Apache-2.0", "dependencies": { "@preact/signals-core": "^1.13.0", @@ -691,7 +691,6 @@ }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", @@ -793,7 +792,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ @@ -814,7 +812,6 @@ }, "node_modules/bignumber.js": { "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", "dev": true, "license": "MIT", @@ -860,7 +857,6 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "dev": true, "license": "BSD-3-Clause" @@ -1126,7 +1122,6 @@ }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dev": true, "license": "Apache-2.0", @@ -1555,7 +1550,6 @@ }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true, "license": "MIT" @@ -1759,7 +1753,6 @@ }, "node_modules/gaxios": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "dev": true, "license": "Apache-2.0", @@ -1776,7 +1769,6 @@ }, "node_modules/gcp-metadata": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "dev": true, "license": "Apache-2.0", @@ -1871,7 +1863,6 @@ }, "node_modules/google-artifactregistry-auth": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/google-artifactregistry-auth/-/google-artifactregistry-auth-3.5.0.tgz", "integrity": "sha512-SIvVBPjVr0KvYFEJEZXKfELt8nvXwTKl6IHyOT7pTHBlS8Ej2UuTOJeKWYFim/JztSjUyna9pKQxa3VhTA12Fg==", "dev": true, "license": "Apache-2.0", @@ -1886,7 +1877,6 @@ }, "node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "dev": true, "license": "Apache-2.0", @@ -1904,7 +1894,6 @@ }, "node_modules/google-logging-utils": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", "dev": true, "license": "Apache-2.0", @@ -1920,7 +1909,6 @@ }, "node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "dev": true, "license": "MIT", @@ -2015,7 +2003,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", @@ -2288,7 +2275,6 @@ }, "node_modules/json-bigint": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "dev": true, "license": "MIT", @@ -2340,7 +2326,6 @@ }, "node_modules/jwa": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "dev": true, "license": "MIT", @@ -2352,7 +2337,6 @@ }, "node_modules/jws": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "dev": true, "license": "MIT", @@ -2645,7 +2629,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "license": "MIT", @@ -3238,7 +3221,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ @@ -3536,7 +3518,6 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true, "license": "MIT" @@ -3679,7 +3660,6 @@ }, "node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, "funding": [ @@ -3717,14 +3697,12 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "license": "MIT", diff --git a/samples/client/lit/gallery_v0_9/package-lock.json b/samples/client/lit/gallery_v0_9/package-lock.json index f794cb2fd..0c5d58df8 100644 --- a/samples/client/lit/gallery_v0_9/package-lock.json +++ b/samples/client/lit/gallery_v0_9/package-lock.json @@ -22,7 +22,7 @@ }, "../../../../renderers/lit": { "name": "@a2ui/lit", - "version": "0.8.4", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "@a2ui/web_core": "file:../web_core", @@ -66,7 +66,7 @@ }, "../../../../renderers/web_core": { "name": "@a2ui/web_core", - "version": "0.8.8", + "version": "0.9.1", "license": "Apache-2.0", "dependencies": { "@preact/signals-core": "^1.13.0", @@ -78,6 +78,7 @@ "@angular/core": "^21.2.5", "@types/node": "^24.11.0", "c8": "^11.0.0", + "google-artifactregistry-auth": "^3.5.0", "gts": "^7.0.0", "rxjs": "^7.8.2", "typescript": "^5.8.3", diff --git a/samples/client/lit/gallery_v0_9/src/local-gallery.ts b/samples/client/lit/gallery_v0_9/src/local-gallery.ts index 094a98ff1..8b111d806 100644 --- a/samples/client/lit/gallery_v0_9/src/local-gallery.ts +++ b/samples/client/lit/gallery_v0_9/src/local-gallery.ts @@ -14,10 +14,12 @@ * limitations under the License. */ -import { LitElement, html, css, nothing, PropertyValues } from "lit"; +import { LitElement, html, css, nothing } from "lit"; +import { provide } from "@lit/context"; import { customElement, state } from "lit/decorators.js"; import { MessageProcessor } from "@a2ui/web_core/v0_9"; -import { minimalCatalog, basicCatalog } from "@a2ui/lit/v0_9"; +import { minimalCatalog, basicCatalog, Context } from "@a2ui/lit/v0_9"; +import { renderMarkdown } from "@a2ui/markdown-it"; // Try avoiding direct deep import if A2uiMessage is not exported at the top level, using any for now as this is just a type for the array of messages interface DemoItem { id: string; @@ -36,6 +38,9 @@ export class LocalGallery extends LitElement { @state() accessor processedMessageCount = 0; @state() accessor currentDataModelText = "{}"; + @provide({ context: Context.markdown }) + private accessor markdownRenderer = renderMarkdown; + private processor = new MessageProcessor( [minimalCatalog, basicCatalog], (action: any) => { diff --git a/samples/client/lit/package-lock.json b/samples/client/lit/package-lock.json index 154896027..5f57845af 100644 --- a/samples/client/lit/package-lock.json +++ b/samples/client/lit/package-lock.json @@ -8,7 +8,7 @@ "name": "@a2ui/lit-samples", "version": "0.8.1", "workspaces": [ - "contact", + "custom-components-example", "shell" ], "dependencies": { @@ -28,7 +28,7 @@ }, "../../../renderers/lit": { "name": "@a2ui/lit", - "version": "0.8.4", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "@a2ui/web_core": "file:../web_core", @@ -2021,7 +2021,7 @@ }, "../../../renderers/web_core": { "name": "@a2ui/web_core", - "version": "0.8.8", + "version": "0.9.1", "license": "Apache-2.0", "dependencies": { "@preact/signals-core": "^1.13.0", @@ -2033,6 +2033,7 @@ "@angular/core": "^21.2.5", "@types/node": "^24.11.0", "c8": "^11.0.0", + "google-artifactregistry-auth": "^3.5.0", "gts": "^7.0.0", "rxjs": "^7.8.2", "typescript": "^5.8.3", @@ -5277,6 +5278,27 @@ "contact": { "name": "@a2ui/contact", "version": "0.8.1", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@a2a-js/sdk": "^0.3.4", + "@a2ui/lit": "file:../../../../renderers/lit", + "@lit-labs/signals": "^0.1.3", + "@lit/context": "^1.1.4", + "@modelcontextprotocol/ext-apps": "^1.1.2", + "lit": "^3.3.1" + }, + "devDependencies": { + "dotenv": "^17.2.3", + "typescript": "^5.8.3", + "uuid": "^13.0.0", + "vite": "^7.1.11", + "wireit": "^0.15.0-pre.2" + } + }, + "custom-components-example": { + "name": "@a2ui/custom-components-example", + "version": "0.8.1", "license": "Apache-2.0", "dependencies": { "@a2a-js/sdk": "^0.3.4", @@ -5294,8 +5316,9 @@ "wireit": "^0.15.0-pre.2" } }, - "contact/node_modules/uuid": { + "custom-components-example/node_modules/uuid": { "version": "13.0.0", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -5332,8 +5355,8 @@ } } }, - "node_modules/@a2ui/contact": { - "resolved": "contact", + "node_modules/@a2ui/custom-components-example": { + "resolved": "custom-components-example", "link": true }, "node_modules/@a2ui/lit": {