Skip to content

Sidebar

Live Preview

RetailOS
SUDIRMAN · JKT-003
Penjualan
Dashboard
Transaksi
Retur
Operasional
Stok
Opname
3
Pengaturan
AK
Ahmad Kasir
Kasir Senior

The sidebar is the primary navigation element for all web portals. It follows a consistent structure across apps while allowing per-app navigation groups.

Anatomy

+--- Sidebar (240px) ---+
|                        |
|  [Logo] RetailOS       |  <- Brand
|  SUDIRMAN · JKT-003   |  <- Store label (monospace)
|                        |
|  ─────────────────     |  <- Divider
|                        |
|  PENJUALAN             |  <- Group label (uppercase)
|  ● Dashboard           |  <- Active item (green border)
|    Transaksi           |  <- Inactive item
|    Retur               |
|                        |
|  OPERASIONAL           |
|    Stok                |
|    Penerimaan          |
|    Opname         (3)  |  <- Badge counter
|                        |
|  ANALITIK              |
|    Laporan             |
|                        |
|  ─────────────────     |
|                        |
|  ⚙ Pengaturan         |  <- Settings (bottom)
|  🌙 Dark Mode         |  <- Theme toggle
|  « Collapse            |  <- Collapse button
|                        |
|  ┌─────────────────┐   |
|  │ (●) Ahmad Kasir │   |  <- User profile
|  │     Kasir Sr.   │   |
|  └─────────────────┘   |
+------------------------+

Brand Section

tsx
<div className="flex items-center gap-3 px-5 py-4">
  <Logo className="w-8 h-8 text-brand" />
  <span className="font-jakarta font-bold text-[15px] text-brand">
    RetailOS
  </span>
</div>

Store Label

Displayed in monospace, uppercase. Shows the store name and code for context.

tsx
<div className="px-5 pb-3">
  <span className="font-mono text-[11px] font-medium tracking-[0.08em] uppercase text-text-3">
    SUDIRMAN · JKT-003
  </span>
</div>

Each group has an uppercase label and a list of nav items.

Group Label

css
.nav-group-label {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 16px 20px 8px;
}
StateLeft BorderText ColorFont WeightBackground
Defaultnonetext-2400transparent
Hovernonetext-1400transparent (or very subtle bg-hover)
Active3px solid brandtext-1600bg-inset
css
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 400;
  color: var(--text-2);
  border-left: 3px solid transparent;
  transition: color 100ms ease-out;
  cursor: pointer;
}

.nav-item:hover {
  color: var(--text-1);
}

.nav-item.active {
  color: var(--text-1);
  font-weight: 600;
  border-left-color: var(--color-brand);
  background-color: var(--bg-inset);
}

.nav-item .icon {
  width: 16px;
  height: 16px;
  stroke-width: 1.5;
  opacity: 0.5;
}

.nav-item.active .icon {
  opacity: 0.8;
}

Active state

The active nav item uses a 3px left border in brand green + bold text + inset background. It does NOT use a full green fill background. The green should be restrained.

Badge Counter

Small rounded pill for notification counts.

tsx
<span className="ml-auto bg-danger text-white text-[10px] font-semibold rounded-full px-[6px] py-[1px] min-w-[18px] text-center">
  3
</span>

Bottom Section

Settings, dark mode toggle, and collapse button are pinned to the bottom of the sidebar.

tsx
<div className="mt-auto border-t border-border pt-2 pb-4">
  <NavItem icon={<Settings size={16} />} label="Pengaturan" />

  <button className="nav-item w-full" onClick={toggleDarkMode}>
    <Moon size={16} strokeWidth={1.5} />
    <span>Dark Mode</span>
    <Toggle checked={isDark} className="ml-auto" />
  </button>

  <button className="nav-item w-full" onClick={toggleCollapse}>
    <ChevronsLeft size={16} strokeWidth={1.5} />
    <span>Collapse</span>
  </button>
</div>

User Profile

Pinned to the very bottom. Shows avatar, name, and role.

tsx
<div className="px-4 pb-4 pt-2 border-t border-border">
  <div className="flex items-center gap-3">
    <div className="w-8 h-8 rounded-full bg-brand/10 text-brand flex items-center justify-center text-xs font-semibold">
      AK
    </div>
    <div>
      <div className="text-[13px] font-medium text-text-1">Ahmad Kasir</div>
      <div className="text-[11px] text-text-3">Kasir Senior</div>
    </div>
  </div>
</div>

Collapsed State

When collapsed, the sidebar shrinks to 64px and shows only icons. Hovering an icon shows a tooltip with the label.

PropertyExpandedCollapsed
Width240px64px
LabelsVisibleHidden (tooltip on hover)
Group labelsVisibleHidden
Store labelVisibleHidden
User nameVisibleAvatar only

DO and DON'T

DO

  • Keep navigation groups organized by workflow area
  • Use the 3px left border pattern for active state
  • Show the store label so users always know which store context they are in
  • Pin settings and user profile to the bottom

DON'T

  • Don't use a full green background fill for active items
  • Don't add more than 6 navigation groups --- consolidate or use sub-pages
  • Don't nest navigation items more than one level deep in the sidebar
  • Don't hide the sidebar on desktop --- it should always be visible (collapsible, not removable)

RetailOS - Sistem ERP Retail Modern untuk Indonesia