Files
gpui-native-kit/docs/CHECKLIST.md
T
2026-11-08 09:07:23 +07:00

193 lines
10 KiB
Markdown

# gpui-native-kit — checklist
The living queue. Every element lands through the review gate: API sketch →
implementation → tests → gallery panel → review. Conventions and rules live in
[AGENTS.md](../AGENTS.md); the gpui pin lives in the workspace `Cargo.toml`
(resolved in `Cargo.lock`, zed @ `504a7f2cf25b817cda3998cab93473adef15f93c`).
[signed](https://git.reya.info/reya/signed)
is the first downstream consumer; its screens drive the order.
## Next
## Queue — to follow
Platform metric adoption continues one component at a time; each stop goes
through the review gate and a gallery pass.
- [ ] **Combobox platform chrome** — popup border behind
`Theme::borders.overlays`; the trigger follows the input stop's field
treatment.
- [ ] **Command palette platform chrome** — overlay border gate.
- [ ] **Switch platform chrome** — stated track and knob dims
(`switch_height` / `switch_width` / `switch_knob`, inset and travel
derived); borderless knob.
Gaps surfaced by the signed comparison; ordered by signed's usage.
- [ ] **Virtual list** — generic virtualized variable-height rows with a
scroll handle, promoted from the editor views' pattern over gpui's
`list`; signed's PR lists and commit diff drive it.
- [ ] **Editable code field** — syntax-highlighted editable multiline field,
the code view's highlighter over the input's editing model; signed's
repo file browser.
- [ ] **Dropdown menu** — trigger button + popover + menu composite, three
signed call sites; must stay a real component, not a wrapper.
- [ ] **Motion easing helpers** — cubic ease-out and lerp beside
`theme::Motion`; low priority, gpui's animation primitives cover most
cases.
- [ ] **Markdown view follow-ups** — streaming `append` with a coalesced
background parse, text selection with copy, per-block a11y roles,
GFM alerts + table column alignment, per-fence highlight reuse,
`soft_break_as_hard_break`; ranked notes in
[markdown-view-comparison.md](markdown-view-comparison.md).
- [ ] **Editor follow-ups** — language detection by file path, meta line
overlay, per-view config overrides (line height, gutter visibility).
- [ ] **Pickers** — Calendar / DatePicker, TimeField, ColorPicker (decide at
unit time).
- [ ] **Layout follow-ups** — persistence, pane zoom, bottom dock,
collapse-to-edge; each waits for a real consumer.
- [ ] **Platform screenshot passes** — a Linux run (Omarchy / KDE / GNOME) and
the first Windows hardware build, side by side with macOS.
## Landed
### theme (`crates/theme`)
- [x] Theme engine — resolve overlay chain, OKLCH accent ramps, presets,
per-platform elevation stacks, `titlebar_height`, size table (`Sizable`)
- [x] Platform sources — macOS (NSColor), Windows 11 (UISettings), GNOME
(portal), KDE (kdeglobals), Omarchy (colors.toml), neutral fallback;
live watchers for each
- [x] Platform metric fidelity — stated control/input/menu-row/switch
metrics and the full radius ladder per platform, Linux root fonts
(GNOME gsettings `font-name`, KDE `kdeglobals font=`), per-source
border + focus chrome (`Theme::borders`), and a per-platform spacing
unit (`Theme::spacing`); overlay borders engage in dark mode, where
floating layers separate by border instead of shadow — dark elevation
shadows are dropped entirely, since they only muddied the dark scrim.
Components adopt the tokens one by one (see Next and Queue)
### icons (`crates/icons`)
- [x] `IconRole` + bundled Lucide fallback, Segoe Fluent codepoints (Windows),
freedesktop theme walker (Linux/Omarchy)
### core (`crates/core`)
- [x] Button platform chrome — every variant always paints the hairline
border, sized outside the stated control height (`BORDER_WIDTH`); where
the platform paints no border (`Theme::borders.buttons`, ghost) the
border takes the fill's color and disappears, so sizes match across
platforms; icon-bearing buttons pad with `dense_padding_x` instead of
`padding_x`
- [x] Button loading state — `.loading(true)` shows the spinner in place of
the icon and suppresses activation; Spinner gained a `.color` override
for accent-filled surfaces
- [x] Input platform chrome — the field always paints the hairline border,
sized outside the stated field height; where the platform paints no
border (`Theme::borders.fields`) it takes the field's fill; focus
recolors the border on Windows / KDE and paints the accent ring on
macOS / GNOME via `Theme::borders.focus_ring`; the shared `focus_ring`
band paints at half ink (every focusable control picks it up)
- [x] Input prefix / suffix — elements docked inside the field's edges,
typically small ghost buttons; a docked click activates the control
without reaching the field's caret handler, and the text region shrinks
to make room
- [x] Select platform chrome — the trigger takes the input treatment: the
hairline border always painted, sized outside the stated field height
and taking the fill's color where the platform paints none; open
recolors the border on Windows / KDE and paints the accent ring on
macOS / GNOME, so the trigger matches a focused field; the menu
popup's border sits behind `Theme::borders.overlays`, disappearing
into the surface where the platform paints none
- [x] Menu platform chrome — the popup border behind `Theme::borders.overlays`
(and dark mode); the panel padding and separator margins come from
`Theme::spacing`, and every action row renders at the stated
`menu_item_height` with content centered, so the stated metric is the
whole row; rows carry debug selectors for headless geometry tests
- [x] Popover platform chrome — the panel border behind
`Theme::borders.overlays` (and dark mode); the anchor gap is the
spacing unit and rides `anchored().offset`, not a margin, so the
window-edge clamp stays intact; the panel carries a debug selector
- [x] Dialog platform chrome — the panel border behind
`Theme::borders.overlays` (and dark mode), taking the surface color
where the platform paints none
- [x] Toast platform chrome — the pill border behind
`Theme::borders.overlays` (and dark mode), taking the surface color
where the platform paints none; the pill rides the popover elevation,
so dark mode's no-shadow rule applies to it too
- [x] Tooltip platform chrome — the panel border behind
`Theme::borders.overlays` (and dark mode), taking the surface color
where the platform paints none, and riding the popover elevation for
the light-mode shadow; anchored tooltips hang below the
hovered parent (`Tooltip::anchored(text, id)`) so they never cover it —
the element records its painted bounds with `record_anchor_bounds`
(`Button` does), the panel hangs below that with the spacing gap, and
it flips above the parent when it would overflow the window bottom
(the panel records its own height after the first frame); unanchored
tooltips fall back to the cursor-offset wrapper
- [x] Alert platform chrome — the banner border behind
`Theme::borders.overlays` (and dark mode), taking the surface color
where the platform paints none; it rides the popover elevation, so
dark mode's no-shadow rule applies to it too
- [x] Button, Checkbox, Switch, Radio + RadioGroup, Toggle, Link, Slider,
Progress, Avatar (image + seeded pixel-art fallback)
- [x] Spinner — painted ring + rotating-icon variant, indeterminate and
determinate; replaces `Tab::busy`'s placeholder
- [x] Input — single-line, password with reveal, multiline, undo/redo, actions
+ key context, caret blink
- [x] ScrollArea, Popover, Menu, Tooltip, Dialog / AlertDialog, Toast,
Alert + alerts stack
- [x] Select, Segmented, ContextMenu, EmptyState, Badge
- [x] Field — label / description / error around any control, block and
settings-row variants
- [x] Status dot — colored state bead, Badge's variant vocabulary, optional
screen-reader label
- [x] Combobox — type-to-filter picker with a caller-owned matcher, create /
keep / revert blur modes
- [x] Command palette — filtered actions; the matcher stays caller-owned
- [x] Scrollbar — overlay thumbs for gpui's `list` and `uniform_list`,
platform autohide with a `visibility` override
- [x] Clipboard button — copies a value, confirms with a brief check mark
that reverts itself
- [x] Separator — horizontal and vertical hairline rules; menu separators
stay menu-scoped
### data (`crates/data`)
- [x] List, Tree, Tabs (underline default + signed pill), Sidebar (scrolls
internally)
### editor (`crates/editor`)
- [x] Code view — tree-sitter highlighted, virtualized rows with a gutter
and the overlay scrollbar; per-language grammar features, roles map to
the theme's semantic palette at render
- [x] Code view interactions — active line, text selection with copy,
incremental line re-highlight
- [x] Diff view — unified rows via `similar`, highlighted with the code
view's palette; change washes from the ramps, `scroll_to_first_change`
- [x] Markdown view — `pulldown-cmark` blocks rendered as formatted text:
headings, emphasis runs, ordered/task lists, quotes, fenced code
highlighted with the code view's palette, tables, clickable links;
virtualized variable-height rows over gpui's `list`
### layout (`crates/layout`)
- [x] ResizeHandle
- [x] Shell — left/right sidebar regions + center, application-owned
`LayoutState`
- [x] Window frame — client-side decorations under `Decorations::Client`
- [x] Dock — pane tree, panel registry, tab context menus
- [x] Drag-to-split — `PanelDrag` payload, edge + center drop zones
- [x] Titlebar + window controls — app-owned window dragging, per-platform
buttons, `Theme::titlebar_height`
- [x] Sidebar auto-open — `PanelDescriptor::right_sidebar` + `DockSidebar`
- [x] Resizable group — stacked panes with drag dividers outside the dock,
per-pane floors, double-click reset, keyboard steps
### gallery (`examples/gallery`)
- [x] Component browser — the shell with the catalog in its sidebar, every
element a dock panel