Skip to content

Lightweight, flexible drag-and-drop architecture for building nested, reorderable trees and complex UIs without the boilerplate. Powered by DnD Kit under the hood, built for real-world apps.

Notifications You must be signed in to change notification settings

thesandybridge/dnd-sandbox

Repository files navigation

🗂️ Agenda DnD Demo

This is a performant, testable drag-and-drop agenda editor built with @dnd-kit/core, Next.js App Router, and React. It supports:

  • Nested, sortable blocks (section, topic, objective)
  • Modifier key interactions (Shift to collapse/expand sections)
  • Accessible drag handles with overlays
  • User-defined block content via a generic TreeProvider
  • Deep testing: unit, performance, and E2E

📦 Setup

pnpm install
pnpm dev

Visit http://localhost:3000


🧠 Architecture

This editor is built around two key providers:

BlockProvider

Manages tree structure and mutation logic:

  • Block creation, deletion, and movement
  • Internal maps (blockMap, childrenMap, indexMap) for fast lookups
  • Reducer-based state model

You can pass initial data via:

<BlockProvider initialBlocks={myBlocks}>
  <Agenda />
</BlockProvider>

TreeProvider<T>

Generic context for rendering block content:

  • Accepts a Map<string, T> of block content
  • Renders items via a user-supplied ItemRenderer
  • Provides collapse state, DnD state, and keyboard modifiers
<TreeProvider
  data={myContentMap}
  ItemRenderer={({ id, content }) => <MyCustomItem id={id} content={content} />}
/>

🧪 Testing

Unit tests (Jest)

Includes reducer logic, structural correctness, and performance profiling.

pnpm test
  • tests/agendaReducer.test.ts — core reducer behavior
  • tests/reparentBlocks.test.ts — logic for drop target resolution
  • tests/agendaReducerPerformance.test.ts — randomized move performance

E2E tests (Playwright)

Simulates real drag-and-drop behavior across many elements.

pnpm test:e2e
pnpm test:e2e:headed

To customize the E2E test size:

await page.goto('/test?sections=5&topics=10')

Tests generate screenshots in /screenshots.


📁 File Structure

app/
  ├── components/
  │   ├── Agenda.tsx
  │   ├── TreeRenderer.tsx
  │   └── ...
  ├── providers/
  │   ├── BlockProvider.tsx
  │   └── TreeProvider.tsx
  ├── reducers/
  │   ├── blockReducer.ts
  │   └── expandReducer.ts
  ├── hooks/
  │   ├── useModifierKey.ts
  │   └── useAgendaDetails.ts
  └── test/
      └── page.tsx

🧼 Roadmap

  • Add keyboard accessibility for DnD
  • Virtualize block rendering (e.g., react-virtual)
  • Real API layer + persistence
  • Publish as a reusable component library

About

Lightweight, flexible drag-and-drop architecture for building nested, reorderable trees and complex UIs without the boilerplate. Powered by DnD Kit under the hood, built for real-world apps.

Resources

Stars

Watchers

Forks