shadcn.io is not affiliated with official shadcn/ui
Milestone Tracker CRUD Block for React
A launch plan's milestones with a due date and a dependency each, where a date cannot pass its dependency, a milestone cannot be completed while its dependency is open, and Delete is blocked while others depend on it.
Installation
Overview
Plan a launch whose steps wait for each other, with this milestone tracker for React with Base UI. A hairline frame with a plus mark on each corner holds six milestones in a frame of fixed height. Each has a Checkbox for done, a title with a line that says what it waits for or what waits for it, a date field and a native select for the milestone it depends on. The rules live in the dependencies: a due date must be on or after its dependency's, and the row says why in a line that is always there ("Must be on or after 9 Nov, when Design freeze is due"); a milestone whose dependency is open shows a lock and "Waiting for Design freeze" instead of its box; and Delete is blocked while others depend on it, naming them ("Beta, Launch depend on this; change them first"). An allowed delete leaves an Undo in the foot. A draft row closes the panel with a title, a date and a dependency, and its Add milestone button is the only Shine Button. The band is ruled by Guides, and an Empty state shows when every milestone is gone. For launch plans, grant timelines, build orders and any list where one item cannot move before another.
FAQ
How do I load my own milestones?
Edit START: a milestone has an id, a title, a due ISO date, a done flag and after, the id of the milestone it depends on or an empty string. A milestone can depend only on one that is earlier in the list, which also rules out loops.
What does the date rule refuse?
A date earlier than the dependency's, an empty date, and moving a date later than a milestone that depends on it. The refused value stays in the field with the reason beside it, and the milestone keeps its last good date. Choosing a dependency that is due later than the milestone, or that is still open while the milestone is done, is refused the same way.
When can a milestone be completed?
When its dependency is done. Until then the box is replaced by a lock and the reason. The other way round, a milestone cannot be reopened while one that depends on it is done: the status line names it.
Why does Delete sometimes do nothing?
While others depend on a milestone Delete answers with their names instead of removing it, so a plan never holds a dependency on something that is gone. Change or delete those first. Any other delete leaves an Undo that restores it in place.
What stays local, and how do I wire a real save?
Milestones live in state in this tab and a reload restores the six; nothing is sent. In your app write each change from tick, changeDue, changeAfter, add and remove, and keep the same checks on the server, since the dependency rules belong to the data.