Tac UIv1.1.2

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

tsx
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.

tsx
<SingleColumnPage
  maxWidth="lg"
  header={<Header sticky bordered>Navigation</Header>}
  footer={<Footer>Footer</Footer>}
>
  <p>Page content goes here</p>
</SingleColumnPage>
PropTypeDefaultDescription
maxWidth"sm" | "md" | "lg" | "xl" | "full""lg"Maximum width of the content column. sm=640px, md=768px, lg=1024px, xl=1280px.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<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>
PropTypeDefaultDescription
sidebarReact.ReactNode-Content rendered inside the sidebar panel. Required.
sidebarWidthnumber280Width of the sidebar in pixels when expanded.
sidebarPosition"left" | "right""left"Which side the sidebar is placed on.
collapsiblebooleanfalseWhether the sidebar can be collapsed via a toggle button.
defaultCollapsedbooleanfalseInitial collapsed state when uncontrolled.
sidebarLabelReact.ReactNode-Label displayed in the sidebar header area.
sidebarIconReact.ReactNode-Icon displayed before the label in the sidebar header.
sidebarFillHeightbooleantrueWhether the sidebar fills the remaining vertical space.
sidebarRoundedbooleanfalseWhether the sidebar has rounded corners with a floating card style.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<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>
PropTypeDefaultDescription
sidebarReact.ReactNode-Content rendered inside the left sidebar panel. Required.
sidebarWidthnumber260Width of the sidebar in pixels when expanded.
collapsiblebooleanfalseWhether the sidebar can be collapsed via a toggle button.
defaultCollapsedbooleanfalseInitial collapsed state when uncontrolled.
sidebarLabelReact.ReactNode-Label displayed in the sidebar header area.
sidebarIconReact.ReactNode-Icon displayed before the label in the sidebar header.
sidebarFillHeightbooleantrueWhether the sidebar fills the remaining vertical space.
sidebarRoundedbooleanfalseWhether the sidebar has rounded corners with a floating card style.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<SplitPage
  left={<div>Left panel content</div>}
  right={<div>Right panel content</div>}
  header={<Header sticky bordered>App</Header>}
/>
PropTypeDefaultDescription
leftReact.ReactNode-Content rendered in the left panel. Required.
rightReact.ReactNode-Content rendered in the right panel. Required.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<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>
PropTypeDefaultDescription
columns2 | 3 | 43Number of grid columns at the widest breakpoint. Responsive: 2-col uses md breakpoint, 3-col uses md+lg, 4-col uses sm+lg.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<StackedPage header={<Header sticky bordered>Navigation</Header>}>
  <section>Hero Section</section>
  <section>Features</section>
  <section>Testimonials</section>
</StackedPage>
PropTypeDefaultDescription
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<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>
PropTypeDefaultDescription
leftSidebarReact.ReactNode-Content rendered in the left sidebar panel. Required.
rightSidebarReact.ReactNode-Content rendered in the right sidebar panel. Required.
leftWidthnumber240Width of the left sidebar in pixels.
rightWidthnumber240Width of the right sidebar in pixels.
leftCollapsiblebooleanfalseWhether the left sidebar can be collapsed.
rightCollapsiblebooleanfalseWhether the right sidebar can be collapsed.
defaultLeftCollapsedbooleanfalseInitial collapsed state for the left sidebar.
defaultRightCollapsedbooleanfalseInitial collapsed state for the right sidebar.
leftLabelReact.ReactNode-Label displayed in the left sidebar header.
leftIconReact.ReactNode-Icon displayed before the left sidebar label.
rightLabelReact.ReactNode-Label displayed in the right sidebar header.
rightIconReact.ReactNode-Icon displayed before the right sidebar label.
leftFillHeightbooleantrueWhether the left sidebar fills the remaining vertical space.
rightFillHeightbooleantrueWhether the right sidebar fills the remaining vertical space.
leftRoundedbooleanfalseWhether the left sidebar has a rounded floating card style.
rightRoundedbooleanfalseWhether the right sidebar has a rounded floating card style.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<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>
PropTypeDefaultDescription
leftSidebarReact.ReactNode-Content rendered in the left navigation sidebar. Required.
rightSidebarReact.ReactNode-Content rendered in the right aside sidebar. Required.
leftWidthnumber220Width of the left sidebar in pixels.
rightWidthnumber220Width of the right sidebar in pixels.
leftCollapsiblebooleanfalseWhether the left sidebar can be collapsed.
rightCollapsiblebooleanfalseWhether the right sidebar can be collapsed.
defaultLeftCollapsedbooleanfalseInitial collapsed state for the left sidebar.
defaultRightCollapsedbooleanfalseInitial collapsed state for the right sidebar.
leftLabelReact.ReactNode-Label displayed in the left sidebar header.
leftIconReact.ReactNode-Icon displayed before the left sidebar label.
rightLabelReact.ReactNode-Label displayed in the right sidebar header.
rightIconReact.ReactNode-Icon displayed before the right sidebar label.
leftFillHeightbooleantrueWhether the left sidebar fills the remaining vertical space.
rightFillHeightbooleantrueWhether the right sidebar fills the remaining vertical space.
leftRoundedbooleanfalseWhether the left sidebar has a rounded floating card style.
rightRoundedbooleanfalseWhether the right sidebar has a rounded floating card style.
headerReact.ReactNode-Content rendered in the full-width top header slot.
footerReact.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.

tsx
<AsymmetricPage
  primary={<div>Main article</div>}
  secondary={<div>Related content</div>}
  ratio="2:1"
  header={<Header sticky bordered>App</Header>}
/>
PropTypeDefaultDescription
primaryReact.ReactNode-Content rendered in the primary (wider by default) panel. Required.
secondaryReact.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.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

tsx
<AppPage
  maxWidth="sm"
  elevated
  safeArea
  header={<Header sticky bordered>App</Header>}
  footer={<Footer bordered>Footer</Footer>}
>
  <p>Mobile-optimized content</p>
</AppPage>
PropTypeDefaultDescription
maxWidth"xs" | "sm" | "md" | "lg""sm"Maximum content width. xs=360px, sm=390px, md=430px, lg=520px.
elevatedbooleanfalseRender as an elevated card with borders and shadow on wider screens (sm+ breakpoint).
safeAreabooleantrueApply safe-area inset padding (env(safe-area-inset-*)) for native webview environments.
stickyHeaderbooleantrueWhether the header sticks to the top of the viewport.
stickyFooterbooleanfalseWhether the footer sticks to the bottom of the viewport.
headerReact.ReactNode-Content rendered in the top header slot.
footerReact.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.

Header — sticky bordered
Header — sticky bordered blur autoHide
tsx
// Basic header
<Header sticky bordered>Navigation</Header>

// Blur + auto-hide header
<Header sticky bordered blur autoHide>
  <span>Logo</span>
  <nav>Links</nav>
</Header>
PropTypeDefaultDescription
stickybooleanfalseWhether the header sticks to the top of the viewport on scroll (sticky top-0 with z-index).
borderedbooleantrueWhether to render a bottom border separating the header from content.
blurbooleanfalseApply backdrop blur with semi-transparent background (bg-[var(--card)]/80 backdrop-blur-lg). Great for overlapping scroll content.
autoHidebooleanfalseAuto-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
tsx
<Footer bordered>
  <p>© 2025 Company</p>
</Footer>
PropTypeDefaultDescription
borderedbooleantrueWhether 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.

Navigation
Home
Settings
tsx
<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>
PropTypeDefaultDescription
widthnumber280Width 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.
labelReact.ReactNode-Label displayed in the sidebar header. Hidden when collapsed.
iconReact.ReactNode-Icon displayed before the label in the sidebar header. Shown alone when collapsed.
collapsiblebooleanfalseWhether a toggle button is rendered to collapse/expand the sidebar.
collapsedbooleanfalseControlled collapsed state of the sidebar.
onCollapse(collapsed: boolean) => void-Callback fired when the collapse toggle is clicked.
fillHeightbooleantrueWhether the sidebar fills the remaining vertical space (h-full).
roundedbooleanfalseWhether the sidebar has rounded corners with a floating card style (border + margin + rounded corners).
swapOnCollapsebooleanfalseWhen true, the icon is hidden when expanded and the label is hidden when collapsed, swapping between them.
footerReact.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.

PropTypeDefaultDescription
labelReact.ReactNode-Label displayed in the sidebar header. Hidden when collapsed.
iconReact.ReactNode-Icon displayed before the label. Shown alone when collapsed.
swapOnCollapsebooleanfalseWhen true, the icon is hidden when expanded and the label is hidden when collapsed, swapping between them.
childrenReact.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.

PropTypeDefaultDescription
labelstring-Group label displayed above items. Hidden when sidebar is collapsed.
iconReact.ReactNode-Icon displayed before the label. Shown alone when sidebar is collapsed and collapseDisplay="group".
activebooleanfalseWhether 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).
collapsiblebooleanfalseWhether the group can be expanded/collapsed by clicking the header (chevron toggle).
defaultOpenbooleantrueWhether 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).

PropTypeDefaultDescription
iconReact.ReactNode-Icon rendered before the label. Shown alone when sidebar is collapsed. Items without icons are hidden when collapsed.
activebooleanfalseWhether 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.

PropTypeDefaultDescription
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.

PropTypeDefaultDescription
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.

Home
Search
Alerts
Profile
tsx
<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>
PropTypeDefaultDescription
positionFloatingMenuBarPosition"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.
borderedbooleantrueWhether to render a border around the menu bar.
blurbooleantrueWhether 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.

PropTypeDefaultDescription
iconReact.ReactNode-The icon to display. Required.
labelstring-Optional text label displayed below the icon.
activebooleanfalseWhether 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.

PropTypeDefaultDescription
sidebarbooleanfalseWhether to render a sidebar alongside the main content.
sidebarPosition"left" | "right""left"Which side the sidebar appears on.
headerReact.ReactNode-Content rendered in the sticky header slot.
footerReact.ReactNode-Content rendered in the footer slot.

Hooks

Layout-related hooks for building custom sidebar components.

PropTypeDefaultDescription
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.