Skip to content

Sidebar Card

Floating white sidebar card with generous radius on a tinted page: two-dot logo, nav with lavender active pill, butter “tip of the day” card and user row; horizontal nav on mobile.

soft-flat/layout/sidebar-card
Open ↗

Source

"use client";

import type { ReactNode } from "react";
import { BarChart3, CalendarDays, CheckCircle2, Home, Sparkles, type LucideIcon } from "lucide-react";
import { cn } from "@/lib/utils";

export interface SidebarCardProps {
  items?: { label: string; href: string; icon: LucideIcon }[];
  activeHref?: string;
  tip?: { title: string; text: string; cta: { label: string; href: string } };
  user?: { name: string; plan: string; emoji: string };
  children?: ReactNode;
  className?: string;
}

/** Floating white sidebar card with generous radius: logo, nav with lavender active pill, a butter “tip of the day” card and the user row at the bottom. */
export function SidebarCard({
  items = [
    { label: "Dashboard", href: "#dash", icon: Home },
    { label: "My tasks", href: "#tasks", icon: CheckCircle2 },
    { label: "Calendar", href: "#calendar", icon: CalendarDays },
    { label: "Reports", href: "#reports", icon: BarChart3 },
  ],
  activeHref = "#tasks",
  tip = { title: "Tip of the day", text: "Drag a task onto a day in the week view to schedule it.", cta: { label: "Try it", href: "#week" } },
  user = { name: "Tom Becker", plan: "Bloom plan", emoji: "🐻" },
  children,
  className,
}: SidebarCardProps) {
  return (
    <div className={cn("min-h-dvh bg-da-surface-2 text-da-fg lg:flex", className)}>
      <aside className="p-4 lg:sticky lg:top-0 lg:h-dvh">
        <div className="flex flex-col rounded-[32px] bg-da-surface p-5 shadow-da-md lg:h-full lg:w-64">
          <p className="flex items-center gap-2 font-da-display text-xl font-extrabold">
            <span aria-hidden className="flex -space-x-1.5">
              <span className="size-5 rounded-full bg-da-primary" />
              <span className="size-5 rounded-full bg-da-accent" />
            </span>
            Planta
          </p>
          <nav aria-label="Main" className="mt-6 lg:flex-1">
            <ul className="flex gap-1 overflow-x-auto lg:flex-col">
              {items.map((it) => {
                const active = it.href === activeHref;
                return (
                  <li key={it.href}>
                    <a
                      href={it.href}
                      aria-current={active ? "page" : undefined}
                      className={cn(
                        "da-focus da-transition flex h-11 items-center gap-3 rounded-da-pill px-4 text-[15px] font-medium whitespace-nowrap",
                        active ? "bg-da-primary/12 font-semibold text-da-fg" : "text-da-muted-fg hover:bg-da-surface-2",
                      )}
                    >
                      <it.icon aria-hidden className={cn("size-5", active && "text-da-primary")} />
                      {it.label}
                    </a>
                  </li>
                );
              })}
            </ul>
          </nav>
          <div className="mt-6 hidden rounded-da-lg bg-da-warning/25 p-4 lg:block">
            <p className="flex items-center gap-1.5 font-da-display font-extrabold">
              <Sparkles aria-hidden className="size-4" /> {tip.title}
            </p>
            <p className="mt-1 text-sm text-da-muted-fg">{tip.text}</p>
            <a href={tip.cta.href} className="da-focus mt-3 inline-flex rounded-da-pill bg-da-fg px-4 py-1.5 text-sm font-semibold text-da-bg">
              {tip.cta.label}
            </a>
          </div>
          <div className="mt-4 hidden items-center gap-3 lg:flex">
            <span aria-hidden className="grid size-10 place-items-center rounded-full bg-da-secondary text-xl">
              {user.emoji}
            </span>
            <span className="text-sm leading-tight">
              <span className="block font-semibold">{user.name}</span>
              <span className="text-da-muted-fg">{user.plan}</span>
            </span>
          </div>
        </div>
      </aside>
      <main className="min-w-0 flex-1">{children}</main>
    </div>
  );
}

export default SidebarCard;

modules/soft-flat/layout/sidebar-card/index.tsx

Props

PropTypeDefaultDescription
items{ label, href, icon }[]—Links.
activeHrefstring—Current.
tip{ title, text, cta }—Tip card.
user{ name, plan, emoji }—User row.
childrenReactNode—Content.

Other sidebar variants in Soft Flat

Sidebar in other art directions

App Sidebar

App shell with a sticky left sidebar: workspace header, grouped nav with yellow active state and counters, usage meter, user footer. Becomes a top bar + slide-over drawer below lg.

BrutalistSidebar

Icon Rail

Compact 80px icon rail: ink brand square, square icon links with yellow active state, red counters and ink tooltips on hover/focus, settings pinned at the bottom. Server-safe, CSS-only tooltips.

BrutalistSidebar

Sidebar Collapsible

App sidebar that collapses from 256px to a 76px icon column with a stepped width animation; ink active item, labels become sr-only when collapsed, collapse toggle pinned at the bottom.

BrutalistSidebar

Sidebar Dual

Two-level navigation: an ink icon rail switches sections, and a paper second panel lists that section's links with counts and a yellow active link. Second panel hides on very small screens.

BrutalistSidebar

App Sidebar

Floating frosted sidebar inset from the viewport edges: gradient-orb brand, pill nav items with an ink active state and gradient badges, workspace group, gradient promo card and user chip. Becomes a floating pill top bar + glass drawer below lg.

GlassSidebar

Sidebar Adaptive

Adaptive navigation: a full glass sidebar with brand, gradient action button, labelled links and a usage meter on desktop; a floating bottom tab bar with a raised gradient “+” on mobile.

GlassSidebar

Sidebar Channels

Chat-app style double sidebar: a column of gradient workspace squircles plus a glass channel panel with collapsible sections, private/live icons, unread counts and LIVE meeting badges; drawer on mobile.

GlassSidebar

Sidebar Floating

Floating glass icon rail detached from the viewport edges: gradient logo orb, gradient active item, unread badges, glass tooltips on hover/focus, settings and avatar at the bottom; a floating bottom bar on mobile.

GlassSidebar

App Sidebar

Linear-style app shell: 240px translucent sidebar with workspace switcher, search, "New" button with shortcut, grouped 32px nav rows with counters, team list with color squares and settings at the bottom. Slide-in drawer below lg.

MinimalSidebar

Sidebar Inset

Inset app shell: the sidebar sits on the tinted page background while content lives in a raised rounded panel. Workspace header, collapsible nested sections with guide line, support/settings and user card; drawer on mobile.

MinimalSidebar

Sidebar Rail

Sidebar that collapses between a 224px labelled list and a 56px icon rail (⌘B or bottom button) with tooltips on hover/focus and corner badges; icon-only on mobile. Controlled or uncontrolled.

MinimalSidebar

Sidebar Tree

Docs / settings sidebar with a filter box and a nested collapsible tree auto-expanded to the active page (highlighted in indigo); stacks above content on mobile.

MinimalSidebar

App Sidebar

Typographic app sidebar: hairline right border, logo + site switcher, mono group labels, plain text links with right-aligned mono counts; the active link is ink with a signal dot; drawer on mobile.

Mono CleanSidebar

Sidebar Icons

Narrow icon rail (56px) of square hairline cells; the active cell is filled ink; labels appear as mono tooltips to the right on hover/focus; turns into a bottom bar on mobile.

Mono CleanSidebar

Sidebar Ink

Ink sidebar (stays near-black in dark mode): giant numbered text links “01 Overview”, the active one full white with an arrow, a storage meter as a hairline bar at the bottom; drawer on mobile.

Mono CleanSidebar

Sidebar Tree

CMS page tree: nested pages drawn with hairline guide lines and +/− toggles (aria-expanded), mono “Pages” header with an add button; active page ink with signal dot; drawer on mobile.

Mono CleanSidebar

App Sidebar

Classic enterprise app shell: white bordered sidebar with brand, entity switcher, grouped nav (uppercase group labels, count badges, blue active state), settings and user footer; off-canvas drawer on mobile.

Neo CorporateSidebar

Sidebar Collapsible

Sidebar that collapses from 240px to a 64px icon rail with a toggle button (aria-expanded); collapsed items keep tooltips (title) and sr-only labels. Always a rail on small screens.

Neo CorporateSidebar

Sidebar Dual

Two-level navigation: a narrow icon rail of top-level sections (tooltips, aria-pressed) and a secondary panel listing the selected section’s pages; the panel hides below md.

Neo CorporateSidebar

Sidebar Navy

Dark navy sidebar (fg-colored in light mode, surface in dark mode — dark in both): brand, search field, nav with white-tint active state and badges, and a cash-balance card at the bottom; drawer on mobile.

Neo CorporateSidebar

App Sidebar

Calm app shell: cream sidebar with leaf logo, pill nav items (sage pill for the active page), a small “this year” footprint card with a sprout, and settings at the bottom; drawer on mobile.

Organic SoftSidebar

Sidebar Floating

Floating sidebar: a rounded cream panel inset from the page edges with a soft shadow, italic serif group labels, a sage “New entry” pill and sage-tinted active items; drawer on mobile.

Organic SoftSidebar

Sidebar Garden

Deep sage sidebar (dark sage tint in dark mode) with cream text, a translucent active pill, count bubbles, rolling hills illustrated along the bottom and the user’s name on the hill; drawer on mobile.

Organic SoftSidebar

Sidebar Rail

Slim round icon rail: circular icon links on a sand column, the active one a sage circle with a leaf-shaped marker; labels appear as soft tooltips on hover/focus; becomes a bottom tab bar on mobile.

Organic SoftSidebar