@tenphi/renderer 0.19.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/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/client/appearance.d.ts +12 -0
- package/dist/client/appearance.d.ts.map +1 -0
- package/dist/client/appearance.js +66 -0
- package/dist/client/appearance.js.map +1 -0
- package/dist/client/code-copy.d.ts +1 -0
- package/dist/client/code-copy.js +63 -0
- package/dist/client/code-copy.js.map +1 -0
- package/dist/client/heading-links.d.ts +6 -0
- package/dist/client/heading-links.d.ts.map +1 -0
- package/dist/client/heading-links.js +87 -0
- package/dist/client/heading-links.js.map +1 -0
- package/dist/client/mobile-toc.d.ts +1 -0
- package/dist/client/mobile-toc.js +28 -0
- package/dist/client/mobile-toc.js.map +1 -0
- package/dist/client/navigation.d.ts +1 -0
- package/dist/client/navigation.js +112 -0
- package/dist/client/navigation.js.map +1 -0
- package/dist/client/page-copy.d.ts +1 -0
- package/dist/client/page-copy.js +34 -0
- package/dist/client/page-copy.js.map +1 -0
- package/dist/client/search.d.ts +13 -0
- package/dist/client/search.d.ts.map +1 -0
- package/dist/client/search.js +87 -0
- package/dist/client/search.js.map +1 -0
- package/dist/client/sidebar.d.ts +1 -0
- package/dist/client/sidebar.js +93 -0
- package/dist/client/sidebar.js.map +1 -0
- package/dist/client/tabs.d.ts +6 -0
- package/dist/client/tabs.d.ts.map +1 -0
- package/dist/client/tabs.js +64 -0
- package/dist/client/tabs.js.map +1 -0
- package/dist/components/Callout.astro +15 -0
- package/dist/components/Card.astro +13 -0
- package/dist/components/CodeGroup.astro +47 -0
- package/dist/components/ContrastIcon.astro +29 -0
- package/dist/components/EditLink.astro +11 -0
- package/dist/components/GlobalStyles.js +1675 -0
- package/dist/components/HeaderLinks.astro +84 -0
- package/dist/components/Icon.astro +39 -0
- package/dist/components/LastUpdated.astro +17 -0
- package/dist/components/LayoutComponents.js +866 -0
- package/dist/components/Logo.astro +37 -0
- package/dist/components/MobileNavigationTabs.astro +79 -0
- package/dist/components/MobileTocList.astro +22 -0
- package/dist/components/PackageVersion.astro +25 -0
- package/dist/components/PageActions.astro +29 -0
- package/dist/components/Pagination.astro +29 -0
- package/dist/components/Preview.astro +34 -0
- package/dist/components/SidebarList.astro +122 -0
- package/dist/components/SiteLogo.astro +40 -0
- package/dist/components/SiteTitle.astro +7 -0
- package/dist/components/Steps.astro +6 -0
- package/dist/components/Tab.astro +10 -0
- package/dist/components/TableOfContents.astro +23 -0
- package/dist/components/Tabs.astro +16 -0
- package/dist/components/TastyComponents.js +255 -0
- package/dist/components/VersionSwitcher.astro +44 -0
- package/dist/components/appearance-preferences.test.ts +91 -0
- package/dist/components/appearance-preferences.ts +57 -0
- package/dist/components/component-styles.test.ts +129 -0
- package/dist/components/component-styles.ts +65 -0
- package/dist/components/customize-component.js +8 -0
- package/dist/components/props.d.ts +38 -0
- package/dist/components/props.d.ts.map +1 -0
- package/dist/components/props.js +1 -0
- package/dist/components/props.ts +30 -0
- package/dist/components/svg-icon.test.ts +11 -0
- package/dist/components/svg-icon.ts +11 -0
- package/dist/components/tasty-states.d.ts +2 -0
- package/dist/components/tasty-states.js +42 -0
- package/dist/components-public.d.ts +21 -0
- package/dist/components.d.ts +10 -0
- package/dist/components.js +9 -0
- package/dist/content.d.ts +11 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +16 -0
- package/dist/content.js.map +1 -0
- package/dist/eslint-plugin.d.ts +32 -0
- package/dist/eslint-plugin.d.ts.map +1 -0
- package/dist/eslint-plugin.js +155 -0
- package/dist/eslint-plugin.js.map +1 -0
- package/dist/icons/arrow-left.svg +1 -0
- package/dist/icons/arrow-right.svg +1 -0
- package/dist/icons/check.svg +1 -0
- package/dist/icons/chevron-down.svg +1 -0
- package/dist/icons/chevron-right.svg +1 -0
- package/dist/icons/close.svg +1 -0
- package/dist/icons/copy.svg +1 -0
- package/dist/icons/device-desktop.svg +1 -0
- package/dist/icons/favicon.svg +11 -0
- package/dist/icons/menu.svg +1 -0
- package/dist/icons/moon.svg +1 -0
- package/dist/icons/palette.svg +1 -0
- package/dist/icons/search.svg +1 -0
- package/dist/icons/sun.svg +1 -0
- package/dist/index-BuX_Sb5c.d.ts +10 -0
- package/dist/index-BuX_Sb5c.d.ts.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1648 -0
- package/dist/index.js.map +1 -0
- package/dist/localization.d.ts +69 -0
- package/dist/localization.d.ts.map +1 -0
- package/dist/localization.js +195 -0
- package/dist/localization.js.map +1 -0
- package/dist/markdown/rendered-content.d.ts +6 -0
- package/dist/markdown/rendered-content.d.ts.map +1 -0
- package/dist/markdown/rendered-content.js +34 -0
- package/dist/markdown/rendered-content.js.map +1 -0
- package/dist/messages-B_3xUzUb.js +14 -0
- package/dist/messages-B_3xUzUb.js.map +1 -0
- package/dist/navigation.d.ts +31 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +165 -0
- package/dist/navigation.js.map +1 -0
- package/dist/overrides/DraftContentNotice.astro +8 -0
- package/dist/overrides/EmptyFooter.astro +3 -0
- package/dist/overrides/Footer.astro +23 -0
- package/dist/overrides/Head.astro +59 -0
- package/dist/overrides/Header.astro +139 -0
- package/dist/overrides/Hero.astro +73 -0
- package/dist/overrides/LanguageSelect.astro +63 -0
- package/dist/overrides/MarkdownContent.astro +14 -0
- package/dist/overrides/MobileMenuFooter.astro +15 -0
- package/dist/overrides/MobileMenuToggle.astro +36 -0
- package/dist/overrides/MobileTableOfContents.astro +37 -0
- package/dist/overrides/PageFrame.astro +35 -0
- package/dist/overrides/Search.astro +64 -0
- package/dist/overrides/Sidebar.astro +89 -0
- package/dist/overrides/SocialIcons.astro +27 -0
- package/dist/overrides/ThemeSelect.astro +148 -0
- package/dist/page-metadata.d.ts +13 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +109 -0
- package/dist/page-metadata.js.map +1 -0
- package/dist/route-context.d.ts +85 -0
- package/dist/route-context.d.ts.map +1 -0
- package/dist/route-context.js +116 -0
- package/dist/route-context.js.map +1 -0
- package/dist/routes/DocsPage.astro +91 -0
- package/dist/routes/NotFound.astro +12 -0
- package/dist/routes/Page.astro +120 -0
- package/dist/styling.d.ts +17 -0
- package/dist/styling.d.ts.map +1 -0
- package/dist/styling.js +17 -0
- package/dist/styling.js.map +1 -0
- package/dist/tasty-states-BDKIbfw2.js +65 -0
- package/dist/tasty-states-BDKIbfw2.js.map +1 -0
- package/dist/theme/defaults.d.ts +21 -0
- package/dist/theme/defaults.d.ts.map +1 -0
- package/dist/theme/defaults.js +93 -0
- package/dist/theme/defaults.js.map +1 -0
- package/dist/theme/fonts.ts +64 -0
- package/dist/theme/shiki-theme.d.ts +13 -0
- package/dist/theme/shiki-theme.d.ts.map +1 -0
- package/dist/theme/shiki-theme.js +328 -0
- package/dist/theme/shiki-theme.js.map +1 -0
- package/dist/theme/tasty-config.d.ts +13 -0
- package/dist/theme/tasty-config.d.ts.map +1 -0
- package/dist/theme/tasty-config.js +16 -0
- package/dist/theme/tasty-config.js.map +1 -0
- package/dist/ui.d.ts +6 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +53 -0
- package/dist/ui.js.map +1 -0
- package/dist/versioning.d.ts +11 -0
- package/dist/versioning.d.ts.map +1 -0
- package/dist/versioning.js +38 -0
- package/dist/versioning.js.map +1 -0
- package/package.json +92 -0
- package/tasty.config.mjs +1 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { routeLocale } from "./localization.js";
|
|
2
|
+
import { pagePublishing, routeUrl } from "@tenphi/docs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/page-metadata.ts
|
|
5
|
+
function pageMetadata(entry, content, existing) {
|
|
6
|
+
const localeConfig = content.locales ? { locales: content.locales } : {};
|
|
7
|
+
const publishing = pagePublishing(entry, {
|
|
8
|
+
site: content.site,
|
|
9
|
+
...content.locales ? { locales: content.locales } : {},
|
|
10
|
+
build: { base: content.base }
|
|
11
|
+
});
|
|
12
|
+
const { canonical, title, image, index } = publishing;
|
|
13
|
+
const owned = /* @__PURE__ */ new Set([
|
|
14
|
+
"og:title",
|
|
15
|
+
"og:url",
|
|
16
|
+
"og:image",
|
|
17
|
+
"og:image:alt",
|
|
18
|
+
"og:image:width",
|
|
19
|
+
"og:image:height",
|
|
20
|
+
"twitter:card",
|
|
21
|
+
"twitter:title",
|
|
22
|
+
"twitter:image",
|
|
23
|
+
"twitter:image:alt",
|
|
24
|
+
"robots"
|
|
25
|
+
]);
|
|
26
|
+
const head = existing.filter((tag) => tag.tag !== "title" && !(tag.tag === "link" && tag.attrs?.rel === "canonical") && !(tag.tag === "meta" && owned.has(String(tag.attrs?.name ?? tag.attrs?.property).toLowerCase())));
|
|
27
|
+
const meta = (name, value, property = false) => head.push({
|
|
28
|
+
tag: "meta",
|
|
29
|
+
attrs: {
|
|
30
|
+
[property ? "property" : "name"]: name,
|
|
31
|
+
content: value
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
head.push({
|
|
35
|
+
tag: "title",
|
|
36
|
+
content: escapeHtml(title)
|
|
37
|
+
});
|
|
38
|
+
if (/^https?:/.test(canonical)) {
|
|
39
|
+
head.push({
|
|
40
|
+
tag: "link",
|
|
41
|
+
attrs: {
|
|
42
|
+
rel: "canonical",
|
|
43
|
+
href: canonical
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
meta("og:url", canonical, true);
|
|
47
|
+
}
|
|
48
|
+
meta("og:title", title, true);
|
|
49
|
+
meta("twitter:title", title);
|
|
50
|
+
meta("twitter:card", image ? "summary_large_image" : "summary");
|
|
51
|
+
if (!index) meta("robots", "noindex, follow");
|
|
52
|
+
if (image) {
|
|
53
|
+
const path = image.src.startsWith("/") ? `${content.base.replace(/\/$/, "")}${image.src}` : image.src;
|
|
54
|
+
const url = content.site.url ? new URL(path, content.site.url).href : path;
|
|
55
|
+
meta("og:image", url, true);
|
|
56
|
+
meta("og:image:alt", image.alt, true);
|
|
57
|
+
meta("twitter:image", url);
|
|
58
|
+
meta("twitter:image:alt", image.alt);
|
|
59
|
+
if (image.width && image.height) {
|
|
60
|
+
meta("og:image:width", String(image.width), true);
|
|
61
|
+
meta("og:image:height", String(image.height), true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
meta("cookbook:source", entry.sourcePath);
|
|
65
|
+
if (publishing.version?.label ?? content.site.version) meta("cookbook:version", publishing.version?.label ?? content.site.version);
|
|
66
|
+
if (content.site.seo?.copyPage !== false && !entry.frontmatter.draft) head.push({
|
|
67
|
+
tag: "link",
|
|
68
|
+
attrs: {
|
|
69
|
+
rel: "alternate",
|
|
70
|
+
type: "text/markdown",
|
|
71
|
+
title: "Markdown",
|
|
72
|
+
href: agentPagePath(entry.route, content.base)
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const configured = entry.frontmatter.seo?.breadcrumbs;
|
|
76
|
+
if (configured !== false && (configured || content.site.seo?.breadcrumbs) && /^https?:/.test(canonical)) {
|
|
77
|
+
const crumbs = configured ?? content.routes.filter((route) => (route.discoverable !== false || route.route === entry.route) && routeLocale(route.route, localeConfig) === routeLocale(entry.route, localeConfig) && (route.route === "/" || route.route === entry.route || entry.route.startsWith(`${route.route}/`))).sort((a, b) => a.route.length - b.route.length).map((route) => ({
|
|
78
|
+
name: route.title,
|
|
79
|
+
url: route.route === entry.route ? canonical : routeUrl(route.route, content.base, content.site.url)
|
|
80
|
+
}));
|
|
81
|
+
if (configured && crumbs.at(-1)?.url !== canonical) throw new Error(`seo.breadcrumbs in ${entry.sourcePath} must end with the page's canonical URL (${canonical}).`);
|
|
82
|
+
if (crumbs.length >= 2) head.push({
|
|
83
|
+
tag: "script",
|
|
84
|
+
attrs: { type: "application/ld+json" },
|
|
85
|
+
content: JSON.stringify({
|
|
86
|
+
"@context": "https://schema.org",
|
|
87
|
+
"@type": "BreadcrumbList",
|
|
88
|
+
itemListElement: crumbs.map((crumb, index) => ({
|
|
89
|
+
"@type": "ListItem",
|
|
90
|
+
position: index + 1,
|
|
91
|
+
name: crumb.name,
|
|
92
|
+
item: crumb.url
|
|
93
|
+
}))
|
|
94
|
+
}).replaceAll("<", "\\u003c")
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return head;
|
|
98
|
+
}
|
|
99
|
+
/** Stable short asset names also support deeply nested and non-ASCII routes. */
|
|
100
|
+
function agentPagePath(route, base = "/") {
|
|
101
|
+
return `${base.replace(/\/$/, "")}/_cookbook/pages/${createHash("sha256").update(route).digest("hex").slice(0, 32)}.md`;
|
|
102
|
+
}
|
|
103
|
+
function escapeHtml(value) {
|
|
104
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { agentPagePath, pageMetadata };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=page-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-metadata.js","names":[],"sources":["../src/page-metadata.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { routeLocale } from \"./localization.js\";\nimport {\n pagePublishing,\n routeUrl,\n type DocsEntry,\n type DocsRoute,\n type HeadConfig,\n type SiteConfig,\n type DocsConfig,\n} from \"@tenphi/docs\";\n\nexport function pageMetadata(\n entry: DocsEntry,\n content: {\n site: SiteConfig;\n base: string;\n routes: DocsRoute[];\n locales?: DocsConfig[\"locales\"];\n },\n existing: HeadConfig[],\n): HeadConfig[] {\n const localeConfig = content.locales ? { locales: content.locales } : {};\n const publishing = pagePublishing(entry, {\n site: content.site,\n ...(content.locales ? { locales: content.locales } : {}),\n build: { base: content.base },\n });\n const { canonical, title, image, index } = publishing;\n const owned = new Set([\n \"og:title\",\n \"og:url\",\n \"og:image\",\n \"og:image:alt\",\n \"og:image:width\",\n \"og:image:height\",\n \"twitter:card\",\n \"twitter:title\",\n \"twitter:image\",\n \"twitter:image:alt\",\n \"robots\",\n ]);\n const head = existing.filter(\n (tag) =>\n tag.tag !== \"title\" &&\n !(tag.tag === \"link\" && tag.attrs?.rel === \"canonical\") &&\n !(\n tag.tag === \"meta\" &&\n owned.has(String(tag.attrs?.name ?? tag.attrs?.property).toLowerCase())\n ),\n );\n const meta = (name: string, value: string, property = false) =>\n head.push({\n tag: \"meta\",\n attrs: { [property ? \"property\" : \"name\"]: name, content: value },\n });\n head.push({ tag: \"title\", content: escapeHtml(title) });\n if (/^https?:/.test(canonical)) {\n head.push({ tag: \"link\", attrs: { rel: \"canonical\", href: canonical } });\n meta(\"og:url\", canonical, true);\n }\n meta(\"og:title\", title, true);\n meta(\"twitter:title\", title);\n meta(\"twitter:card\", image ? \"summary_large_image\" : \"summary\");\n if (!index) meta(\"robots\", \"noindex, follow\");\n if (image) {\n const path = image.src.startsWith(\"/\")\n ? `${content.base.replace(/\\/$/, \"\")}${image.src}`\n : image.src;\n const url = content.site.url ? new URL(path, content.site.url).href : path;\n meta(\"og:image\", url, true);\n meta(\"og:image:alt\", image.alt, true);\n meta(\"twitter:image\", url);\n meta(\"twitter:image:alt\", image.alt);\n if (image.width && image.height) {\n meta(\"og:image:width\", String(image.width), true);\n meta(\"og:image:height\", String(image.height), true);\n }\n }\n meta(\"cookbook:source\", entry.sourcePath);\n if (publishing.version?.label ?? content.site.version)\n meta(\n \"cookbook:version\",\n publishing.version?.label ?? content.site.version!,\n );\n if (content.site.seo?.copyPage !== false && !entry.frontmatter.draft)\n head.push({\n tag: \"link\",\n attrs: {\n rel: \"alternate\",\n type: \"text/markdown\",\n title: \"Markdown\",\n href: agentPagePath(entry.route, content.base),\n },\n });\n const configured = entry.frontmatter.seo?.breadcrumbs;\n if (\n configured !== false &&\n (configured || content.site.seo?.breadcrumbs) &&\n /^https?:/.test(canonical)\n ) {\n const crumbs =\n configured ??\n content.routes\n .filter(\n (route) =>\n (route.discoverable !== false || route.route === entry.route) &&\n routeLocale(route.route, localeConfig) ===\n routeLocale(entry.route, localeConfig) &&\n (route.route === \"/\" ||\n route.route === entry.route ||\n entry.route.startsWith(`${route.route}/`)),\n )\n .sort((a, b) => a.route.length - b.route.length)\n .map((route) => ({\n name: route.title,\n url:\n route.route === entry.route\n ? canonical\n : routeUrl(route.route, content.base, content.site.url),\n }));\n if (configured && crumbs.at(-1)?.url !== canonical)\n throw new Error(\n `seo.breadcrumbs in ${entry.sourcePath} must end with the page's canonical URL (${canonical}).`,\n );\n if (crumbs.length >= 2)\n head.push({\n tag: \"script\",\n attrs: { type: \"application/ld+json\" },\n content: JSON.stringify({\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: crumbs.map((crumb, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: crumb.name,\n item: crumb.url,\n })),\n }).replaceAll(\"<\", \"\\\\u003c\"),\n });\n }\n return head;\n}\n\n/** Stable short asset names also support deeply nested and non-ASCII routes. */\nexport function agentPagePath(route: string, base = \"/\"): string {\n return `${base.replace(/\\/$/, \"\")}/_cookbook/pages/${createHash(\"sha256\").update(route).digest(\"hex\").slice(0, 32)}.md`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ResolvedNavigationLayout } from "./navigation.js";
|
|
2
|
+
import { DocsConfig, DocsHeading, DocsRoute, HeadConfig } from "@tenphi/docs";
|
|
3
|
+
//#region src/route-context.d.ts
|
|
4
|
+
type SidebarEntry = {
|
|
5
|
+
type: "link";
|
|
6
|
+
label: string;
|
|
7
|
+
href: string;
|
|
8
|
+
isCurrent: boolean;
|
|
9
|
+
attrs: Record<string, string>;
|
|
10
|
+
badge?: {
|
|
11
|
+
text: string;
|
|
12
|
+
variant?: string;
|
|
13
|
+
class?: string;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
type: "group";
|
|
17
|
+
label: string;
|
|
18
|
+
entries: SidebarEntry[];
|
|
19
|
+
badge?: {
|
|
20
|
+
text: string;
|
|
21
|
+
variant?: string;
|
|
22
|
+
class?: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
interface TocItem {
|
|
26
|
+
slug: string;
|
|
27
|
+
text: string;
|
|
28
|
+
children: TocItem[];
|
|
29
|
+
}
|
|
30
|
+
interface CookbookRoute {
|
|
31
|
+
id: string;
|
|
32
|
+
lang: string;
|
|
33
|
+
dir: "ltr" | "rtl";
|
|
34
|
+
hasSidebar: boolean;
|
|
35
|
+
siteTitle: string;
|
|
36
|
+
siteTitleHref: string;
|
|
37
|
+
entry: {
|
|
38
|
+
data: Record<string, any>;
|
|
39
|
+
};
|
|
40
|
+
entryMeta: {
|
|
41
|
+
lang: string;
|
|
42
|
+
dir: "ltr" | "rtl";
|
|
43
|
+
locale: string;
|
|
44
|
+
};
|
|
45
|
+
sidebar: SidebarEntry[];
|
|
46
|
+
pagination: {
|
|
47
|
+
prev?: {
|
|
48
|
+
href: string;
|
|
49
|
+
label: string;
|
|
50
|
+
};
|
|
51
|
+
next?: {
|
|
52
|
+
href: string;
|
|
53
|
+
label: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
toc?: {
|
|
57
|
+
items: TocItem[];
|
|
58
|
+
};
|
|
59
|
+
head: HeadConfig[];
|
|
60
|
+
editUrl?: string;
|
|
61
|
+
lastUpdated?: Date;
|
|
62
|
+
}
|
|
63
|
+
type Content = {
|
|
64
|
+
routes: DocsRoute[];
|
|
65
|
+
base: string;
|
|
66
|
+
site: {
|
|
67
|
+
title?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
};
|
|
70
|
+
locales?: DocsConfig["locales"];
|
|
71
|
+
defaultLocale?: string;
|
|
72
|
+
translations?: DocsConfig["translations"];
|
|
73
|
+
tableOfContents?: DocsConfig["tableOfContents"];
|
|
74
|
+
head?: HeadConfig[];
|
|
75
|
+
};
|
|
76
|
+
declare function createRouteContext(input: {
|
|
77
|
+
pathname: string;
|
|
78
|
+
frontmatter: Record<string, any>;
|
|
79
|
+
headings: DocsHeading[];
|
|
80
|
+
layout: ResolvedNavigationLayout;
|
|
81
|
+
content: Content;
|
|
82
|
+
}): CookbookRoute;
|
|
83
|
+
//#endregion
|
|
84
|
+
export { CookbookRoute, SidebarEntry, TocItem, createRouteContext };
|
|
85
|
+
//# sourceMappingURL=route-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-context.d.ts","names":[],"sources":["../src/route-context.ts"],"mappings":";;;KAoBY;EAEN;EACA;EACA;EACA;EACA,OAAO;EACP;IAAU;IAAc;IAAkB;;;EAG1C;EACA;EACA,SAAS;EACT;IAAU;IAAc;IAAkB;;;UAG/B;EACf;EACA;EACA,UAAU;;UAGK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;IAAS,MAAM;;EACf;IAAa;IAAc;IAAoB;;EAC/C,SAAS;EACT;IACE;MAAS;MAAc;;IACvB;MAAS;MAAc;;;EAEzB;IAAQ,OAAO;;EACf,MAAM;EACN;EACA,cAAc;;KAGX;EACH,QAAQ;EACR;EACA;IAAQ;IAAgB;;EACxB,UAAU;EACV;EACA,eAAe;EACf,kBAAkB;EAClB,OAAO;;iBAGO,mBAAmB;EACjC;EACA,aAAa;EACb,UAAU;EACV,QAAQ;EACR,SAAS;IACP"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { navigationPath, normalizeNavigationPath, pageSidebar } from "./navigation.js";
|
|
2
|
+
import { localeHref, localizedNavigation, requestLanguage, routeLocale } from "./localization.js";
|
|
3
|
+
//#region src/route-context.ts
|
|
4
|
+
function createRouteContext(input) {
|
|
5
|
+
const { pathname, frontmatter, headings, layout, content } = input;
|
|
6
|
+
const currentPath = navigationPath(pathname, content.base);
|
|
7
|
+
const locale = routeLocale(currentPath, content);
|
|
8
|
+
const lang = requestLanguage(pathname, content.base, content);
|
|
9
|
+
const dir = content.locales?.[locale]?.dir ?? "ltr";
|
|
10
|
+
const localized = localizedNavigation(layout, content.routes, currentPath, content);
|
|
11
|
+
const sidebar = resolveSidebar(pageSidebar(localized.layout, localized.routes), currentPath, content);
|
|
12
|
+
const links = flattenLinks(sidebar);
|
|
13
|
+
const currentIndex = links.findIndex((link) => link.isCurrent);
|
|
14
|
+
const previous = resolvePaginationLink(frontmatter.prev, currentIndex >= 0 ? links[currentIndex - 1] : void 0, content, currentPath);
|
|
15
|
+
const next = resolvePaginationLink(frontmatter.next, currentIndex >= 0 ? links[currentIndex + 1] : void 0, content, currentPath);
|
|
16
|
+
const pagination = {
|
|
17
|
+
...previous ? { prev: previous } : {},
|
|
18
|
+
...next ? { next } : {}
|
|
19
|
+
};
|
|
20
|
+
const toc = resolveToc(headings, frontmatter, content);
|
|
21
|
+
const head = [
|
|
22
|
+
...content.head ?? [],
|
|
23
|
+
...frontmatter.head ?? [],
|
|
24
|
+
...frontmatter.description || content.site.description ? [{
|
|
25
|
+
tag: "meta",
|
|
26
|
+
attrs: {
|
|
27
|
+
name: "description",
|
|
28
|
+
content: frontmatter.description ?? content.site.description
|
|
29
|
+
}
|
|
30
|
+
}] : []
|
|
31
|
+
];
|
|
32
|
+
return {
|
|
33
|
+
id: currentPath,
|
|
34
|
+
lang,
|
|
35
|
+
dir,
|
|
36
|
+
hasSidebar: frontmatter.template !== "splash",
|
|
37
|
+
siteTitle: content.site.title ?? "Documentation",
|
|
38
|
+
siteTitleHref: content.base,
|
|
39
|
+
entry: { data: frontmatter },
|
|
40
|
+
entryMeta: {
|
|
41
|
+
lang,
|
|
42
|
+
dir,
|
|
43
|
+
locale
|
|
44
|
+
},
|
|
45
|
+
sidebar,
|
|
46
|
+
pagination,
|
|
47
|
+
...toc ? { toc } : {},
|
|
48
|
+
head,
|
|
49
|
+
...typeof frontmatter.editUrl === "string" ? { editUrl: frontmatter.editUrl } : {},
|
|
50
|
+
...frontmatter.lastUpdated instanceof Date ? { lastUpdated: frontmatter.lastUpdated } : {}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function resolveSidebar(items, currentPath, content) {
|
|
54
|
+
return items.map((item) => {
|
|
55
|
+
if ("link" in item) {
|
|
56
|
+
const href = localeHref(item.link, currentPath, content.routes, content, content.base);
|
|
57
|
+
return {
|
|
58
|
+
type: "link",
|
|
59
|
+
label: item.label,
|
|
60
|
+
href,
|
|
61
|
+
isCurrent: href.startsWith("/") && !href.startsWith("//") && navigationPath(new URL(href, "https://cookbook.invalid").pathname, content.base) === currentPath,
|
|
62
|
+
attrs: item.attrs ?? {}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
type: "group",
|
|
67
|
+
label: item.label,
|
|
68
|
+
entries: resolveSidebar(item.items, currentPath, content)
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function flattenLinks(items) {
|
|
73
|
+
return items.flatMap((item) => item.type === "link" ? [item] : flattenLinks(item.entries));
|
|
74
|
+
}
|
|
75
|
+
function resolvePaginationLink(configured, automatic, content, currentPath) {
|
|
76
|
+
if (configured === false) return void 0;
|
|
77
|
+
if (configured === void 0) return automatic && {
|
|
78
|
+
href: automatic.href,
|
|
79
|
+
label: automatic.label
|
|
80
|
+
};
|
|
81
|
+
const link = typeof configured === "string" ? configured : configured && typeof configured === "object" && "link" in configured && typeof configured.link === "string" ? configured.link : automatic?.href;
|
|
82
|
+
if (!link) return void 0;
|
|
83
|
+
const label = configured && typeof configured === "object" && "label" in configured && typeof configured.label === "string" ? configured.label : content.routes.find((route) => normalizeNavigationPath(route.route) === normalizeNavigationPath(link))?.title ?? automatic?.label ?? link;
|
|
84
|
+
return {
|
|
85
|
+
href: localeHref(link, currentPath, content.routes, content, content.base),
|
|
86
|
+
label
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function resolveToc(headings, frontmatter, content) {
|
|
90
|
+
const option = frontmatter.tableOfContents ?? content.tableOfContents;
|
|
91
|
+
if (option === false) return void 0;
|
|
92
|
+
const min = typeof option === "object" ? option.minHeadingLevel ?? 2 : 2;
|
|
93
|
+
const max = typeof option === "object" ? option.maxHeadingLevel ?? 3 : 3;
|
|
94
|
+
const roots = [];
|
|
95
|
+
const stack = [];
|
|
96
|
+
for (const heading of headings) {
|
|
97
|
+
if (heading.depth < min || heading.depth > max) continue;
|
|
98
|
+
const item = {
|
|
99
|
+
slug: heading.slug,
|
|
100
|
+
text: heading.text,
|
|
101
|
+
children: []
|
|
102
|
+
};
|
|
103
|
+
while (stack.length && stack[stack.length - 1].depth >= heading.depth) stack.pop();
|
|
104
|
+
if (stack.length) stack[stack.length - 1].item.children.push(item);
|
|
105
|
+
else roots.push(item);
|
|
106
|
+
stack.push({
|
|
107
|
+
depth: heading.depth,
|
|
108
|
+
item
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return roots.length ? { items: roots } : void 0;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { createRouteContext };
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=route-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-context.js","names":[],"sources":["../src/route-context.ts"],"sourcesContent":["import type {\n DocsConfig,\n DocsHeading,\n DocsRoute,\n HeadConfig,\n} from \"@tenphi/docs\";\nimport {\n localeHref,\n localizedNavigation,\n requestLanguage,\n routeLocale,\n} from \"./localization.js\";\nimport {\n navigationPath,\n normalizeNavigationPath,\n pageSidebar,\n type ResolvedNavigationLayout,\n type PageSidebarItem,\n} from \"./navigation.js\";\n\nexport type SidebarEntry =\n | {\n type: \"link\";\n label: string;\n href: string;\n isCurrent: boolean;\n attrs: Record<string, string>;\n badge?: { text: string; variant?: string; class?: string };\n }\n | {\n type: \"group\";\n label: string;\n entries: SidebarEntry[];\n badge?: { text: string; variant?: string; class?: string };\n };\n\nexport interface TocItem {\n slug: string;\n text: string;\n children: TocItem[];\n}\n\nexport interface CookbookRoute {\n id: string;\n lang: string;\n dir: \"ltr\" | \"rtl\";\n hasSidebar: boolean;\n siteTitle: string;\n siteTitleHref: string;\n entry: { data: Record<string, any> };\n entryMeta: { lang: string; dir: \"ltr\" | \"rtl\"; locale: string };\n sidebar: SidebarEntry[];\n pagination: {\n prev?: { href: string; label: string };\n next?: { href: string; label: string };\n };\n toc?: { items: TocItem[] };\n head: HeadConfig[];\n editUrl?: string;\n lastUpdated?: Date;\n}\n\ntype Content = {\n routes: DocsRoute[];\n base: string;\n site: { title?: string; description?: string };\n locales?: DocsConfig[\"locales\"];\n defaultLocale?: string;\n translations?: DocsConfig[\"translations\"];\n tableOfContents?: DocsConfig[\"tableOfContents\"];\n head?: HeadConfig[];\n};\n\nexport function createRouteContext(input: {\n pathname: string;\n frontmatter: Record<string, any>;\n headings: DocsHeading[];\n layout: ResolvedNavigationLayout;\n content: Content;\n}): CookbookRoute {\n const { pathname, frontmatter, headings, layout, content } = input;\n const currentPath = navigationPath(pathname, content.base);\n const locale = routeLocale(currentPath, content);\n const lang = requestLanguage(pathname, content.base, content);\n const dir = content.locales?.[locale]?.dir ?? \"ltr\";\n const localized = localizedNavigation(\n layout,\n content.routes,\n currentPath,\n content,\n );\n const sidebar = resolveSidebar(\n pageSidebar(localized.layout, localized.routes),\n currentPath,\n content,\n );\n const links = flattenLinks(sidebar);\n const currentIndex = links.findIndex((link) => link.isCurrent);\n const previous = resolvePaginationLink(\n frontmatter.prev,\n currentIndex >= 0 ? links[currentIndex - 1] : undefined,\n content,\n currentPath,\n );\n const next = resolvePaginationLink(\n frontmatter.next,\n currentIndex >= 0 ? links[currentIndex + 1] : undefined,\n content,\n currentPath,\n );\n const pagination = {\n ...(previous ? { prev: previous } : {}),\n ...(next ? { next } : {}),\n };\n const toc = resolveToc(headings, frontmatter, content);\n const head: HeadConfig[] = [\n ...(content.head ?? []),\n ...(frontmatter.head ?? []),\n ...(frontmatter.description || content.site.description\n ? [\n {\n tag: \"meta\",\n attrs: {\n name: \"description\",\n content: frontmatter.description ?? content.site.description,\n },\n },\n ]\n : []),\n ];\n return {\n id: currentPath,\n lang,\n dir,\n hasSidebar: frontmatter.template !== \"splash\",\n siteTitle: content.site.title ?? \"Documentation\",\n siteTitleHref: content.base,\n entry: { data: frontmatter },\n entryMeta: { lang, dir, locale },\n sidebar,\n pagination,\n ...(toc ? { toc } : {}),\n head,\n ...(typeof frontmatter.editUrl === \"string\"\n ? { editUrl: frontmatter.editUrl }\n : {}),\n ...(frontmatter.lastUpdated instanceof Date\n ? { lastUpdated: frontmatter.lastUpdated }\n : {}),\n };\n}\n\nfunction resolveSidebar(\n items: PageSidebarItem[],\n currentPath: string,\n content: Content,\n): SidebarEntry[] {\n return items.map((item): SidebarEntry => {\n if (\"link\" in item) {\n const href = localeHref(\n item.link,\n currentPath,\n content.routes,\n content,\n content.base,\n );\n return {\n type: \"link\",\n label: item.label,\n href,\n isCurrent:\n href.startsWith(\"/\") &&\n !href.startsWith(\"//\") &&\n navigationPath(\n new URL(href, \"https://cookbook.invalid\").pathname,\n content.base,\n ) === currentPath,\n attrs: item.attrs ?? {},\n };\n }\n return {\n type: \"group\",\n label: item.label,\n entries: resolveSidebar(item.items, currentPath, content),\n };\n });\n}\n\nfunction flattenLinks(\n items: SidebarEntry[],\n): Extract<SidebarEntry, { type: \"link\" }>[] {\n return items.flatMap((item) =>\n item.type === \"link\" ? [item] : flattenLinks(item.entries),\n );\n}\n\nfunction resolvePaginationLink(\n configured: unknown,\n automatic: Extract<SidebarEntry, { type: \"link\" }> | undefined,\n content: Content,\n currentPath: string,\n): { href: string; label: string } | undefined {\n if (configured === false) return undefined;\n if (configured === undefined)\n return automatic && { href: automatic.href, label: automatic.label };\n const link =\n typeof configured === \"string\"\n ? configured\n : configured &&\n typeof configured === \"object\" &&\n \"link\" in configured &&\n typeof configured.link === \"string\"\n ? configured.link\n : automatic?.href;\n if (!link) return undefined;\n const label =\n configured &&\n typeof configured === \"object\" &&\n \"label\" in configured &&\n typeof configured.label === \"string\"\n ? configured.label\n : (content.routes.find(\n (route) =>\n normalizeNavigationPath(route.route) ===\n normalizeNavigationPath(link),\n )?.title ??\n automatic?.label ??\n link);\n return {\n href: localeHref(link, currentPath, content.routes, content, content.base),\n label,\n };\n}\n\nfunction resolveToc(\n headings: DocsHeading[],\n frontmatter: Record<string, any>,\n content: Content,\n): { items: TocItem[] } | undefined {\n const option = frontmatter.tableOfContents ?? content.tableOfContents;\n if (option === false) return undefined;\n const min = typeof option === \"object\" ? (option.minHeadingLevel ?? 2) : 2;\n const max = typeof option === \"object\" ? (option.maxHeadingLevel ?? 3) : 3;\n const roots: TocItem[] = [];\n const stack: Array<{ depth: number; item: TocItem }> = [];\n for (const heading of headings) {\n if (heading.depth < min || heading.depth > max) continue;\n const item: TocItem = {\n slug: heading.slug,\n text: heading.text,\n children: [],\n };\n while (stack.length && stack[stack.length - 1]!.depth >= heading.depth)\n stack.pop();\n if (stack.length) stack[stack.length - 1]!.item.children.push(item);\n else roots.push(item);\n stack.push({ depth: heading.depth, item });\n }\n return roots.length ? { items: roots } : undefined;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Page from "./Page.astro";
|
|
3
|
+
import { content, mdxLoaders } from "virtual:cookbook/config";
|
|
4
|
+
|
|
5
|
+
export const prerender = true;
|
|
6
|
+
|
|
7
|
+
export function getStaticPaths() {
|
|
8
|
+
const entries = content.entries;
|
|
9
|
+
return [
|
|
10
|
+
...entries.map((entry) => ({
|
|
11
|
+
params: { route: entry.route === "/" ? undefined : entry.route.slice(1) },
|
|
12
|
+
props: { entry, routes: content.routes },
|
|
13
|
+
})),
|
|
14
|
+
...Object.entries(content.redirects).flatMap(([alias, target]) => {
|
|
15
|
+
const entry = entries.find((entry) => entry.route === target);
|
|
16
|
+
return entry
|
|
17
|
+
? [
|
|
18
|
+
{
|
|
19
|
+
params: { route: alias === "/" ? undefined : alias.slice(1) },
|
|
20
|
+
props: { entry, routes: content.routes, redirect: target },
|
|
21
|
+
},
|
|
22
|
+
]
|
|
23
|
+
: [];
|
|
24
|
+
}),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const { entry, routes, redirect } = Astro.props;
|
|
29
|
+
if (redirect)
|
|
30
|
+
return Astro.redirect(`${content.base.replace(/\/$/, "")}${redirect}`, 301);
|
|
31
|
+
const loadMdx = mdxLoaders[entry.route];
|
|
32
|
+
if (!entry.rendered && !loadMdx) {
|
|
33
|
+
throw new Error(`Cookbook did not render ${entry.sourcePath}.`);
|
|
34
|
+
}
|
|
35
|
+
const mdx = loadMdx ? await loadMdx() : undefined;
|
|
36
|
+
const MdxContent = mdx?.default;
|
|
37
|
+
const headings = mdx?.getHeadings
|
|
38
|
+
? await mdx.getHeadings()
|
|
39
|
+
: (entry.rendered?.headings ?? []);
|
|
40
|
+
const lastUpdated =
|
|
41
|
+
typeof entry.frontmatter.lastUpdated === "string"
|
|
42
|
+
? new Date(entry.frontmatter.lastUpdated)
|
|
43
|
+
: entry.frontmatter.lastUpdated;
|
|
44
|
+
const hero = entry.hero;
|
|
45
|
+
const frontmatter = {
|
|
46
|
+
...entry.metadata,
|
|
47
|
+
...entry.frontmatter,
|
|
48
|
+
title: entry.title,
|
|
49
|
+
...(entry.description ? { description: entry.description } : {}),
|
|
50
|
+
...(entry.frontmatter.tableOfContents !== undefined
|
|
51
|
+
? { tableOfContents: entry.frontmatter.tableOfContents }
|
|
52
|
+
: {}),
|
|
53
|
+
...(entry.frontmatter.editUrl !== undefined
|
|
54
|
+
? { editUrl: entry.frontmatter.editUrl }
|
|
55
|
+
: {}),
|
|
56
|
+
...(entry.frontmatter.template !== undefined
|
|
57
|
+
? { template: entry.frontmatter.template }
|
|
58
|
+
: {}),
|
|
59
|
+
...(hero !== undefined ? { hero } : {}),
|
|
60
|
+
...(lastUpdated !== undefined ? { lastUpdated } : {}),
|
|
61
|
+
...(entry.frontmatter.prev !== undefined
|
|
62
|
+
? { prev: entry.frontmatter.prev }
|
|
63
|
+
: {}),
|
|
64
|
+
...(entry.frontmatter.next !== undefined
|
|
65
|
+
? { next: entry.frontmatter.next }
|
|
66
|
+
: {}),
|
|
67
|
+
...(entry.frontmatter.banner !== undefined
|
|
68
|
+
? { banner: entry.frontmatter.banner }
|
|
69
|
+
: {}),
|
|
70
|
+
...(entry.frontmatter.pagefind !== undefined
|
|
71
|
+
? { pagefind: entry.frontmatter.pagefind }
|
|
72
|
+
: {}),
|
|
73
|
+
head: [
|
|
74
|
+
...(entry.frontmatter.head ?? []).filter(
|
|
75
|
+
(tag) =>
|
|
76
|
+
!entry.frontmatter.draft ||
|
|
77
|
+
tag.tag !== "meta" ||
|
|
78
|
+
tag.attrs?.name !== "robots",
|
|
79
|
+
),
|
|
80
|
+
...(entry.frontmatter.draft
|
|
81
|
+
? [{ tag: "meta", attrs: { name: "robots", content: "noindex, follow" } }]
|
|
82
|
+
: []),
|
|
83
|
+
],
|
|
84
|
+
...(entry.frontmatter.draft ? { pagefind: false } : {}),
|
|
85
|
+
...(entry.frontmatter.draft ? { draft: true } : {}),
|
|
86
|
+
};
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
<Page frontmatter={frontmatter} headings={headings}>
|
|
90
|
+
{MdxContent ? <MdxContent /> : <div set:html={entry.rendered?.html ?? ""} />}
|
|
91
|
+
</Page>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Page from "./Page.astro";
|
|
3
|
+
import { content } from "virtual:cookbook/config";
|
|
4
|
+
import { messages } from "../localization.js";
|
|
5
|
+
|
|
6
|
+
export const prerender = true;
|
|
7
|
+
const ui = messages(content.locales?.root?.lang ?? "en", content);
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<Page frontmatter={{ title: ui.notFound, pagefind: false }} headings={[]}>
|
|
11
|
+
<p>{ui.notFoundDescription}</p>
|
|
12
|
+
</Page>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { DocsHeading } from "@tenphi/docs";
|
|
3
|
+
import { content } from "virtual:cookbook/config";
|
|
4
|
+
import { layout } from "virtual:cookbook/layout";
|
|
5
|
+
import { createRouteContext } from "../route-context.js";
|
|
6
|
+
import { uiTranslations } from "../ui.js";
|
|
7
|
+
import Head from "virtual:cookbook/components/Head";
|
|
8
|
+
import Header from "virtual:cookbook/components/Header";
|
|
9
|
+
import Sidebar from "virtual:cookbook/components/Sidebar";
|
|
10
|
+
import PageFrame from "virtual:cookbook/components/PageFrame";
|
|
11
|
+
import Footer from "virtual:cookbook/components/Footer";
|
|
12
|
+
import Hero from "virtual:cookbook/components/Hero";
|
|
13
|
+
import MarkdownContent from "virtual:cookbook/components/MarkdownContent";
|
|
14
|
+
import MobileTableOfContents from "virtual:cookbook/components/MobileTableOfContents";
|
|
15
|
+
import DraftContentNotice from "virtual:cookbook/components/DraftContentNotice";
|
|
16
|
+
import TableOfContents from "virtual:cookbook/components/TableOfContents";
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
frontmatter: Record<string, any>;
|
|
20
|
+
headings: DocsHeading[];
|
|
21
|
+
}
|
|
22
|
+
const route = createRouteContext({
|
|
23
|
+
pathname: Astro.url.pathname,
|
|
24
|
+
frontmatter: Astro.props.frontmatter,
|
|
25
|
+
headings: Astro.props.headings,
|
|
26
|
+
layout,
|
|
27
|
+
content,
|
|
28
|
+
});
|
|
29
|
+
Astro.locals.cookbookRoute = route;
|
|
30
|
+
const translations = uiTranslations(route.lang, content);
|
|
31
|
+
Astro.locals.t = (key: string) => translations[key] ?? key;
|
|
32
|
+
const { data } = route.entry;
|
|
33
|
+
const indexed = route.id !== "/404" && data.pagefind !== false && !data.draft;
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<html
|
|
37
|
+
lang={route.lang}
|
|
38
|
+
dir={route.dir}
|
|
39
|
+
data-theme="dark"
|
|
40
|
+
data-has-sidebar={route.hasSidebar ? "" : undefined}
|
|
41
|
+
data-has-toc={route.toc ? "" : undefined}
|
|
42
|
+
data-has-hero={data.hero ? "" : undefined}
|
|
43
|
+
>
|
|
44
|
+
<head>
|
|
45
|
+
<meta charset="utf-8" />
|
|
46
|
+
<Head />
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<a class="cookbook-skip-link" href="#main-content"
|
|
50
|
+
>{Astro.locals.t("page.skipToContent")}</a
|
|
51
|
+
>
|
|
52
|
+
<PageFrame>
|
|
53
|
+
<Header slot="header" />
|
|
54
|
+
{route.hasSidebar && <Sidebar slot="sidebar" />}
|
|
55
|
+
<div>
|
|
56
|
+
{
|
|
57
|
+
route.toc && (
|
|
58
|
+
<aside class="right-sidebar-container cookbook-print-hidden">
|
|
59
|
+
<div class="right-sidebar">
|
|
60
|
+
<MobileTableOfContents />
|
|
61
|
+
<div class="right-sidebar-panel">
|
|
62
|
+
<h2>{Astro.locals.t("tableOfContents.onThisPage")}</h2>
|
|
63
|
+
<nav
|
|
64
|
+
aria-label={Astro.locals.t("tableOfContents.onThisPage")}
|
|
65
|
+
>
|
|
66
|
+
<TableOfContents items={route.toc.items} />
|
|
67
|
+
</nav>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</aside>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
<div class="main-pane">
|
|
74
|
+
<main
|
|
75
|
+
id="main-content"
|
|
76
|
+
data-pagefind-body={indexed ? "" : undefined}
|
|
77
|
+
lang={route.entryMeta.lang}
|
|
78
|
+
dir={route.entryMeta.dir}
|
|
79
|
+
>
|
|
80
|
+
{
|
|
81
|
+
data.banner && (
|
|
82
|
+
<div class="cookbook-banner" set:html={data.banner.content} />
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
{
|
|
86
|
+
data.hero ? (
|
|
87
|
+
<div class="content-panel">
|
|
88
|
+
<div class="cookbook-container">
|
|
89
|
+
<Hero />
|
|
90
|
+
<MarkdownContent>
|
|
91
|
+
<slot />
|
|
92
|
+
</MarkdownContent>
|
|
93
|
+
<Footer />
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
) : (
|
|
97
|
+
<>
|
|
98
|
+
<div class="content-panel">
|
|
99
|
+
<div class="cookbook-container">
|
|
100
|
+
<h1 id="_top" data-page-title set:html={data.title} />
|
|
101
|
+
{data.draft && <DraftContentNotice />}
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="content-panel">
|
|
105
|
+
<div class="cookbook-container">
|
|
106
|
+
<MarkdownContent>
|
|
107
|
+
<slot />
|
|
108
|
+
</MarkdownContent>
|
|
109
|
+
<Footer />
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
</main>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</PageFrame>
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Styles as Styles$1 } from "@tenphi/tasty/core";
|
|
2
|
+
import { ElementsDefinition, ModPropsInput, Styles, StylesInterface, SubElementProps, TastyElementOptions, TastyPolymorphicComponent, TokenPropsInput, VariantMap, mergeStyles, tasty, useGlobalStyles } from "@tenphi/tasty";
|
|
3
|
+
import { ElementType, ForwardRefExoticComponent, JSX, PropsWithoutRef, RefAttributes } from "react";
|
|
4
|
+
//#region src/define-component.d.ts
|
|
5
|
+
type SubElementTag<Definition extends ElementsDefinition[string]> = Definition extends string ? Definition : Definition extends {
|
|
6
|
+
as?: infer Tag;
|
|
7
|
+
} ? Tag extends keyof JSX.IntrinsicElements ? Tag : "div" : "div";
|
|
8
|
+
type SubElements<E extends ElementsDefinition> = { [Name in keyof E]: ForwardRefExoticComponent<PropsWithoutRef<SubElementProps<SubElementTag<E[Name]>>> & RefAttributes<SubElementTag<E[Name]> extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[SubElementTag<E[Name]>] : unknown>>; };
|
|
9
|
+
/** Create a named Tasty component with theme.styles[name] merged into its defaults. */
|
|
10
|
+
declare function defineComponent<K extends readonly (keyof StylesInterface)[], V extends VariantMap, E extends ElementsDefinition = Record<string, never>, AsType extends ElementType = "div", M extends ModPropsInput = readonly never[], TP extends TokenPropsInput = readonly never[]>(name: string, options: TastyElementOptions<K, V, E, AsType, M, TP>): TastyPolymorphicComponent<AsType, K, V, M, TP> & SubElements<E>;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/components/component-styles.d.ts
|
|
13
|
+
/** Merge a partial theme override into a built-in or consumer style tree. */
|
|
14
|
+
declare function resolveComponentStyles(name: string, baseStyles: Styles$1): Styles$1;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { type Styles, defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles };
|
|
17
|
+
//# sourceMappingURL=styling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styling.d.ts","names":[],"sources":["../src/define-component.ts","../src/components/component-styles.ts"],"mappings":";;;;KAoBK,cAAc,mBAAmB,8BACpC,4BACI,aACA;EAAqB,WAAW;IAC9B,kBAAkB,IAAI,oBACpB;KAKL,YAAY,UAAU,yBACxB,cAAc,IAAI,0BACjB,gBAAgB,gBAAgB,cAAc,EAAE,WAC9C,cACE,cAAc,EAAE,qBAAqB,wBACjC,sBAAsB,cAAc,EAAE;;iBAOlC,gBACd,0BAA0B,oBAC1B,UAAU,YACV,UAAU,qBAAqB,uBAC/B,eAAe,qBACf,UAAU,kCACV,WAAW,oCAEX,cACA,SAAS,oBAAoB,GAAG,GAAG,GAAG,QAAQ,GAAG,MAChD,0BAA0B,QAAQ,GAAG,GAAG,GAAG,MAAM,YAAY;;;;iBCjChD,uBACd,cACA,YAAY,WACX"}
|
package/dist/styling.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { i as resolveComponentStyles, t as configureCookbookStates } from "./tasty-states-BDKIbfw2.js";
|
|
2
|
+
import { mergeStyles, tasty, tasty as tasty$1, useGlobalStyles } from "@tenphi/tasty";
|
|
3
|
+
//#region src/define-component.ts
|
|
4
|
+
/** Create a named Tasty component with theme.styles[name] merged into its defaults. */
|
|
5
|
+
function defineComponent(name, options) {
|
|
6
|
+
return tasty$1({
|
|
7
|
+
...options,
|
|
8
|
+
styles: resolveComponentStyles(name, options.styles ?? {})
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/styling.ts
|
|
13
|
+
configureCookbookStates();
|
|
14
|
+
//#endregion
|
|
15
|
+
export { defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=styling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styling.js","names":["tasty"],"sources":["../src/define-component.ts","../src/styling.ts"],"sourcesContent":["import {\n tasty,\n type ElementsDefinition,\n type ModPropsInput,\n type StylesInterface,\n type SubElementProps,\n type TastyElementOptions,\n type TastyPolymorphicComponent,\n type TokenPropsInput,\n type VariantMap,\n} from \"@tenphi/tasty\";\nimport type {\n ElementType,\n ForwardRefExoticComponent,\n JSX,\n PropsWithoutRef,\n RefAttributes,\n} from \"react\";\nimport { resolveComponentStyles } from \"./components/component-styles.js\";\n\ntype SubElementTag<Definition extends ElementsDefinition[string]> =\n Definition extends string\n ? Definition\n : Definition extends { as?: infer Tag }\n ? Tag extends keyof JSX.IntrinsicElements\n ? Tag\n : \"div\"\n : \"div\";\n\n// Use public Tasty types so declarations do not leak its private sub-element aliases.\ntype SubElements<E extends ElementsDefinition> = {\n [Name in keyof E]: ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<SubElementTag<E[Name]>>> &\n RefAttributes<\n SubElementTag<E[Name]> extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[SubElementTag<E[Name]>]\n : unknown\n >\n >;\n};\n\n/** Create a named Tasty component with theme.styles[name] merged into its defaults. */\nexport function defineComponent<\n K extends readonly (keyof StylesInterface)[],\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n AsType extends ElementType = \"div\",\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n name: string,\n options: TastyElementOptions<K, V, E, AsType, M, TP>,\n): TastyPolymorphicComponent<AsType, K, V, M, TP> & SubElements<E> {\n return tasty<K, V, E, AsType, M, TP>({\n ...options,\n styles: resolveComponentStyles(name, options.styles ?? {}),\n }) as TastyPolymorphicComponent<AsType, K, V, M, TP> & SubElements<E>;\n}\n","import { configureCookbookStates } from \"./components/tasty-states.js\";\n\n// Consumer components can be evaluated before Cookbook's own components.\nconfigureCookbookStates();\n\nexport { tasty, useGlobalStyles, mergeStyles } from \"@tenphi/tasty\";\nexport type { Styles } from \"@tenphi/tasty\";\nexport { defineComponent } from \"./define-component.js\";\nexport { resolveComponentStyles } from \"./components/component-styles.js\";\n"],"mappings":";;;;AA0CA,SAAgB,gBAQd,MACA,SACiE;CACjE,OAAOA,QAA8B;EACnC,GAAG;EACH,QAAQ,uBAAuB,MAAM,QAAQ,UAAU,CAAC,CAAC;CAC3D,CAAC;AACH;;;ACtDA,wBAAwB"}
|