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.

Navbar

Dashboard

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

Navbar

Dashboard

Navbar

Dashboard

Navbar

Dashboard

Navbar

Dashboard

Navbar

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.

Navbar

Dashboard

Navbar

Dashboard

Navbar

Dashboard

Navbar

Dashboard

Navbar

Dashboard

Navbar

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.

The Sidebar.Head component is used to render the header of the sidebar. It can have a logo a title and a toggle button.

Navbar

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>

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.

Navbar

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.

Navbar

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.

Navbar

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.

Navbar

Dashboard

<View>
  <Sidebar>
    <Sidebar.Nav>
      <Sidebar.Nav.Section>
        <Sidebar.Nav.Section.Item icon={<RocketLaunch />} label="Dashboard" 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.

Navbar

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.

Navbar

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>

The Sidebar.Footer component is used to render the footer of the sidebar.

Navbar

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

PropTypeDescriptionDefault
colorSidebarColorSets the sidebar colorslate
expandedbooleanSets the initial sidebar statetrue
shadowSidebarShadowSets the shadow sizelg

Sidebar.Nav.Section

PropTypeDescriptionDefault
isChildbooleanAdds a background color when the parent Item gets expandedfalse

Sidebar.Nav.Section.Item

PropTypeDescriptionDefault
asElementTypeDefines the type of the rendered elementa
asPropsRecord<string, any>Defines the as Element propertiesundefined
iconReactNodeSets the item iconundefined
labelstringSets the item labelundefined
activebooleanSets the item statefalse
collapsedbooleanSets the item's initial collapsed statetrue

Events

EventTypeDescription
onToggle(state: SidebarState) => voidFires 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;
};