Skip to content

feat: add highlightPeak action-request for host-driven peak highlighting - #315

Merged
vcnainala merged 2 commits into
developmentfrom
feat/highlight-peak-action-request
Oct 4, 2026
Merged

vcnainala merged 2 commits into
developmentfrom
feat/highlight-peak-action-request

Conversation

@vcnainala

Copy link
Copy Markdown
Member

Summary

  • Add highlightPeak and clearHighlight actions on the existing nmr-wrapper:action-request channel so hosts can highlight a peak by id or by nucleus + ppm.
  • Bridge into NMRium’s private highlight context via a Vite resolveId redirect so highlighting works without reloading spectrum state.
  • Cover the flow with a demo button and a Playwright e2e test.

Test plan

  • Load the demo (/#/demo), click Test load from json, then Test highlight peak — one peak marker should thicken; Clear highlight should clear it.
  • From an embedding host, postMessage { type: 'nmr-wrapper:action-request', data: { type: 'highlightPeak', params: { nucleus: '13C', ppm: 77.95 } } } and confirm the matching peak highlights.
  • Send clearHighlight and confirm the sticky highlight is removed.
  • Send an invalid request (missing id / nucleus+ppm) and confirm nmr-wrapper:error is emitted without breaking later actions.
  • npm run check-types
  • npx playwright test --project chromium -g "should highlight a peak"

Allow embedding hosts to highlight a peak by id or nucleus+ppm over the
existing nmr-wrapper:action-request channel, without reloading spectrum state.
Avoid import() return types, fix import order, and stop updating refs during render.
@vcnainala
vcnainala merged commit 2193ddf into development Oct 4, 2026
4 checks passed
@vcnainala
vcnainala deleted the feat/highlight-peak-action-request branch October 4, 2026 08:56
@vcnainala

Copy link
Copy Markdown
Member Author

Hi Hamed, thanks for looking at this, and agreed: I don't want this to rely on hacks either.

Why it's needed: In qm-nmr-calc, the results page shows the molecule (2D and 3D) and the list of calculated shifts in the host page, next to the NMRium iframe. When a user clicks an atom or a shift row, the matching calculated peak should be highlighted in NMRium. NMRium's highlight context works well when the trigger happens inside NMRium (hover a peak or an atom in its own structure panel). Here the trigger is outside, in a different document behind a cross-origin iframe, so postMessage is the only way to reach it. The same need applies to any host that has its own structure or assignment table next to the spectrum. A second issue: NMRium regenerates peak ids on load, so the host can't target a peak by the id it sent — matching by nucleus + ppm is needed as a fallback.

On the implementation: You're right that we should not hack around the private highlight context. The bridge didn't keep a separate copy of the state (it dispatched into NMRium's own provider), but it did that by redirecting a private NMRium module through Vite and using internal reducer actions — exactly the coupling we should avoid. I also merged this before your review, which I shouldn't have done. I'm reverting it on development so nothing depends on it in the meantime.

Proposal: Make highlight state controllable in NMRium itself, along these lines:

  • optional highlight prop on <NMRium> (e.g. { highlighted, highlightedPermanently, sourceData }) together with an onHighlightChange callback, following the usual controlled/uncontrolled pattern so existing behaviour stays the same when the prop isn't passed;
  • the wrapper then maps nmr-wrapper:action-request (highlightPeak / clearHighlight) to that public API, with no module aliasing.

I'll open an issue on cheminfo/nmrium with the proposed API, and re-implement the wrapper actions once that lands. Happy to adjust the shape once you and the team agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant