Sidebar
Playground
TSX
'use client';
import { useId, useState } from 'react';
import {
Avatar,
Button,
Icon,
Sidebar,
SidebarHeader,
SidebarContent,
SidebarFooter,
SidebarTrigger,
} from '@mbsw/ui';
import {
Bell,
Building2,
Blocks,
ChevronDown,
ChevronRight,
CircleCheck,
FileText,
KanbanSquare,
LayoutDashboard,
Palette,
Settings2,
} from 'lucide-react';
export default function Demo() {
const settings = {
"title": "워크스페이스"
};
const teamList = useId();
const [selected, setSelected] = useState('overview');
const [expanded, setExpanded] = useState<Record<string, boolean>>({
product: true,
design: true,
});
const items = [
{ id: 'overview', label: "개요", icon: LayoutDashboard },
{ id: 'tasks', label: "작업", icon: CircleCheck },
{ id: 'notifications', label: "알림", icon: Bell },
];
const teams = [
{
id: 'product',
label: "프로덕트 팀",
items: [
{ id: 'projects', label: "프로젝트", icon: KanbanSquare },
{ id: 'documents', label: "문서", icon: FileText },
],
},
{
id: 'design',
label: "디자인 팀",
items: [
{
id: 'design-system',
label: "디자인시스템",
icon: Blocks,
},
{ id: 'resources', label: "리소스", icon: Palette },
],
},
];
const renderItem = (item: (typeof items)[number], nested = false) => (
<Button
key={item.id}
size="sm"
variant={selected === item.id ? 'solid' : 'ghost'}
tone="secondary"
leadingIcon={item.icon}
style={{
width: '100%',
justifyContent: 'flex-start',
...(nested ? { paddingInlineStart: 21 } : {}),
}}
aria-pressed={selected === item.id}
onClick={() => setSelected(item.id)}
>
{item.label}
</Button>
);
return (
<>
<Sidebar
className="example-sidebar-playground"
aria-label={"프로젝트 탐색"}
style={{
height: 340,
background: 'var(--riido-surface-0)',
borderRadius: 'var(--riido-primitive-radius-radius-xs)',
}}
labels={{
collapse: "사이드바 접기",
expand: "사이드바 펼치기",
}}
>
<SidebarHeader
style={{
minHeight: 'var(--riido-primitive-spacing-spacing-7)',
paddingInlineStart: 10,
paddingInlineEnd: 4,
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: 8,
minWidth: 0,
}}
>
<Icon
icon={Building2}
size="sm"
decorative
style={{ flexShrink: 0 }}
/>
<span
style={{
minWidth: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: 13,
fontWeight: 600,
}}
title={settings.title}
>
{settings.title}
</span>
</div>
<SidebarTrigger />
</SidebarHeader>
<SidebarContent>
<nav
aria-label={"프로젝트 탐색"}
style={{ display: 'grid', gap: 12 }}
>
<div style={{ display: 'grid', gap: 2 }}>
{items.map((item) => renderItem(item))}
</div>
<section aria-label={"팀"}>
<h2
style={{
margin: '0 0 4px',
paddingInline: 10,
fontSize: 11,
fontWeight: 500,
color: 'var(--riido-foreground-tertiary)',
}}
>
{"팀"}
</h2>
{teams.map((team) => (
<div key={team.id}>
<Button
size="sm"
variant="ghost"
tone="secondary"
leadingIcon={expanded[team.id] ? ChevronDown : ChevronRight}
style={{ width: '100%', justifyContent: 'flex-start' }}
aria-expanded={expanded[team.id]}
aria-controls={`${teamList}-${team.id}`}
onClick={() =>
setExpanded((current) => ({
...current,
[team.id]: !current[team.id],
}))
}
>
{team.label}
</Button>
<div
id={`${teamList}-${team.id}`}
hidden={!expanded[team.id]}
>
<div style={{ display: 'grid', gap: 2 }}>
{team.items.map((item) => renderItem(item, true))}
</div>
</div>
</div>
))}
</section>
{renderItem({
id: 'settings',
label: "설정",
icon: Settings2,
})}
</nav>
</SidebarContent>
<SidebarFooter style={{ paddingBlockEnd: 8 }}>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: 8,
paddingBlockStart: 8,
paddingInline: 10,
borderTop: '1px solid var(--riido-border-divider)',
}}
>
<Avatar
size="sm"
initials="M"
label={"김민지"}
aria-hidden="true"
/>
<span style={{ fontSize: 12 }}>{"김민지"}</span>
</div>
</SidebarFooter>
</Sidebar>
</>
);
}
Usage
SidebarHeader, SidebarContent, SidebarFooter로 탐색 영역을 구성합니다. SidebarTrigger는 SidebarHeader 안에 한 개 배치하며 아이콘을 자동으로 제공합니다. collapsed와 onCollapsedChange로 접힘 상태를 관리하거나 defaultCollapsed로 초기 상태를 지정합니다. labels로 접기·펼치기 문구를 설정합니다. 링크, 선택 상태와 라우팅은 앱에서 구성합니다.
TSX
'use client';
import {
Sidebar,
SidebarHeader,
SidebarContent,
SidebarTrigger,
} from '@mbsw/ui';
export default function Example() {
return (
<Sidebar
aria-label={"프로젝트 탐색"}
style={{ height: 200 }}
labels={{
collapse: "사이드바 접기",
expand: "사이드바 펼치기",
}}
>
<SidebarHeader
style={{ minHeight: 'var(--riido-primitive-spacing-spacing-7)' }}
>
<span>{"워크스페이스"}</span>
<SidebarTrigger />
</SidebarHeader>
<SidebarContent>{"개요"}</SidebarContent>
</Sidebar>
);
}
Playground의 Code 탭에서 현재 설정과 동작이 포함된 예제 전체를 복사할 수 있습니다. 공통 CSS 설치는 설치하기를 확인하세요.