88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Database, Layout, Cog, Settings, Palette, Monitor } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export interface ToolbarButton {
|
|
id: string;
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
shortcut: string;
|
|
group: "source" | "editor";
|
|
panelWidth: number;
|
|
}
|
|
|
|
interface LeftUnifiedToolbarProps {
|
|
buttons: ToolbarButton[];
|
|
panelStates: Record<string, { isOpen: boolean; badge?: number }>;
|
|
onTogglePanel: (panelId: string) => void;
|
|
}
|
|
|
|
export const LeftUnifiedToolbar: React.FC<LeftUnifiedToolbarProps> = ({ buttons, panelStates, onTogglePanel }) => {
|
|
// 그룹별로 버튼 분류
|
|
const sourceButtons = buttons.filter((btn) => btn.group === "source");
|
|
const editorButtons = buttons.filter((btn) => btn.group === "editor");
|
|
|
|
const renderButton = (button: ToolbarButton) => {
|
|
const isActive = panelStates[button.id]?.isOpen || false;
|
|
const badge = panelStates[button.id]?.badge;
|
|
|
|
return (
|
|
<Button
|
|
key={button.id}
|
|
variant="ghost"
|
|
onClick={() => onTogglePanel(button.id)}
|
|
title={`${button.label} (${button.shortcut})`}
|
|
className={cn(
|
|
"flex h-14 w-14 flex-col items-center justify-center gap-1 rounded-lg transition-all duration-200",
|
|
isActive
|
|
? "bg-gradient-to-br from-blue-500 to-blue-600 text-white shadow-lg hover:from-blue-600 hover:to-blue-700"
|
|
: "text-slate-600 hover:bg-slate-100 hover:text-slate-900",
|
|
)}
|
|
>
|
|
<div className="relative">
|
|
{button.icon}
|
|
{isActive && <div className="absolute -top-1 -right-1 h-2 w-2 rounded-full bg-white" />}
|
|
{badge !== undefined && badge > 0 && (
|
|
<div className="absolute -top-2 -right-2 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-[10px] font-bold text-white shadow-md">
|
|
{badge > 99 ? "99+" : badge}
|
|
</div>
|
|
)}
|
|
</div>
|
|
<span className="text-[10px] font-medium">{button.label}</span>
|
|
</Button>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-full w-[60px] flex-col border-r border-slate-200 bg-white">
|
|
{/* 입력/소스 그룹 */}
|
|
<div className="flex flex-col gap-1 border-b border-slate-200 p-1">{sourceButtons.map(renderButton)}</div>
|
|
|
|
{/* 편집/설정 그룹 */}
|
|
<div className="flex flex-col gap-1 p-1">{editorButtons.map(renderButton)}</div>
|
|
|
|
{/* 하단 여백 */}
|
|
<div className="flex-1" />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// 기본 버튼 설정 (통합 패널 1개)
|
|
export const defaultToolbarButtons: ToolbarButton[] = [
|
|
// 통합 패널 (컴포넌트 + 편집 탭)
|
|
{
|
|
id: "unified",
|
|
label: "패널",
|
|
icon: <Layout className="h-5 w-5" />,
|
|
shortcut: "P",
|
|
group: "source",
|
|
panelWidth: 240,
|
|
},
|
|
];
|
|
|
|
export default LeftUnifiedToolbar;
|