This repository was archived by the owner on Oct 4, 2026. It is now read-only.
Repository navigation
feat(ui): image map cluster selection mode - #42
Merged
Merged
Conversation
lstein
marked this pull request as draft
August 2, 2026 22:24
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 2, 2026 22:38
aa21512 to
32045e9
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 2, 2026 22:38
3990b04 to
5784c6a
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 3, 2026 01:38
32045e9 to
bf26409
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
2 times, most recently
from
August 3, 2026 02:26
1966859 to
238768f
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
2 times, most recently
from
August 3, 2026 18:20
0015963 to
32b12f4
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 3, 2026 18:21
238768f to
0fca217
Compare
lstein
marked this pull request as ready for review
August 3, 2026 18:28
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 4, 2026 01:43
0fca217 to
f204e11
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 4, 2026 01:43
32b12f4 to
2d68eb8
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 4, 2026 05:37
f204e11 to
d0c4e2e
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
2 times, most recently
from
August 4, 2026 14:58
312156e to
8a2e9a2
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 4, 2026 14:58
d0c4e2e to
6c2d8df
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 4, 2026 22:32
8a2e9a2 to
c47f5ae
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 4, 2026 22:32
6c2d8df to
a423504
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 5, 2026 00:31
c47f5ae to
e239eca
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
2 times, most recently
from
August 5, 2026 00:38
3374c16 to
ce5c18d
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
2 times, most recently
from
August 5, 2026 01:18
78b62a5 to
a43f464
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
2 times, most recently
from
August 5, 2026 01:21
69fa638 to
f717ca1
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 5, 2026 01:21
a43f464 to
311ecaa
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 7, 2026 20:41
311ecaa to
4bf36a2
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
2 times, most recently
from
August 9, 2026 18:27
085ded4 to
7361fbb
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
2 times, most recently
from
August 13, 2026 03:21
29de7d4 to
7646455
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 13, 2026 03:21
7361fbb to
a9713ff
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 13, 2026 03:26
7646455 to
ef0eb5c
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 13, 2026 03:26
a9713ff to
1e8a8f0
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 13, 2026 04:37
ef0eb5c to
353ef22
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 13, 2026 04:37
1e8a8f0 to
46c3278
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 13, 2026 23:17
353ef22 to
6ad08aa
Compare
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 13, 2026 23:17
46c3278 to
4d13895
Compare
lstein
force-pushed
the
feat/image-map-08-live-theme
branch
from
August 15, 2026 21:16
79f59b2 to
cc3029f
Compare
Adds PhotoMapAI's cluster-click behavior as an opt-in mode:
- A header toggle (persisted in the widget's values) switches map clicks
between selecting one image and selecting the clicked point's whole
DBSCAN cluster.
- Cluster clicks multi-select the cluster in the gallery via
setGalleryMultiSelection, ordered by distance from the clicked point
(proximity ordering) and capped at 5000 members; the clicked image
becomes the primary selection, so Preview follows it. Noise points fall
back to single selection.
- The gallery's multi-selection renders on the map as a "Highlighted
Points" trace — larger, white-outlined, between the base points and the
gold current-image marker — regardless of where the selection was made.
Amended during the rebase onto the re-architected webv2:
- The header toggle ships through the widget implementation's
`headerActions` slot (the old single-manifest index.ts is gone) and
patches its persisted value via `useWorkbenchCommands().widgets
.patchValues('image-map', ...)` instead of dispatching
`patchWidgetValues`; IconButton/Tooltip come from `@platform/ui` and
`WidgetViewProps` from `@workbench/widgetContracts`.
- Cluster clicks now go through `useWorkbenchCommands().gallery
.setItemMultiSelection(itemKeys, primaryItem)`: the ordered names are
wrapped as kind-tagged keys with `toGalleryItemKey({ kind: 'image',
name })` (map points are always images) and the clicked image is
hydrated through `galleryImages.resolveMany` +
`legacyGeneratedImageToGalleryItem`, sharing the single-select path's
monotonic click sequence. Single select (the plain-click clear) is
unchanged: `gallery.selectItem` already collapses the multi-selection.
- The highlight overlay reads the persisted selection with
`getPersistedSelectedGalleryItemKeys` and parses the kind-tagged keys
back to bare image names (`parseGalleryItemKey`, images only) — on this
architecture `selectedImageNames` stores GalleryItemKeys, not names.
- Performance baselines recaptured (build + browser, browser verified
passing twice): the image-map implementation chunk loads at editor boot
via the singleton host, so the header toggle and cluster wiring grow
editor owned bytes by 65 (launchpad owned -3 minifier drift).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The base PRs merged, so this branch was replayed onto main and its stale baseline-regeneration commits dropped. These numbers come from a fresh build.
lstein
force-pushed
the
feat/image-map-09-cluster-select
branch
from
August 16, 2026 19:29
5fce8c1 to
76adc9a
Compare
…trol Three findings from an adversarial review of cluster selection: - `selectCluster` now calls `commands.gallery.selectBoard` before dispatching, as `selectImage` already did. The map spans every accessible board while the selection commands stamp `selectedImageQuery` from whatever board the gallery is currently showing, so a cluster picked from another board left that query describing a list none of its images were in — the grid never showed the selection and Preview's next/prev went dead. That is the regression the sibling call's comment exists to prevent; the cluster path had simply not inherited it. - The header control is `ToggleIconButton` from @platform/ui rather than a hand-rolled IconButton. The shared component is this exact control, and its filled-when-on convention is what makes "on" legible; the local copy rendered subtle-gray where every other toggle in the app renders solid accent. - `selectCluster` has tests: board-before-selection ordering, the name to image-kinded-key mapping with its clicked-point anchor, the unresolvable primary, and the sequence guard shared with `selectImage` — the last being the behaviour the hook's doc comment claims but nothing checked. The duplicated `Boolean(values.clickSelectsCluster)` reads move behind one accessor, which costs the editor bundle one small module; the baseline records it. Selection semantics (unhydrated cluster keys, and the size of a persisted selection) are deliberately left alone.
…ster-select Only the two generated performance baselines conflicted; main's webv2 changes (232 files, including the new queue-status widget) do not touch this branch's code. Both baselines are regenerated from a fresh build of the merged tree rather than resolved by hand.
lstein
enabled auto-merge
August 17, 2026 01:07
lstein
added a commit
that referenced
this pull request
Aug 18, 2026
…'s cursor Both failures were the same root cause, and neither was a product bug: these suites drive real browser input, and the cursor keeps whatever position the last test left it in. ConditioningRebalanceBars — "reports the tap under the pointer" blocked #42's CI. Instrumenting the failure showed the intended index 7 arriving and then a spurious 6 after it (calls [1, 7, 7, 6]), because the real cursor was resting on the track and emitting its own pointer events at its own location, which the component reported. The same run showed the track's `left` at -393 rather than 0: an earlier test had scrolled the document sideways, moving which bar sits under a stationary cursor. Teardown now parks the pointer and resets the scroll offset. FeatureHint — the harness comments that "the mouse starts at the viewport origin" and insets the trigger by 120px accordingly. That holds only for the first test: once one has hovered the trigger, the next render mounts a fresh trigger underneath the pointer and the card opens before the test asks it to. It surfaced as a strict-mode violation, `CLIP skip` matching the trigger and the already-open card's heading and paragraph. Teardown now returns the pointer to the origin, restoring the assumption the harness documents. Measured over ten consecutive full browser runs: neither test failed once, where before each failed roughly one run in three. Two earlier theories are not in this commit because instrumentation refuted them: the track's width was stable (960px in both the measured and live rects), so waiting for layout to settle fixed nothing, and moving the real cursor with `userEvent.hover(document.body)` made things worse because body's centre can sit over the component under test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 9 of the Image Map stack — PhotoMapAI's cluster-click behavior:
setGalleryMultiSelectionwith the members ordered by distance from the click (proximity ordering, capped at 5000); the clicked image becomes primary so Preview follows. Noise points fall back to single selection.hoverinfo: 'skip'so it never shadows the base points.Known accepted gap (also noted in the floating-windows PR): floating windows render widgets without header/footer chrome, so the mode toggle is only reachable while docked.
Testing
Cluster collection (proximity order, noise/unknown handling, cap keeps nearest incl. the clicked point), highlight trace builder (multi-only, outline), full suite + lint + build green at the stack top.
🤖 Generated with Claude Code