--- // Docs layout for the @tabler/docs app. // Standalone layout with its own ; does NOT use BaseLayout.astro. // Development uses the unminified assets; production additionally emits the SEO metadata. import { site } from '@shared/lib/site'; import libs from '@tabler/core/libs.json'; import docs from '@data/docs.json'; import Icon from '@ui/Icon.astro'; import DocsNavbar from '@components/DocsNavbar.astro'; import DocsMenu from '@components/DocsMenu.astro'; import DocsToc from '@components/DocsToc.astro'; import type { TocItem } from '@components/DocsToc.astro'; import DocsPagination from '@components/DocsPagination.astro'; import Prose from '@ui/Prose.astro'; import PageScripts from '@shared/components/PageScripts.astro'; interface Props { /** front matter: the page's h1 heading */ title: string; /** front matter: optional SEO title override */ seoTitle?: string; /** front matter: lead below the title (p.text-secondary.fs-3.lh-3) */ summary?: string; /** front matter: SEO description */ description?: string; /** front matter: optional SEO description override */ seoDescription?: string; /** front matter `added-in`: renders the "Added in X" badge next to the h1 */ addedIn?: string; /** Table of contents (h2/h3 from the markdown content) — see DocsToc.astro */ toc?: TocItem[]; /** * Page URL in the docs namespace, e.g. "/ui/components/alert/". * By default derived from Astro.url.pathname by stripping the /docs prefix. * Drives the active menu entry, pagination, the "Edit this page" link, and * the relative favicon path. */ url?: string; /** Extra libraries from libs.json (css+js) */ docsLibs?: string[]; /** hides child and previous/next page navigation */ hidePagination?: boolean; /** repo-relative source path for the "Edit this page" link, e.g. "docs/pages/ui/components/alert.mdx" */ editPath?: string; } const { title, seoTitle, summary, description, seoDescription, addedIn, toc = [], docsLibs = [], hidePagination = false, editPath, } = Astro.props; const environment = process.env.NODE_ENV || 'production'; // Strip /docs prefix (and optional .html) for the docs namespace URL. const docsUrl = Astro.props.url ?? (() => { let p = Astro.url.pathname.replace(/^\/docs(?=\/|$)/, '').replace(/\.html$/, ''); if (!p.endsWith('/')) p += '/'; return p; })(); const pageSection = docsUrl.startsWith('/ui/') ? 'UI' : docsUrl.startsWith('/icons/') ? 'Icons' : docsUrl.startsWith('/illustrations/') ? 'Illustrations' : docsUrl.startsWith('/emails/') ? 'Emails' : ''; const metaTitle = seoTitle ?? title; const metaDescription = seoDescription ?? description; const siteName = pageSection ? `Tabler ${pageSection} Documentation` : 'Tabler Documentation'; const canonicalUrl = new URL(docsUrl, Astro.site ?? site.docsUrl).href; // Relative asset base: for /ui/components/alert/ -> "../../.." const depth = docsUrl.split('/').filter(Boolean).length; const relative = depth === 0 ? '.' : '../'.repeat(depth).slice(0, -1); // Source path for the "Edit this page" link. Prefer the real path passed by the // MDX layout; fall back to the flat-page convention (docs/pages/.mdx). const editFilePath = editPath ?? `docs/pages${docsUrl.replace(/\/$/, '')}.mdx`; // docs-libs + clipboard (always included). In dev, file names stay unchanged // (e.g. dist/clipboard.min.js keeps .min). type Lib = { npm?: string; js?: string[]; css?: string[] }; const libEntries = Object.entries(libs as Record); const libUrl = (lib: Lib, file: string) => file.startsWith('http://') || file.startsWith('https://') ? file : `/dist/libs/${lib.npm}/${file}`; const docsLibCss = libEntries .filter(([name]) => docsLibs.includes(name)) .flatMap(([, lib]) => (lib.css ?? []).map((file) => libUrl(lib, file))); const docsLibJs = libEntries .filter(([name]) => docsLibs.includes(name) || name === 'clipboard') .flatMap(([, lib]) => (lib.js ?? []).map((file) => libUrl(lib, file))); // Eventually belongs in src/lib/site.ts (out of scope for this task). const opencollectiveUrl = 'https://opencollective.com/tabler'; const xUrl = 'https://x.com/tabler_io'; const linkedinUrl = 'https://www.linkedin.com/company/tabler-io'; const year = new Date().getFullYear(); type DocsLink = { title: string; url: string; icon: string }; const docsLinks = docs.links as DocsLink[]; --- {metaTitle} | {siteName} { environment === 'production' && ( {metaDescription && } {metaDescription && } {metaDescription && } ) } { environment === 'development' && ( ) } {site.cssPlugins.map((plugin) => )} { docsLibCss.length > 0 && ( '} /> {docsLibCss.map((href) => )} '} /> ) } {/* is:inline — see MIGRATION.md (without it Astro adds data-astro-cid-*) */}

{title}

{ addedIn && (
Added in {addedIn}
) }

{summary}

{/* Page must supply headings with ids (MDX does this by default). */} {!hidePagination && }
© {year} Tabler. All rights reserved.
{ docsLibJs.length > 0 && ( '} /> {docsLibJs.map((src) =>