첫 커밋: 로컬 프로젝트 업로드
This commit is contained in:
105
baron-sso/common/shell/AppSidebar.tsx
Normal file
105
baron-sso/common/shell/AppSidebar.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import { Menu, SquareMenu } from "lucide-react";
|
||||
import type { ComponentType, ReactNode } from "react";
|
||||
import { shellLayoutClasses } from "./layout";
|
||||
|
||||
export type ShellSidebarNavItem = {
|
||||
labelKey: string;
|
||||
labelFallback: string;
|
||||
to: string;
|
||||
icon: ComponentType<{ size?: number | string }>;
|
||||
isExternal?: boolean;
|
||||
end?: boolean;
|
||||
isActive?: boolean;
|
||||
};
|
||||
|
||||
type ShellSidebarProps = {
|
||||
brandLabel: string;
|
||||
brandTitle: string;
|
||||
brandIcon?: ReactNode;
|
||||
navContent: ReactNode;
|
||||
footerContent: ReactNode;
|
||||
collapsed?: boolean;
|
||||
onToggleCollapsed?: () => void;
|
||||
collapseLabel?: string;
|
||||
expandLabel?: string;
|
||||
};
|
||||
|
||||
export function AppSidebar({
|
||||
brandLabel,
|
||||
brandTitle,
|
||||
brandIcon,
|
||||
navContent,
|
||||
footerContent,
|
||||
collapsed = false,
|
||||
onToggleCollapsed,
|
||||
collapseLabel = "Collapse sidebar",
|
||||
expandLabel = "Expand sidebar",
|
||||
}: ShellSidebarProps) {
|
||||
return (
|
||||
<aside
|
||||
className={
|
||||
collapsed ? shellLayoutClasses.asideCollapsed : shellLayoutClasses.aside
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className={
|
||||
collapsed
|
||||
? shellLayoutClasses.brandSectionCollapsed
|
||||
: shellLayoutClasses.brandSection
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
collapsed
|
||||
? shellLayoutClasses.brandWrapCollapsed
|
||||
: shellLayoutClasses.brandWrap
|
||||
}
|
||||
>
|
||||
{onToggleCollapsed ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggleCollapsed}
|
||||
className="grid h-11 w-11 place-items-center rounded-xl border border-border bg-primary/15 text-primary shadow-[0_12px_30px_rgba(54,211,153,0.22)] transition hover:bg-primary/20"
|
||||
aria-label={collapsed ? expandLabel : collapseLabel}
|
||||
title={collapsed ? expandLabel : collapseLabel}
|
||||
>
|
||||
<span className="sr-only">
|
||||
{collapsed ? expandLabel : collapseLabel}
|
||||
</span>
|
||||
{collapsed ? <Menu size={20} /> : <SquareMenu size={20} />}
|
||||
</button>
|
||||
) : (
|
||||
<div
|
||||
className={
|
||||
collapsed
|
||||
? shellLayoutClasses.brandIconCollapsed
|
||||
: shellLayoutClasses.brandIcon
|
||||
}
|
||||
>
|
||||
{brandIcon}
|
||||
</div>
|
||||
)}
|
||||
<div className={collapsed ? "hidden" : "block"}>
|
||||
<p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">
|
||||
{brandLabel}
|
||||
</p>
|
||||
<h1 className="text-lg font-semibold">{brandTitle}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav
|
||||
className={
|
||||
collapsed
|
||||
? shellLayoutClasses.navWrapCollapsed
|
||||
: shellLayoutClasses.navWrap
|
||||
}
|
||||
>
|
||||
{navContent}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div>{footerContent}</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user