From b19da25d32b01d2c32c66d8481be56cc993b5922 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 8 Sep 2026 09:56:07 -0400 Subject: [PATCH] =?UTF-8?q?docs(plans):=20instance=20picker=20design=20?= =?UTF-8?q?=E2=80=94=20keyboard=20activation=20via=20TreeView=20selection,?= =?UTF-8?q?=20tab-out=20does=20not=20close,=20explicit=20handlers,=20loadi?= =?UTF-8?q?ng=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29 --- docs/plans/2026-09-08-instance-picker-design.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/plans/2026-09-08-instance-picker-design.md b/docs/plans/2026-09-08-instance-picker-design.md index e2faf4b5..dd087bcb 100644 --- a/docs/plans/2026-09-08-instance-picker-design.md +++ b/docs/plans/2026-09-08-instance-picker-design.md @@ -28,7 +28,7 @@ Alternatives rejected: **Search.** The field text is a case-insensitive `Contains` on `UniqueName`. With a non-empty filter the forest is rebuilt to the matching instances plus their ancestor areas, and the tree is force-expanded (`ExpandAll` after the rebuild, as the template picker does). Clearing the text restores the full forest and collapses everything (`CollapseAll`). -**Keyboard.** `Enter` selects the first visible matching instance (document order); `ArrowDown` from the field moves focus into the tree (its roving-tabindex arrow navigation and `Enter`/`Space` activation already exist); `Escape` closes and restores the field text to the current selection. Tabbing out closes as well. +**Keyboard.** `Enter` selects the first visible matching instance (document order); `ArrowDown` from the field moves focus into the tree (its roving-tabindex arrow navigation; the picker passes `Selectable` + `SelectedKeyChanged` so `Enter`/`Space` on an instance row selects it and on an area row toggles it — the same handler the mouse uses); `Escape` closes and restores the field text to the current selection. Tabbing out does **not** close the panel (a correct focus-out needs `relatedTarget`, i.e. JS interop, which this design avoids); the next click anywhere lands on the backdrop and closes it, which is acceptable. **Outside click.** A transparent fixed backdrop (the same `tv-ctx-overlay` pattern `TreeView` uses for its context menu) sits under the panel while open and closes it on click. No JS interop. @@ -50,8 +50,8 @@ A parent that changes `Areas`/`Instances` (site change) resets the field text an ## 3. Page wiring -- **Flow Debugger** (`FlowDebugger.razor` / `.razor.cs`): `LoadInstancesAsync` also loads `_areas` via `ITemplateEngineRepository.GetAreasBySiteIdAsync(siteId)`; the `` becomes the picker with `ItemLabel` = `UniqueName (State)`, `Disabled="@_connected"`, `DataTestPrefix="debug-instance"`. `OnInstanceSelectionChanged`, `?instanceId=` and localStorage reconnect unchanged. +- **Flow Debugger** (`FlowDebugger.razor` / `.razor.cs`): `LoadInstancesAsync` also loads `_areas` via `ITemplateEngineRepository.GetAreasBySiteIdAsync(siteId)`; the `` becomes the picker with `ItemLabel` = `UniqueName (State)`, `Disabled="@(_connected || _instancesLoading)"`, `DataTestPrefix="debug-instance"`, `SelectedInstanceIdChanged="OnInstancePicked"`. `OnInstanceSelectionChanged`, `?instanceId=` and localStorage reconnect unchanged. ## 4. Security