From 30ed2260037193fb8cd5d0d0106aada265ae8906 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:08:16 -0500 Subject: [PATCH 01/10] feat(theme): add DocCard component with Markdown --- .../src/theme/DocCard/index.tsx | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx new file mode 100644 index 000000000..f87a0dfe6 --- /dev/null +++ b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx @@ -0,0 +1,142 @@ +/* ============================================================================ + * Copyright (c) Palo Alto Networks + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * ========================================================================== */ + +import React, { type ReactNode } from "react"; + +import isInternalUrl from "@docusaurus/isInternalUrl"; +import Link from "@docusaurus/Link"; +import type { + PropSidebarItemCategory, + PropSidebarItemLink, +} from "@docusaurus/plugin-content-docs"; +import { + useDocById, + findFirstSidebarItemLink, +} from "@docusaurus/plugin-content-docs/client"; +import { usePluralForm } from "@docusaurus/theme-common"; +import { translate } from "@docusaurus/Translate"; +import type { Props } from "@theme/DocCard"; +import Heading from "@theme/Heading"; +import Markdown from "@theme/Markdown"; +import clsx from "clsx"; + +import styles from "./styles.module.css"; + +function useCategoryItemsPlural() { + const { selectMessage } = usePluralForm(); + return (count: number) => + selectMessage( + count, + translate( + { + message: "1 item|{count} items", + id: "theme.docs.DocCard.categoryDescription.plurals", + description: + "The default description for a category card in the generated index about how many items this category includes", + }, + { count } + ) + ); +} + +function CardContainer({ + className, + href, + children, +}: { + className?: string; + href: string; + children: ReactNode; +}): ReactNode { + return ( + + {children} + + ); +} + +function CardLayout({ + className, + href, + icon, + title, + description, +}: { + className?: string; + href: string; + icon: ReactNode; + title: string; + description?: string; +}): ReactNode { + return ( + + + {icon} {title} + + {description && ( +

+ {description} +

+ )} +
+ ); +} + +function CardCategory({ item }: { item: PropSidebarItemCategory }): ReactNode { + const href = findFirstSidebarItemLink(item); + const categoryItemsPlural = useCategoryItemsPlural(); + + // Unexpected: categories that don't have a link have been filtered upfront + if (!href) { + return null; + } + + return ( + + ); +} + +function CardLink({ item }: { item: PropSidebarItemLink }): ReactNode { + const icon = isInternalUrl(item.href) ? "📄️" : "🔗"; + const doc = useDocById(item.docId ?? undefined); + return ( + + ); +} + +export default function DocCard({ item }: Props): ReactNode { + switch (item.type) { + case "link": + return ; + case "category": + return ; + default: + throw new Error(`unknown item type ${JSON.stringify(item)}`); + } +} From 74b466d04c969c299c218b3536eed2ba690bf6d0 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:21:16 -0500 Subject: [PATCH 02/10] Fix DocCard build by importing docs utils directly --- .../docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx index f87a0dfe6..758a343dc 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx +++ b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx @@ -16,7 +16,7 @@ import type { import { useDocById, findFirstSidebarItemLink, -} from "@docusaurus/plugin-content-docs/client"; +} from "@docusaurus/plugin-content-docs/lib/client/docsUtils"; import { usePluralForm } from "@docusaurus/theme-common"; import { translate } from "@docusaurus/Translate"; import type { Props } from "@theme/DocCard"; From 5a303304380ef58c710372fa62ed3bb250ae0ee9 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:33:09 -0500 Subject: [PATCH 03/10] Add missing DocCard styles --- .../src/theme/DocCard/styles.module.css | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 packages/docusaurus-theme-openapi-docs/src/theme/DocCard/styles.module.css diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/styles.module.css b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/styles.module.css new file mode 100644 index 000000000..1c2ea4382 --- /dev/null +++ b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/styles.module.css @@ -0,0 +1,34 @@ +/* ========================================================================== */ +/* Copyright (c) Palo Alto Networks + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * ========================================================================== */ + +.cardContainer { + --ifm-link-color: var(--ifm-color-emphasis-800); + --ifm-link-hover-color: var(--ifm-color-emphasis-700); + --ifm-link-hover-decoration: none; + + box-shadow: 0 1.5px 3px 0 rgb(0 0 0 / 15%); + border: 1px solid var(--ifm-color-emphasis-200); + transition: all var(--ifm-transition-fast) ease; + transition-property: border, box-shadow; +} + +.cardContainer:hover { + border-color: var(--ifm-color-primary); + box-shadow: 0 3px 6px 0 rgb(0 0 0 / 20%); +} + +.cardContainer *:last-child { + margin-bottom: 0; +} + +.cardTitle { + font-size: 1.2rem; +} + +.cardDescription { + font-size: 0.8rem; +} From daab76a9161f59195f93a74c4ae362605c414feb Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:30:54 -0500 Subject: [PATCH 04/10] Add doc card markdown test spec --- .../__fixtures__/docCards/openapi.yaml | 20 +++++++++++++++++++ .../src/openapi/openapi.test.ts | 14 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml new file mode 100644 index 000000000..8bccf1674 --- /dev/null +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml @@ -0,0 +1,20 @@ +openapi: 3.0.3 +info: + title: DocCard Markdown Example + version: 1.0.0 +paths: + /docs: + get: + summary: Doc card operation + description: | + Returns documentation. + Supports **markdown** and HTML in descriptions. + tags: + - docCards + responses: + "200": + description: OK + +tags: + - name: docCards + description: This tag shows **markdown** and HTML in the doc card. diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts index 678a003ff..80818c0b3 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts @@ -37,4 +37,18 @@ describe("openapi", () => { ).toBeDefined(); }); }); + + describe("doc card markdown", () => { + it("preserves markdown and html in tag descriptions", async () => { + const results = await readOpenapiFiles( + posixPath(path.join(__dirname, "__fixtures__/docCards")) + ); + const yaml = results.find((x) => x.source.endsWith("openapi.yaml")); + expect(yaml).toBeTruthy(); + const tag = yaml?.data.tags?.find((t) => t.name === "docCards"); + expect(tag?.description).toBe( + "This tag shows **markdown** and HTML in the doc card." + ); + }); + }); }); From 68da33a7495e1ca7ea9bc54abe4cbcb48f37a95a Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:56:30 -0500 Subject: [PATCH 05/10] Add doc card example spec to demo --- demo/examples/tests/docCards.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 demo/examples/tests/docCards.yaml diff --git a/demo/examples/tests/docCards.yaml b/demo/examples/tests/docCards.yaml new file mode 100644 index 000000000..8bccf1674 --- /dev/null +++ b/demo/examples/tests/docCards.yaml @@ -0,0 +1,20 @@ +openapi: 3.0.3 +info: + title: DocCard Markdown Example + version: 1.0.0 +paths: + /docs: + get: + summary: Doc card operation + description: | + Returns documentation. + Supports **markdown** and HTML in descriptions. + tags: + - docCards + responses: + "200": + description: OK + +tags: + - name: docCards + description: This tag shows **markdown** and HTML in the doc card. From d971831164e56cbdcf54cb98bc284c004149107e Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:18:09 -0500 Subject: [PATCH 06/10] Fix DocCard Markdown rendering --- .../src/theme/DocCard/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx index 758a343dc..10188fb4c 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx +++ b/packages/docusaurus-theme-openapi-docs/src/theme/DocCard/index.tsx @@ -85,12 +85,12 @@ function CardLayout({ {icon} {title} {description && ( -

- {description} -

+ {description} + )} ); From 99017758a0917ae9d210c817010fd127087678f0 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:38:21 -0500 Subject: [PATCH 07/10] Update doc card spec to place markup in first sentence --- demo/examples/tests/docCards.yaml | 5 ++--- .../src/openapi/__fixtures__/docCards/openapi.yaml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/demo/examples/tests/docCards.yaml b/demo/examples/tests/docCards.yaml index 8bccf1674..cc1fb992c 100644 --- a/demo/examples/tests/docCards.yaml +++ b/demo/examples/tests/docCards.yaml @@ -6,9 +6,8 @@ paths: /docs: get: summary: Doc card operation - description: | - Returns documentation. - Supports **markdown** and HTML in descriptions. + description: > + Returns documentation with **markdown** and HTML in descriptions. tags: - docCards responses: diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml index 8bccf1674..cc1fb992c 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml @@ -6,9 +6,8 @@ paths: /docs: get: summary: Doc card operation - description: | - Returns documentation. - Supports **markdown** and HTML in descriptions. + description: > + Returns documentation with **markdown** and HTML in descriptions. tags: - docCards responses: From 8f65ebc804ae7f8395cbc6d0cb73c8041c229441 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:01:56 -0500 Subject: [PATCH 08/10] Add admonition example to doc card spec --- demo/examples/tests/docCards.yaml | 12 ++++++++++++ .../src/openapi/__fixtures__/docCards/openapi.yaml | 12 ++++++++++++ .../src/openapi/openapi.test.ts | 2 ++ 3 files changed, 26 insertions(+) diff --git a/demo/examples/tests/docCards.yaml b/demo/examples/tests/docCards.yaml index cc1fb992c..943b5ce85 100644 --- a/demo/examples/tests/docCards.yaml +++ b/demo/examples/tests/docCards.yaml @@ -13,6 +13,18 @@ paths: responses: "200": description: OK + /docs-admon: + get: + summary: Doc card admonition operation + description: > + :::info + Returns documentation with **markdown** and HTML in descriptions inside an admonition. + ::: + tags: + - docCards + responses: + "200": + description: OK tags: - name: docCards diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml index cc1fb992c..943b5ce85 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml @@ -13,6 +13,18 @@ paths: responses: "200": description: OK + /docs-admon: + get: + summary: Doc card admonition operation + description: > + :::info + Returns documentation with **markdown** and HTML in descriptions inside an admonition. + ::: + tags: + - docCards + responses: + "200": + description: OK tags: - name: docCards diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts index 80818c0b3..7718a2597 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts @@ -49,6 +49,8 @@ describe("openapi", () => { expect(tag?.description).toBe( "This tag shows **markdown** and HTML in the doc card." ); + const op = yaml?.data.paths?.["/docs-admon"]?.get; + expect(op?.description).toContain(":::info"); }); }); }); From 8de684e4e41d395775f04a441ba7e8216d77151e Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:35:06 -0500 Subject: [PATCH 09/10] Remove admonition example from doc card spec --- demo/examples/tests/docCards.yaml | 12 ------------ .../src/openapi/__fixtures__/docCards/openapi.yaml | 12 ------------ .../src/openapi/openapi.test.ts | 6 ++++-- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/demo/examples/tests/docCards.yaml b/demo/examples/tests/docCards.yaml index 943b5ce85..cc1fb992c 100644 --- a/demo/examples/tests/docCards.yaml +++ b/demo/examples/tests/docCards.yaml @@ -13,18 +13,6 @@ paths: responses: "200": description: OK - /docs-admon: - get: - summary: Doc card admonition operation - description: > - :::info - Returns documentation with **markdown** and HTML in descriptions inside an admonition. - ::: - tags: - - docCards - responses: - "200": - description: OK tags: - name: docCards diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml index 943b5ce85..cc1fb992c 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/docCards/openapi.yaml @@ -13,18 +13,6 @@ paths: responses: "200": description: OK - /docs-admon: - get: - summary: Doc card admonition operation - description: > - :::info - Returns documentation with **markdown** and HTML in descriptions inside an admonition. - ::: - tags: - - docCards - responses: - "200": - description: OK tags: - name: docCards diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts index 7718a2597..18a2dd4de 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts @@ -49,8 +49,10 @@ describe("openapi", () => { expect(tag?.description).toBe( "This tag shows **markdown** and HTML in the doc card." ); - const op = yaml?.data.paths?.["/docs-admon"]?.get; - expect(op?.description).toContain(":::info"); + const op = yaml?.data.paths?.["/docs"]?.get; + expect(op?.description.trim()).toBe( + "Returns documentation with **markdown** and HTML in descriptions." + ); }); }); }); From e665a3dc658804bf3bd90017eac02148612e6020 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:45:02 -0500 Subject: [PATCH 10/10] Fix openapi test optional chaining --- .../docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts index 18a2dd4de..c3958b22e 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts +++ b/packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts @@ -50,7 +50,7 @@ describe("openapi", () => { "This tag shows **markdown** and HTML in the doc card." ); const op = yaml?.data.paths?.["/docs"]?.get; - expect(op?.description.trim()).toBe( + expect(op?.description?.trim()).toBe( "Returns documentation with **markdown** and HTML in descriptions." ); });