- TypeScript 88.3%
- SCSS 7.7%
- JavaScript 1.8%
- CSS 1.5%
- HTML 0.7%
|
|
||
|---|---|---|
| .forgejo | ||
| public | ||
| src | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .prettierignore | ||
| .prettierrc | ||
| eslint.config.mjs | ||
| index.html | ||
| package.json | ||
| README.es.md | ||
| README.md | ||
| README.ru.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
| yarn.lock | ||
Sorting Algorithms Visualizer
Language / Язык / Idioma: English | Русский | Español
An interactive educational web application for exploring and visualizing 8 classic sorting algorithms step by step. Enter your own array, choose the sort direction, adjust the animation speed, and watch every comparison and swap happen in real time.
Table of Contents
Features
- Step-by-step animation — each comparison, swap, and final placement is highlighted in a distinct color
- Custom input — enter any sequence of integers separated by spaces
- Sort direction — toggle between ascending and descending order
- Adjustable speed — a slider controls the animation delay from slow (educational) to fast
- Algorithm details — each algorithm has a Description tab, a Properties tab with time/space complexity, and an interactive Testing tab
- Binary tree visualization — Heap Sort shows the heap structure as a binary tree during sorting
- GIF previews — animated previews demonstrate the algorithm before you run it
- Multilingual UI — full support for English, Russian, and Spanish; switched instantly in the header
Algorithms
| Algorithm | Best | Average | Worst | Space |
|---|---|---|---|---|
| Bubble Sort | O(n) | O(n²) | O(n²) | O(1) |
| Cocktail Shaker Sort | O(n) | O(n²) | O(n²) | O(1) |
| Comb Sort | O(n log n) | O(n²) | O(n²) | O(1) |
| Insertion Sort | O(n) | O(n²) | O(n²) | O(1) |
| Selection Sort | O(n²) | O(n²) | O(n²) | O(1) |
| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(1) |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) |
| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) |
Tech Stack
| Layer | Technology |
|---|---|
| UI Framework | React 19 |
| Language | TypeScript 5 |
| Styling | SCSS Modules |
| Build tool | Vite |
| Package manager | Yarn |
| Testing | Vitest + React Testing Library |
| Lint / format | ESLint 10 (flat config, perfectionist), Prettier, pre-commit |
| i18n | Custom React Context (no external lib) |
Getting Started
Prerequisites
- Node.js 20.19+, 22.13+ or 24+ (22 recommended, matching CI)
- Yarn 1.x
Installation
git clone https://git.smekhov-alex.com/Smeh_alex/sa_sorts
cd sa_sorts
yarn
Available Commands
| Command | Description |
|---|---|
yarn start |
Start the development server |
yarn build |
Build for production into the dist/ folder |
yarn test |
Run the full test suite with Vitest |
yarn test:watch |
Run Vitest in watch mode |
yarn lint |
ESLint over src and tests (lint:fix to autofix) |
yarn format |
Prettier over the sources |
Project Structure
sa_sorts/
├── public/ # Static HTML shell
├── src/
│ ├── types/
│ │ └── sorts.ts # SortNames enum + SortedArrayItem interface
│ ├── context/
│ │ └── LangContext.tsx # LangProvider, useLang hook, LANGS constant
│ ├── locales/
│ │ ├── types.ts # Translations interface
│ │ ├── en.ts / ru.ts / es.ts # Translation objects
│ │ └── index.ts # Re-exports + translations map
│ ├── components/
│ │ ├── Header/ # App header with language toggle
│ │ ├── SortingList/ # List of all algorithm accordions
│ │ ├── SortingItem/ # Accordion card: tabs + algorithm data
│ │ ├── DescriptionTab/ # Algorithm description with GIF
│ │ ├── PropertiesTab/ # Time/space complexity table
│ │ ├── SortingTab/ # Interactive sort + animation engine
│ │ │ ├── funcs/ # 8 top-level async sort functions
│ │ │ ├── subFuncs/ # Shared recursive/iterative helpers
│ │ │ └── utils/ # Atomic animation state helpers
│ │ └── BinaryTree/ # Binary heap tree for Heap Sort
│ ├── gifs/ # Animated previews for each algorithm
│ ├── icons/ # SVG icons
│ └── styles/ # Global styles and variables
├── tests/ # Vitest test suites (mirrors src/)
│ ├── setupTests.ts # jest-dom matchers, RTL cleanup, jsdom storages
│ └── reporters/ # Compact custom test reporter
├── vitest.config.ts # jsdom environment + the app's Vite plugins
└── .forgejo/
├── actions/ # Composite actions reused by the workflows
└── workflows/
├── lint.yml # CI: tsc --noEmit + ESLint on every PR
├── tests.yml # CI: runs tests on every PR
├── build-static.yml # CI: production build on every PR
├── audit.yml # CI: dependency audit on every PR
├── pre-commit.yml # CI: pre-commit hooks on every PR
└── deploy.yml # CD: all checks + deploy on push to main
Animation Engine
The animation is driven by asynchronous sort functions that mutate a SortedArrayItem[] array in place. After each logical step the function calls setWithTimer, which:
- Checks a
isCancelled()flag (set on component unmount or sort restart) - Calls React's
setSortedArrayto trigger a re-render - Awaits a
setTimeoutwith the currentgetDelay()value
The AnimationControl object ({ isCancelled, getDelay }) is threaded through every sort function, sub-function, and utility helper via CallFunctionProps, keeping the UI layer fully decoupled from the algorithm logic.
Element states (rendered with distinct colors):
SortedArrayItem field |
Meaning |
|---|---|
isSelected |
Currently being compared |
isSwitching |
Being swapped right now |
isEndPosition |
Permanently in its final sorted position |
element === -1 |
Invisible divider (used in Merge Sort partitions) |
Internationalization
The UI is fully translated into English, Russian, and Spanish. Language is switched at runtime — no page reload required.
How it works:
src/locales/contains one typed translation object per language (en.ts,ru.ts,es.ts) that conform toTranslationsLangProviderwraps the app and stores the active language inuseState; the resolvedtranslationobject is memoized withuseMemo- Any component consumes translations via the
useLang()hook:const { lang, translation, setLang } = useLang() - The language toggle buttons in the
HeadercallsetLangdirectly
Adding a new language:
- Create
src/locales/<code>.tsimplementingTranslations - Add it to the
translationsmap andLANGSarray insrc/locales/index.ts
Testing
Tests live in tests/ and run via Vitest, configured in vitest.config.ts.
yarn test # single run
yarn test:watch # watch mode
Coverage: 184 tests across 19 test suites — all green.
Key setup details:
- Tests reuse the app's Vite plugins, so path aliases (
vite-tsconfig-paths) and SVG (?react), GIF and SCSS Modules imports work without manual mocks - Vitest globals are disabled: each test file imports
describe/it/expect/vifromvitest tests/setupTests.tsregisters the jest-dom matchers, cleans React Testing Library up after each test and restores the jsdom storages (Node >= 24 defines its ownlocalStorage)- The default language in
LangProvideris'en'; component tests usetranslations.endirectly
CI/CD
Continuous integration and deployment run on Forgejo Actions. Reusable steps are factored into composite actions under .forgejo/actions/; every workflow caches node_modules on the yarn.lock hash.
| Workflow | Trigger | What it does |
|---|---|---|
lint.yml |
pull request | tsc --noEmit and ESLint |
tests.yml |
pull request | 5 parallel jobs — array_transforms, components, context, utils, sorts — each running yarn test tests/<dir> |
build-static.yml |
pull request | A production build |
audit.yml |
pull request | yarn audit; fails on high or critical findings only |
pre-commit.yml |
pull request | Every pre-commit hook across the whole tree |
deploy.yml |
push to main |
Re-runs all five checks, then builds and rsyncs dist/ to the server |
Pre-commit hooks
pip install pre-commit
pre-commit install
Runs the standard file hygiene hooks, ESLint with --fix over src and tests, and Prettier. In CI the ESLint hook is skipped (SKIP: eslint) — lint.yml covers it with the dependencies installed.
License
This project is open-source. Source code is available at git.smekhov-alex.com/Smeh_alex/sa_sorts.