KQ-1345 · PROJECT/TRACKER
Project Tracker
A complete project screen: a projects sidebar with the composed pin, a view switch whose thumb slides on snap, and the tasks as a list, a board or a timeline — switching is one morph, each task's plate gliding from row to card to date bar on glide while its title glides without stretching. Board cards are carried 1:1 to another column and fly into their slot; timeline bars slide along their row and land on the projected day on snap with the release velocity. A task opens in a drawer (over, pushing or rising) with every field editable and the composed watch and delete buttons; arrows rove the tasks, Shift with Left or Right moves a card a column or a bar's due date, Space ticks, Escape closes.
Up and Down move between tasks, Space marks a task done, Enter opens it.
Arrow keys move between cards, Shift with Left or Right moves the card to the next column, Enter opens it.
Left and Right move the task a day, Shift with Left or Right changes its due date, Up and Down move between tasks, Enter opens it.
Field app 3.0
9 tasks · 2 done
field app 3.0 · list · 9 tasks · 2 done
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/project-tracker
Props
- projects
- TrackerProject[]
- default defaultTrackerProjects
- The projects in the sidebar: id, name and the three-letter key that prefixes task numbers.
- people
- TrackerPerson[]
- default defaultTrackerPeople
- Everyone a task can be assigned to.
- tasks / defaultTasks
- TrackerTask[]
- default — / defaultTrackerTasks
- Every project's tasks: status, priority, assignee, start and due dates, tag, description, subtasks and watchers.
- onTasksChange
- (tasks: TrackerTask[]) => void
- default —
- Fires with every task after any change: a status, a drop, a date, an edit, a new task or a deletion.
- project / defaultProject
- string
- default — / first project
- The project on screen.
- onProjectChange
- (id: string) => void
- default —
- Fires from the sidebar row or key that chose a project.
- view / defaultView
- "list" | "board" | "timeline"
- default — / "list"
- The tasks as a list grouped by status, a board of status columns, or bars on a timeline.
- onViewChange
- (view: TrackerView) => void
- default —
- Fires from the view switch with the new view.
- task / defaultTask
- string | null
- default — / null
- The task open in the drawer; null closes it.
- onTaskChange
- (id: string | null) => void
- default —
- Fires from the row, card, bar or key that opened a task, and with null when the drawer closes.
- pinned / defaultPinned
- string[]
- default — / ["field"]
- Pinned project ids, shown first in the sidebar.
- onPinnedChange
- (ids: string[]) => void
- default —
- Fires from the pin with every pinned id.
- onTaskCreate
- (task: TrackerTask) => void
- default —
- A task was made with New task.
- onTaskUpdate
- (task: TrackerTask, previous: TrackerTask) => void
- default —
- A task changed, with what it was before.
- onTaskDelete
- (task: TrackerTask) => void
- default —
- A task was deleted, after its undo window.
- now
- Date | number
- default defaultTrackerNow
- Today: the timeline's line, and what is due or late.
- drawer
- "overlay" | "push" | "sheet"
- default "overlay"
- How the task drawer presents: over the work from the right, pushing the work aside, or rising from the bottom.
- density
- "compact" | "cozy" | "roomy"
- default "cozy"
- Row height 32, 40 or 48px, with card padding and the timeline's rows and days to match.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the tasks have arrived: skeleton rows, or a message with Try again.
- onRetry
- () => void
- default —
- Try again was pressed after the tasks failed to load.
- label
- string
- default "Project tracker"
- The screen's accessible name.
- sound
- boolean
- default false
- Play the swishes and clicks; the composed pin, watch and delete buttons play their own.
- disabled
- boolean
- default false
- Greys the screen out and makes it inert.
- className
- string
- default —
- Classes for the screen's frame.
| Prop | Type | Default | Description |
|---|---|---|---|
| projects | TrackerProject[] | defaultTrackerProjects | The projects in the sidebar: id, name and the three-letter key that prefixes task numbers. |
| people | TrackerPerson[] | defaultTrackerPeople | Everyone a task can be assigned to. |
| tasks / defaultTasks | TrackerTask[] | — / defaultTrackerTasks | Every project's tasks: status, priority, assignee, start and due dates, tag, description, subtasks and watchers. |
| onTasksChange | (tasks: TrackerTask[]) => void | — | Fires with every task after any change: a status, a drop, a date, an edit, a new task or a deletion. |
| project / defaultProject | string | — / first project | The project on screen. |
| onProjectChange | (id: string) => void | — | Fires from the sidebar row or key that chose a project. |
| view / defaultView | "list" | "board" | "timeline" | — / "list" | The tasks as a list grouped by status, a board of status columns, or bars on a timeline. |
| onViewChange | (view: TrackerView) => void | — | Fires from the view switch with the new view. |
| task / defaultTask | string | null | — / null | The task open in the drawer; null closes it. |
| onTaskChange | (id: string | null) => void | — | Fires from the row, card, bar or key that opened a task, and with null when the drawer closes. |
| pinned / defaultPinned | string[] | — / ["field"] | Pinned project ids, shown first in the sidebar. |
| onPinnedChange | (ids: string[]) => void | — | Fires from the pin with every pinned id. |
| onTaskCreate | (task: TrackerTask) => void | — | A task was made with New task. |
| onTaskUpdate | (task: TrackerTask, previous: TrackerTask) => void | — | A task changed, with what it was before. |
| onTaskDelete | (task: TrackerTask) => void | — | A task was deleted, after its undo window. |
| now | Date | number | defaultTrackerNow | Today: the timeline's line, and what is due or late. |
| drawer | "overlay" | "push" | "sheet" | "overlay" | How the task drawer presents: over the work from the right, pushing the work aside, or rising from the bottom. |
| density | "compact" | "cozy" | "roomy" | "cozy" | Row height 32, 40 or 48px, with card padding and the timeline's rows and days to match. |
| status | "ready" | "loading" | "error" | "ready" | Whether the tasks have arrived: skeleton rows, or a message with Try again. |
| onRetry | () => void | — | Try again was pressed after the tasks failed to load. |
| label | string | "Project tracker" | The screen's accessible name. |
| sound | boolean | false | Play the swishes and clicks; the composed pin, watch and delete buttons play their own. |
| disabled | boolean | false | Greys the screen out and makes it inert. |
| className | string | — | Classes for the screen's frame. |