Layout
Pre-built page layout compositions and building block components for common application patterns. All page layouts share a common shell with optional header and footer slots.
Import
import { SingleColumnPage, SidebarPage, DualSidebarPage, StackedPage, HolyGrailPage, SplitPage, GridPage, AsymmetricPage, PageLayout, Header, Sidebar, Main, Footer, Container } from '@tac-ui/web';SingleColumnPage
A centered single-column layout ideal for content-focused pages like blog posts, articles, documentation, and landing pages. Content is horizontally centered with responsive padding and a configurable max-width constraint.
<SingleColumnPage
maxWidth="lg"
header={<Header sticky bordered>Navigation</Header>}
footer={<Footer>Footer</Footer>}
>
<p>Page content goes here</p>
</SingleColumnPage>| Prop | Type | Default | Description |
|---|---|---|---|
| maxWidth | "sm" | "md" | "lg" | "xl" | "full" | "lg" | Maximum width of the content column. sm=640px, md=768px, lg=1024px, xl=1280px. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
SidebarPage
A layout with a fixed-width sidebar and a scrollable main content area. The standard app shell pattern used for admin panels, settings pages, and navigation-heavy applications. The sidebar supports collapsing, positioning on either side, rounded floating style, and custom header with label/icon.
<SidebarPage
sidebar={<nav>Sidebar navigation</nav>}
sidebarWidth={280}
sidebarPosition="left"
sidebarLabel="Navigation"
sidebarIcon={<Menu size={18} />}
sidebarRounded
collapsible
defaultCollapsed={false}
header={<Header sticky bordered>Navigation</Header>}
>
<p>Main content</p>
</SidebarPage>| Prop | Type | Default | Description |
|---|---|---|---|
| sidebar | React.ReactNode | - | Content rendered inside the sidebar panel. Required. |
| sidebarWidth | number | 280 | Width of the sidebar in pixels when expanded. |
| sidebarPosition | "left" | "right" | "left" | Which side the sidebar is placed on. |
| collapsible | boolean | false | Whether the sidebar can be collapsed via a toggle button. |
| defaultCollapsed | boolean | false | Initial collapsed state when uncontrolled. |
| sidebarLabel | React.ReactNode | - | Label displayed in the sidebar header area. |
| sidebarIcon | React.ReactNode | - | Icon displayed before the label in the sidebar header. |
| sidebarFillHeight | boolean | true | Whether the sidebar fills the remaining vertical space. |
| sidebarRounded | boolean | false | Whether the sidebar has rounded corners with a floating card style. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
DashboardPage
A dashboard layout with a left-anchored navigation sidebar and a main content area. Similar to SidebarPage but specialized for dashboard use cases where the sidebar is always on the left. Commonly combined with GridPage children for card-based dashboard grids.
<DashboardPage
sidebar={<nav>Dashboard nav</nav>}
sidebarWidth={260}
sidebarLabel="Dashboard"
collapsible
header={<Header sticky bordered blur>App Header</Header>}
>
<GridPage columns={3}>
<Card>Stats</Card>
<Card>Chart</Card>
<Card>Table</Card>
</GridPage>
</DashboardPage>| Prop | Type | Default | Description |
|---|---|---|---|
| sidebar | React.ReactNode | - | Content rendered inside the left sidebar panel. Required. |
| sidebarWidth | number | 260 | Width of the sidebar in pixels when expanded. |
| collapsible | boolean | false | Whether the sidebar can be collapsed via a toggle button. |
| defaultCollapsed | boolean | false | Initial collapsed state when uncontrolled. |
| sidebarLabel | React.ReactNode | - | Label displayed in the sidebar header area. |
| sidebarIcon | React.ReactNode | - | Icon displayed before the label in the sidebar header. |
| sidebarFillHeight | boolean | true | Whether the sidebar fills the remaining vertical space. |
| sidebarRounded | boolean | false | Whether the sidebar has rounded corners with a floating card style. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
SplitPage
A two-pane layout with equal-width left and right panels separated by a border. Ideal for side-by-side comparisons, authentication pages (hero + form), dual-panel editors, or before/after views. Each panel scrolls independently.
<SplitPage
left={<div>Left panel content</div>}
right={<div>Right panel content</div>}
header={<Header sticky bordered>App</Header>}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| left | React.ReactNode | - | Content rendered in the left panel. Required. |
| right | React.ReactNode | - | Content rendered in the right panel. Required. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
GridPage
A responsive grid layout that distributes children into columns. Columns are responsive by default: single column on mobile, scaling up to the configured column count on wider screens. Useful for card grids, image galleries, and product listings.
<GridPage
columns={3}
header={<Header sticky bordered>App</Header>}
>
<Card>Item 1</Card>
<Card>Item 2</Card>
<Card>Item 3</Card>
<Card>Item 4</Card>
</GridPage>| Prop | Type | Default | Description |
|---|---|---|---|
| columns | 2 | 3 | 4 | 3 | Number of grid columns at the widest breakpoint. Responsive: 2-col uses md breakpoint, 3-col uses md+lg, 4-col uses sm+lg. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
StackedPage
A vertically stacked layout where children fill the main column in document order. Each child is rendered as a full-width section in a flex column. Ideal for multi-section landing pages, onboarding flows, and long-scroll storytelling pages.
<StackedPage header={<Header sticky bordered>Navigation</Header>}>
<section>Hero Section</section>
<section>Features</section>
<section>Testimonials</section>
</StackedPage>| Prop | Type | Default | Description |
|---|---|---|---|
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
DualSidebarPage
Three-column layout with independent left and right sidebars flanking the main content. Each sidebar has its own width, collapsibility, label, icon, and style options. Useful for IDE-like interfaces, email clients, or content management systems where navigation and detail panels coexist.
<DualSidebarPage
leftSidebar={<nav>Navigation</nav>}
rightSidebar={<aside>Details panel</aside>}
leftWidth={240}
rightWidth={240}
leftCollapsible
rightCollapsible
leftLabel="Explorer"
rightLabel="Properties"
header={<Header sticky bordered>App</Header>}
>
<p>Main content</p>
</DualSidebarPage>| Prop | Type | Default | Description |
|---|---|---|---|
| leftSidebar | React.ReactNode | - | Content rendered in the left sidebar panel. Required. |
| rightSidebar | React.ReactNode | - | Content rendered in the right sidebar panel. Required. |
| leftWidth | number | 240 | Width of the left sidebar in pixels. |
| rightWidth | number | 240 | Width of the right sidebar in pixels. |
| leftCollapsible | boolean | false | Whether the left sidebar can be collapsed. |
| rightCollapsible | boolean | false | Whether the right sidebar can be collapsed. |
| defaultLeftCollapsed | boolean | false | Initial collapsed state for the left sidebar. |
| defaultRightCollapsed | boolean | false | Initial collapsed state for the right sidebar. |
| leftLabel | React.ReactNode | - | Label displayed in the left sidebar header. |
| leftIcon | React.ReactNode | - | Icon displayed before the left sidebar label. |
| rightLabel | React.ReactNode | - | Label displayed in the right sidebar header. |
| rightIcon | React.ReactNode | - | Icon displayed before the right sidebar label. |
| leftFillHeight | boolean | true | Whether the left sidebar fills the remaining vertical space. |
| rightFillHeight | boolean | true | Whether the right sidebar fills the remaining vertical space. |
| leftRounded | boolean | false | Whether the left sidebar has a rounded floating card style. |
| rightRounded | boolean | false | Whether the right sidebar has a rounded floating card style. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
HolyGrailPage
Classic holy-grail layout: full-width header and footer with a three-column body containing navigation, main content, and an aside. Structurally similar to DualSidebarPage but semantically designed for the traditional web layout pattern with header/footer spanning the full width.
<HolyGrailPage
leftSidebar={<nav>Nav</nav>}
rightSidebar={<aside>Aside</aside>}
leftCollapsible
rightCollapsible
header={<Header sticky bordered>App</Header>}
footer={<Footer bordered>Footer</Footer>}
>
<p>Main content</p>
</HolyGrailPage>| Prop | Type | Default | Description |
|---|---|---|---|
| leftSidebar | React.ReactNode | - | Content rendered in the left navigation sidebar. Required. |
| rightSidebar | React.ReactNode | - | Content rendered in the right aside sidebar. Required. |
| leftWidth | number | 220 | Width of the left sidebar in pixels. |
| rightWidth | number | 220 | Width of the right sidebar in pixels. |
| leftCollapsible | boolean | false | Whether the left sidebar can be collapsed. |
| rightCollapsible | boolean | false | Whether the right sidebar can be collapsed. |
| defaultLeftCollapsed | boolean | false | Initial collapsed state for the left sidebar. |
| defaultRightCollapsed | boolean | false | Initial collapsed state for the right sidebar. |
| leftLabel | React.ReactNode | - | Label displayed in the left sidebar header. |
| leftIcon | React.ReactNode | - | Icon displayed before the left sidebar label. |
| rightLabel | React.ReactNode | - | Label displayed in the right sidebar header. |
| rightIcon | React.ReactNode | - | Icon displayed before the right sidebar label. |
| leftFillHeight | boolean | true | Whether the left sidebar fills the remaining vertical space. |
| rightFillHeight | boolean | true | Whether the right sidebar fills the remaining vertical space. |
| leftRounded | boolean | false | Whether the left sidebar has a rounded floating card style. |
| rightRounded | boolean | false | Whether the right sidebar has a rounded floating card style. |
| header | React.ReactNode | - | Content rendered in the full-width top header slot. |
| footer | React.ReactNode | - | Content rendered in the full-width bottom footer slot. |
AsymmetricPage
Two-pane layout with a configurable flex ratio between the primary and secondary panels. The secondary panel has a card-style background and a left border. Ideal for article + sidebar, main content + related items, or any layout where one pane should be visually dominant.
<AsymmetricPage
primary={<div>Main article</div>}
secondary={<div>Related content</div>}
ratio="2:1"
header={<Header sticky bordered>App</Header>}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| primary | React.ReactNode | - | Content rendered in the primary (wider by default) panel. Required. |
| secondary | React.ReactNode | - | Content rendered in the secondary panel (card background). Required. |
| ratio | "2:1" | "3:1" | "1:2" | "1:3" | "2:1" | Flex width ratio between primary and secondary panels. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
AppPage
A narrow, fixed-width layout optimized for mobile apps and webview embedding. Full-width on small screens, centered with an optional elevated card style on larger screens. Supports safe-area inset padding for native iOS/Android webview environments, and independently controllable sticky header/footer.
<AppPage
maxWidth="sm"
elevated
safeArea
header={<Header sticky bordered>App</Header>}
footer={<Footer bordered>Footer</Footer>}
>
<p>Mobile-optimized content</p>
</AppPage>| Prop | Type | Default | Description |
|---|---|---|---|
| maxWidth | "xs" | "sm" | "md" | "lg" | "sm" | Maximum content width. xs=360px, sm=390px, md=430px, lg=520px. |
| elevated | boolean | false | Render as an elevated card with borders and shadow on wider screens (sm+ breakpoint). |
| safeArea | boolean | true | Apply safe-area inset padding (env(safe-area-inset-*)) for native webview environments. |
| stickyHeader | boolean | true | Whether the header sticks to the top of the viewport. |
| stickyFooter | boolean | false | Whether the footer sticks to the bottom of the viewport. |
| header | React.ReactNode | - | Content rendered in the top header slot. |
| footer | React.ReactNode | - | Content rendered in the bottom footer slot. |
Building Blocks
Low-level layout primitives used to compose the page layouts above. These can also be used independently to build custom layouts.
Header
Top-level page header bar (64px height) with optional sticky positioning, bottom border, backdrop blur, and auto-hide on scroll. Uses flex row layout for aligning navigation items. The header preserves its height via shrink-0, preventing compression in flex column containers.
// Basic header
<Header sticky bordered>Navigation</Header>
// Blur + auto-hide header
<Header sticky bordered blur autoHide>
<span>Logo</span>
<nav>Links</nav>
</Header>| Prop | Type | Default | Description |
|---|---|---|---|
| sticky | boolean | false | Whether the header sticks to the top of the viewport on scroll (sticky top-0 with z-index). |
| bordered | boolean | true | Whether to render a bottom border separating the header from content. |
| blur | boolean | false | Apply backdrop blur with semi-transparent background (bg-[var(--card)]/80 backdrop-blur-lg). Great for overlapping scroll content. |
| autoHide | boolean | false | Auto-hide the header when scrolling down, reappear when scrolling up. Triggers after 64px of scroll. Works best combined with sticky. |
Footer
Page footer bar with optional top border. Renders a footer element with card background and horizontal padding.
<Footer bordered>
<p>© 2025 Company</p>
</Footer>| Prop | Type | Default | Description |
|---|---|---|---|
| bordered | boolean | true | Whether to render a top border separating the footer from content. |
Sidebar
Collapsible side panel that can be positioned on the left or right of the layout. Features animated collapse/expand transitions, a header area with label, icon, and toggle button, a scrollable content area, and an optional pinned footer. When collapsed, the sidebar shrinks to 64px (icon-only width). The rounded variant renders the sidebar as a floating card with margins and rounded corners.
<Sidebar
width={280}
position="left"
label="Navigation"
icon={<Menu size={18} />}
collapsible
collapsed={collapsed}
onCollapse={setCollapsed}
rounded
swapOnCollapse
footer={<SidebarFooter>Settings</SidebarFooter>}
>
<SidebarGroup label="Menu">
<SidebarItem variant="filled" size="md" icon={<Home />} active>Home</SidebarItem>
<SidebarItem variant="filled" size="md" icon={<Settings />}>Settings</SidebarItem>
</SidebarGroup>
</Sidebar>| Prop | Type | Default | Description |
|---|---|---|---|
| width | number | 280 | Width of the sidebar in pixels when expanded. Collapsed width is always 64px. |
| position | "left" | "right" | "left" | Which side of the layout the sidebar appears on. Controls border side and toggle icon direction. |
| label | React.ReactNode | - | Label displayed in the sidebar header. Hidden when collapsed. |
| icon | React.ReactNode | - | Icon displayed before the label in the sidebar header. Shown alone when collapsed. |
| collapsible | boolean | false | Whether a toggle button is rendered to collapse/expand the sidebar. |
| collapsed | boolean | false | Controlled collapsed state of the sidebar. |
| onCollapse | (collapsed: boolean) => void | - | Callback fired when the collapse toggle is clicked. |
| fillHeight | boolean | true | Whether the sidebar fills the remaining vertical space (h-full). |
| rounded | boolean | false | Whether the sidebar has rounded corners with a floating card style (border + margin + rounded corners). |
| swapOnCollapse | boolean | false | When true, the icon is hidden when expanded and the label is hidden when collapsed, swapping between them. |
| footer | React.ReactNode | - | Content rendered in a fixed footer area at the bottom of the sidebar. |
Sidebar Sub-components
Components designed to be used inside Sidebar for structured navigation. They automatically respond to the parent Sidebar's collapsed state via SidebarContext.
SidebarHeader
Renders the sidebar header area. Use label/icon props for simple usage, or pass custom children for full control over collapsed/expanded rendering. Reads collapsed, collapsible, and position from SidebarContext. The collapse toggle button is automatically rendered when collapsible is enabled in the parent Sidebar.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | React.ReactNode | - | Label displayed in the sidebar header. Hidden when collapsed. |
| icon | React.ReactNode | - | Icon displayed before the label. Shown alone when collapsed. |
| swapOnCollapse | boolean | false | When true, the icon is hidden when expanded and the label is hidden when collapsed, swapping between them. |
| children | React.ReactNode | - | Custom content that replaces the default label/icon rendering. Use useSidebarContext() inside children to react to collapsed state. |
SidebarGroup
Groups sidebar items under an optional label with support for collapsible sections. When the sidebar is collapsed, behavior depends on the collapseDisplay prop: "children" (default) shows the child items as icon-only, "group" shows only the group icon.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | - | Group label displayed above items. Hidden when sidebar is collapsed. |
| icon | React.ReactNode | - | Icon displayed before the label. Shown alone when sidebar is collapsed and collapseDisplay="group". |
| active | boolean | false | Whether a child item in this group is currently active. Highlights the group label with primary color. |
| collapseDisplay | "group" | "children" | "children" | What to show when the sidebar is collapsed. "group" shows the group icon only, "children" shows child items (icon-only). |
| collapsible | boolean | false | Whether the group can be expanded/collapsed by clicking the header (chevron toggle). |
| defaultOpen | boolean | true | Whether the group is open by default when collapsible is enabled. |
SidebarItem
Individual navigation item with optional icon and active state. When the sidebar is collapsed, only the icon is visible. Items without icons are hidden when collapsed. Supports three active style variants: "subtle" (muted text, point color active), "filled" (primary background), and "foreground" (primary text + bold).
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | React.ReactNode | - | Icon rendered before the label. Shown alone when sidebar is collapsed. Items without icons are hidden when collapsed. |
| active | boolean | false | Whether this item is currently active/selected. |
| variant | "subtle" | "filled" | "foreground" | "subtle" | Active style variant. "subtle" uses muted text with point color when active, "filled" uses primary background color, "foreground" uses primary text color with bold weight. |
| size | "sm" | "md" | "sm" | Size of the sidebar item. "sm" uses compact padding and 13px text, "md" uses standard padding and 14px text. |
SidebarContent
Arbitrary sidebar content container. Fully hidden with animation when the sidebar is collapsed. Useful for search bars, status indicators, or any non-navigation content.
SidebarFooter
Footer area pinned to the bottom of the sidebar. Content is hidden with animation when collapsed. Useful for user profiles, settings links, or version info.
Container
Centered content wrapper with responsive horizontal padding (px-4 on mobile, px-6 on sm, px-8 on lg) and configurable max-width. A general-purpose content constraint component.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "xl" | "full" | "lg" | Maximum width of the container. sm=640px, md=768px, lg=1024px, xl=1280px, full=no limit. |
Main
Primary content area that grows to fill available space (flex-1) with padding and optional max-width constraint. Used as the main content region inside layout compositions.
| Prop | Type | Default | Description |
|---|---|---|---|
| maxWidth | "sm" | "md" | "lg" | "xl" | "full" | "full" | Maximum width of the main content area with auto horizontal centering. |
FloatingMenuBar
A floating navigation bar that hovers over page content with a pill-shaped appearance. Supports 9 positions in a 3x3 grid (top/middle/bottom x left/center/right), backdrop blur, and border. Commonly used as a bottom tab bar in mobile/app-like layouts or as a floating action toolbar.
<FloatingMenuBar position="bottom-center" bordered blur>
<FloatingMenuItem icon={<Home size={18} />} label="Home" active />
<FloatingMenuItem icon={<Search size={18} />} label="Search" />
<FloatingMenuItem icon={<Bell size={18} />} label="Alerts" />
<FloatingMenuItem icon={<User size={18} />} label="Profile" />
</FloatingMenuBar>| Prop | Type | Default | Description |
|---|---|---|---|
| position | FloatingMenuBarPosition | "bottom-center" | Where the bar is anchored on the screen. 9 positions: top-left, top-center, top-right, middle-left, middle-center, middle-right, bottom-left, bottom-center, bottom-right. |
| bordered | boolean | true | Whether to render a border around the menu bar. |
| blur | boolean | true | Whether to apply a backdrop blur effect (backdrop-blur-lg). |
FloatingMenuItem
An individual item inside a FloatingMenuBar. Renders an icon with an optional text label underneath. Active state highlights the item with the primary color.
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | React.ReactNode | - | The icon to display. Required. |
| label | string | - | Optional text label displayed below the icon. |
| active | boolean | false | Whether this item is the currently active route. Shows primary color when active. |
PageLayout
Low-level full-page layout shell combining a header, optional sidebar, main content area, and footer. This is the base primitive used internally — prefer the higher-level page compositions (SidebarPage, DashboardPage, etc.) for most use cases.
| Prop | Type | Default | Description |
|---|---|---|---|
| sidebar | boolean | false | Whether to render a sidebar alongside the main content. |
| sidebarPosition | "left" | "right" | "left" | Which side the sidebar appears on. |
| header | React.ReactNode | - | Content rendered in the sticky header slot. |
| footer | React.ReactNode | - | Content rendered in the footer slot. |
Hooks
Layout-related hooks for building custom sidebar components.
| Prop | Type | Default | Description |
|---|---|---|---|
| useSidebarContext() | { collapsed: boolean; collapsible: boolean; position: "left" | "right"; onCollapse?: (collapsed: boolean) => void } | - | Returns the current sidebar context including collapsed state, collapsible flag, position, and onCollapse callback. Use inside Sidebar children to conditionally render content based on sidebar state. |