Skip to content

Custom Reference Integration

Many deployments need to display a local catalog of references, highlight citations as authors select them, and sync back to an external service. The demo already implements this pattern—this guide distills the moving parts so you can recreate it in your own UI.

Data Flow

  1. Host app owns the reference list (from your API, CSL store, etc.).
  2. Editor emits events (editor-change, editor-selection-change) whenever the document or selection changes.
  3. Sidebar components (like the provided ReferencePanel) render references, highlight matches, and dispatch drag/drop or click events back to the editor.

Step-by-Step

1. Render Your Reference Panel

import { ReferencePanel } from '@sciflow/editor-start/demo';

const panel = new ReferencePanel(document.querySelector('#references-list'));
panel.render(referenceData);

You can copy the source from packages/editor/start/demo/js/references-panel.js if you prefer to customize the markup.

2. Listen for Document Updates

editor.addEventListener('editor-change', (event) => {
  const { doc } = event.detail;
  latestDoc = doc;
  panel.render(resolveReferences(doc));
});

resolveReferences is your hook to fetch or derive metadata (CSL JSON, raw citations, etc.).

3. Highlight References Based on Selection

editor.addEventListener('editor-selection-change', (event) => {
  const selection = event.detail;
  const referencedIds = collectCitationIds(editor.editorView, selection);
  panel.highlight(referencedIds);
});

collectCitationIds can reuse the logic from the demo (view.state.doc.nodesBetween(from, to, …)), keeping everything in sync without extra DOM queries.

4. Support Drag-and-Drop Insertion

The demo writes a custom payload when the user drags a reference item:

transfer.setData('application/x-sciflow-reference', 'sidebar');
transfer.setData('application/json', JSON.stringify({
  type: 'reference',
  id: reference.id,
  text: reference.rawCitation,
}));

The citation feature automatically consumes this payload via the drop handler in packages/editor/core/src/lib/features/citation/index.ts, calling runInsertCitation. Reuse the same MIME types so no extra work is required in the editor.

Fast verification

Enable the outline/reference sidebars in the demo (packages/editor/start/demo/index.html) and drop a reference into the editor. If it works there, it will work in your application as long as you copy the same data payload and events.

Optional: Programmatic Insertion

If you prefer buttons or menus to drag-and-drop:

const insertCitation = editor.commands?.commands?.insertCitation;
if (insertCitation) {
  insertCitation({
    items: [{ id: 'reference-1' }],
    text: '[1]',
    style: 'apa',
  });
}

Async lookups

Resolve metadata (authors, titles) before calling the command. The editor only stores what you send in text plus whatever you include in the node attributes.