# UI 구현 핵심 패턴 ## 1. 메인 앱 = React + MUI, 팝업 = Vanilla JS - 메인 윈도우만 React 번들 (781KB) - 팝업들은 개별 HTML + 순수 JS (빠른 로딩) - 각 팝업: recording-tip, result-popup, info-tip, mic-tip, mode-tip, ask-window ## 2. MUI 테마 설정 ```javascript createTheme({ palette: { mode: 'light' | 'dark', primary: { main: 'rgb(31, 93, 242)' }, background: { default: '#F9F9F9'/'#121212', paper: '#FFFFFF'/'#1E1E1E' } }, typography: { fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI"' }, shape: { borderRadius: 12 }, components: { MuiButton: { root: { textTransform: 'none', fontWeight: 500 } } } }) ``` ## 3. RecordingTip 웨이브 바 - 9개 바, 코사인 분포: `cos(n * PI / 2)` 가중치 - 100ms 간격 setInterval - 오디오 레벨 → targetAmplitude, smoothing: `v += (S - v) * 0.5` - 최소 2px, 최대 28px + 랜덤 변동 ±35% ## 4. Thinking 프로그레스 바 - 시간 기반: `min(95, (1 - 1/(1 + 1.5*t)) * 100)%` — 95%에 점근 수렴 - requestAnimationFrame 루프 ## 5. 2-Phase 윈도우 리사이즈 (깜빡임 방지) ``` prepare(state, params) → 숨겨진 span으로 폭 측정 → measured(width) IPC → 메인 프로세스에서 윈도우 리사이즈 → show(state) → CSS 클래스 적용 → 보이기 ``` ## 6. 앱 구조 (React 컴포넌트 트리) ``` App ├── ThemeProvider (light/dark/auto, localStorage) ├── Drawer (240px, permanent) │ ├── NavItems [Dashboard, Dictionary, CustomCommand] │ └── BottomBar [Account, Settings] └── Content Area ├── Dashboard (통계 + 최근 세션) ├── History (검색 + 재시도) ├── Dictionary └── Settings (Modal) ``` ## 7. 라우팅 - React Router 미사용, 순수 useState 기반 - `currentRoute` state → switch 문으로 렌더링