Skip to content

Selection & Sync ​

Hatchlings provides a shared SelectionState class that synchronizes selection, caret position, and keyboard navigation across multiple views of the same sequence.

Overview ​

When PlasmidViewer and SequenceViewer display the same construct, you often want selection in one view to be reflected in the other. SelectionState is a Svelte 5 reactive class that manages this.

svelte
<script>
  import { PlasmidViewer, SequenceViewer, SelectionState } from '@molbiohive/hatchlings';

  const selection = new SelectionState(2686); // sequence length

  let plasmidData = { ... };
  let sequenceData = { ... };
</script>

<PlasmidViewer data={plasmidData} selectionState={selection} width={500} height={500} />
<SequenceViewer data={sequenceData} selectionState={selection} width={660} height={400} />

Click or drag in either view — the selection updates in both.

SelectionState API ​

Constructor ​

ts
const selection = new SelectionState(sequenceLength: number);

Reactive Properties ​

PropertyTypeDescription
caretPositionnumberCurrent cursor position (bp)
selectionStartnumber | nullStart of selection range
selectionEndnumber | nullEnd of selection range
isDraggingbooleanWhether a drag is in progress
selectedAnnotationIdsSet<string>IDs of selected features

Computed Properties ​

PropertyTypeDescription
range{ start, end } | nullCurrent selection range (handles circular wrapping)
hasSelectionbooleanWhether a range is selected
wrapsbooleanWhether selection wraps around origin (circular)
selectionLengthnumberLength of selection in bp

Methods ​

MethodDescription
setCaret(position)Move cursor without selecting
setSelection(start, end)Set explicit selection range
clearSelection()Clear all selection
selectAnnotation(id, multi?)Select a feature by ID
selectAll()Select the entire sequence
moveCaret(delta, extend?)Keyboard navigation (extend = shift-held)
startDrag(position)Begin drag selection
updateDragLinear(position)Update drag for linear topology
updateDragCircular(start, end)Update drag for circular topology
endDrag()Finish drag selection

Event Callbacks ​

Components emit selection events alongside the shared state:

EventPayloadDescription
onselect{ start, end }Region selected (drag completed)
onselectionchange{ start, end } | nullSelection changed (real-time during drag)
oncaretmovenumberCaret position changed
onpartclickPartFeature clicked
oncopysequencestringSequence copied to clipboard
svelte
<PlasmidViewer
  data={plasmidData}
  selectionState={selection}
  onselect={(sel) => console.log(`Selected ${sel.start}..${sel.end}`)}
  onpartclick={(part) => console.log(`Clicked ${part.name}`)}
/>

Circular Wrapping ​

For circular sequences, selection can wrap around the origin (position 0). When start > end, the selection spans from start to the end of the sequence and continues from 0 to end:

Sequence: 0 ──────────── 2686
Selection:     ████               ████
               end=500            start=2400

Wraps: true
Length: (2686 - 2400) + 500 = 786 bp

SelectionState handles this automatically — both PlasmidViewer (arc selection) and SequenceViewer (highlighted rows) display wrapping correctly.

Components with Selection Support ​

ComponentselectionState propSelection behavior
PlasmidVieweryesArc selection on circular map, range on linear
SequenceVieweryesRow-based text selection with shift+click
TraceViewernoInternal scrollbar-based navigation
AlignmentViewernoColumn highlight on hover