Per m's v1 picks (2026-05-29):
- Q6 (icon picker): yes, with curated keys + SVG registry.
- Q8 (show_count badge): yes, opt-in checkbox + sidebar badge.
Icon registry (web/icons.go):
- 7 curated keys: folder (default), clock, star, tag, inbox, box,
file-text. Each maps to a Feather-style 24x24 SVG matching the rest
of the projax sidebar aesthetic. Returns template.HTML so layout.tmpl
emits markup verbatim. Unknown / nil keys fall back to folder.
- RenderViewIcon(*string) is template-callable; IconRegistryKeys()
feeds the editor's <select>.
- Funcs map in web/server.go gains a "renderIcon" entry.
show_count badge (web/server.go + web/templates/layout.tmpl):
- render() now computes per-saved-view counts when ANY view in the
list has ShowCount=true. One ListAll per render, shared across all
show-count views; for each opted-in view the persisted filter_json
is decoded into a TreeFilter and matched against every item.
- Counts pass to the template as UserViewCounts (slug → count). The
template renders {{index $counts $slug}} inside a nav-badge span
next to the view's name.
Template updates:
- layout.tmpl: replaces the diamond-glyph placeholder with
{{renderIcon .Icon}}; show_count views emit a .nav-badge next to
their name.
- view_editor.tmpl: icon <select> now sourced from IconKeys data
(the editor handler passes IconRegistryKeys()).
CSS additions:
- nav-badge: muted-color, surface-background, pill-shaped, pushed to
the right via margin-left:auto so the badge aligns with the row's
end regardless of name length.
- nav-item-user-view.active .nav-badge: switches to accent border +
color so the active row's badge stays legible.
Tests:
- TestSidebarShowCountBadge — seeds show_count=true view, asserts
.nav-badge markup in the sidebar.
- TestSidebarIconRenders — seeds icon=star view, asserts the
distinctive star polygon path lands in the sidebar SVG.
Drag-reorder UI stays parked (m's Q7=(b) v2). sort_order column is
server-assigned MAX+1 on create; the column was wired in slice A and
ReorderViews is ready for slice G's followup.