Sidebar
A sidebar navigation menu.
The Sidebar component provides quick access to the main navigation of a web application. It is a composite component that can have multiple sections. Each section can have a title and a list of links. It is responsive and can be collapsed on smaller screens.
Dashboard
import { Sidebar, useSidebar, Overlay } from '@rewind-ui/core';
function App() {
const [expanded, setExpanded] = useState(true);
const [mobile, setMobile] = useState(false);
const sidebar = useSidebar();
return (
<div className="relative flex flex-row w-full h-full min-h-[35rem]">
<Sidebar
onToggle={(state: SidebarState) => {
setExpanded(state.expanded);
setMobile(state.mobile);
}}
className="absolute"
>
<Sidebar.Head>
<Sidebar.Head.Logo>
<Image src="/images/rewind.svg" width={48} height={48} alt="Rewind-UI" />
</Sidebar.Head.Logo>
<Sidebar.Head.Title>Rewind-UI</Sidebar.Head.Title>
<Sidebar.Head.Toggle />
</Sidebar.Head>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item icon={<RocketLaunch />} label="Dashboard" href="#" active />
</Sidebar.Nav.Section>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Management</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<Briefcase />} label="Clients" href="#" />
<Sidebar.Nav.Section.Item icon={<Users />} label="Users" as="button">
<Sidebar.Nav.Section isChild>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="List all"
href="#"
/>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="Add new"
href="#"
/>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="Archived"
href="#"
/>
</Sidebar.Nav.Section>
</Sidebar.Nav.Section.Item>
<Sidebar.Nav.Section.Item icon={<Shield />} label="Roles" href="#" />
<Sidebar.Nav.Section.Item icon={<Key />} label="Permissions" href="#" />
<Sidebar.Nav.Section.Item icon={<Sliders />} label="Settings" href="#" />
</Sidebar.Nav.Section>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Support</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<LifeRing />} label="Contact" href="#" />
<Sidebar.Nav.Section.Item icon={<EnvelopeOpen />} label="Tickets" href="#" />
<Sidebar.Separator />
<Sidebar.Nav.Section.Item icon={<Book />} label="Documentation" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
<Sidebar.Footer>
<div className="flex flex-col justify-center items-center text-sm">
<span className="font-semibold">Rewind-UI</span>
<span>version x.y.z</span>
</div>
</Sidebar.Footer>
</Sidebar>
<main
className={`transition-all transform duration-100 text-slate-700 flex w-full flex-col items-center ${
expanded ? 'md:ml-64' : 'md:ml-20'
}`}
>
{mobile && (
<Overlay
blur="none"
onClick={() => {
sidebar.toggleMobile();
}}
className="md:hidden z-40"
/>
)}
<header className="flex flex-row sticky top-0 px-8 items-center bg-white border-b border-b-gray-100 w-full shadow-sm min-h-[4rem]">
<span>Navbar</span>
<Button
onClick={() => {
sidebar.toggleMobile();
}}
size="sm"
color="white"
icon
className="ml-auto flex md:hidden"
>
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512">
<path d="M448 96c0-17.7-14.3-32-32-32H32C14.3 64 0 78.3 0 96s14.3 32 32 32H416c17.7 0 32-14.3 32-32zm0 320c0-17.7-14.3-32-32-32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32z" />
<path
className="opacity-50"
d="M0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32z"
/>
</svg>
</Button>
</header>
<div className="w-full h-full p-8">
<p>Dashboard</p>
</div>
<div className="flex sticky bottom-0 items-center bg-white w-full min-h-[4rem] px-8">
<span>Footer</span>
</div>
</main>
</div>
);
}
Admin panel demo
A full-sized sample Admin panel can be seen here.
Import
Import the Sidebar
component and the useSidebar
hook using the following import statement.
import { Sidebar, useSidebar } from '@rewind-ui/core';
Colors
The following colors are available for the Sidebar
component: white
, gray
, dark
, slate
and zinc
.
Dashboard
Dashboard
Dashboard
Dashboard
Dashboard
<View>
<Sidebar color="white">
// ...
</Sidebar>
<Sidebar color="gray">
// ...
</Sidebar>
<Sidebar color="dark">
// ...
</Sidebar>
<Sidebar color="slate">
// ...
</Sidebar>
<Sidebar color="zinc">
// ...
</Sidebar>
</View>
Shadows
Available shadow
values are: none
, sm
, base
, md
, lg
and xl
.
Shadow property adds a subtle shadow to the sidebar.
Dashboard
Dashboard
Dashboard
Dashboard
Dashboard
Dashboard
<View>
<Sidebar shadow="none">
// ...
</Sidebar>
<Sidebar shadow="sm">
// ...
</Sidebar>
<Sidebar shadow="base">
// ...
</Sidebar>
<Sidebar shadow="md">
// ...
</Sidebar>
<Sidebar shadow="lg">
// ...
</Sidebar>
<Sidebar shadow="xl">
// ...
</Sidebar>
</View>
Composition
The Sidebar
component is a composite component that can have multiple sections.
Head
The Sidebar.Head
component is used to render the header of the sidebar. It can have a logo a title and a toggle button.
Dashboard
<View>
<Sidebar>
<Sidebar.Head>
<Sidebar.Head.Logo>
<Image src="/images/rewind.svg" width={48} height={48} alt="Rewind-UI" />
</Sidebar.Head.Logo>
<Sidebar.Head.Title>Rewind-UI</Sidebar.Head.Title>
<Sidebar.Head.Toggle />
</Sidebar.Head>
</Sidebar>
</View>
Nav
The Sidebar.Nav
component is used to render the navigation links of the sidebar. It can have multiple Sidebar.Nav.Section
components and each one can have multiple Sidebar.Nav.Section.Item
components.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item icon={<RocketLaunch />} label="Dashboard" href="#" active />
</Sidebar.Nav.Section>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item icon={<LifeRing />} label="Contact" href="#" />
<Sidebar.Nav.Section.Item icon={<EnvelopeOpen />} label="Tickets" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Title
The Sidebar.Nav.Section.Title
component is used to render the title of a section.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item icon={<RocketLaunch />} label="Dashboard" href="#" active />
</Sidebar.Nav.Section>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Support</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<LifeRing />} label="Contact" href="#" />
<Sidebar.Nav.Section.Item icon={<EnvelopeOpen />} label="Tickets" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Separator
The Sidebar.Separator
component is used to render a separator between sections or items.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Support</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<LifeRing />} label="Contact" href="#" />
<Sidebar.Separator />
<Sidebar.Nav.Section.Item icon={<EnvelopeOpen />} label="Tickets" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Item
The Sidebar.Nav.Section.Item
component is used to render an item of a section.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item
icon={<RocketLaunch />}
label={
<span>
Dashboard
<Badge color="red" size="xs" className="ml-2">Beta</Badge>
</span>
}
href="#"
active
/>
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Render as
The Sidebar.Nav.Section.Item
component accepts an as
prop that defines the type of the rendered element.
The as
prop can be used to render the item as a Next.js Link for example.
The asProps
property can be used to pass props to the rendered element.
Dashboard
import Link from 'next/link';
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Item icon={<RocketLaunch />} label="Dashboard" as={Link} asProps={{ href: '/ '}} active />
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Child Items
The Sidebar.Nav.Section.Item
component support inner section that will be rendered as a collapsible menu.
The parent item can be rendered as a button using the as
prop.
The underlying Sidebar.Nav.Section
component can be rendered as a child section using the isChild
prop. Adding the isChild
prop will add a different background color to the section.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Management</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<Users />} label="Users" as="button">
<Sidebar.Nav.Section isChild>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="List all"
href="#"
/>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="Add new"
href="#"
/>
<Sidebar.Nav.Section.Item
icon={<span className="w-1 h-1 rounded bg-transparent" />}
label="Archived"
href="#"
/>
</Sidebar.Nav.Section>
</Sidebar.Nav.Section.Item>
<Sidebar.Nav.Section.Item icon={<Shield />} label="Roles" href="#" />
<Sidebar.Nav.Section.Item icon={<Key />} label="Permissions" href="#" />
<Sidebar.Nav.Section.Item icon={<Sliders />} label="Settings" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
</Sidebar>
</View>
Footer
The Sidebar.Footer
component is used to render the footer of the sidebar.
Dashboard
<View>
<Sidebar>
<Sidebar.Nav>
<Sidebar.Nav.Section>
<Sidebar.Nav.Section.Title>Support</Sidebar.Nav.Section.Title>
<Sidebar.Nav.Section.Item icon={<LifeRing />} label="Contact" href="#" />
<Sidebar.Separator />
<Sidebar.Nav.Section.Item icon={<EnvelopeOpen />} label="Tickets" href="#" />
</Sidebar.Nav.Section>
</Sidebar.Nav>
<Sidebar.Footer>
<div className="flex flex-col justify-center items-center text-sm">
<span className="font-semibold">Rewind-UI</span>
<span>version x.y.z</span>
</div>
</Sidebar.Footer>
</Sidebar>
</View>
Hook
The useSidebar
hook can be used to toggle the visibility of the Sidebar on smaller screens.
import { useSidebar, Sidebar, Button } from '@rewind-ui/core';
export const App = () => {
const sidebar = useSidebar();
return (
<div className="relative flex flex-row w-full h-full">
<Sidebar>
// ...
</Sidebar>
<Button onClick={() => sidebar.toggleMobile()} className="ml-auto flex md:hidden">
Toggle
</Button>
</div>
);
};
API Reference
Properties
Sidebar
Prop | Type | Description | Default |
---|---|---|---|
color | SidebarColor | Sets the sidebar color | slate |
expanded | boolean | Sets the initial sidebar state | true |
shadow | SidebarShadow | Sets the shadow size | lg |
Prop | Type | Description | Default |
---|---|---|---|
isChild | boolean | Adds a background color when the parent Item gets expanded | false |
Prop | Type | Description | Default |
---|---|---|---|
as | ElementType | Defines the type of the rendered element | a |
asProps | Record<string, any> | Defines the as Element properties | undefined |
icon | ReactNode | Sets the item icon | undefined |
label | ReactNode | Sets the item label | undefined |
active | boolean | Sets the item state | false |
collapsed | boolean | Sets the item's initial collapsed state | true |
Events
Sidebar
Event | Type | Description |
---|---|---|
onToggle | (state: SidebarState) => void | Fires when the sidebar state is changed |
Types
type SidebarColor = 'white' | 'gray' | 'dark' | 'slate' | 'zinc';
type SidebarShadow = 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl';
type SidebarState = {
expanded: boolean;
hovered: boolean;
mobile: boolean;
};