Stacked layout
You don't have enough features to fill a sidebar anyway, plus they aren't going to be cool forever.
import { Avatar } from '@/components/avatar'
import {
Dropdown,
DropdownButton,
DropdownDivider,
DropdownItem,
DropdownLabel,
DropdownMenu,
} from '@/components/dropdown'
import { Navbar, NavbarDivider, NavbarItem, NavbarLabel, NavbarSection, NavbarSpacer } from '@/components/navbar'
import { Sidebar, SidebarBody, SidebarHeader, SidebarItem, SidebarLabel, SidebarSection } from '@/components/sidebar'
import { StackedLayout } from '@/components/stacked-layout'
import {
ArrowRightStartOnRectangleIcon,
ChevronDownIcon,
Cog8ToothIcon,
LightBulbIcon,
PlusIcon,
ShieldCheckIcon,
UserIcon,
} from '@heroicons/react/16/solid'
import { InboxIcon, MagnifyingGlassIcon } from '@heroicons/react/20/solid'
const navItems = [
{ label: 'Home', url: '/' },
{ label: 'Events', url: '/events' },
{ label: 'Orders', url: '/orders' },
{ label: 'Broadcasts', url: '/broadcasts' },
{ label: 'Settings', url: '/settings' },
]
function TeamDropdownMenu() {
return (
<DropdownMenu className="min-w-80 lg:min-w-64" anchor="bottom start">
<DropdownItem href="/teams/1/settings">
<Cog8ToothIcon />
<DropdownLabel>Settings</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/teams/1">
<Avatar slot="icon" src="/tailwind-logo.svg" />
<DropdownLabel>Tailwind Labs</DropdownLabel>
</DropdownItem>
<DropdownItem href="/teams/2">
<Avatar slot="icon" initials="WC" className="bg-purple-500 text-white" />
<DropdownLabel>Workcation</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/teams/create">
<PlusIcon />
<DropdownLabel>New team…</DropdownLabel>
</DropdownItem>
</DropdownMenu>
)
}
function Example() {
return (
<StackedLayout
navbar={
<Navbar>
<Dropdown>
<DropdownButton as={NavbarItem} className="max-lg:hidden">
<Avatar src="/tailwind-logo.svg" />
<NavbarLabel>Tailwind Labs</NavbarLabel>
<ChevronDownIcon />
</DropdownButton>
<TeamDropdownMenu />
</Dropdown>
<NavbarDivider className="max-lg:hidden" />
<NavbarSection className="max-lg:hidden">
{navItems.map(({ label, url }) => (
<NavbarItem key={label} href={url}>
{label}
</NavbarItem>
))}
</NavbarSection>
<NavbarSpacer />
<NavbarSection>
<NavbarItem href="/search" aria-label="Search">
<MagnifyingGlassIcon />
</NavbarItem>
<NavbarItem href="/inbox" aria-label="Inbox">
<InboxIcon />
</NavbarItem>
<Dropdown>
<DropdownButton as={NavbarItem}>
<Avatar src="/profile-photo.jpg" square />
</DropdownButton>
<DropdownMenu className="min-w-64" anchor="bottom end">
<DropdownItem href="/my-profile">
<UserIcon />
<DropdownLabel>My profile</DropdownLabel>
</DropdownItem>
<DropdownItem href="/settings">
<Cog8ToothIcon />
<DropdownLabel>Settings</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/privacy-policy">
<ShieldCheckIcon />
<DropdownLabel>Privacy policy</DropdownLabel>
</DropdownItem>
<DropdownItem href="/share-feedback">
<LightBulbIcon />
<DropdownLabel>Share feedback</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/logout">
<ArrowRightStartOnRectangleIcon />
<DropdownLabel>Sign out</DropdownLabel>
</DropdownItem>
</DropdownMenu>
</Dropdown>
</NavbarSection>
</Navbar>
}
sidebar={
<Sidebar>
<SidebarHeader>
<Dropdown>
<DropdownButton as={SidebarItem} className="lg:mb-2.5">
<Avatar src="/tailwind-logo.svg" />
<SidebarLabel>Tailwind Labs</SidebarLabel>
<ChevronDownIcon />
</DropdownButton>
<TeamDropdownMenu />
</Dropdown>
</SidebarHeader>
<SidebarBody>
<SidebarSection>
{navItems.map(({ label, url }) => (
<SidebarItem key={label} href={url}>
{label}
</SidebarItem>
))}
</SidebarSection>
</SidebarBody>
</Sidebar>
}
>
{children}
</StackedLayout>
)
}
import { Avatar } from '@/components/avatar'
import {
Dropdown,
DropdownButton,
DropdownDivider,
DropdownItem,
DropdownLabel,
DropdownMenu,
} from '@/components/dropdown'
import { Navbar, NavbarDivider, NavbarItem, NavbarLabel, NavbarSection, NavbarSpacer } from '@/components/navbar'
import { Sidebar, SidebarBody, SidebarHeader, SidebarItem, SidebarLabel, SidebarSection } from '@/components/sidebar'
import { StackedLayout } from '@/components/stacked-layout'
import {
ArrowRightStartOnRectangleIcon,
ChevronDownIcon,
Cog8ToothIcon,
LightBulbIcon,
PlusIcon,
ShieldCheckIcon,
UserIcon,
} from '@heroicons/react/16/solid'
import { InboxIcon, MagnifyingGlassIcon } from '@heroicons/react/20/solid'
const navItems = [
{ label: 'Home', url: '/' },
{ label: 'Events', url: '/events' },
{ label: 'Orders', url: '/orders' },
{ label: 'Broadcasts', url: '/broadcasts' },
{ label: 'Settings', url: '/settings' },
]
function TeamDropdownMenu() {
return (
<DropdownMenu className="min-w-80 lg:min-w-64" anchor="bottom start">
<DropdownItem href="/teams/1/settings">
<Cog8ToothIcon />
<DropdownLabel>Settings</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/teams/1">
<Avatar slot="icon" src="/tailwind-logo.svg" />
<DropdownLabel>Tailwind Labs</DropdownLabel>
</DropdownItem>
<DropdownItem href="/teams/2">
<Avatar slot="icon" initials="WC" className="bg-purple-500 text-white" />
<DropdownLabel>Workcation</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/teams/create">
<PlusIcon />
<DropdownLabel>New team…</DropdownLabel>
</DropdownItem>
</DropdownMenu>
)
}
function Example() {
return (
<StackedLayout
navbar={
<Navbar>
<Dropdown>
<DropdownButton as={NavbarItem} className="max-lg:hidden">
<Avatar src="/tailwind-logo.svg" />
<NavbarLabel>Tailwind Labs</NavbarLabel>
<ChevronDownIcon />
</DropdownButton>
<TeamDropdownMenu />
</Dropdown>
<NavbarDivider className="max-lg:hidden" />
<NavbarSection className="max-lg:hidden">
{navItems.map(({ label, url }) => (
<NavbarItem key={label} href={url}>
{label}
</NavbarItem>
))}
</NavbarSection>
<NavbarSpacer />
<NavbarSection>
<NavbarItem href="/search" aria-label="Search">
<MagnifyingGlassIcon />
</NavbarItem>
<NavbarItem href="/inbox" aria-label="Inbox">
<InboxIcon />
</NavbarItem>
<Dropdown>
<DropdownButton as={NavbarItem}>
<Avatar src="/profile-photo.jpg" square />
</DropdownButton>
<DropdownMenu className="min-w-64" anchor="bottom end">
<DropdownItem href="/my-profile">
<UserIcon />
<DropdownLabel>My profile</DropdownLabel>
</DropdownItem>
<DropdownItem href="/settings">
<Cog8ToothIcon />
<DropdownLabel>Settings</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/privacy-policy">
<ShieldCheckIcon />
<DropdownLabel>Privacy policy</DropdownLabel>
</DropdownItem>
<DropdownItem href="/share-feedback">
<LightBulbIcon />
<DropdownLabel>Share feedback</DropdownLabel>
</DropdownItem>
<DropdownDivider />
<DropdownItem href="/logout">
<ArrowRightStartOnRectangleIcon />
<DropdownLabel>Sign out</DropdownLabel>
</DropdownItem>
</DropdownMenu>
</Dropdown>
</NavbarSection>
</Navbar>
}
sidebar={
<Sidebar>
<SidebarHeader>
<Dropdown>
<DropdownButton as={SidebarItem} className="lg:mb-2.5">
<Avatar src="/tailwind-logo.svg" />
<SidebarLabel>Tailwind Labs</SidebarLabel>
<ChevronDownIcon />
</DropdownButton>
<TeamDropdownMenu />
</Dropdown>
</SidebarHeader>
<SidebarBody>
<SidebarSection>
{navItems.map(({ label, url }) => (
<SidebarItem key={label} href={url}>
{label}
</SidebarItem>
))}
</SidebarSection>
</SidebarBody>
</Sidebar>
}
>
{children}
</StackedLayout>
)
}
Component API
Prop | Default | Description |
---|---|---|
StackedLayout extends the JSX <div> element | ||
navbar | - | The Navbar menu for desktop screen sizes. |
sidebar | - | The Sidebar menu for mobile screen sizes. |
children | - | The page content. |
Examples
Basic example
Wrap your page content with the StackedLayout
component to create a stacked layout, using the navbar
prop for your
top navigation menu, and the sidebar
prop for your mobile menu content:
import { Navbar } from '@/components/navbar'
import { Sidebar } from '@/components/sidebar'
import { StackedLayout } from '@/components/stacked-layout'
function Example({ children }) {
return (
<StackedLayout
navbar={<Navbar>{/* Your navbar content */}</Navbar>}
sidebar={<Sidebar>{/* Your sidebar content */}</Sidebar>}
>
{/* Your page content */}
</StackedLayout>
)
}
import { Navbar } from '@/components/navbar'
import { Sidebar } from '@/components/sidebar'
import { StackedLayout } from '@/components/stacked-layout'
function Example({ children }) {
return (
<StackedLayout
navbar={<Navbar>{/* Your navbar content */}</Navbar>}
sidebar={<Sidebar>{/* Your sidebar content */}</Sidebar>}
>
{/* Your page content */}
</StackedLayout>
)
}
See the Navbar
and Sidebar
docs for more details.
Setting the overscroll background
Adding the following classes to the html
element in your project to make sure the site background matches the layout
background when overscrolling the body:
<html class="bg-white lg:bg-zinc-100 dark:bg-zinc-900 dark:lg:bg-zinc-950">
<head>
<!-- ... -->
</head>
<body>
<!-- ... -->
</body>
</html>
<html class="bg-white lg:bg-zinc-100 dark:bg-zinc-900 dark:lg:bg-zinc-950">
<head>
<!-- ... -->
</head>
<body>
<!-- ... -->
</body>
</html>