Search the Qalma docs

Type at least two characters to get started.

Docs

Selection

SelectionPlugin exposes the current editor selection as a read-only query and emits a DOM event whenever that selection may have changed. It does not render a contextual toolbar, bubble menu, tooltip, or overlay.

import { SelectionPlugin, TextFormattingKit, createQalmaEditor } from '@qalma/editor';

const editor = createQalmaEditor({
  content: '<p>Select text to show your app toolbar.</p>',
  plugins: [SelectionPlugin, ...TextFormattingKit],
});

Public API

Contract Description
query<SelectionState>('selection') Returns { empty, from, to, text } for the current editor selection.
qalma-selection-update Bubbling DOM event emitted from the editor view when selection state moves.

The event detail is the same SelectionState shape returned by the query.

Contextual Toolbar Pattern

Keep the floating UI in your application. The plugin gives you document state; your app can use the browser DOM selection, CDK overlay, Spartan popover, or another overlay primitive for placement.

afterNextRender(() => {
  const surface = this.contentHost().nativeElement;
  const refresh = () => this.refreshSelectionToolbar();

  surface.addEventListener('qalma-selection-update', refresh);

  this.destroyRef.onDestroy(() => {
    surface.removeEventListener('qalma-selection-update', refresh);
  });
});
refreshSelectionToolbar(): void {
  const selection = this.editor.query<SelectionState>('selection');

  if (!selection || selection.empty || selection.text.trim().length === 0) {
    this.toolbarPlacement.set(null);
    return;
  }

  const range = window.getSelection()?.getRangeAt(0);
  const rect = range?.getBoundingClientRect();

  this.toolbarPlacement.set(
    rect ? { left: rect.left + rect.width / 2, top: rect.top - 8 } : null,
  );
}
@if (toolbarPlacement(); as placement) {
  <qalma-toolbar
    label="Selection formatting"
    class="contextual-toolbar"
    [style.left.px]="placement.left"
    [style.top.px]="placement.top"
  >
    <button type="button" qalmaCommand="toggleBold">Bold</button>
    <button type="button" qalmaCommand="toggleItalic">Italic</button>
    <button type="button" qalmaCommand="toggleInlineCode">Code</button>
  </qalma-toolbar>
}

The docs playground uses this pattern with a Spartan/helm-style toolbar layered above selected text. The editor library still owns only the headless query and event contract.