Sort Modes & Reordering
Tasks, Lists, and Steps have a persisted custom order (drag-and-drop) and an optional temporary sort chosen from a menu. Sorting produces a view order; drag-and-drop sets the persisted fractional rank (Product Brief §5.2 “Drag-and-drop / ordering rules”).
The pieces that turn a chosen mode into a rendered view order:
flowchart LR Menu["Sort menu (Tasks scope)"] --> Store["sort-mode-store.ts<br/>setSortMode / getSortMode"] Store --> Sub["subscribeSortMode(...)"] Sub --> Render["renderSortMode(items, mode)<br/>(sort-modes.ts)"] Store --> Default["defaultSortForView(view)"] Render --> Cmp["compareRanks(a, b)<br/>for custom order"] Render --> View["view order (rank never mutated)"]
Sort modes
Section titled “Sort modes”src/lib/rank/sort-modes.ts — renderSortMode(items, mode) returns items in the chosen SortMode, using compareRanks for custom order. Per-scope modes (matching the scope sort policy):
- Tasks:
custom,alphabetical,due,created,importance. - Lists:
custom,alphabetical,created. - Steps:
custom,alphabetical,created.
Passing due/importance for Lists or Steps falls back to (rank, id) order. (Only the Tasks scope exposes the full sort dropdown; Lists and Steps reorder by drag-and-drop.)
How renderSortMode dispatches per mode, and how that relates to drag-and-drop writing rank:
flowchart TD
Mode{SortMode?} -->|custom| Custom["sort by (rank, id)<br/>compareRanks"]
Mode -->|alphabetical| Alpha["sort by title then id"]
Mode -->|created| Created["sort by createdAt then id"]
Mode -->|due| Due{"dueDate defined?<br/>(Tasks only)"}
Mode -->|importance| Imp{"starred?<br/>(Tasks only)"}
Due -->|no field| Fallback["fall back to (rank, id)"]
Imp -->|no field| Fallback
Custom --> View["view order (no rank write)"]
Alpha --> View
Created --> View
Drag["drag-and-drop"] --> Rank["generateKeyBetween → persist rank"]
Sort-mode store
Section titled “Sort-mode store”src/lib/prefs/sort-mode-store.ts keeps the active mode per scope instance (ScopeInstanceKey): getSortMode(...), setSortMode(scopeKey, mode), subscribeSortMode(...), and defaultSortForView(view) for the default per built-in View. The store is observable so sort menus and lists re-render on change.
Persisted order
Section titled “Persisted order”Custom order is the fractional rank (per-List for Tasks, per-Task for Steps, per-User for Lists/Groups). Sorting never mutates rank; it only reorders the view. See the Fractional Rank Algorithm.
Related: Fractional Rank Algorithm, My Day & Owner-Scoped Views, List Sidebar & Drag-Drop (deferred guide).