feat(ui): double-click a step to start the picture there; double-click a screen for what happens on it

- StepsView / StepNode: a double-click on any step with a symbol re-anchors the Steps picture on it (the panel's Start here) — an endpoint or another screen drawn as a boundary opens as its own chapter in one gesture; detected in the view's click path (two clicks on one box within 400 ms) since the flow canvas does not reliably pass dblclick on, with ondblclick kept
- ScreensView / ScreenNode: a double-click on a screen (or an origin) opens its Steps picture
- a boundary's panel says it is not entered instead of "nothing leaves this step"; tooltips and the boundary notes mention the gesture
- spec §3.13, CHANGELOG

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REFyW9hmNrxhwN5wxRoAkC
This commit is contained in:
Colby McHenry
2026-08-29 11:09:09 -05:00
co-authored by Claude Fable 5
parent dff4e50e98
commit 435a7fd37a
6 changed files with 64 additions and 9 deletions
+5 -2
View File
@@ -25,6 +25,8 @@
selected: boolean;
dimmed: boolean;
onSelect: (id: string) => void;
/** Open what happens from this screen (the Steps picture) — a double-click. */
onOpen?: (id: string) => void;
}
);
const layout = $derived(node.layout);
@@ -54,12 +56,13 @@
class:unreached={info.unreached}
style={`width:${layout.width}px;height:${layout.height}px`}
onclick={() => node.onSelect(info.id)}
ondblclick={() => node.onOpen?.(info.id)}
aria-pressed={node.selected}
title={info.origin
title={(info.origin
? `${info.label} navigates, but no screen reaches it within the walk. In ${info.sub}.`
: `${info.label} rendered by ${info.sub}${info.entry ? '. The entry screen.' : ''}${
info.unreached ? '. No transition in the graph reaches it from the entry.' : ''
}`}
}`) + (node.onOpen ? ' Double-click for what happens here.' : '')}
>
<span class="name">{#if info.entry}<span class="mark" aria-hidden="true">●</span>{/if}{info.label}</span>
<span class="sub">{info.sub}</span>