fix(gui): address review — stale smoke case, tooltip trigger overlap, collapse contract docs

- The real-browser collapse smoke tracked the old chrome: visible HARNESS
  text (the wordmark svg is aria-hidden now), an 'Expand sidebar' label
  (renamed 'Open sidebar'), a 300px settle (default is 280), and an
  immediate focus assert (rail search defers focus past the slide). The
  case now tracks the brand span, polls the deferred focus, and uses the
  current labels and width.
- Tooltip treated hover and focus as one trigger: leaving with the mouse
  dropped the bubble of a still-focused anchor (and vice versa). The two
  triggers are tracked independently; the bubble hides only after both
  clear. Spec pins both orders.
- The ui-sidebar README and the bilingual collapse note still described
  the retired geometry morph; both now state the slide + crossfade
  contract, the fixed-width (never-conceding) sidebar, and the rail's
  whale-mark/tooltip chrome.
This commit is contained in:
imccyu
2026-07-24 01:30:01 +08:00
parent 9dbe11d647
commit 75d37654cb
8 changed files with 53 additions and 23 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# @deepseek-ai/dsh-client-ui-layout
Shell plugin: three-column AppFrame (drag handles, concession chain) + ctx.layout viewing-state service (nav, panel widths, persist); defines the sidebar/conversation/details/conversation.empty slots. A closed sidebar retains a 56px control rail while details closes to zero width; collapse/expand animates the grid tracks on the deepsuite sider curve. Contract: api-contracts v3 §5.
Shell plugin: three-column AppFrame (drag handles, concession chain) + ctx.layout viewing-state service (nav, panel widths, persist); defines the sidebar/conversation/details/conversation.empty slots. The sidebar is fixed-width (it never concedes to viewport pressure — only details shrinks, then auto-closes); a closed sidebar retains a 56px control rail while details closes to zero width; collapse/expand animates the grid tracks on the deepsuite sider curve. Contract: api-contracts v3 §5.
Slot declarations use the composed-props entry form (`owner` share, no full `props`): the exported OwnerShare contracts are `SidebarOwnerProps` / `ConvOwnerProps` / `DetailsOwnerProps` / `EmptyOwnerProps` — registrants reference them via `OwnerOf<'sidebar' | ...>` and compose their own injected share locally. No entry declares `children` (declaring it requires the registered component to carry the slots face — reserved for future business slots): delegation authority is the component-side whitelist, i.e. AppFrame's `ScopedSlots<FrameSlotKey>` face over sidebar/conversation/details/conversation.empty. Since the root-slot rework the frame itself registers into 'root' and renders those child slots at its own render sites; the shell only renders 'root'.