Files
tabler/shared/layouts/DefaultLayout.astro
T

112 lines
4.4 KiB
Plaintext

---
import BaseLayout from './BaseLayout.astro'
import Navbar from '@shared/components/navbar/Navbar.astro'
import Sidebar from '@shared/components/navbar/Sidebar.astro'
import PageHeader from '@shared/components/layout/PageHeader.astro'
import Footer from '@shared/components/layout/Footer.astro'
import type { ThemeKey } from '@shared/lib/theme-config'
interface Props {
title?: string | undefined
/** Script/CSS library keys passed to BaseLayout */
pageLibs?: string[]
/** title shown in the page header; defaults to `title`, pass false for no page header */
pageHeader?: string | false | undefined
/** renders a layout/headers/{file} component instead of the title block */
pageHeaderFile?: string | undefined
/** small text above the page title */
pretitle?: string | undefined
/** text below the page title */
description?: string | undefined
/** active menu entry, e.g. "layout.vertical" */
pageMenu?: string | undefined
/** where the main menu lives: the top navbar or the vertical sidebar */
navbarPosition?: 'horizontal' | 'vertical'
/** container width: default, fluid or boxed */
layout?: 'default' | 'fluid' | 'boxed'
/** adds my-auto to the .container-xl */
containerCentered?: boolean
/** page-wrapper-full and no .container-xl around the body */
wrapperFull?: boolean
/** extra classes on the .container-xl */
containerClass?: string
/** extra body classes */
bodyClass?: string
/** dir="rtl" and the RTL stylesheets */
rtl?: boolean
/** sidebar on the end side */
sidebarEnd?: boolean
/** icon-only sidebar rail: folded, or folded until hovered */
sidebarMode?: 'folded' | 'folded-hover'
/** renders the runtime fold toggle button in the sidebar */
sidebarFoldToggle?: boolean
/** transparent sidebar */
navbarTransparent?: boolean
/** condensed single-row navbar */
navbarCondensed?: boolean
/** dark navbar */
navbarDark?: boolean
/** floating navigation: the navbar and the sidebar keep a gap from the edges */
navbarFloating?: boolean
/** sticky navbar */
navbarSticky?: boolean
}
const { title, pageLibs, pageHeader, pageHeaderFile, pretitle, description, pageMenu, navbarPosition, layout, containerCentered, wrapperFull, containerClass, bodyClass, rtl, sidebarEnd, sidebarMode, sidebarFoldToggle, navbarTransparent, navbarCondensed, navbarDark, navbarSticky, navbarFloating } = Astro.props
// Most pages repeat the page title verbatim, so `pageHeader` falls back to `title`.
// Pages that deliberately have no header (blank, playgrounds) pass pageHeader={false}.
const headerTitle = pageHeader === false ? undefined : (pageHeader ?? title)
// The page always renders both navigations and states its own layout as
// data-bs-* attributes on <html>; CSS shows one of them. That is what lets the
// theme settings panel switch the layout at runtime on any page — see
// `shared/lib/theme-config.ts`.
const themeSettings: Partial<Record<ThemeKey, string | undefined>> = {
'navbar-position': navbarPosition,
'layout': layout,
'navbar': navbarSticky ? 'sticky' : undefined,
'navbar-style': navbarFloating ? 'floating' : undefined,
'navbar-theme': navbarDark ? 'dark' : undefined,
'sidebar': sidebarMode,
}
---
<BaseLayout title={title} pageLibs={pageLibs} bodyClass={bodyClass} rtl={rtl} description={description} themeSettings={themeSettings}>
<div class="page">
<!-- BEGIN SIDEBAR -->
<Sidebar end={sidebarEnd} transparent={navbarTransparent} foldToggle={sidebarFoldToggle} breakpoint="lg" pageMenu={pageMenu} />
<!-- END SIDEBAR -->
<!-- BEGIN NAVBAR -->
<Navbar hideSearch pageMenu={pageMenu} condensed={navbarCondensed} />
<!-- END NAVBAR -->
<div class:list={['page-wrapper', wrapperFull && 'page-wrapper-full']}>
<!-- BEGIN PAGE HEADER -->
<PageHeader title={headerTitle} pretitle={pretitle} description={description} file={pageHeaderFile}>
<slot name="page-header-actions" slot="actions" />
</PageHeader>
<!-- END PAGE HEADER -->
<!-- BEGIN PAGE BODY -->
<main id="content" class="page-body">
{
wrapperFull ? (
<slot />
) : (
<div class={`container-xl${containerCentered ? ' my-auto' : ''}${containerClass ? ` ${containerClass}` : ''}`}>
<slot />
</div>
)
}
</main>
<!-- END PAGE BODY -->
<!-- BEGIN FOOTER -->
<Footer />
<!-- END FOOTER -->
</div>
</div>
</BaseLayout>