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
pnpm install
pnpm dev
Visit http://localhost:3000
This editor is built around two key providers:
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>
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} />}
/>
Includes reducer logic, structural correctness, and performance profiling.
pnpm test
tests/agendaReducer.test.ts
— core reducer behaviortests/reparentBlocks.test.ts
— logic for drop target resolutiontests/agendaReducerPerformance.test.ts
— randomized move performance
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
.
app/
├── components/
│ ├── Agenda.tsx
│ ├── TreeRenderer.tsx
│ └── ...
├── providers/
│ ├── BlockProvider.tsx
│ └── TreeProvider.tsx
├── reducers/
│ ├── blockReducer.ts
│ └── expandReducer.ts
├── hooks/
│ ├── useModifierKey.ts
│ └── useAgendaDetails.ts
└── test/
└── page.tsx
- Add keyboard accessibility for DnD
- Virtualize block rendering (e.g.,
react-virtual
) - Real API layer + persistence
- Publish as a reusable component library