diff --git a/src/App.tsx b/src/App.tsx index 84bba9d..a663eed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,47 +8,19 @@ import { computeInterval, SWAP_TRANS_MS, type Step, -} from './visualizer'; - -/* === Mantine UI === */ -import { - Container, - Paper, - Group, - Button, - Title, - Text, - Slider, - ActionIcon, - Accordion, - Badge, - Stack, - Box, - Anchor, -} from '@mantine/core'; +} from './plugins/visualizer'; +/* Mantine */ +import { Container, Paper, Accordion } from '@mantine/core'; import { useTranslation } from 'react-i18next'; -import LanguageSwitcher from './LanguageSwitcher'; -type Kind = 'bubble' | 'quick'; -type Range = { lo: number; hi: number } | null; +import HeaderBar from './components/HeaderBar'; +import ControlBar from './components/ControlBar'; +import SortSection, { BoardState } from './components/SortSection'; +import { BubbleLegend } from './components/algorithms/Bubble'; +import { QuickLegend, QuickOverlay } from './components/algorithms/Quick'; -type BoardState = { - kind: Kind; - data: number[]; - ids: number[]; - steps: Step[]; - stepIndex: number; - finished: boolean; - compare?: [number, number] | null; - swapPair?: [number, number] | null; - candL?: number | null; - candR?: number | null; - pivotIndex: number | null; - range: Range; - boundaryIndex: number | null; - boundaryVisible: boolean; -}; +type Kind = 'bubble' | 'quick'; function makeBoard(kind: Kind, base: number[]): BoardState { const n = base.length; @@ -127,111 +99,8 @@ function applyStep(b: BoardState, step: Step): BoardState { } } -function Bars({ board }: { board: BoardState }) { - const { t } = useTranslation(); - const max = Math.max(...board.data, 1); - const n = board.data.length; - - const isCompare = (idx: number) => - !!board.compare && (idx === board.compare[0] || idx === board.compare[1]); - const isSwap = (idx: number) => - !!board.swapPair && (idx === board.swapPair[0] || idx === board.swapPair[1]); - const isPivot = (idx: number) => board.pivotIndex === idx; - const isCandL = (idx: number) => board.candL === idx; - const isCandR = (idx: number) => board.candR === idx; - - return ( -
- {board.kind === 'quick' && } - - {Array.from({ length: n }, (_, i) => { - const h = (board.data[i] / max) * 100; - const classes = [ - 'bar', - isPivot(i) ? 'pivot' : '', - isCompare(i) ? 'compare' : '', - isSwap(i) ? 'swap' : '', - isCandL(i) ? 'candL' : '', - isCandR(i) ? 'candR' : '', - board.finished ? 'sorted' : '', - ] - .filter(Boolean) - .join(' '); - return ( -
- ); - })} -
- ); -} - -function QuickOverlay({ board }: { board: BoardState }) { - const n = Math.max(board.data.length, 1); - const range = board.range; - const lo = range?.lo ?? 0; - const hi = range?.hi ?? n - 1; - - const showRange = range != null; - const leftPct = (lo / n) * 100; - const rightPct = ((hi + 1) / n) * 100; - const boundaryPct = ((board.boundaryIndex ?? lo) / n) * 100; - - const pivotHeightPct = - board.pivotIndex != null && board.data.length - ? (board.data[board.pivotIndex] / Math.max(...board.data, 1)) * 100 - : null; - - return ( -