--- import ThemeSettings from '@shared/components/demo/ThemeSettings.astro' import { site } from '@shared/lib/site' import { tablerJsPath } from '@shared/lib/assets' import PageModals from '@shared/components/PageModals.astro' import PageScripts from '@shared/components/PageScripts.astro' import Analytics from '@shared/components/Analytics.astro' import libs from '@tabler/core/libs.json' import { themeDefaults, themePresets, sidebarOnlyKeys, navbarOnlyKeys, themeDataAttributes, type ThemeKey } from '@shared/lib/theme-config' interface Props { title?: string | undefined /** Third-party libs from libs.json, e.g. ['apexcharts', 'jsvectormap'] */ pageLibs?: string[] | undefined /** Extra body classes, e.g. "layout-boxed" / "layout-fluid" */ bodyClass?: string | undefined /** dir="rtl" + RTL variants of the tabler/plugin stylesheets */ rtl?: boolean | undefined /** Relative asset base: '.' for root pages, '..' one level deep */ base?: string /** — falls back to the site description */ description?: string | undefined /** layout settings the page renders as data-bs-* on ; the switcher's stored choice still wins */ themeSettings?: Partial> | undefined } const { title, pageLibs = [], bodyClass, rtl = false, base = '.', description, themeSettings = {} } = Astro.props // The page's own layout, in the switcher's vocabulary: rendered before the theme // script runs, so a page keeps its variant until the visitor chooses otherwise. const themeAttributes = themeDataAttributes(themeSettings) // Development build: unminified assets, dev favicon (same rule as DocsLayout). const environment = process.env.NODE_ENV || 'production' const isDevelopment = environment === 'development' const min = isDevelopment ? '' : '.min' // The promo top banner loads on Vercel production deploys only, never on branch // previews, local builds or the packaged demo (VERCEL_ENV is "preview" or unset there). const isProduction = process.env.VERCEL_ENV === 'production' // RTL swaps tabler/plugin stylesheets for their .rtl.css variants (demo stays LTR) const rtlSuffix = rtl ? '.rtl' : '' type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean } const unknownLibs = pageLibs.filter((name) => !(name in libs)) if (unknownLibs.length > 0) { throw new Error(`BaseLayout: unknown pageLibs ${unknownLibs.map((name) => `"${name}"`).join(', ')} — use a key from core/libs.json`) } const pageLibEntries = Object.entries(libs as Record).filter(([name]) => pageLibs.includes(name)) // Google Maps API key comes from the environment (GOOGLE_MAPS_KEY in .env or the // host's settings), never from the source. Without it the script loads keyless. const googleMapsKey = import.meta.env.GOOGLE_MAPS_KEY ?? process.env.GOOGLE_MAPS_KEY ?? '' // External URLs (http/https) are emitted verbatim (with the maps-key placeholder // replaced); local files as ./dist/libs/{npm}/{file}. const libHref = (lib: Lib, file: string) => (/^https?:\/\//.test(file) ? file.replace(googleMapsKey ? 'GOOGLE_MAPS_KEY' : '?key=GOOGLE_MAPS_KEY', googleMapsKey) : `${base}/dist/libs/${lib.npm}/${file}`) const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file))) const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean(lib.head) === head).flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file))) --- {title ? `${title} - ` : ''}{site.title} - {site.descriptionShort} { libCssFiles.length > 0 && ( '} /> {libCssFiles.map((href) => ( ))} '} /> ) } {site.cssPlugins.map((plugin) => )} { libJsFiles(true).length > 0 && ( '} /> {libJsFiles(true).map((src) => ( { libJsFiles(false).length > 0 && ( '} /> {libJsFiles(false).map((src) => ( {isProduction &&