@tenphi/renderer 0.22.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/client-navigation.d.ts +1 -0
- package/dist/client/client-navigation.js +32 -0
- package/dist/client/client-navigation.js.map +1 -0
- package/dist/client/code-copy.js +3 -3
- package/dist/client/code-copy.js.map +1 -1
- package/dist/client/heading-links.js +4 -4
- package/dist/client/heading-links.js.map +1 -1
- package/dist/client/navigation-router.d.ts +2 -0
- package/dist/client/navigation-router.js +36 -0
- package/dist/client/navigation-router.js.map +1 -0
- package/dist/client/navigation.js +3 -3
- package/dist/client/navigation.js.map +1 -1
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +16 -2
- package/dist/client/search.js.map +1 -1
- package/dist/client/table-of-contents.js +2 -2
- package/dist/client/table-of-contents.js.map +1 -1
- package/dist/components/AppearanceInit.astro +6 -0
- package/dist/components/Card.styles.js +1 -0
- package/dist/components/CodeGroup.astro +8 -1
- package/dist/components/CodeGroup.styles.js +1 -2
- package/dist/components/Document.styles.js +54 -25
- package/dist/components/EditLink.astro +1 -1
- package/dist/components/Header.styles.js +13 -13
- package/dist/components/HeaderLinks.astro +4 -8
- package/dist/components/HeaderLinks.styles.js +17 -17
- package/dist/components/Hero.styles.js +28 -30
- package/dist/components/Icon.astro +3 -3
- package/dist/components/LanguageSelect.styles.js +8 -8
- package/dist/components/MainContent.styles.js +3 -3
- package/dist/components/MainPane.styles.js +1 -1
- package/dist/components/MarkdownAlert.styles.js +16 -17
- package/dist/components/MarkdownCodeBlock.styles.js +31 -19
- package/dist/components/MarkdownContent.styles.js +47 -89
- package/dist/components/MarkdownHeading.styles.js +23 -24
- package/dist/components/MarkdownInlineCode.styles.js +1 -1
- package/dist/components/MarkdownTable.styles.js +5 -5
- package/dist/components/Mermaid.styles.js +4 -1
- package/dist/components/MermaidSource.styles.js +1 -1
- package/dist/components/MobileMenuFooter.styles.js +1 -1
- package/dist/components/MobileMenuToggle.styles.js +3 -3
- package/dist/components/MobileNavigationTabs.astro +3 -2
- package/dist/components/MobileNavigationTabs.styles.js +3 -3
- package/dist/components/MobileTableOfContents.styles.js +2 -2
- package/dist/components/PackageVersion.styles.js +1 -1
- package/dist/components/PageFrame.styles.js +6 -6
- package/dist/components/Pagination.astro +2 -2
- package/dist/components/Pagination.styles.js +10 -10
- package/dist/components/Preview.astro +3 -4
- package/dist/components/Preview.styles.js +2 -2
- package/dist/components/Search.styles.js +13 -13
- package/dist/components/SearchButton.styles.js +10 -10
- package/dist/components/SearchResults.styles.js +21 -31
- package/dist/components/SelectPopover.astro +18 -9
- package/dist/components/Sidebar.styles.js +58 -49
- package/dist/components/SidebarList.astro +9 -6
- package/dist/components/SiteLogo.astro +2 -2
- package/dist/components/SiteLogo.styles.js +4 -4
- package/dist/components/SyntaxHighlight.styles.js +69 -48
- package/dist/components/TableOfContents.styles.js +1 -1
- package/dist/components/TableOfContentsLayout.styles.js +7 -7
- package/dist/components/ThemeSelect.styles.js +12 -12
- package/dist/components/TopNavigation.styles.js +1 -1
- package/dist/components/VersionSwitcher.styles.js +1 -1
- package/dist/components/appearance-bootstrap.js +21 -0
- package/dist/components/select-popover-styles.js +14 -14
- package/dist/components/tasty-states.js +10 -9
- package/dist/eslint-plugin.js +6 -9
- package/dist/eslint-plugin.js.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/markdown/rendered-content.js +2 -2
- package/dist/markdown/rendered-content.js.map +1 -1
- package/dist/overrides/Header.astro +8 -12
- package/dist/overrides/Hero.astro +11 -6
- package/dist/overrides/MobileMenuFooter.astro +1 -1
- package/dist/overrides/MobileMenuToggle.astro +6 -5
- package/dist/overrides/PageFrame.astro +4 -3
- package/dist/overrides/Search.astro +22 -15
- package/dist/overrides/Sidebar.astro +2 -3
- package/dist/overrides/ThemeSelect.astro +2 -2
- package/dist/routes/Page.astro +17 -9
- package/dist/styling.js +1 -1
- package/dist/{tasty-states-_JhxFdK1.js → tasty-states-BIgiJQ3N.js} +7 -10
- package/dist/tasty-states-BIgiJQ3N.js.map +1 -0
- package/dist/theme/shiki-theme.d.ts.map +1 -1
- package/dist/theme/shiki-theme.js +37 -19
- package/dist/theme/shiki-theme.js.map +1 -1
- package/package.json +3 -3
- package/dist/tasty-states-_JhxFdK1.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./navigation-router.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/client/client-navigation.ts
|
|
2
|
+
let router;
|
|
3
|
+
function loadRouter() {
|
|
4
|
+
return router ??= import("./navigation-router.js").catch((error) => {
|
|
5
|
+
router = void 0;
|
|
6
|
+
throw error;
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
function navigationLink(target) {
|
|
10
|
+
const link = target instanceof Element ? target.closest("a[href]") : null;
|
|
11
|
+
if (!(link instanceof HTMLAnchorElement) || link.hasAttribute("download") || link.hasAttribute("data-astro-reload") || link.target && link.target !== "_self") return;
|
|
12
|
+
const url = new URL(link.href);
|
|
13
|
+
if (url.origin !== location.origin || !router && url.pathname === location.pathname && url.search === location.search && url.hash) return;
|
|
14
|
+
return link;
|
|
15
|
+
}
|
|
16
|
+
for (const name of ["pointerover", "focusin"]) document.addEventListener(name, (event) => {
|
|
17
|
+
if (navigationLink(event.composedPath()[0])) loadRouter().catch(() => {});
|
|
18
|
+
});
|
|
19
|
+
document.addEventListener("click", (event) => {
|
|
20
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
21
|
+
const link = navigationLink(event.composedPath()[0]);
|
|
22
|
+
if (!link) return;
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
loadRouter().then(({ navigate }) => navigate(link.href, {
|
|
25
|
+
sourceElement: link,
|
|
26
|
+
history: link.dataset.astroHistory === "replace" ? "replace" : "auto"
|
|
27
|
+
})).catch(() => location.assign(link.href));
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
export {};
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=client-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-navigation.js","names":[],"sources":["../../src/client/client-navigation.ts"],"sourcesContent":["// Use Astro's public router without ClientRouter's vendor stylesheet. Cookbook\n// owns link interception and extracted accessibility styles; Astro owns fetch,\n// stylesheet readiness, script execution, history, and route announcements.\nlet router: Promise<typeof import(\"./navigation-router.js\")> | undefined;\nfunction loadRouter() {\n return (router ??= import(\"./navigation-router.js\").catch(\n (error: unknown) => {\n router = undefined;\n throw error;\n },\n ));\n}\n\nfunction navigationLink(target: EventTarget | undefined) {\n const link = target instanceof Element ? target.closest(\"a[href]\") : null;\n if (\n !(link instanceof HTMLAnchorElement) ||\n link.hasAttribute(\"download\") ||\n link.hasAttribute(\"data-astro-reload\") ||\n (link.target && link.target !== \"_self\")\n )\n return;\n const url = new URL(link.href);\n if (\n url.origin !== location.origin ||\n (!router &&\n url.pathname === location.pathname &&\n url.search === location.search &&\n url.hash)\n )\n return;\n // Heading links stay native until a page-navigation intent loads the router.\n return link;\n}\n\n// Download the router on navigation intent, rather than for every reader.\nfor (const name of [\"pointerover\", \"focusin\"]) {\n document.addEventListener(name, (event) => {\n if (navigationLink(event.composedPath()[0]))\n void loadRouter().catch(() => {\n // A later click can retry; native navigation remains the fallback.\n });\n });\n}\n\ndocument.addEventListener(\"click\", (event) => {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n return;\n const link = navigationLink(event.composedPath()[0]);\n if (!link) return;\n event.preventDefault();\n void loadRouter()\n .then(({ navigate }) =>\n navigate(link.href, {\n sourceElement: link,\n history: link.dataset.astroHistory === \"replace\" ? \"replace\" : \"auto\",\n }),\n )\n .catch(() => location.assign(link.href));\n});\n"],"mappings":";AAGA,IAAI;AACJ,SAAS,aAAa;CACpB,OAAQ,WAAW,OAAO,yBAAyB,CAAC,OACjD,UAAmB;EAClB,SAAS,KAAA;EACT,MAAM;CACR,CACF;AACF;AAEA,SAAS,eAAe,QAAiC;CACvD,MAAM,OAAO,kBAAkB,UAAU,OAAO,QAAQ,SAAS,IAAI;CACrE,IACE,EAAE,gBAAgB,sBAClB,KAAK,aAAa,UAAU,KAC5B,KAAK,aAAa,mBAAmB,KACpC,KAAK,UAAU,KAAK,WAAW,SAEhC;CACF,MAAM,MAAM,IAAI,IAAI,KAAK,IAAI;CAC7B,IACE,IAAI,WAAW,SAAS,UACvB,CAAC,UACA,IAAI,aAAa,SAAS,YAC1B,IAAI,WAAW,SAAS,UACxB,IAAI,MAEN;CAEF,OAAO;AACT;AAGA,KAAK,MAAM,QAAQ,CAAC,eAAe,SAAS,GAC1C,SAAS,iBAAiB,OAAO,UAAU;CACzC,IAAI,eAAe,MAAM,aAAa,CAAC,CAAC,EAAE,GACxC,WAAgB,CAAC,CAAC,YAAY,CAE9B,CAAC;AACL,CAAC;AAGH,SAAS,iBAAiB,UAAU,UAAU;CAC5C,IACE,MAAM,oBACN,MAAM,WAAW,KACjB,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,QAEN;CACF,MAAM,OAAO,eAAe,MAAM,aAAa,CAAC,CAAC,EAAE;CACnD,IAAI,CAAC,MAAM;CACX,MAAM,eAAe;CACrB,WAAgB,CAAC,CACd,MAAM,EAAE,eACP,SAAS,KAAK,MAAM;EAClB,eAAe;EACf,SAAS,KAAK,QAAQ,iBAAiB,YAAY,YAAY;CACjE,CAAC,CACH,CAAC,CACA,YAAY,SAAS,OAAO,KAAK,IAAI,CAAC;AAC3C,CAAC"}
|
package/dist/client/code-copy.js
CHANGED
|
@@ -22,17 +22,17 @@ var CookbookCodeBlock = class extends HTMLElement {
|
|
|
22
22
|
try {
|
|
23
23
|
await writeClipboard(code);
|
|
24
24
|
} catch {
|
|
25
|
-
|
|
25
|
+
this.dataset.copyState = "error";
|
|
26
26
|
button.setAttribute("aria-label", message("codeCopyError"));
|
|
27
27
|
button.title = message("codeCopyError");
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
this.dataset.copyState = "copied";
|
|
31
31
|
button.setAttribute("aria-label", message("codeCopied"));
|
|
32
32
|
button.title = message("codeCopied");
|
|
33
33
|
if (this.#resetTimer !== void 0) window.clearTimeout(this.#resetTimer);
|
|
34
34
|
this.#resetTimer = window.setTimeout(() => {
|
|
35
|
-
delete
|
|
35
|
+
delete this.dataset.copyState;
|
|
36
36
|
button.setAttribute("aria-label", message("copyCode"));
|
|
37
37
|
button.title = message("copyCode");
|
|
38
38
|
this.#resetTimer = void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-copy.js","names":[],"sources":["../../src/client/code-copy.ts"],"sourcesContent":["import { message } from \"./messages.js\";\n\nclass CookbookCodeBlock extends HTMLElement {\n #resetTimer: number | undefined;\n\n connectedCallback() {\n const button = this.querySelector<HTMLButtonElement>(\"[data-copy-code]\");\n if (button) {\n button.setAttribute(\"aria-label\", message(\"copyCode\"));\n button.title = message(\"copyCode\");\n }\n this.addEventListener(\"click\", this.#copy);\n }\n\n disconnectedCallback() {\n this.removeEventListener(\"click\", this.#copy);\n if (this.#resetTimer !== undefined) {\n window.clearTimeout(this.#resetTimer);\n }\n }\n\n #copy = async (event: MouseEvent) => {\n const target = event.target;\n const button =\n target instanceof Element\n ? target.closest<HTMLButtonElement>(\"[data-copy-code]\")\n : undefined;\n const code = this.querySelector<HTMLElement>(\"pre code\");\n if (!button || !this.contains(button) || !code) return;\n\n try {\n await writeClipboard(code);\n } catch {\n
|
|
1
|
+
{"version":3,"file":"code-copy.js","names":[],"sources":["../../src/client/code-copy.ts"],"sourcesContent":["import { message } from \"./messages.js\";\n\nclass CookbookCodeBlock extends HTMLElement {\n #resetTimer: number | undefined;\n\n connectedCallback() {\n const button = this.querySelector<HTMLButtonElement>(\"[data-copy-code]\");\n if (button) {\n button.setAttribute(\"aria-label\", message(\"copyCode\"));\n button.title = message(\"copyCode\");\n }\n this.addEventListener(\"click\", this.#copy);\n }\n\n disconnectedCallback() {\n this.removeEventListener(\"click\", this.#copy);\n if (this.#resetTimer !== undefined) {\n window.clearTimeout(this.#resetTimer);\n }\n }\n\n #copy = async (event: MouseEvent) => {\n const target = event.target;\n const button =\n target instanceof Element\n ? target.closest<HTMLButtonElement>(\"[data-copy-code]\")\n : undefined;\n const code = this.querySelector<HTMLElement>(\"pre code\");\n if (!button || !this.contains(button) || !code) return;\n\n try {\n await writeClipboard(code);\n } catch {\n this.dataset.copyState = \"error\";\n button.setAttribute(\"aria-label\", message(\"codeCopyError\"));\n button.title = message(\"codeCopyError\");\n return;\n }\n\n this.dataset.copyState = \"copied\";\n button.setAttribute(\"aria-label\", message(\"codeCopied\"));\n button.title = message(\"codeCopied\");\n\n if (this.#resetTimer !== undefined) {\n window.clearTimeout(this.#resetTimer);\n }\n this.#resetTimer = window.setTimeout(() => {\n delete this.dataset.copyState;\n button.setAttribute(\"aria-label\", message(\"copyCode\"));\n button.title = message(\"copyCode\");\n this.#resetTimer = undefined;\n }, 2_000);\n };\n}\n\nasync function writeClipboard(code: HTMLElement): Promise<void> {\n const value = code.textContent ?? \"\";\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return;\n }\n\n const selection = window.getSelection();\n const previousRanges = selection\n ? Array.from({ length: selection.rangeCount }, (_, index) =>\n selection.getRangeAt(index),\n )\n : [];\n const range = document.createRange();\n range.selectNodeContents(code);\n selection?.removeAllRanges();\n selection?.addRange(range);\n const copied = document.execCommand(\"copy\");\n selection?.removeAllRanges();\n for (const previousRange of previousRanges)\n selection?.addRange(previousRange);\n if (!copied) throw new Error(\"Clipboard unavailable\");\n}\n\nif (!customElements.get(\"cookbook-code-block\")) {\n customElements.define(\"cookbook-code-block\", CookbookCodeBlock);\n}\n"],"mappings":";;AAEA,IAAM,oBAAN,cAAgC,YAAY;CAC1C;CAEA,oBAAoB;EAClB,MAAM,SAAS,KAAK,cAAiC,kBAAkB;EACvE,IAAI,QAAQ;GACV,OAAO,aAAa,cAAc,QAAQ,UAAU,CAAC;GACrD,OAAO,QAAQ,QAAQ,UAAU;EACnC;EACA,KAAK,iBAAiB,SAAS,KAAK,KAAK;CAC3C;CAEA,uBAAuB;EACrB,KAAK,oBAAoB,SAAS,KAAK,KAAK;EAC5C,IAAI,KAAK,gBAAgB,KAAA,GACvB,OAAO,aAAa,KAAK,WAAW;CAExC;CAEA,QAAQ,OAAO,UAAsB;EACnC,MAAM,SAAS,MAAM;EACrB,MAAM,SACJ,kBAAkB,UACd,OAAO,QAA2B,kBAAkB,IACpD,KAAA;EACN,MAAM,OAAO,KAAK,cAA2B,UAAU;EACvD,IAAI,CAAC,UAAU,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC,MAAM;EAEhD,IAAI;GACF,MAAM,eAAe,IAAI;EAC3B,QAAQ;GACN,KAAK,QAAQ,YAAY;GACzB,OAAO,aAAa,cAAc,QAAQ,eAAe,CAAC;GAC1D,OAAO,QAAQ,QAAQ,eAAe;GACtC;EACF;EAEA,KAAK,QAAQ,YAAY;EACzB,OAAO,aAAa,cAAc,QAAQ,YAAY,CAAC;EACvD,OAAO,QAAQ,QAAQ,YAAY;EAEnC,IAAI,KAAK,gBAAgB,KAAA,GACvB,OAAO,aAAa,KAAK,WAAW;EAEtC,KAAK,cAAc,OAAO,iBAAiB;GACzC,OAAO,KAAK,QAAQ;GACpB,OAAO,aAAa,cAAc,QAAQ,UAAU,CAAC;GACrD,OAAO,QAAQ,QAAQ,UAAU;GACjC,KAAK,cAAc,KAAA;EACrB,GAAG,GAAK;CACV;AACF;AAEA,eAAe,eAAe,MAAkC;CAC9D,MAAM,QAAQ,KAAK,eAAe;CAClC,IAAI,UAAU,WAAW,WAAW;EAClC,MAAM,UAAU,UAAU,UAAU,KAAK;EACzC;CACF;CAEA,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,iBAAiB,YACnB,MAAM,KAAK,EAAE,QAAQ,UAAU,WAAW,IAAI,GAAG,UAC/C,UAAU,WAAW,KAAK,CAC5B,IACA,CAAC;CACL,MAAM,QAAQ,SAAS,YAAY;CACnC,MAAM,mBAAmB,IAAI;CAC7B,WAAW,gBAAgB;CAC3B,WAAW,SAAS,KAAK;CACzB,MAAM,SAAS,SAAS,YAAY,MAAM;CAC1C,WAAW,gBAAgB;CAC3B,KAAK,MAAM,iBAAiB,gBAC1B,WAAW,SAAS,aAAa;CACnC,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,uBAAuB;AACtD;AAEA,IAAI,CAAC,eAAe,IAAI,qBAAqB,GAC3C,eAAe,OAAO,uBAAuB,iBAAiB"}
|
|
@@ -2,16 +2,16 @@ import { t as message } from "../messages-bS8G9Pj8.js";
|
|
|
2
2
|
//#region src/client/heading-links.ts
|
|
3
3
|
/** Keep real fragment links as the no-JavaScript and modified-click fallback. */
|
|
4
4
|
function initializeHeadingLinks() {
|
|
5
|
-
for (const content of document.querySelectorAll("
|
|
5
|
+
for (const content of document.querySelectorAll("[data-element=Markdown]")) {
|
|
6
6
|
let status = content.querySelector("[data-heading-copy-status]");
|
|
7
7
|
if (!status) {
|
|
8
8
|
status = document.createElement("span");
|
|
9
|
-
status.
|
|
9
|
+
status.dataset.srOnly = "";
|
|
10
10
|
status.dataset.headingCopyStatus = "";
|
|
11
11
|
status.setAttribute("role", "status");
|
|
12
12
|
content.append(status);
|
|
13
13
|
}
|
|
14
|
-
for (const link of content.querySelectorAll("
|
|
14
|
+
for (const link of content.querySelectorAll("[data-element=MarkdownHeading] > [data-element=Anchor][href^=\"#\"]")) {
|
|
15
15
|
if (link.dataset.copyReady) continue;
|
|
16
16
|
link.dataset.copyReady = "true";
|
|
17
17
|
const heading = link.previousElementSibling?.textContent?.trim() ?? "section";
|
|
@@ -63,7 +63,7 @@ async function copyLink(value) {
|
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
const input = document.createElement("textarea");
|
|
66
|
-
input.
|
|
66
|
+
input.dataset.srOnly = "";
|
|
67
67
|
input.value = value;
|
|
68
68
|
input.readOnly = true;
|
|
69
69
|
const focused = document.activeElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading-links.js","names":["uiMessage","message"],"sources":["../../src/client/heading-links.ts"],"sourcesContent":["import { message as uiMessage } from \"./messages.js\";\n/** Keep real fragment links as the no-JavaScript and modified-click fallback. */\nexport function initializeHeadingLinks(): void {\n for (const content of document.querySelectorAll(\
|
|
1
|
+
{"version":3,"file":"heading-links.js","names":["uiMessage","message"],"sources":["../../src/client/heading-links.ts"],"sourcesContent":["import { message as uiMessage } from \"./messages.js\";\n/** Keep real fragment links as the no-JavaScript and modified-click fallback. */\nexport function initializeHeadingLinks(): void {\n for (const content of document.querySelectorAll(\"[data-element=Markdown]\")) {\n let status = content.querySelector<HTMLElement>(\n \"[data-heading-copy-status]\",\n );\n if (!status) {\n status = document.createElement(\"span\");\n status.dataset.srOnly = \"\";\n status.dataset.headingCopyStatus = \"\";\n status.setAttribute(\"role\", \"status\");\n content.append(status);\n }\n\n for (const link of content.querySelectorAll<HTMLAnchorElement>(\n '[data-element=MarkdownHeading] > [data-element=Anchor][href^=\"#\"]',\n )) {\n if (link.dataset.copyReady) continue;\n link.dataset.copyReady = \"true\";\n const heading =\n link.previousElementSibling?.textContent?.trim() ?? \"section\";\n const label = uiMessage(\"copyHeading\").replace(\"{heading}\", heading);\n link.setAttribute(\"role\", \"button\");\n link.setAttribute(\"aria-label\", label);\n link.title = label;\n let timer: number | undefined;\n let attempt = 0;\n\n link.addEventListener(\"keydown\", (event) => {\n if (\n event.key !== \" \" ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n )\n return;\n event.preventDefault();\n if (!event.repeat) link.click();\n });\n link.addEventListener(\"click\", async (event) => {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n )\n return;\n event.preventDefault();\n window.clearTimeout(timer);\n delete link.dataset.copyState;\n status.textContent = \"\";\n const currentAttempt = ++attempt;\n let message: string;\n let state: string;\n try {\n const url = new URL(link.getAttribute(\"href\")!, window.location.href);\n await copyLink(url.href);\n message = uiMessage(\"linkCopied\");\n state = \"copied\";\n } catch {\n message = uiMessage(\"linkCopyError\");\n state = \"error\";\n }\n if (currentAttempt !== attempt || !link.isConnected) return;\n link.dataset.copyState = state;\n link.setAttribute(\"aria-label\", message);\n link.title = message;\n status.textContent = `${message}: ${heading}`;\n timer = window.setTimeout(() => {\n delete link.dataset.copyState;\n link.setAttribute(\"aria-label\", label);\n link.title = label;\n }, 2_000);\n });\n }\n }\n}\n\nasync function copyLink(value: string): Promise<void> {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return;\n }\n\n // Older browsers and insecure local previews may not expose Clipboard API.\n const input = document.createElement(\"textarea\");\n input.dataset.srOnly = \"\";\n input.value = value;\n input.readOnly = true;\n const focused = document.activeElement;\n const selection = window.getSelection();\n const ranges = selection\n ? Array.from({ length: selection.rangeCount }, (_, index) =>\n selection.getRangeAt(index),\n )\n : [];\n document.body.append(input);\n try {\n input.focus({ preventScroll: true });\n input.select();\n if (!document.execCommand(\"copy\")) throw new Error(\"Clipboard unavailable\");\n } finally {\n input.remove();\n if (focused instanceof HTMLElement) focused.focus({ preventScroll: true });\n selection?.removeAllRanges();\n for (const range of ranges) selection?.addRange(range);\n }\n}\n"],"mappings":";;;AAEA,SAAgB,yBAA+B;CAC7C,KAAK,MAAM,WAAW,SAAS,iBAAiB,yBAAyB,GAAG;EAC1E,IAAI,SAAS,QAAQ,cACnB,4BACF;EACA,IAAI,CAAC,QAAQ;GACX,SAAS,SAAS,cAAc,MAAM;GACtC,OAAO,QAAQ,SAAS;GACxB,OAAO,QAAQ,oBAAoB;GACnC,OAAO,aAAa,QAAQ,QAAQ;GACpC,QAAQ,OAAO,MAAM;EACvB;EAEA,KAAK,MAAM,QAAQ,QAAQ,iBACzB,qEACF,GAAG;GACD,IAAI,KAAK,QAAQ,WAAW;GAC5B,KAAK,QAAQ,YAAY;GACzB,MAAM,UACJ,KAAK,wBAAwB,aAAa,KAAK,KAAK;GACtD,MAAM,QAAQA,QAAU,aAAa,CAAC,CAAC,QAAQ,aAAa,OAAO;GACnE,KAAK,aAAa,QAAQ,QAAQ;GAClC,KAAK,aAAa,cAAc,KAAK;GACrC,KAAK,QAAQ;GACb,IAAI;GACJ,IAAI,UAAU;GAEd,KAAK,iBAAiB,YAAY,UAAU;IAC1C,IACE,MAAM,QAAQ,OACd,MAAM,UACN,MAAM,WACN,MAAM,WACN,MAAM,UAEN;IACF,MAAM,eAAe;IACrB,IAAI,CAAC,MAAM,QAAQ,KAAK,MAAM;GAChC,CAAC;GACD,KAAK,iBAAiB,SAAS,OAAO,UAAU;IAC9C,IACE,MAAM,oBACN,MAAM,WAAW,KACjB,MAAM,UACN,MAAM,WACN,MAAM,WACN,MAAM,UAEN;IACF,MAAM,eAAe;IACrB,OAAO,aAAa,KAAK;IACzB,OAAO,KAAK,QAAQ;IACpB,OAAO,cAAc;IACrB,MAAM,iBAAiB,EAAE;IACzB,IAAIC;IACJ,IAAI;IACJ,IAAI;KAEF,MAAM,SAAS,IADC,IAAI,KAAK,aAAa,MAAM,GAAI,OAAO,SAAS,IAC/C,CAAC,CAAC,IAAI;KACvB,YAAUD,QAAU,YAAY;KAChC,QAAQ;IACV,QAAQ;KACN,YAAUA,QAAU,eAAe;KACnC,QAAQ;IACV;IACA,IAAI,mBAAmB,WAAW,CAAC,KAAK,aAAa;IACrD,KAAK,QAAQ,YAAY;IACzB,KAAK,aAAa,cAAcC,SAAO;IACvC,KAAK,QAAQA;IACb,OAAO,cAAc,GAAGA,UAAQ,IAAI;IACpC,QAAQ,OAAO,iBAAiB;KAC9B,OAAO,KAAK,QAAQ;KACpB,KAAK,aAAa,cAAc,KAAK;KACrC,KAAK,QAAQ;IACf,GAAG,GAAK;GACV,CAAC;EACH;CACF;AACF;AAEA,eAAe,SAAS,OAA8B;CACpD,IAAI,UAAU,WAAW,WAAW;EAClC,MAAM,UAAU,UAAU,UAAU,KAAK;EACzC;CACF;CAGA,MAAM,QAAQ,SAAS,cAAc,UAAU;CAC/C,MAAM,QAAQ,SAAS;CACvB,MAAM,QAAQ;CACd,MAAM,WAAW;CACjB,MAAM,UAAU,SAAS;CACzB,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,SAAS,YACX,MAAM,KAAK,EAAE,QAAQ,UAAU,WAAW,IAAI,GAAG,UAC/C,UAAU,WAAW,KAAK,CAC5B,IACA,CAAC;CACL,SAAS,KAAK,OAAO,KAAK;CAC1B,IAAI;EACF,MAAM,MAAM,EAAE,eAAe,KAAK,CAAC;EACnC,MAAM,OAAO;EACb,IAAI,CAAC,SAAS,YAAY,MAAM,GAAG,MAAM,IAAI,MAAM,uBAAuB;CAC5E,UAAU;EACR,MAAM,OAAO;EACb,IAAI,mBAAmB,aAAa,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;EACzE,WAAW,gBAAgB;EAC3B,KAAK,MAAM,SAAS,QAAQ,WAAW,SAAS,KAAK;CACvD;AACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { initializeTabs } from "./tabs.js";
|
|
2
|
+
import { navigate } from "astro:transitions/client";
|
|
3
|
+
//#region src/client/navigation-router.ts
|
|
4
|
+
document.addEventListener("astro:before-swap", (event) => {
|
|
5
|
+
const transition = event;
|
|
6
|
+
transition.viewTransition.skipTransition();
|
|
7
|
+
for (const name of ["data-theme", "data-contrast"]) {
|
|
8
|
+
const value = document.documentElement.getAttribute(name);
|
|
9
|
+
if (value === null) transition.newDocument.documentElement.removeAttribute(name);
|
|
10
|
+
else transition.newDocument.documentElement.setAttribute(name, value);
|
|
11
|
+
}
|
|
12
|
+
const sidebar = document.querySelector("#cookbook__sidebar");
|
|
13
|
+
const key = sidebar?.querySelector("cookbook-sidebar")?.dataset.storageKey;
|
|
14
|
+
const scroll = sidebar?.scrollTop ?? 0;
|
|
15
|
+
const swap = transition.swap;
|
|
16
|
+
transition.swap = () => {
|
|
17
|
+
swap();
|
|
18
|
+
const next = document.querySelector("#cookbook__sidebar");
|
|
19
|
+
if (next && key && next.querySelector("cookbook-sidebar")?.dataset.storageKey === key && matchMedia("(min-width: 50rem)").matches) next.scrollTop = scroll;
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
document.addEventListener("astro:after-swap", () => {
|
|
23
|
+
initializeTabs();
|
|
24
|
+
if (!location.hash) {
|
|
25
|
+
window.scrollTo({
|
|
26
|
+
top: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
behavior: "instant"
|
|
29
|
+
});
|
|
30
|
+
document.getElementById("main-content")?.focus({ preventScroll: true });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export { navigate };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=navigation-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-router.js","names":[],"sources":["../../src/client/navigation-router.ts"],"sourcesContent":["import type { TransitionBeforeSwapEvent } from \"astro:transitions/client\";\nimport { initializeTabs } from \"./tabs.js\";\nexport { navigate } from \"astro:transitions/client\";\n\n// Load swap behavior with the router, before the first client navigation.\ndocument.addEventListener(\"astro:before-swap\", (event) => {\n const transition = event as TransitionBeforeSwapEvent;\n // Instant swaps avoid the browser's default full-page crossfade.\n transition.viewTransition.skipTransition();\n for (const name of [\"data-theme\", \"data-contrast\"]) {\n const value = document.documentElement.getAttribute(name);\n if (value === null)\n transition.newDocument.documentElement.removeAttribute(name);\n else transition.newDocument.documentElement.setAttribute(name, value);\n }\n const sidebar = document.querySelector<HTMLElement>(\"#cookbook__sidebar\");\n const key =\n sidebar?.querySelector<HTMLElement>(\"cookbook-sidebar\")?.dataset.storageKey;\n const scroll = sidebar?.scrollTop ?? 0;\n const swap = transition.swap;\n transition.swap = () => {\n swap();\n const next = document.querySelector<HTMLElement>(\"#cookbook__sidebar\");\n if (\n next &&\n key &&\n next.querySelector<HTMLElement>(\"cookbook-sidebar\")?.dataset\n .storageKey === key &&\n matchMedia(\"(min-width: 50rem)\").matches\n )\n next.scrollTop = scroll;\n };\n});\n\ndocument.addEventListener(\"astro:after-swap\", () => {\n // Enhance incoming panels synchronously, before a frame can show every\n // no-JavaScript panel and then jump when page-load scripts hide them.\n initializeTabs();\n // Keep fragment navigation intact, but reset article scroll on page changes,\n // including Back/Forward. Sidebar scroll is independent of the document.\n if (!location.hash) {\n window.scrollTo({ top: 0, left: 0, behavior: \"instant\" });\n document.getElementById(\"main-content\")?.focus({ preventScroll: true });\n }\n});\n"],"mappings":";;;AAKA,SAAS,iBAAiB,sBAAsB,UAAU;CACxD,MAAM,aAAa;CAEnB,WAAW,eAAe,eAAe;CACzC,KAAK,MAAM,QAAQ,CAAC,cAAc,eAAe,GAAG;EAClD,MAAM,QAAQ,SAAS,gBAAgB,aAAa,IAAI;EACxD,IAAI,UAAU,MACZ,WAAW,YAAY,gBAAgB,gBAAgB,IAAI;OACxD,WAAW,YAAY,gBAAgB,aAAa,MAAM,KAAK;CACtE;CACA,MAAM,UAAU,SAAS,cAA2B,oBAAoB;CACxE,MAAM,MACJ,SAAS,cAA2B,kBAAkB,CAAC,EAAE,QAAQ;CACnE,MAAM,SAAS,SAAS,aAAa;CACrC,MAAM,OAAO,WAAW;CACxB,WAAW,aAAa;EACtB,KAAK;EACL,MAAM,OAAO,SAAS,cAA2B,oBAAoB;EACrE,IACE,QACA,OACA,KAAK,cAA2B,kBAAkB,CAAC,EAAE,QAClD,eAAe,OAClB,WAAW,oBAAoB,CAAC,CAAC,SAEjC,KAAK,YAAY;CACrB;AACF,CAAC;AAED,SAAS,iBAAiB,0BAA0B;CAGlD,eAAe;CAGf,IAAI,CAAC,SAAS,MAAM;EAClB,OAAO,SAAS;GAAE,KAAK;GAAG,MAAM;GAAG,UAAU;EAAU,CAAC;EACxD,SAAS,eAAe,cAAc,CAAC,EAAE,MAAM,EAAE,eAAe,KAAK,CAAC;CACxE;AACF,CAAC"}
|
|
@@ -8,7 +8,7 @@ var CookbookSidebarPane = class extends HTMLElement {
|
|
|
8
8
|
this.#listeners?.abort();
|
|
9
9
|
this.#listeners = new AbortController();
|
|
10
10
|
const { signal } = this.#listeners;
|
|
11
|
-
this.#trigger = document.querySelector("
|
|
11
|
+
this.#trigger = document.querySelector("[data-element=MobileMenuToggle][popovertarget=\"cookbook__sidebar\"]") ?? void 0;
|
|
12
12
|
const desktop = matchMedia("(min-width: 50rem)");
|
|
13
13
|
const syncViewport = () => {
|
|
14
14
|
if (desktop.matches) {
|
|
@@ -31,7 +31,7 @@ var CookbookSidebarPane = class extends HTMLElement {
|
|
|
31
31
|
if (open) {
|
|
32
32
|
this.getBoundingClientRect();
|
|
33
33
|
this.setAttribute("data-open", "");
|
|
34
|
-
for (const element of document.querySelectorAll("
|
|
34
|
+
for (const element of document.querySelectorAll("[data-element=HeaderFrame], [data-element=MainFrame], [data-element=SkipLink]")) {
|
|
35
35
|
this.#inert.set(element, element.inert);
|
|
36
36
|
element.inert = true;
|
|
37
37
|
}
|
|
@@ -44,7 +44,7 @@ var CookbookSidebarPane = class extends HTMLElement {
|
|
|
44
44
|
}, { signal });
|
|
45
45
|
this.addEventListener("keydown", (event) => {
|
|
46
46
|
if (desktop.matches || !this.matches(":popover-open")) return;
|
|
47
|
-
const sections = this.querySelector("
|
|
47
|
+
const sections = this.querySelector("[data-element=MobileNavigationTabs] details[open]");
|
|
48
48
|
if (event.key === "Escape" && sections) {
|
|
49
49
|
event.preventDefault();
|
|
50
50
|
sections.open = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","names":[],"sources":["../../src/client/navigation.ts"],"sourcesContent":["import { initializePopoverMotion } from \"./popover-motion.js\";\n\nclass CookbookSidebarPane extends HTMLElement {\n #listeners?: AbortController;\n #inert = new Map<HTMLElement, boolean>();\n #trigger: HTMLButtonElement | undefined;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n this.#trigger =\n document.querySelector<HTMLButtonElement>(\n '
|
|
1
|
+
{"version":3,"file":"navigation.js","names":[],"sources":["../../src/client/navigation.ts"],"sourcesContent":["import { initializePopoverMotion } from \"./popover-motion.js\";\n\nclass CookbookSidebarPane extends HTMLElement {\n #listeners?: AbortController;\n #inert = new Map<HTMLElement, boolean>();\n #trigger: HTMLButtonElement | undefined;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n this.#trigger =\n document.querySelector<HTMLButtonElement>(\n '[data-element=MobileMenuToggle][popovertarget=\"cookbook__sidebar\"]',\n ) ?? undefined;\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const syncViewport = () => {\n if (desktop.matches) {\n if (this.matches(\":popover-open\")) this.hidePopover();\n this.#release();\n this.popover = null;\n this.removeAttribute(\"role\");\n this.removeAttribute(\"aria-modal\");\n } else {\n this.popover = \"auto\";\n this.setAttribute(\"role\", \"dialog\");\n this.setAttribute(\"aria-modal\", \"true\");\n }\n };\n syncViewport();\n desktop.addEventListener(\"change\", syncViewport, { signal });\n this.addEventListener(\n \"toggle\",\n () => {\n const open = !desktop.matches && this.matches(\":popover-open\");\n this.#trigger?.setAttribute(\"aria-expanded\", String(open));\n if (open) {\n // Establish the closed position after the popover enters the top\n // layer so its attribute change transitions from an actual layout.\n // Tasty's global SSR renderer does not preserve @starting-style.\n this.getBoundingClientRect();\n this.setAttribute(\"data-open\", \"\");\n for (const element of document.querySelectorAll<HTMLElement>(\n \"[data-element=HeaderFrame], [data-element=MainFrame], [data-element=SkipLink]\",\n )) {\n this.#inert.set(element, element.inert);\n element.inert = true;\n }\n this.querySelector<HTMLElement>(\"[autofocus]\")?.focus({\n preventScroll: true,\n });\n } else {\n const restoreFocus =\n this.contains(document.activeElement) ||\n document.activeElement === document.body;\n this.#release();\n if (restoreFocus && !desktop.matches) this.#trigger?.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"keydown\",\n (event) => {\n if (desktop.matches || !this.matches(\":popover-open\")) return;\n const sections = this.querySelector<HTMLDetailsElement>(\n \"[data-element=MobileNavigationTabs] details[open]\",\n );\n if (event.key === \"Escape\" && sections) {\n event.preventDefault();\n sections.open = false;\n sections.querySelector(\"summary\")?.focus();\n return;\n }\n if (event.key !== \"Tab\") return;\n const focusable = Array.from(\n this.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), select:not([disabled]), input:not([disabled]), summary, [tabindex=\"0\"]',\n ),\n ).filter(\n (element) =>\n element.tabIndex >= 0 && element.getClientRects().length > 0,\n );\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) {\n event.preventDefault();\n this.focus();\n return;\n }\n if (\n event.shiftKey &&\n (document.activeElement === first || document.activeElement === this)\n ) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"click\",\n (event) => {\n if (\n !event.defaultPrevented &&\n event.target instanceof Element &&\n event.target.closest(\"a[href]\") &&\n this.matches(\":popover-open\")\n )\n this.hidePopover();\n },\n { signal },\n );\n }\n\n #release() {\n this.removeAttribute(\"data-open\");\n for (const [element, inert] of this.#inert) element.inert = inert;\n this.#inert.clear();\n this.#trigger?.setAttribute(\"aria-expanded\", \"false\");\n }\n\n disconnectedCallback() {\n this.#listeners?.abort();\n this.#release();\n }\n}\n\nclass CookbookHeaderLinks extends HTMLElement {\n #listeners?: AbortController;\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n const panel = this.querySelector<HTMLElement>(\"[popover]\");\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const close = () => {\n if (panel?.matches(\":popover-open\")) panel.hidePopover();\n };\n if (panel) initializePopoverMotion(panel, signal);\n desktop.addEventListener(\n \"change\",\n () => {\n if (desktop.matches) close();\n },\n { signal },\n );\n panel?.addEventListener(\n \"click\",\n (event) => {\n if (event.target instanceof Element && event.target.closest(\"a[href]\"))\n close();\n },\n { signal },\n );\n }\n disconnectedCallback() {\n this.#listeners?.abort();\n }\n}\n\nif (!customElements.get(\"cookbook-sidebar-pane\"))\n customElements.define(\"cookbook-sidebar-pane\", CookbookSidebarPane);\nif (!customElements.get(\"cookbook-header-links\"))\n customElements.define(\"cookbook-header-links\", CookbookHeaderLinks);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","names":[],"sources":["../../src/client/search.ts"],"mappings":";KAAK;EAAiB;EAAa,cAAc;;
|
|
1
|
+
{"version":3,"file":"search.d.ts","names":[],"sources":["../../src/client/search.ts"],"mappings":";KAAK;EAAiB;EAAa,cAAc;;KAE5C,kBAAkB;EACrB,iBAAiB,QAAQ,iBAAiB;;;iBAI5B,iBACd,SAAS,aACT,SAAS,iBACT,sBACA"}
|
package/dist/client/search.js
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
function initializeSearch(element, options, development, base) {
|
|
4
4
|
if (element.dataset.initialized) return;
|
|
5
5
|
element.dataset.initialized = "true";
|
|
6
|
+
const listeners = new AbortController();
|
|
7
|
+
const persistenceKey = element.dataset.searchKey;
|
|
8
|
+
if (persistenceKey) element.setAttribute("data-astro-transition-persist", persistenceKey);
|
|
6
9
|
const open = element.querySelector("[data-open-modal]");
|
|
7
10
|
const close = element.querySelector("[data-close-modal]");
|
|
8
11
|
const dialog = element.querySelector("dialog");
|
|
9
|
-
const frame = element.querySelector("
|
|
12
|
+
const frame = element.querySelector("[data-element=Frame]");
|
|
10
13
|
const status = element.querySelector("[data-search-status]");
|
|
11
14
|
const input = element.querySelector("[data-search-input]");
|
|
12
15
|
const clear = element.querySelector("[data-clear-search]");
|
|
@@ -118,13 +121,24 @@ function initializeSearch(element, options, development, base) {
|
|
|
118
121
|
document.body.removeAttribute("data-search-modal-open");
|
|
119
122
|
returnFocus?.focus();
|
|
120
123
|
});
|
|
124
|
+
document.addEventListener("astro:before-swap", (event) => {
|
|
125
|
+
generation += 1;
|
|
126
|
+
returnFocus = null;
|
|
127
|
+
if (dialog.open) dialog.close();
|
|
128
|
+
dialog.removeAttribute("data-open");
|
|
129
|
+
document.body.removeAttribute("data-search-modal-open");
|
|
130
|
+
const next = event.newDocument;
|
|
131
|
+
const nextRoot = persistenceKey ? [...next.querySelectorAll("site-search")].find((root) => root.dataset.searchKey === persistenceKey) : void 0;
|
|
132
|
+
if (nextRoot) nextRoot.setAttribute("data-astro-transition-persist", persistenceKey);
|
|
133
|
+
else listeners.abort();
|
|
134
|
+
}, { signal: listeners.signal });
|
|
121
135
|
window.addEventListener("keydown", (event) => {
|
|
122
136
|
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
|
123
137
|
event.preventDefault();
|
|
124
138
|
if (dialog.open && !closing) hide();
|
|
125
139
|
else show();
|
|
126
140
|
}
|
|
127
|
-
});
|
|
141
|
+
}, { signal: listeners.signal });
|
|
128
142
|
}
|
|
129
143
|
//#endregion
|
|
130
144
|
export { initializeSearch };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":[],"sources":["../../src/client/search.ts"],"sourcesContent":["type SearchResult = { url: string; sub_results?: SearchResult[] };\ntype PagefindOptions = Record<string, unknown> & {\n processResult?: (result: SearchResult) => SearchResult | void;\n};\n\n/** Own the dialog lifecycle; Pagefind owns indexing, filtering and result rendering. */\nexport function initializeSearch(\n element: HTMLElement,\n options: PagefindOptions,\n development: boolean,\n base: string,\n): void {\n if (element.dataset.initialized) return;\n element.dataset.initialized = \"true\";\n const open = element.querySelector<HTMLButtonElement>(\"[data-open-modal]\")!;\n const close = element.querySelector<HTMLButtonElement>(\"[data-close-modal]\")!;\n const dialog = element.querySelector(\"dialog\")!;\n const frame = element.querySelector(\".dialog-frame\")!;\n const status = element.querySelector<HTMLElement>(\"[data-search-status]\");\n const input = element.querySelector<HTMLInputElement>(\"[data-search-input]\");\n const clear = element.querySelector<HTMLButtonElement>(\"[data-clear-search]\");\n const shortcut = open.querySelector(\"kbd\")!;\n if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {\n shortcut.querySelector(\"kbd\")!.textContent = \"⌘\";\n open.setAttribute(\"aria-keyshortcuts\", \"Meta+K\");\n }\n delete shortcut.dataset.pending;\n let initialized: Promise<void> | undefined;\n let engineInput: HTMLInputElement | null = null;\n let returnFocus: HTMLElement | null = null;\n let closing = false;\n let generation = 0;\n const updateSearch = () => {\n if (clear) clear.hidden = !input?.value;\n if (engineInput) {\n engineInput.value = input?.value ?? \"\";\n engineInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n };\n input?.addEventListener(\"input\", updateSearch);\n clear?.addEventListener(\"click\", () => {\n if (!input) return;\n input.value = \"\";\n updateSearch();\n input.focus();\n });\n const initialize = () => {\n if (development) return Promise.resolve();\n return (initialized ??= (async () => {\n // @ts-expect-error Pagefind publishes no declarations for its default UI.\n const { PagefindUI } = await import(\"@pagefind/default-ui\");\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n const format = (url: string) =>\n element.hasAttribute(\"data-strip-trailing-slash\")\n ? url.replace(/(.)\\/(#.*)?$/, \"$1$2\")\n : url;\n new PagefindUI({\n ...options,\n element: element.querySelector(\"[data-search-results]\"),\n baseUrl: base,\n bundlePath: `${base.replace(/\\/$/, \"\")}/pagefind/`,\n showImages: false,\n showSubResults: true,\n translations,\n processResult(result: SearchResult) {\n result = options.processResult?.(result) ?? result;\n result.url = format(result.url);\n result.sub_results?.forEach((child) => {\n child.url = format(child.url);\n });\n return result;\n },\n });\n engineInput = element.querySelector(\".pagefind-ui__search-input\");\n element.querySelector(\".pagefind-ui__form\")?.removeAttribute(\"role\");\n // Cookbook owns the field so focus stays within the opening tap on mobile.\n // Pagefind still owns query processing and its lazily rendered results.\n element\n .querySelectorAll<HTMLElement>(\n \".pagefind-ui__search-input, .pagefind-ui__search-clear\",\n )\n .forEach((control) => {\n control.hidden = true;\n control.tabIndex = -1;\n });\n updateSearch();\n })().catch((error: unknown) => {\n initialized = undefined;\n if (status) {\n status.hidden = false;\n // Reuse the localized Pagefind error, with a plain fallback.\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n status.textContent =\n translations.error ?? \"Search could not load. Close and try again.\";\n }\n throw error;\n }));\n };\n const show = (trigger?: HTMLElement) => {\n if (dialog.open && !closing) return;\n generation += 1;\n closing = false;\n if (!dialog.open) {\n returnFocus =\n trigger ??\n (document.activeElement instanceof HTMLElement &&\n document.activeElement !== document.body\n ? document.activeElement\n : open);\n dialog.removeAttribute(\"data-open\");\n dialog.showModal();\n }\n // Do this synchronously, before the lazy import releases user activation.\n input?.focus({ preventScroll: true });\n // Establish the initial state after entering the top layer. The global\n // style renderer does not preserve @starting-style in server output.\n dialog.getBoundingClientRect();\n dialog.setAttribute(\"data-open\", \"\");\n document.body.setAttribute(\"data-search-modal-open\", \"\");\n if (!development && status) status.hidden = true;\n void initialize().catch(() => {\n /* Keep the close control usable when the search bundle fails. */\n });\n };\n const hide = async () => {\n if (!dialog.open || closing) return;\n closing = true;\n const current = ++generation;\n dialog.removeAttribute(\"data-open\");\n // Keep the modal in the top layer until its exit transition has finished.\n // This also works in browsers without discrete display/overlay transitions.\n await Promise.allSettled(\n dialog\n .getAnimations()\n .filter((animation) =>\n Number.isFinite(animation.effect?.getComputedTiming().endTime),\n )\n .map((animation) => animation.finished),\n );\n if (current === generation && dialog.open) dialog.close();\n };\n open.addEventListener(\"click\", () => {\n show(open);\n });\n open.disabled = false;\n close.addEventListener(\"click\", () => void hide());\n dialog.addEventListener(\"cancel\", (event) => {\n event.preventDefault();\n void hide();\n });\n dialog.addEventListener(\"click\", (event) => {\n if (!(event.target instanceof Element)) return;\n if (event.target.closest(\"a[href]\") || !frame.contains(event.target))\n void hide();\n });\n dialog.addEventListener(\"close\", () => {\n dialog.removeAttribute(\"data-open\");\n closing = false;\n document.body.removeAttribute(\"data-search-modal-open\");\n returnFocus?.focus();\n });\n window.addEventListener(\"keydown\", (event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"k\") {\n event.preventDefault();\n if (dialog.open && !closing) void hide();\n else void show();\n }\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search.js","names":[],"sources":["../../src/client/search.ts"],"sourcesContent":["type SearchResult = { url: string; sub_results?: SearchResult[] };\nimport type { TransitionBeforeSwapEvent } from \"astro:transitions/client\";\ntype PagefindOptions = Record<string, unknown> & {\n processResult?: (result: SearchResult) => SearchResult | void;\n};\n\n/** Own the dialog lifecycle; Pagefind owns indexing, filtering and result rendering. */\nexport function initializeSearch(\n element: HTMLElement,\n options: PagefindOptions,\n development: boolean,\n base: string,\n): void {\n if (element.dataset.initialized) return;\n element.dataset.initialized = \"true\";\n const listeners = new AbortController();\n // Astro strips transition attributes from unhydrated framework roots. Apply\n // the public persistence hook here and to the incoming matching search root.\n const persistenceKey = element.dataset.searchKey;\n if (persistenceKey)\n element.setAttribute(\"data-astro-transition-persist\", persistenceKey);\n const open = element.querySelector<HTMLButtonElement>(\"[data-open-modal]\")!;\n const close = element.querySelector<HTMLButtonElement>(\"[data-close-modal]\")!;\n const dialog = element.querySelector(\"dialog\")!;\n const frame = element.querySelector(\"[data-element=Frame]\")!;\n const status = element.querySelector<HTMLElement>(\"[data-search-status]\");\n const input = element.querySelector<HTMLInputElement>(\"[data-search-input]\");\n const clear = element.querySelector<HTMLButtonElement>(\"[data-clear-search]\");\n const shortcut = open.querySelector(\"kbd\")!;\n if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {\n shortcut.querySelector(\"kbd\")!.textContent = \"⌘\";\n open.setAttribute(\"aria-keyshortcuts\", \"Meta+K\");\n }\n delete shortcut.dataset.pending;\n let initialized: Promise<void> | undefined;\n let engineInput: HTMLInputElement | null = null;\n let returnFocus: HTMLElement | null = null;\n let closing = false;\n let generation = 0;\n const updateSearch = () => {\n if (clear) clear.hidden = !input?.value;\n if (engineInput) {\n engineInput.value = input?.value ?? \"\";\n engineInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n };\n input?.addEventListener(\"input\", updateSearch);\n clear?.addEventListener(\"click\", () => {\n if (!input) return;\n input.value = \"\";\n updateSearch();\n input.focus();\n });\n const initialize = () => {\n if (development) return Promise.resolve();\n return (initialized ??= (async () => {\n // @ts-expect-error Pagefind publishes no declarations for its default UI.\n const { PagefindUI } = await import(\"@pagefind/default-ui\");\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n const format = (url: string) =>\n element.hasAttribute(\"data-strip-trailing-slash\")\n ? url.replace(/(.)\\/(#.*)?$/, \"$1$2\")\n : url;\n new PagefindUI({\n ...options,\n element: element.querySelector(\"[data-search-results]\"),\n baseUrl: base,\n bundlePath: `${base.replace(/\\/$/, \"\")}/pagefind/`,\n showImages: false,\n showSubResults: true,\n translations,\n processResult(result: SearchResult) {\n result = options.processResult?.(result) ?? result;\n result.url = format(result.url);\n result.sub_results?.forEach((child) => {\n child.url = format(child.url);\n });\n return result;\n },\n });\n // Pagefind generates and controls these nodes; its UI API exposes only classes.\n engineInput = element.querySelector(\".pagefind-ui__search-input\");\n element.querySelector(\".pagefind-ui__form\")?.removeAttribute(\"role\");\n // Cookbook owns the field so focus stays within the opening tap on mobile.\n // Pagefind still owns query processing and its lazily rendered results.\n element\n .querySelectorAll<HTMLElement>(\n \".pagefind-ui__search-input, .pagefind-ui__search-clear\",\n )\n .forEach((control) => {\n control.hidden = true;\n control.tabIndex = -1;\n });\n updateSearch();\n })().catch((error: unknown) => {\n initialized = undefined;\n if (status) {\n status.hidden = false;\n // Reuse the localized Pagefind error, with a plain fallback.\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n status.textContent =\n translations.error ?? \"Search could not load. Close and try again.\";\n }\n throw error;\n }));\n };\n const show = (trigger?: HTMLElement) => {\n if (dialog.open && !closing) return;\n generation += 1;\n closing = false;\n if (!dialog.open) {\n returnFocus =\n trigger ??\n (document.activeElement instanceof HTMLElement &&\n document.activeElement !== document.body\n ? document.activeElement\n : open);\n dialog.removeAttribute(\"data-open\");\n dialog.showModal();\n }\n // Do this synchronously, before the lazy import releases user activation.\n input?.focus({ preventScroll: true });\n // Establish the initial state after entering the top layer. The global\n // style renderer does not preserve @starting-style in server output.\n dialog.getBoundingClientRect();\n dialog.setAttribute(\"data-open\", \"\");\n document.body.setAttribute(\"data-search-modal-open\", \"\");\n if (!development && status) status.hidden = true;\n void initialize().catch(() => {\n /* Keep the close control usable when the search bundle fails. */\n });\n };\n const hide = async () => {\n if (!dialog.open || closing) return;\n closing = true;\n const current = ++generation;\n dialog.removeAttribute(\"data-open\");\n // Keep the modal in the top layer until its exit transition has finished.\n // This also works in browsers without discrete display/overlay transitions.\n await Promise.allSettled(\n dialog\n .getAnimations()\n .filter((animation) =>\n Number.isFinite(animation.effect?.getComputedTiming().endTime),\n )\n .map((animation) => animation.finished),\n );\n if (current === generation && dialog.open) dialog.close();\n };\n open.addEventListener(\"click\", () => {\n show(open);\n });\n open.disabled = false;\n close.addEventListener(\"click\", () => void hide());\n dialog.addEventListener(\"cancel\", (event) => {\n event.preventDefault();\n void hide();\n });\n dialog.addEventListener(\"click\", (event) => {\n if (!(event.target instanceof Element)) return;\n if (event.target.closest(\"a[href]\") || !frame.contains(event.target))\n void hide();\n });\n dialog.addEventListener(\"close\", () => {\n dialog.removeAttribute(\"data-open\");\n closing = false;\n document.body.removeAttribute(\"data-search-modal-open\");\n returnFocus?.focus();\n });\n document.addEventListener(\n \"astro:before-swap\",\n (event) => {\n // Keep the query and lazy engine for matching localized search shells,\n // while dismissing the modal before the destination content is displayed.\n generation += 1;\n returnFocus = null;\n if (dialog.open) dialog.close();\n dialog.removeAttribute(\"data-open\");\n document.body.removeAttribute(\"data-search-modal-open\");\n const next = (event as TransitionBeforeSwapEvent).newDocument;\n const nextRoot = persistenceKey\n ? [...next.querySelectorAll<HTMLElement>(\"site-search\")].find(\n (root) => root.dataset.searchKey === persistenceKey,\n )\n : undefined;\n if (nextRoot)\n nextRoot.setAttribute(\"data-astro-transition-persist\", persistenceKey!);\n else listeners.abort();\n },\n { signal: listeners.signal },\n );\n window.addEventListener(\n \"keydown\",\n (event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"k\") {\n event.preventDefault();\n if (dialog.open && !closing) void hide();\n else void show();\n }\n },\n { signal: listeners.signal },\n );\n}\n"],"mappings":"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"}
|
|
@@ -33,7 +33,7 @@ var CookbookTableOfContents = class extends HTMLElement {
|
|
|
33
33
|
};
|
|
34
34
|
#sync = () => {
|
|
35
35
|
this.#frame = 0;
|
|
36
|
-
const marker = (document.querySelector("
|
|
36
|
+
const marker = (document.querySelector("[data-element=HeaderFrame]")?.getBoundingClientRect().bottom ?? 0) + 24;
|
|
37
37
|
let current = this.#entries[0];
|
|
38
38
|
for (const entry of this.#entries) {
|
|
39
39
|
if (entry.heading.getBoundingClientRect().top > marker + 2) break;
|
|
@@ -44,7 +44,7 @@ var CookbookTableOfContents = class extends HTMLElement {
|
|
|
44
44
|
this.#active?.removeAttribute("aria-current");
|
|
45
45
|
current.link.setAttribute("aria-current", "location");
|
|
46
46
|
this.#active = current.link;
|
|
47
|
-
const sidebar = this.closest("
|
|
47
|
+
const sidebar = this.closest("[data-element=Content]");
|
|
48
48
|
if (!sidebar || sidebar.getClientRects().length === 0) return;
|
|
49
49
|
const sidebarRect = sidebar.getBoundingClientRect();
|
|
50
50
|
const linkRect = current.link.getBoundingClientRect();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-of-contents.js","names":[],"sources":["../../src/client/table-of-contents.ts"],"sourcesContent":["class CookbookTableOfContents extends HTMLElement {\n #entries: Array<{ link: HTMLAnchorElement; heading: HTMLElement }> = [];\n #active?: HTMLAnchorElement;\n #listeners?: AbortController;\n #frame = 0;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n this.#entries = Array.from(\n this.querySelectorAll<HTMLAnchorElement>('nav a[href^=\"#\"]'),\n ).flatMap((link) => {\n const heading = document.getElementById(\n decodeURIComponent(link.hash.slice(1)),\n );\n return heading ? [{ link, heading }] : [];\n });\n if (this.#entries.length === 0) return;\n\n const options = { signal: this.#listeners.signal };\n window.addEventListener(\"scroll\", this.#schedule, {\n ...options,\n passive: true,\n });\n window.addEventListener(\"resize\", this.#schedule, options);\n window.addEventListener(\"hashchange\", this.#schedule, options);\n this.#schedule();\n }\n\n disconnectedCallback() {\n this.#listeners?.abort();\n cancelAnimationFrame(this.#frame);\n }\n\n #schedule = () => {\n if (!this.#frame) this.#frame = requestAnimationFrame(this.#sync);\n };\n\n #sync = () => {\n this.#frame = 0;\n const header = document.querySelector<HTMLElement>(\"
|
|
1
|
+
{"version":3,"file":"table-of-contents.js","names":[],"sources":["../../src/client/table-of-contents.ts"],"sourcesContent":["class CookbookTableOfContents extends HTMLElement {\n #entries: Array<{ link: HTMLAnchorElement; heading: HTMLElement }> = [];\n #active?: HTMLAnchorElement;\n #listeners?: AbortController;\n #frame = 0;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n this.#entries = Array.from(\n this.querySelectorAll<HTMLAnchorElement>('nav a[href^=\"#\"]'),\n ).flatMap((link) => {\n const heading = document.getElementById(\n decodeURIComponent(link.hash.slice(1)),\n );\n return heading ? [{ link, heading }] : [];\n });\n if (this.#entries.length === 0) return;\n\n const options = { signal: this.#listeners.signal };\n window.addEventListener(\"scroll\", this.#schedule, {\n ...options,\n passive: true,\n });\n window.addEventListener(\"resize\", this.#schedule, options);\n window.addEventListener(\"hashchange\", this.#schedule, options);\n this.#schedule();\n }\n\n disconnectedCallback() {\n this.#listeners?.abort();\n cancelAnimationFrame(this.#frame);\n }\n\n #schedule = () => {\n if (!this.#frame) this.#frame = requestAnimationFrame(this.#sync);\n };\n\n #sync = () => {\n this.#frame = 0;\n const header = document.querySelector<HTMLElement>(\n \"[data-element=HeaderFrame]\",\n );\n const marker = (header?.getBoundingClientRect().bottom ?? 0) + 24;\n let current = this.#entries[0];\n for (const entry of this.#entries) {\n if (entry.heading.getBoundingClientRect().top > marker + 2) break;\n current = entry;\n }\n if (\n window.scrollY > 0 &&\n window.scrollY + window.innerHeight >=\n document.documentElement.scrollHeight - 2\n )\n current = this.#entries.at(-1);\n if (!current || current.link === this.#active) return;\n\n this.#active?.removeAttribute(\"aria-current\");\n current.link.setAttribute(\"aria-current\", \"location\");\n this.#active = current.link;\n\n const sidebar = this.closest<HTMLElement>(\"[data-element=Content]\");\n if (!sidebar || sidebar.getClientRects().length === 0) return;\n const sidebarRect = sidebar.getBoundingClientRect();\n const linkRect = current.link.getBoundingClientRect();\n if (linkRect.top < sidebarRect.top + 16)\n sidebar.scrollTop += linkRect.top - sidebarRect.top - 16;\n else if (linkRect.bottom > sidebarRect.bottom - 16)\n sidebar.scrollTop += linkRect.bottom - sidebarRect.bottom + 16;\n };\n}\n\nif (!customElements.get(\"cookbook-table-of-contents\"))\n customElements.define(\"cookbook-table-of-contents\", CookbookTableOfContents);\n"],"mappings":";AAAA,IAAM,0BAAN,cAAsC,YAAY;CAChD,WAAqE,CAAC;CACtE;CACA;CACA,SAAS;CAET,oBAAoB;EAClB,KAAK,YAAY,MAAM;EACvB,KAAK,aAAa,IAAI,gBAAgB;EACtC,KAAK,WAAW,MAAM,KACpB,KAAK,iBAAoC,oBAAkB,CAC7D,CAAC,CAAC,SAAS,SAAS;GAClB,MAAM,UAAU,SAAS,eACvB,mBAAmB,KAAK,KAAK,MAAM,CAAC,CAAC,CACvC;GACA,OAAO,UAAU,CAAC;IAAE;IAAM;GAAQ,CAAC,IAAI,CAAC;EAC1C,CAAC;EACD,IAAI,KAAK,SAAS,WAAW,GAAG;EAEhC,MAAM,UAAU,EAAE,QAAQ,KAAK,WAAW,OAAO;EACjD,OAAO,iBAAiB,UAAU,KAAK,WAAW;GAChD,GAAG;GACH,SAAS;EACX,CAAC;EACD,OAAO,iBAAiB,UAAU,KAAK,WAAW,OAAO;EACzD,OAAO,iBAAiB,cAAc,KAAK,WAAW,OAAO;EAC7D,KAAK,UAAU;CACjB;CAEA,uBAAuB;EACrB,KAAK,YAAY,MAAM;EACvB,qBAAqB,KAAK,MAAM;CAClC;CAEA,kBAAkB;EAChB,IAAI,CAAC,KAAK,QAAQ,KAAK,SAAS,sBAAsB,KAAK,KAAK;CAClE;CAEA,cAAc;EACZ,KAAK,SAAS;EAId,MAAM,UAHS,SAAS,cACtB,4BAEmB,CAAC,EAAE,sBAAsB,CAAC,CAAC,UAAU,KAAK;EAC/D,IAAI,UAAU,KAAK,SAAS;EAC5B,KAAK,MAAM,SAAS,KAAK,UAAU;GACjC,IAAI,MAAM,QAAQ,sBAAsB,CAAC,CAAC,MAAM,SAAS,GAAG;GAC5D,UAAU;EACZ;EACA,IACE,OAAO,UAAU,KACjB,OAAO,UAAU,OAAO,eACtB,SAAS,gBAAgB,eAAe,GAE1C,UAAU,KAAK,SAAS,GAAG,EAAE;EAC/B,IAAI,CAAC,WAAW,QAAQ,SAAS,KAAK,SAAS;EAE/C,KAAK,SAAS,gBAAgB,cAAc;EAC5C,QAAQ,KAAK,aAAa,gBAAgB,UAAU;EACpD,KAAK,UAAU,QAAQ;EAEvB,MAAM,UAAU,KAAK,QAAqB,wBAAwB;EAClE,IAAI,CAAC,WAAW,QAAQ,eAAe,CAAC,CAAC,WAAW,GAAG;EACvD,MAAM,cAAc,QAAQ,sBAAsB;EAClD,MAAM,WAAW,QAAQ,KAAK,sBAAsB;EACpD,IAAI,SAAS,MAAM,YAAY,MAAM,IACnC,QAAQ,aAAa,SAAS,MAAM,YAAY,MAAM;OACnD,IAAI,SAAS,SAAS,YAAY,SAAS,IAC9C,QAAQ,aAAa,SAAS,SAAS,YAAY,SAAS;CAChE;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,4BAA4B,GAClD,eAAe,OAAO,8BAA8B,uBAAuB"}
|
|
@@ -24,10 +24,17 @@ const highlight = codeGroupHighlighting();
|
|
|
24
24
|
<cookbook-code-block
|
|
25
25
|
class="td-code-block"
|
|
26
26
|
data-element="MarkdownCodeBlock"
|
|
27
|
+
data-diff={
|
|
28
|
+
item.language === "diff" || item.language === "patch"
|
|
29
|
+
? ""
|
|
30
|
+
: undefined
|
|
31
|
+
}
|
|
27
32
|
>
|
|
28
33
|
<Code
|
|
29
34
|
code={item.code}
|
|
30
|
-
lang={
|
|
35
|
+
lang={
|
|
36
|
+
item.language === "patch" ? "diff" : (item.language ?? "text")
|
|
37
|
+
}
|
|
31
38
|
theme={highlight.theme}
|
|
32
39
|
transformers={highlight.transformers}
|
|
33
40
|
embeddedLangs={highlight.langs}
|
|
@@ -15,10 +15,9 @@ export const CodeGroupRoot = defineComponent("CodeGroup", {
|
|
|
15
15
|
blockMargin: "$margin-block-start $margin-block-end",
|
|
16
16
|
inlineMargin: "0",
|
|
17
17
|
},
|
|
18
|
-
Pre: { $: "pre" },
|
|
18
|
+
Pre: { $: "pre", preset: "code" },
|
|
19
19
|
Code: {
|
|
20
20
|
$: "pre code",
|
|
21
|
-
preset: "code",
|
|
22
21
|
color: "#syntax-text",
|
|
23
22
|
whiteSpace: "pre",
|
|
24
23
|
},
|
|
@@ -29,7 +29,7 @@ export default function DocumentStyles() {
|
|
|
29
29
|
resolveComponentStyles("Layout", {
|
|
30
30
|
overflow: {
|
|
31
31
|
"": null,
|
|
32
|
-
":has(#cookbook__sidebar:popover-open) &
|
|
32
|
+
":has(#cookbook__sidebar:popover-open) & !@md": "hidden",
|
|
33
33
|
},
|
|
34
34
|
colorScheme: {
|
|
35
35
|
"": "dark",
|
|
@@ -38,21 +38,21 @@ export default function DocumentStyles() {
|
|
|
38
38
|
},
|
|
39
39
|
"$docs-nav-height": {
|
|
40
40
|
"": "4.5rem",
|
|
41
|
-
":has(
|
|
42
|
-
"
|
|
43
|
-
"
|
|
41
|
+
":has(TopNavigation)": "7.25rem",
|
|
42
|
+
"!@md": "3.5rem",
|
|
43
|
+
"!@md & [data-has-sidebar]": "6.5rem",
|
|
44
44
|
},
|
|
45
45
|
"$docs-nav-pad-x": {
|
|
46
46
|
"": "clamp(1.25rem, 2.5vw, 2rem)",
|
|
47
|
-
"
|
|
47
|
+
"!@md": "1rem",
|
|
48
48
|
},
|
|
49
|
-
"$docs-nav-gap": { "": "0.75rem", "
|
|
49
|
+
"$docs-nav-gap": { "": "0.75rem", "!@md": "0.5rem" },
|
|
50
50
|
"$docs-sidebar-pad-x": "1.5rem",
|
|
51
51
|
"$docs-content-pad-x": {
|
|
52
52
|
"": "clamp(1.5rem, calc((100% - $content-width) / 2), 4rem)",
|
|
53
|
-
"
|
|
53
|
+
"!@md": "1rem",
|
|
54
54
|
},
|
|
55
|
-
"$docs-menu-button-size": { "": "2.5rem", "
|
|
55
|
+
"$docs-menu-button-size": { "": "2.5rem", "!@md": "2.25rem" },
|
|
56
56
|
"$docs-mobile-toc-height": "0rem",
|
|
57
57
|
Islands: {
|
|
58
58
|
$: "astro-island, astro-slot, astro-static-slot",
|
|
@@ -144,46 +144,75 @@ export default function DocumentStyles() {
|
|
|
144
144
|
},
|
|
145
145
|
},
|
|
146
146
|
Hidden: {
|
|
147
|
-
$: ":where(*)
|
|
147
|
+
$: ":where(*)",
|
|
148
148
|
hide: {
|
|
149
149
|
"": null,
|
|
150
|
-
"@own([hidden] |
|
|
150
|
+
"@own([hidden] | hidden)": true,
|
|
151
151
|
},
|
|
152
152
|
},
|
|
153
153
|
PrintHidden: {
|
|
154
|
-
$: "
|
|
155
|
-
display: { "@media:print": "none" },
|
|
154
|
+
$: "*",
|
|
155
|
+
display: { "": null, "@own(print-hidden) & @media:print": "none" },
|
|
156
156
|
},
|
|
157
157
|
DesktopBlock: {
|
|
158
|
-
$: "
|
|
159
|
-
display: {
|
|
158
|
+
$: "*",
|
|
159
|
+
display: {
|
|
160
|
+
"": null,
|
|
161
|
+
"@own(desktop-block)": "block",
|
|
162
|
+
"@own(desktop-block) & !@md": "none",
|
|
163
|
+
},
|
|
160
164
|
},
|
|
161
165
|
DesktopFlex: {
|
|
162
|
-
$: "
|
|
163
|
-
display: {
|
|
166
|
+
$: "*",
|
|
167
|
+
display: {
|
|
168
|
+
"": null,
|
|
169
|
+
"@own(desktop-flex)": "flex",
|
|
170
|
+
"@own(desktop-flex) & !@md": "none",
|
|
171
|
+
},
|
|
164
172
|
},
|
|
165
173
|
ScreenReaderOnly: {
|
|
166
|
-
$: "
|
|
167
|
-
"$visually-hidden-size": "1px",
|
|
174
|
+
$: "*",
|
|
175
|
+
"$visually-hidden-size": { "": null, "@own(sr-only)": "1px" },
|
|
176
|
+
position: { "": null, "@own(sr-only)": "absolute" },
|
|
177
|
+
inlineSize: { "": null, "@own(sr-only)": "$visually-hidden-size" },
|
|
178
|
+
blockSize: { "": null, "@own(sr-only)": "$visually-hidden-size" },
|
|
179
|
+
padding: { "": null, "@own(sr-only)": "0" },
|
|
180
|
+
margin: { "": null, "@own(sr-only)": "($visually-hidden-size * -1)" },
|
|
181
|
+
overflow: { "": null, "@own(sr-only)": "hidden" },
|
|
182
|
+
clip: { "": null, "@own(sr-only)": "rect(0, 0, 0, 0)" },
|
|
183
|
+
whiteSpace: { "": null, "@own(sr-only)": "nowrap" },
|
|
184
|
+
border: { "": null, "@own(sr-only)": "0" },
|
|
185
|
+
},
|
|
186
|
+
RouteAnnouncer: {
|
|
187
|
+
// Astro's public router creates this class; its generated markup has
|
|
188
|
+
// no owned data-element hook. Keep the bridge scoped to its announcer.
|
|
189
|
+
$: ".astro-route-announcer",
|
|
168
190
|
position: "absolute",
|
|
191
|
+
inset: "0 top, 0 left",
|
|
192
|
+
"$visually-hidden-size": "1px",
|
|
169
193
|
inlineSize: "$visually-hidden-size",
|
|
170
194
|
blockSize: "$visually-hidden-size",
|
|
171
|
-
padding: "0",
|
|
172
|
-
margin: "($visually-hidden-size * -1)",
|
|
173
195
|
overflow: "hidden",
|
|
174
196
|
clip: "rect(0, 0, 0, 0)",
|
|
175
197
|
whiteSpace: "nowrap",
|
|
176
|
-
border: "0",
|
|
177
198
|
},
|
|
178
199
|
Strong: { $: ":where(strong), :where(b)", preset: "strong" },
|
|
179
200
|
Link: { $: "a", color: "#accent-text" },
|
|
180
201
|
NarrowBlock: {
|
|
181
|
-
$: "
|
|
182
|
-
display: {
|
|
202
|
+
$: "*",
|
|
203
|
+
display: {
|
|
204
|
+
"": null,
|
|
205
|
+
"@own(narrow)": "none",
|
|
206
|
+
"@own(narrow) & !@lg": "block",
|
|
207
|
+
},
|
|
183
208
|
},
|
|
184
209
|
MobileBlock: {
|
|
185
|
-
$: "
|
|
186
|
-
display: {
|
|
210
|
+
$: "*",
|
|
211
|
+
display: {
|
|
212
|
+
"": null,
|
|
213
|
+
"@own(mobile)": "none",
|
|
214
|
+
"@own(mobile) & !@md": "block",
|
|
215
|
+
},
|
|
187
216
|
},
|
|
188
217
|
Code: {
|
|
189
218
|
$: ":where(code), :where(kbd), :where(samp), :where(pre)",
|