Sidebar structure

This commit is contained in:
2025-11-11 19:15:47 +01:00
parent 01aaca1ca2
commit 2ea4f34e7a
6 changed files with 136 additions and 5 deletions
@@ -1,13 +1,21 @@
import { cn } from "@/lib/utils";
import { Button } from "./ui/button";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarMenu,
SidebarProvider,
useSidebar,
} from "./ui/sidebar";
} from "@/components/ui/sidebar";
import EntitySwitch, { Entity } from "./Entity";
const workspaceEntities: Entity[] = [
{
name: "Project alpha",
kind: "group",
children: [{ name: "Tasks", kind: "todo" }],
},
];
export default function AppSidebar({
children,
@@ -18,7 +26,13 @@ export default function AppSidebar({
<SidebarProvider>
<Sidebar>
<SidebarHeader />
<SidebarContent></SidebarContent>
<SidebarContent>
<SidebarMenu>
{workspaceEntities.map((entity, i) => (
<EntitySwitch entity={entity} key={i} />
))}
</SidebarMenu>
</SidebarContent>
<SidebarFooter />
</Sidebar>
<main className="w-svw">{children}</main>
+52
View File
@@ -0,0 +1,52 @@
import { CollapsibleTrigger } from "@radix-ui/react-collapsible";
import {
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "../ui/sidebar";
import { Collapsible, CollapsibleContent } from "../ui/collapsible";
import { ChevronDown } from "lucide-react";
export interface Entity {
name: string;
kind: "group" | "todo";
children?: Entity[];
}
export default function EntitySwitch({ entity }: { entity: Entity }) {
switch (entity.kind) {
case "group":
return (
<Collapsible defaultOpen className="group/collapsible">
<SidebarGroup>
<SidebarGroupLabel asChild>
<SidebarMenuButton asChild>
<CollapsibleTrigger>
{entity.name}
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
</CollapsibleTrigger>
</SidebarMenuButton>
</SidebarGroupLabel>
<CollapsibleContent>
<SidebarGroupContent>
<SidebarMenu>
{entity.children?.map((entity, i) => (
<EntitySwitch entity={entity} key={i} />
))}
</SidebarMenu>
</SidebarGroupContent>
</CollapsibleContent>
</SidebarGroup>
</Collapsible>
);
case "todo":
return (
<SidebarMenuItem>
<SidebarMenuButton>{entity.name}</SidebarMenuButton>
</SidebarMenuItem>
);
}
}
+33
View File
@@ -0,0 +1,33 @@
"use client"
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
function Collapsible({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
}
function CollapsibleTrigger({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
return (
<CollapsiblePrimitive.CollapsibleTrigger
data-slot="collapsible-trigger"
{...props}
/>
)
}
function CollapsibleContent({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
return (
<CollapsiblePrimitive.CollapsibleContent
data-slot="collapsible-content"
{...props}
/>
)
}
export { Collapsible, CollapsibleTrigger, CollapsibleContent }