SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
2.1 KB · 47 lines tsx
Raw Blame History
1"use client";2import * as React from "react";3import Link from "next/link";4import { ChevronLeft, Menu } from "lucide-react";5import { useApp } from "@/components/app/store";6import { Button } from "@/components/ui/button";7import { cn } from "@/lib/utils";89/**10 * Compact 48 px page bar shared by Projects / Library / Prompts.11 * Phone: hamburger (opens the drawer) or a back link; title truncates; actions on the right (icon buttons).12 * Desktop: same bar, so pages keep a stable top edge across the workspace.13 */14export function WorkspacePageHeader({ title, subtitle, back, actions, leading, className }: { title: React.ReactNode; subtitle?: React.ReactNode; back?: string; actions?: React.ReactNode; leading?: React.ReactNode; className?: string }) {15  const { setSidebarOpen } = useApp();16  return (17    <header className={cn("flex h-12 shrink-0 items-center gap-1.5 border-b border-border px-2 sm:px-4", className)}>18      {back ? (19        <Button asChild variant="ghost" size="icon-sm" className="tap -ml-0.5">20          <Link href={back} aria-label="Back">21            <ChevronLeft />22          </Link>23        </Button>24      ) : (25        <Button variant="ghost" size="icon-sm" className="tap md:hidden" onClick={() => setSidebarOpen(true)} aria-label="Open sidebar">26          <Menu />27        </Button>28      )}29      {leading}30      <div className="min-w-0 flex-1">31        <h1 className="truncate text-[15px] font-semibold leading-5 tracking-tight">{title}</h1>32        {subtitle ? <p className="truncate text-[11.5px] leading-4 text-fg-subtle">{subtitle}</p> : null}33      </div>34      {actions ? <div className="flex shrink-0 items-center gap-1">{actions}</div> : null}35    </header>36  );37}3839/** Scrollable page body under the header (the document never scrolls). */40export function WorkspacePageBody({ children, className, width = "max-w-5xl" }: { children: React.ReactNode; className?: string; width?: string }) {41  return (42    <main className="min-h-0 flex-1 overflow-y-auto scrollbar-thin contain-scroll">43      <div className={cn("mx-auto w-full px-4 py-4 sm:px-6 sm:py-6 lg:px-8", width, className)}>{children}</div>44    </main>45  );46}47