Repository navigation
Conversation
Allow hosts to drive NMRium highlight state through optional `highlight` / `onHighlightChange` props so iframe embeddings no longer need to reach into the private HighlightProvider module.
This was referenced Oct 4, 2026
A dispatch that changed identity with onChange re-ran every useHighlight unmount cleanup, clearing highlights and looping when hosts passed an inline callback. Read the latest onChange from a ref synced in a layout effect instead of writing refs during render, and memoize the controlled value so consumers do not re-render on every provider render.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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
highlight/onHighlightChangeprops on<NMRium>, so embedding hosts can drive highlighting (peaks, ranges, signals) without reaching into the privateHighlightProvidermodule.HighlightProviderkeeps a single source of truth: in controlled mode it renders fromvalue, runs the existing reducer, and reports public state throughonChange. Uncontrolled behaviour is unchanged whenhighlightis omitted. A controlled host must also handleonHighlightChange, otherwise NMRium's own hover/click highlights are not rendered (documented on the prop).dispatchkeeps a stable identity. EveryuseHighlightconsumer runs an unmount effect keyed on it, so a per-render identity would clear highlights and loop when a host passes an inline callback. The latest state,onChangeand mode are read from refs synced in a layout effect (not written during render), and the controlled value is memoized so consumers do not re-render on every provider render.NMRiumHighlightState,HighlightEventSource, andemptyHighlightStatefrom the package entry.TestHighlight. The repo has no React component test setup, so provider behaviour is covered by the demo and by the wrapper's Playwright tests (see below).Closes #4401
Related: nmrium-react-wrapper#315 (reverted in #316), nmrium-react-wrapper#317 (consumer of this API)
Note for hosts
Hosts that set a highlight from outside should use
sourceData: { type: 'UNKNOWN' }. The Delete/Backspace handler deletes the highlightedPEAK/SIGNAL_1D/RANGEsource, so claiming one of those would let a keypress delete user data.Release question
The wrapper is still on React 18 /
nmrium@^2.7. The same change is backported onvcnainala:feat/controllable-highlight-v2.8. Would you prefer a 2.x release with the backport, or should the wrapper move to React 19 and NMRium 3?Performance note
In controlled mode every hover fires
onHighlightChangeand re-renders the host. For typical embedding (highlight on click, not continuous hover mirroring) this is fine. If a host mirrors hover at scale, the controlled value can be kept in a small store read only byHighlightProviderso the outer provider tree does not re-render.Test plan
npx vitest run src/component/highlight(5 tests)npm run check-types, eslint, prettier on the changed files