Align every sidebar list (tags in both modes, views, settings, memo
detail) on shared slot and count-rail primitives so icons, labels, and
digits sit on the same vertical lines. Tree branches show their # mark
at rest and swap in the chevron on hover or keyboard focus; views rows
gain glyphs and move onto the same grammar, with ViewsSection extracted
to its own module.
- Generate UUID v4 values in the client with validated custom UID
support.\n- Show immutable UIDs where Space titles need
disambiguation.\n- Standardize Space surfaces on the Lucide Astroid
icon.
Preserve the underlying database error across all drivers and cover the wrapping behavior with focused tests. Make creation tests wait for the asynchronous completion callbacks to avoid timing-dependent assertions.
- Treat All as an unfiltered Space collection while preserving exact Space filters.
- Keep global resources outside remembered Space context and preserve memo navigation origins.
- Surface Space placement consistently across memo, attachment, and visibility UI.
Give the home/attachments/inbox navigator one shared pill anatomy so the
active label expands and collapses as a single smooth motion: constant
px-[7px] padding with the label in a grid column animating 0fr to 1fr,
tooltips kept mounted via Base UI's disabled prop, and the scope control
as one always-mounted uncontrolled DropdownMenu that vetoes the menu and
navigates when off the scope routes. The unread badge scales in and out,
and the scope chevron rotates while its menu is open.
The tooltip anchors to a wrapper span because a disabled tooltip stamps
data-trigger-disabled on its trigger element, which Base UI's shared
floating logic would read as the menu trigger being disabled.
Tag completion filtered candidates with a full-path prefix test, so a
nested tag was only reachable by retyping its whole ancestry: `#Mem`
offered nothing for `software/hosted/Memos`.
Rank candidates instead — full-path prefix, then path-segment start,
then any other position — and keep that order by opting out of
CodeMirror's own fuzzy filtering.
Fixes#6190
The rail had two navigation grammars for the same destinations: a
compact icon strip on recognized routes, and StaticNavigation — full
labeled rows — on everything else (/about, /403, /404, wildcard).
Crossing onto one of those pages rearranged the entire rail, and any
route nobody remembered to classify silently inherited the alternate
layout.
Make the frame invariant instead: header, global strip, contextual
content, footer — on every route. Pages without a specific sidebar
tenant now fall back to the default library content (the home
collection for signed-in users, explore for guests), following the
convention that error and utility pages render inside the persistent
shell rather than degrading it. The memo-detail route gets the same
fallback while the page has not yet published its descriptor, instead
of a blank scroll area.
Off the collection routes the library is display-plus-navigation, so
StatisticsView and TagsSection accept a navigationTarget: calendar and
tag clicks land on / or /explore with the filter in the query string,
which RootLayout's route-change effect would otherwise wipe.
StaticNavigation is deleted, About returns to living only in the user
menu (the showAbout prop is gone), and the guest strip now marks About
active on /about.
Calendar cells were `aspect-square w-full`, so cell height was a pure
function of rail width. Dragging the rail from 224px to its 400px max
took the calendar block from 231px to 382px — a 65% jump that pushed
Views and Tags out of view, left a 12px numeral floating in a 50px box,
and turned the selected day into a 50x50 slab against a rail whose every
other row is 30px.
Split the cell in two: the button spans its whole column and takes the
pointer, while a chip inside it carries the fill, the ring and the today
dot, and stops growing at `maxSize`. A chip is therefore
`min(column, 30px)` — narrow rails are untouched (224px still yields
25px cells, 170px of grid) and wider ones spend the surplus on hit area
instead of height, holding the grid at 200px from 258px up.
The today dot stops detaching as a side effect: it is positioned against
a chip that no longer grows, rather than against a cell floor that
drifted 19px below the numeral at full width.
remark-gfm passes checked as undefined for unchecked task items, so the
Base UI Checkbox mounted uncontrolled and permanently ignored the
checked=true arriving after "Check all tasks" rewrote the memo content.
Coerce the prop to a boolean so the checkbox is always controlled.
Also drop the `${updateTime}` suffixes from memo React keys and the
comment editor cache key: a protobuf-es Timestamp stringifies to
"[object Object]", so the suffix was a constant — the keys were
effectively name-only already, and now say so honestly.
Fixesusememos/memos#6143
- expose display settings from the Views header and refine layout controls
- add explicit tag list/tree navigation with accessible expansion behavior
- cover view persistence, menu behavior, and tag tree construction