AppShell
The application frame — hand it your nav and you're done.
The frame around the whole app. Hand groups an array of nav entries and you get a collapsible
sidebar — or a header, for narrow screens. Use it instead of assembling
Sidebar yourself.
export const client = "only";
import { AppShell } from "@squadbase/vantage/components";
import { Button } from "@squadbase/vantage/ui";
import { LayoutDashboard, Table2, Settings } from "lucide-react";
const groups = [
{
label: "分析",
items: [
{ label: "概要", href: "/", icon: LayoutDashboard, isActive: true },
{ label: "売上", href: "/sales", icon: Table2, badge: "12" },
],
},
{
label: "管理",
items: [{ label: "設定", href: "/settings", icon: Settings }],
},
];
export default function Example() {
// AppShell の中のサイドバーは position: fixed です。ビューポート全体を占めるのが
// 本来の使い方なので、プレビューでも枠で囲まずそのまま置いています。
return (
<AppShell
groups={groups}
actions={<Button size="sm" variant="outline">エクスポート</Button>}
onNavigate={() => {}}
>
<div className="w-[34rem] p-6 text-sm text-muted-foreground">ここにページの中身が入ります。</div>
</AppShell>
);
}
import { AppShell } from "@squadbase/vantage/components";
import type { NavGroup, NavItem } from "@squadbase/vantage/components";
groups?NavGroup[]
The navigation: an array of `{ label?, items: NavItem[] }`.
NavGroup[]variant?"sidebar" | "header"
A sidebar frame, or a header with a select.
"sidebar" | "header""sidebar"actions?ReactNode
Rendered at the top right.
ReactNodeheader?ReactNode
Replaces the default header wholesale.
ReactNodedefaultOpen?boolean
With `variant="sidebar"`, whether it starts open.
booleantruelinkComponent?ElementType
The link component used to render items.
ElementTypeonNavigate?(href: string) => void
Fired when an item is chosen; defaults to `location.assign`.
(href: string) => voidNavItem
interface NavItem {
label: string;
href: string;
icon?: ComponentType<{ className?: string }>;
isActive?: boolean;
disabled?: boolean;
badge?: string;
children?: NavItem[]; // collapsible sub-items
}
An item with children becomes a disclosure.
Wiring it to the router
Pass onNavigate for client-side navigation.
import { useNavigate } from "@squadbase/vantage/router";
const navigate = useNavigate();
<AppShell groups={groups} onNavigate={(href) => navigate({ to: href })}>
{children}
</AppShell>;
Highlighting is explicit: set isActive by comparing the current route’s path with each href.