Custom layouts
With slots and directives you have all the tools you need to:
- render into specific areas of the layout using slots
- control any aspect of your app using directives
Slots and directives lets you decouple content from the layout, so you can use any layout you want, even have multiple layouts for different parts of your app.
1. Any HTML can be your layout
Take any HTML, set where content should be rendered using the slot targets, connect directives to control any aspect of your app (layout, theme, etc.) and you have a custom layout.
my-custom-layout.tsx
import { DropdownContentContainerProvider } from "@contember/admin"
import {
commonSlotTargets,
CommonSlotTargets,
useDocumentTitle,
useLayoutSlotRegistryContext,
} from "@contember/layout"
import { useDirectives } from "./components/Directives"
import { SlotTargets, slotTargets } from "./components/Slots"
export function MyCustomLayout() {
const { activeSlots } = useLayoutSlotRegistryContext()
const directives = useDirectives()
useDocumentTitle(directives.title)
return (
<div className="layout">
<header className="layout__header">
{activeSlots.has(commonSlotTargets.Back) ? <CommonSlotTargets.Back /> : null}
{activeSlots.has(commonSlotTargets.Logo) ? <CommonSlotTargets.Logo /> : null}
{activeSlots.has(commonSlotTargets.Actions) ? <CommonSlotTargets.Actions /> : null}
</header>
<main className="layout__main">
<h1>{directives.title}</h1>
{activeSlots.has(slotTargets.Subtitle) ? <SlotTargets.Subtitle /> : null}
{activeSlots.has(commonSlotTargets.Content) ? <CommonSlotTargets.Content /> : null}
</main>
<aside className="layout__aside">
{activeSlots.has(commonSlotTargets.Navigation) ? <CommonSlotTargets.Navigation /> : null}
{activeSlots.has(commonSlotTargets.Sidebar) ? <CommonSlotTargets.Sidebar /> : null}
</aside>
<footer className="layout__footer">
</footer>
<DropdownContentContainerProvider />
<div id="portal-root" />
</div>
)
}
2. Using your custom layout
Now that we have a layout, we need to connect it with Contember, swap it anytime you need.
admin/components/Layout.tsx
import * as React from 'react'
import { MyCustomLayout } from '../my-custom-layout'
export const Layout = ({
children: pages,
}: React.PropsWithChildren) => (
<>
<MyCustomLayout />
{pages}
</>
)