---
import ThemeSettings from '@shared/components/demo/ThemeSettings.astro'
import { site } from '@shared/lib/site'
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', 'vector-map'] */
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; addon?: string; maps?: string[] }
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)))
// Tabler add-on bundles (dist/js) a page needs, loaded after tabler.js, and the
// map files of the vector map (dist/js/maps), which are plain data.
const libAddons = pageLibEntries.flatMap(([, lib]) => (lib.addon ? [lib.addon] : []))
const libMaps = pageLibEntries.flatMap(([, lib]) => lib.maps ?? [])
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) => (
))}
'} />
)
}
Skip to main content
{
libJsFiles(false).length > 0 && (
'} />
{libJsFiles(false).map((src) => (
))}
'} />
)
}
{libAddons.map((addon) => )}
{libMaps.map((map) => )}
{isProduction && }