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.

KQ-1345 · PROJECT/TRACKER

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

To do3

In progress2

In review2

Done2

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.