Files
tabler/shared/layouts/BaseLayout.astro
T

211 lines
7.6 KiB
Plaintext

---
import ThemeSettings from '@ui/ThemeSettings.astro'
import { site } from '@shared/lib/site'
import PageModals from '@shared/components/PageModals.astro'
import libs from '@tabler/core/libs.json'
interface Props {
title?: string
/** page-libs from the Eleventy front matter, e.g. ['apexcharts', 'jsvectormap'] */
pageLibs?: string[]
/** body-class front matter, e.g. "layout-boxed" / "layout-fluid" */
bodyClass?: string
/** layout-rtl — dir="rtl" + RTL variants of the tabler/plugin stylesheets */
rtl?: boolean
/** relative asset base (Liquid `page | relative`): '.' for root pages, '..' one level deep */
base?: string
}
const { title, pageLibs = [], bodyClass, rtl = false, base = '.' } = Astro.props
// PoC mirrors the Eleventy development build: unminified assets, dev favicon.
const environment = 'development'
const min = environment === 'development' ? '' : '.min'
// 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 pageLibEntries = Object.entries(libs as Record<string, Lib>).filter(([name]) => pageLibs.includes(name))
// dev build uses the dev Google Maps key (Liquid: google-maps-key)
const googleMapsKey = site.googleMapsDevKey
// Liquid: 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('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)))
---
<!doctype html>
<html lang="en" dir={rtl ? 'rtl' : undefined}>
<head>
<!-- BEGIN META -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>{title ? `${title} - ` : ''}{site.title} - {site.descriptionShort}</title>
<link rel="icon" href={`${base}/favicon-dev.ico`} type="image/x-icon" />
<link rel="shortcut icon" href={`${base}/favicon-dev.ico`} type="image/x-icon" />
<!-- END META -->
{
libCssFiles.length > 0 && (
<Fragment>
<Fragment set:html={'<!-- BEGIN PAGE LEVEL STYLES -->'} />
{libCssFiles.map((href) => (
<link href={href} rel="stylesheet" />
))}
<Fragment set:html={'<!-- END PAGE LEVEL STYLES -->'} />
</Fragment>
)
}
<!-- BEGIN GLOBAL MANDATORY STYLES -->
<link href={`${base}/dist/css/tabler${rtlSuffix}${min}.css`} rel="stylesheet" />
<!-- END GLOBAL MANDATORY STYLES -->
<!-- BEGIN PLUGINS STYLES -->
{site.cssPlugins.map((plugin) => <link href={`${base}/dist/css/tabler-${plugin}${rtlSuffix}${min}.css`} rel="stylesheet" />)}
<!-- END PLUGINS STYLES -->
<!-- BEGIN DEMO STYLES -->
<link href={`${base}/preview/css/demo${min}.css`} rel="stylesheet" />
<!-- END DEMO STYLES -->
{
libJsFiles(true).length > 0 && (
<Fragment>
<Fragment set:html={'<!-- BEGIN PAGE LIBRARIES -->'} />
{libJsFiles(true).map((src) => (
<script is:inline src={src} defer />
))}
<Fragment set:html={'<!-- END PAGE LIBRARIES -->'} />
</Fragment>
)
}
<!-- BEGIN CUSTOM FONT -->
{/* is:inline: keep the tag verbatim — Astro's scoped-style pipeline would add data-astro-cid-* attributes across the page */}
<style is:inline>
@import url('https://rsms.me/inter/inter.css');
</style>
<!-- END CUSTOM FONT -->
</head>
<body class={bodyClass}>
<a href="#content" class="visually-hidden skip-link">Skip to main content</a>
<!-- BEGIN GLOBAL THEME SCRIPT -->
<script is:inline src={`${base}/dist/js/tabler-theme${min}.js`}></script>
<!-- END GLOBAL THEME SCRIPT -->
<slot />
{/* equivalent of {% modals %}: modals registered by the page components */}
<PageModals />
<ThemeSettings />
{
libJsFiles(false).length > 0 && (
<Fragment>
<Fragment set:html={'<!-- BEGIN PAGE LIBRARIES -->'} />
{libJsFiles(false).map((src) => (
<script is:inline src={src} defer />
))}
<Fragment set:html={'<!-- END PAGE LIBRARIES -->'} />
</Fragment>
)
}
<!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
<script is:inline src={`${base}/dist/js/tabler${min}.js`} defer></script>
<!-- END GLOBAL MANDATORY SCRIPTS -->
<!-- BEGIN DEMO SCRIPTS -->
<script is:inline src={`${base}/preview/js/demo${min}.js`} defer></script>
<!-- END DEMO SCRIPTS -->
<!-- BEGIN PAGE SCRIPTS -->
<script is:inline>
/*
This script handles the theme settings offcanvas functionality
It saves the selected settings to localStorage and applies them to the document
It also updates the URL with the selected settings as query parameters
It also has a reset button to clear all settings and revert to default
This is just a demo script to show how to implement theme settings. You can modify it as needed.
*/
document.addEventListener('DOMContentLoaded', function () {
var themeConfig = {
'theme': 'light',
'theme-base': 'gray',
'theme-font': 'sans-serif',
'theme-primary': 'blue',
'theme-radius': '1',
}
var url = new URL(window.location)
var form = document.getElementById('offcanvas-settings')
var resetButton = document.getElementById('reset-changes')
var checkItems = function () {
for (var key in themeConfig) {
var value = window.localStorage['tabler-' + key] || themeConfig[key]
if (!!value) {
var radios = form.querySelectorAll(`[name="${key}"]`)
if (!!radios) {
radios.forEach((radio) => {
radio.checked = radio.value === value
})
}
}
}
}
form.addEventListener('change', function (event) {
var target = event.target,
name = target.name,
value = target.value
for (var key in themeConfig) {
if (name === key) {
var applied = value
if (key === 'theme' && value === 'auto') {
applied = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
if (applied !== themeConfig[key]) {
document.documentElement.setAttribute('data-bs-' + key, applied)
} else {
document.documentElement.removeAttribute('data-bs-' + key)
}
window.localStorage.setItem('tabler-' + key, value)
url.searchParams.set(key, value)
}
}
window.history.pushState({}, '', url)
})
resetButton.addEventListener('click', function () {
for (var key in themeConfig) {
var value = themeConfig[key]
document.documentElement.removeAttribute('data-bs-' + key)
window.localStorage.removeItem('tabler-' + key)
url.searchParams.delete(key)
}
checkItems()
window.history.pushState({}, '', url)
})
checkItems()
})
</script>
<!-- END PAGE SCRIPTS -->
</body>
</html>