Files
hyungi_document_server/frontend/src/lib/stores/toast.ts
Hyungi Ahn 8742367bc2 refactor: stores 분리 — toast / uiState 단일 책임화
UX/UI 개편 Phase A-2. lib/stores/ui.ts에 섞여 있던 toast 시스템과
UI layer 상태(미사용 dead export 포함)를 의미 단위로 분리한다.
한 파일이 비대해지는 시나리오를 처음부터 차단(plan 8대 원칙 #7).

- lib/stores/toast.ts 신규 — toasts/addToast/removeToast (Toast interface export)
- lib/stores/uiState.svelte.ts 신규 — drawer 단일 slot + modal stack 클래스 (5대 원칙 #2)
  · openDrawer/closeDrawer/isDrawerOpen
  · openModal/closeTopModal/isModalOpen/modalIndex/topModal
  · handleEscape (modal stack 우선 → drawer)
- lib/stores/ui.ts 삭제 — sidebarOpen/selectedDocId는 어디서도 import되지 않은 dead export였음
- 11개 파일 import 경로 갱신: \$lib/stores/ui → \$lib/stores/toast

uiState는 아직 어디서도 사용 안 함 — Phase B에서 sidebar/meta drawer가 전환될 때
ui.openDrawer('sidebar') 형태로 채택. 동작 변경 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:26:11 +09:00

25 lines
653 B
TypeScript

import { writable } from 'svelte/store';
// Toast 시스템 — UI state(drawer/modal)와 분리된 알림 전용 store
export interface Toast {
id: number;
type: 'success' | 'error' | 'warning' | 'info';
message: string;
}
let toastId = 0;
export const toasts = writable<Toast[]>([]);
export function addToast(type: Toast['type'], message: string, duration = 5000) {
const id = ++toastId;
toasts.update((t) => [...t, { id, type, message }]);
if (duration > 0) {
setTimeout(() => removeToast(id), duration);
}
return id;
}
export function removeToast(id: number) {
toasts.update((t) => t.filter((toast) => toast.id !== id));
}