Build a Gantt chart as a single React component: five project tasks drawn as horizontal bars across a shared 14-day timeline. It's a CSS-grid layout problem wearing a scheduling costume — each bar is positioned by grid-column, not by pixels — plus a small slice of state: clicking a bar selects it, and two buttons nudge the selected task earlier or later in time.
The starter App.tsx renders the chart statically: a day-number header (1–14), one row per task, and each bar placed with grid-column: start + 2 / span duration. Make it interactive:
TASKS array into useState, and track a selectedId (string | null, starting null). Map over the stateful tasks so edits re-render.selectedId to that task's id and adds the selected class (a white outline ring) to that one bar.Name: day X → Y (Nd) — its 1-based start day, end day, and duration. Otherwise show Click a task bar.start by ∓1 day, clamped to [0, 14 − duration] so the bar never runs off either end of the track. Disable both while nothing is selected.Click a task bar below. The − / + buttons are greyed out.Design: day 3 → 7 (4d). The buttons enable.day 4 → 8). Holding + eventually clamps: Design stops at day 11 (11 + 4 = 15, the far edge), never spilling past day 14.grid-column, not left/width. Each bar lives on the same 14-column track; start + 2 / span duration is the whole layout. Column 1 is the name column, so day d sits at grid column d + 2.selectedId — don't track them separately.Math.max(0, Math.min(14 − duration, …)) into the state update so start is always valid; nothing downstream has to defend against an off-track value.styles.css; focus on the state and the shift math.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.