diff --git a/astro.config.ts b/astro.config.ts index b0c19f2e141ee4..8175e6760b1006 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -169,6 +169,7 @@ export default defineConfig({ "./src/mermaid.css", "./src/table.css", "./src/tailwind.css", + "./src/tooltips.css", ], pagination: false, plugins: runLinkCheck diff --git a/package-lock.json b/package-lock.json index 7cae5e6d64b081..cb3915392ae9bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,6 @@ "he": "^1.2.0", "instantsearch.css": "^8.5.0", "instantsearch.js": "^4.74.0", - "littlefoot": "^4.1.1", "lz-string": "^1.5.0", "marked": "^14.1.1", "mermaid": "^11.3.0", @@ -2395,27 +2394,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@pacote/get-style": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@pacote/get-style/-/get-style-2.0.2.tgz", - "integrity": "sha512-5Pwu8fOk0TNjP/yAsw8WgwgOnC1r890i51utJ1vjSjUolbrjv3TEtZHMKY00NzeEXIl3Gt5v8W5po3H/ftdhWw==", - "dev": true - }, - "node_modules/@pacote/pixels": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@pacote/pixels/-/pixels-2.0.2.tgz", - "integrity": "sha512-VkvJ595J6xZ0hIRoD2rJtR0J+k7b5hCs8vzkMvr1/JIlk74MltOGYhCcr4u/iGQeSwkYCi28iLORwO4X4si5XQ==", - "dev": true, - "dependencies": { - "@pacote/get-style": "^2.0.2" - } - }, - "node_modules/@pacote/throttle": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@pacote/throttle/-/throttle-2.0.2.tgz", - "integrity": "sha512-Yn8SbAAFRTiVXBvh8E0aGG44TUZOueQFtHqjIwfYkoKJHknchc3PjktiMbRFBFUCWZiS68lHP9K1gXdGu/Z1vQ==", - "dev": true - }, "node_modules/@pagefind/darwin-arm64": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.1.1.tgz", @@ -7546,17 +7524,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/littlefoot": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/littlefoot/-/littlefoot-4.1.1.tgz", - "integrity": "sha512-Nnk/aHexC97XtgOubB0kNKPECD1ccyD9Zrs9g5P0Cn+/G73w5bNV+9GQGD0s9Bealg+7Rgs9vcDOXCL4fQ7MTg==", - "dev": true, - "dependencies": { - "@pacote/get-style": "2.0.2", - "@pacote/pixels": "2.0.2", - "@pacote/throttle": "2.0.2" - } - }, "node_modules/load-yaml-file": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", diff --git a/package.json b/package.json index d45523fc78f4a2..2dce7df82d58c2 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "he": "^1.2.0", "instantsearch.css": "^8.5.0", "instantsearch.js": "^4.74.0", - "littlefoot": "^4.1.1", "lz-string": "^1.5.0", "marked": "^14.1.1", "mermaid": "^11.3.0", diff --git a/src/components/GlossaryTooltip.astro b/src/components/GlossaryTooltip.astro index c38aa71e4b9ea4..5296452b813375 100644 --- a/src/components/GlossaryTooltip.astro +++ b/src/components/GlossaryTooltip.astro @@ -1,7 +1,6 @@ --- import { z } from "astro:schema"; import { getGlossaryEntry } from "~/util/glossary"; -import "tippy.js/dist/tippy.css"; import { marked } from "marked"; type Props = z.infer; @@ -31,6 +30,7 @@ definition = definition.split(/\r?\n/)[0]; data-tooltip data-content={marked.parse(definition)} class="border-b-2 border-dashed border-accent-600" + tabindex="0" >{ link ? ( @@ -38,24 +38,11 @@ definition = definition.split(/\r?\n/)[0]; ) } + diff --git a/src/components/overrides/Head.astro b/src/components/overrides/Head.astro index d1063d8ba013f1..c2c22ee0630fe6 100644 --- a/src/components/overrides/Head.astro +++ b/src/components/overrides/Head.astro @@ -2,7 +2,7 @@ import type { Props } from "@astrojs/starlight/props"; import Default from "@astrojs/starlight/components/Head.astro"; import { differenceInCalendarDays } from "date-fns"; -import "littlefoot/dist/littlefoot.css"; +import "tippy.js/dist/tippy.css"; import { getEntry } from "astro:content"; import { getPageDescription } from "~/util/description"; @@ -164,51 +164,7 @@ if (Astro.props.entry.data.external_link) { } --- - - + + diff --git a/src/components/overrides/PageSidebar.astro b/src/components/overrides/PageSidebar.astro index c69f72d4037829..72aa0e30d06c64 100644 --- a/src/components/overrides/PageSidebar.astro +++ b/src/components/overrides/PageSidebar.astro @@ -47,6 +47,8 @@ if (Astro.props.toc) { ]; for (const header of headers) { + if (header.id === "footnote-label") continue; + const depth = headerDepth(header); const title = he.decode(header.innerText); diff --git a/src/content/docs/style-guide/components/footnotes.mdx b/src/content/docs/style-guide/components/footnotes.mdx index 18a29904fe05b5..dc2e13f876f126 100644 --- a/src/content/docs/style-guide/components/footnotes.mdx +++ b/src/content/docs/style-guide/components/footnotes.mdx @@ -7,7 +7,7 @@ To create footnotes, use the following syntax: ```mdx live You can use GitHub Flavoured Markdown footnotes![^1] -[^1]: Powered by [littlefoot.js](https://littlefoot.js.org) +[^1]: Powered by [tippy.js](https://atomiks.github.io/tippyjs/) ``` Refer to [Footnotes](/style-guide/formatting/footnotes/) to learn when to use them. \ No newline at end of file diff --git a/src/scripts/footnotes.ts b/src/scripts/footnotes.ts new file mode 100644 index 00000000000000..ee79cb82d3f1c8 --- /dev/null +++ b/src/scripts/footnotes.ts @@ -0,0 +1,26 @@ +import { addTooltip } from "~/util/tippy"; + +const footnotes = document.querySelector("section.footnotes"); + +if (footnotes) { + const notes = footnotes.querySelectorAll("li"); + + for (const note of notes) { + const content = note.querySelector("p") as HTMLParagraphElement; + + const fnrefs = document.querySelectorAll( + `#${note.id.replace("fn", "fnref")}`, + ); + + for (const fnref of fnrefs) { + addTooltip(fnref, content.innerHTML); + + fnref.classList.add("footnote"); + + fnref.setAttribute("tabindex", "0"); + fnref.removeAttribute("href"); + } + } + + footnotes.remove(); +} diff --git a/src/scripts/mermaid.ts b/src/scripts/mermaid.ts new file mode 100644 index 00000000000000..7698f76482a681 --- /dev/null +++ b/src/scripts/mermaid.ts @@ -0,0 +1,36 @@ +import mermaid from "mermaid"; + +const diagrams = document.querySelectorAll("pre.mermaid"); + +let init = false; + +async function render() { + const theme = + document.documentElement.getAttribute("data-theme") === "light" + ? "neutral" + : "dark"; + + for (const diagram of diagrams) { + if (!init) { + diagram.setAttribute("data-diagram", diagram.textContent as string); + } + + const def = diagram.getAttribute("data-diagram") as string; + + mermaid.initialize({ startOnLoad: false, theme }); + await mermaid + .render(`mermaid-${crypto.randomUUID()}`, def) + .then(({ svg }) => (diagram.innerHTML = svg)); + + diagram.setAttribute("data-processed", "true"); + } + + init = true; +} + +const obs = new MutationObserver(() => render()); + +obs.observe(document.documentElement, { + attributes: true, + attributeFilter: ["data-theme"], +}); diff --git a/src/tooltips.css b/src/tooltips.css new file mode 100644 index 00000000000000..7a732a06f29d4e --- /dev/null +++ b/src/tooltips.css @@ -0,0 +1,12 @@ +@tailwind utilities; + +.footnote { + @apply text-xs !text-[--sl-color-accent] font-semibold p-1 -m-1; +} + +.tippy-box { + background-color: var(--sl-color-bg-nav); + border-color: var(--sl-color-text); + border: 0.1em solid; + color: var(--sl-color-white); +} \ No newline at end of file diff --git a/src/util/tippy.ts b/src/util/tippy.ts new file mode 100644 index 00000000000000..69e143806b8e0c --- /dev/null +++ b/src/util/tippy.ts @@ -0,0 +1,18 @@ +import tippy from "tippy.js"; + +export function addTooltip(element: HTMLElement, content: string) { + const id = "#" + CSS.escape(element.id); + + tippy(id, { + content, + allowHTML: true, + interactive: true, + placement: "auto", + arrow: false, + // This is imperfect as it stops you from tabbing into + // links inside the tooltip, but stops tooltips being + // cutoff by the sidebar + // https://atomiks.github.io/tippyjs/v6/faq/#my-tooltip-appears-cut-off-or-is-not-showing-at-all + appendTo: document.body, + }); +}