From 06036bae8d93ef117b7015ec4502e470d0d4f8d7 Mon Sep 17 00:00:00 2001 From: Sage Date: Thu, 20 Nov 2025 02:36:28 +0900 Subject: [PATCH] =?UTF-8?q?feat(window):=20=EC=9C=88=EB=8F=84=EC=9A=B0=20?= =?UTF-8?q?=EC=B5=9C=EC=86=8C=ED=99=94/=EC=B5=9C=EB=8C=80=ED=99=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 최소화/최대화/복원 기능 구현 - Taskbar에서 최소화된 윈도우 복원 기능 추가 - TitleBar 버튼 로직 업데이트 - Window 레이아웃 및 상태 반영 스타일 구현 - useWindowStore에 상태 및 동작 관련 새로운 slice 추가 - windowVariants로 상태 기반 UI 스타일링 지원 --- src/os/Taskbar/Taskbar.tsx | 15 +++++++-- src/os/TitleBar/TitleBar.tsx | 38 +++++++++++++++++++--- src/os/Window/Window.tsx | 61 ++++++++++++++++++++++++++++-------- src/os/Window/variants.ts | 38 ++++++++++++++++++++++ src/stores/useWindowStore.ts | 41 ++++++++++++++++++++++++ src/types/database.types.ts | 20 ------------ 6 files changed, 173 insertions(+), 40 deletions(-) create mode 100644 src/os/Window/variants.ts diff --git a/src/os/Taskbar/Taskbar.tsx b/src/os/Taskbar/Taskbar.tsx index aa45a50..e504dde 100644 --- a/src/os/Taskbar/Taskbar.tsx +++ b/src/os/Taskbar/Taskbar.tsx @@ -52,13 +52,20 @@ export default function Taskbar({ className, config = "default", ...rest }: Task const windows = useWindowStore((state) => state.windows); const activeWindowId = useWindowStore((state) => state.activeWindowId); const setActiveWindow = useWindowStore((state) => state.setActiveWindow); + const minimizedWindows = useWindowStore((state) => state.minimizedWindows); + const restoreWindow = useWindowStore((state) => state.restoreWindow); const showStart = config === "default" || config === "noSystemTray"; const showSystemTray = config === "default" || config === "noStartButton"; const handleTabClick = (id: WindowAppId) => { - // Taskbar 탭 클릭 시 해당 window로 focus - setActiveWindow(id); + const isMinimized = !!minimizedWindows[id]; + + if (isMinimized) { + restoreWindow(id); + } else { + setActiveWindow(id); + } }; return ( @@ -71,12 +78,14 @@ export default function Taskbar({ className, config = "default", ...rest }: Task const app = WINDOW_APPS[window.id]; if (!app) return null; + const isMinimized = !!minimizedWindows[window.id]; + return (
  • handleTabClick(window.id)} />
  • diff --git a/src/os/TitleBar/TitleBar.tsx b/src/os/TitleBar/TitleBar.tsx index 2bacb76..863024f 100644 --- a/src/os/TitleBar/TitleBar.tsx +++ b/src/os/TitleBar/TitleBar.tsx @@ -21,10 +21,13 @@ const sizeConfig = { } as const; export interface TitleBarProps extends React.ComponentPropsWithoutRef<"div">, TitleBarVariantProps { - icon?: FunctionComponent>; // FunctionComponent → ComponentType - title?: string; // text → title (prop 이름 통일) + icon?: FunctionComponent>; + title?: string; buttons?: "all" | "closeOnly" | null; onClose?: () => void; + onMinimize?: () => void; + onMaximize?: () => void; + isMaximized?: boolean; } /** @@ -92,11 +95,33 @@ export default function TitleBar({ title, buttons = null, onClose, + onMinimize, + onMaximize, + isMaximized, className, ...rest }: TitleBarProps) { const { iconClassName, buttonSizeClass, iconSizeClass } = sizeConfig[size ?? "small"]; + const handleButtonMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMinimize = (event: React.MouseEvent) => { + event.stopPropagation(); + onMinimize?.(); + }; + + const handleMaximize = (event: React.MouseEvent) => { + event.stopPropagation(); + onMaximize?.(); + }; + + const handleClose = (event: React.MouseEvent) => { + event.stopPropagation(); + onClose?.(); + }; + return (
    @@ -133,7 +160,9 @@ export default function TitleBar({ @@ -141,7 +170,8 @@ export default function TitleBar({ )}