wing-ops/frontend/src/pages/design/DesignSidebar.tsx

81 lines
2.6 KiB
TypeScript

import type { DesignTheme } from './designTheme';
import type { DesignTab } from './DesignHeader';
export type FoundationsMenuItemId = 'overview' | 'color' | 'typography' | 'radius' | 'layout';
export type ComponentsMenuItemId = 'overview' | 'buttons' | 'text-field' | 'float';
export type MenuItemId = FoundationsMenuItemId | ComponentsMenuItemId;
interface MenuItem {
id: MenuItemId;
label: string;
}
const FOUNDATIONS_MENU: MenuItem[] = [
{ id: 'overview', label: 'Overview' },
{ id: 'color', label: 'Color' },
{ id: 'typography', label: 'Typography' },
{ id: 'radius', label: 'Radius' },
{ id: 'layout', label: 'Layout' },
];
const COMPONENTS_MENU: MenuItem[] = [
{ id: 'overview', label: 'Overview' },
{ id: 'buttons', label: 'Buttons' },
{ id: 'text-field', label: 'Text Field' },
{ id: 'float', label: 'Float' },
];
const SIDEBAR_CONFIG: Record<DesignTab, { title: string; subtitle: string; menu: MenuItem[] }> = {
foundations: { title: 'FOUNDATIONS', subtitle: 'Design Token System', menu: FOUNDATIONS_MENU },
components: { title: 'COMPONENTS', subtitle: 'UI Component Catalog', menu: COMPONENTS_MENU },
};
export interface DesignSidebarProps {
theme: DesignTheme;
activeTab: DesignTab;
activeItem: MenuItemId;
onItemChange: (id: MenuItemId) => void;
}
export function DesignSidebar({ theme, activeTab, activeItem, onItemChange }: DesignSidebarProps) {
const isDark = theme.mode === 'dark';
const { menu } = SIDEBAR_CONFIG[activeTab];
const renderMenuItem = (item: MenuItem) => {
const isActive = activeItem === item.id;
return (
<button
key={item.id}
onClick={() => onItemChange(item.id)}
className="py-3 px-6 flex flex-row items-center w-full text-left transition-colors duration-150 border-l-4"
style={{
borderColor: isActive ? theme.textAccent : 'transparent',
color: isActive ? theme.textAccent : theme.textMuted,
background: isActive
? `linear-gradient(90deg, ${isDark ? 'rgba(76,215,246,0.1)' : 'rgba(6,182,212,0.1)'} 0%, transparent 100%)`
: undefined,
}}
>
<span className="font-sans text-base leading-6">{item.label}</span>
</button>
);
};
return (
<aside
className="w-64 h-full border-r border-solid pt-20 flex flex-col"
style={{
backgroundColor: theme.sidebarBg,
borderColor: theme.sidebarBorder,
boxShadow: `0px 25px 50px -12px ${theme.sidebarShadow}`,
}}
>
{/* 메뉴 네비게이션 */}
<nav className="flex-1 flex flex-col">{menu.map(renderMenuItem)}</nav>
</aside>
);
}
export default DesignSidebar;