import { useState } from "react"; import { AppShell, Flex, PageContainer, Sidebar, Topbar, TopbarItem } from "@godxjp/ui/layout"; import type { SidebarSectionProp } from "@godxjp/ui/layout"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display"; import { Button, Text } from "@godxjp/ui/general"; import { Building2, Hash, LayoutDashboard, MessagesSquare, PanelLeftClose, PanelLeftOpen, Settings, Users, } from "lucide-react"; /** * AppShell · column arrangements. * * THE SHELL HAS TWO INDEPENDENT GEOMETRY AXES, and this page exists so they can be seen next to * each other rather than rediscovered: * * - `topbarSpan` — how far the BAR reaches. "content" starts it beside the sidebar (the rail * runs the full window height); "full" runs it edge to edge with the navigation beneath it. * - `navRail` — how many navigation COLUMNS there are. Passing the slot adds a second, * narrower track before the sidebar: the workspace/organization switcher shape. * * They are axes, not a preset list. All four combinations are real product shapes, so there is no * invalid pairing and nothing to reconcile — which is why the rail is a SLOT and not a fourth * value bolted onto `topbarSpan`. * * Composed only from real @godxjp/ui components. */ const WORKSPACE_RAIL: SidebarSectionProp[] = [ { items: [ { id: "home", label: "ホーム", icon: LayoutDashboard }, { id: "chat", label: "チャット", icon: MessagesSquare }, { id: "people", label: "メンバー", icon: Users }, { id: "admin", label: "管理", icon: Settings }, ], }, ]; const CHANNELS: SidebarSectionProp[] = [ { label: "チャンネル", items: [ { id: "general", label: "general", icon: Hash }, { id: "design", label: "design", icon: Hash }, { id: "incident", label: "incident-2026", icon: Hash }, ], }, { label: "ダイレクトメッセージ", items: [ { id: "dm-sato", label: "佐藤 花子", icon: Users }, { id: "dm-tanaka", label: "田中 一郎", icon: Users }, ], }, ]; export default function Demo() { const [withRail, setWithRail] = useState(true); const [fullSpan, setFullSpan] = useState(false); const [collapsed, setCollapsed] = useState(false); // The rail is ordinary navigation, so it is an ordinary in icon-only mode — the shell // owns the TRACK, never the content that goes in it. const rail = ( ); return ( ); }