/** * 상단 메뉴바 — 알림 팝업 표시 위치·방식 (아이콘 드롭다운) */ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import TradeAlertPopupModeIcon from './TradeAlertPopupModeIcon'; import { TRADE_ALERT_GRID_COL_OPTIONS, buildTradeAlertPopupModeOptions, formatTradeAlertPopupMode, normalizeTradeAlertGridCols, normalizeTradeAlertPopupLayout, normalizeTradeAlertPopupPosition, tradeAlertPopupModeKey, type TradeAlertPopupLayout, type TradeAlertPopupPosition, } from '../utils/tradeAlertPopupLayout'; interface Props { position?: string; layout?: string; gridCols?: number; onPositionChange?: (v: TradeAlertPopupPosition) => void; onLayoutChange?: (v: TradeAlertPopupLayout) => void; onGridColsChange?: (v: number) => void; } export const TradeAlertPopupMenubarSelect: React.FC = ({ position: positionRaw = 'right', layout: layoutRaw = 'stack', gridCols: gridColsRaw = 2, onPositionChange, onLayoutChange, onGridColsChange, }) => { const position = normalizeTradeAlertPopupPosition(positionRaw); const layout = normalizeTradeAlertPopupLayout(layoutRaw); const gridCols = normalizeTradeAlertGridCols(gridColsRaw); const modeKey = tradeAlertPopupModeKey(position, layout); const modeOptions = useMemo(() => buildTradeAlertPopupModeOptions(), []); const [open, setOpen] = useState(false); const rootRef = useRef(null); useEffect(() => { if (!open) return; const onDoc = (e: MouseEvent) => { if (rootRef.current && !rootRef.current.contains(e.target as Node)) { setOpen(false); } }; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); }; document.addEventListener('mousedown', onDoc); document.addEventListener('keydown', onKey); return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); }; }, [open]); const selectMode = useCallback(( nextPos: TradeAlertPopupPosition, nextLay: TradeAlertPopupLayout, ) => { if (nextPos !== position) onPositionChange?.(nextPos); if (nextLay !== layout) onLayoutChange?.(nextLay); setOpen(false); }, [position, layout, onPositionChange, onLayoutChange]); const currentLabel = formatTradeAlertPopupMode(position, layout); return (
{open && (
{modeOptions.map(opt => { const active = opt.key === modeKey; return ( ); })} {layout === 'grid' && (
그리드 열
{TRADE_ALERT_GRID_COL_OPTIONS.map(n => ( ))}
)}
)}
); }; export default TradeAlertPopupMenubarSelect;