An Example React Editor Widget

In this guide, we re-recreate the example color selector widget from the previous tutorial as a React component. The widget adds a section to the editor with three buttons: red, green and blue. Clicking one of the buttons will set an annotation body with the color value, and body purpose of highlighting.

Editor popup

JSX code for the plugin is below. A full project (including a webpack build configuration) is available on GitHub. Here’s what the code does, step by step:

  1. To get the annotation’s current color value, we grab the first body with purpose: 'highlighting'.
  2. The setHighlightBody function is called when the user selects a color. It uses props.onUpsertBody: this callback either replaces the the annotation’s current highlighting body (=update), or adds a new highlighting body, in case the annotation doesn’t have one already (=insert).
  3. The remainder of the code renders the user interface elements: 3 identical buttons in different colors. Clicking a button triggers setHighlightBody.
import React from 'preact/compat';

const HelloWorldWidget = props => {
  // We'll be using 'highlighting' as body purpose for 
  // this type of widget
  const currentHighlight = props.annotation ? 
    props.annotation.bodies.find(b => b.purpose === 'highlighting') : null;

  // This function handles body updates as the user presses buttons
  const setHighlightBody = value => () => {
    props.onUpsertBody(currentHighlight, { value, purpose: 'highlighting' });
  }

  return (
    <div className="helloworld-widget">
      { [ 'red', 'green', 'blue' ].map(color => 
        <button 
          key={color}
          className={currentHighlight?.value === color ? 'selected' : null}
          style={{ backgroundColor: color }}
          onClick={setHighlightBody(color)} />
      )}
    </div>
  )

}

export default HelloWorldWidget;

Using the Plugin

When you include the plugin with a <script> tag, it will make itself available through a global recogito.HelloWorldWidget variable. Add it to the widgets list in the config object when you initialize Annotorious.

<!DOCTYPE html>
<html>
  <head>
    <!-- Load Annotorious first -->
    <link href="/annotorious.min.css" rel="stylesheet">
    <script src="/annotorious.min.js"></script>

    <!-- Load plugin script next -->
    <script src="recogito-helloworld-widget.js"></script>
  </head>
  <body>
    <img id="hallstatt" src="640px-Hallstatt.jpg" />

    <script type="text/javascript">
      (function() {

        // Add plugin to the widgets on init
        var anno = Annotorious.init({
          image: 'hallstatt',
          widgets: [ 
            recogito.HelloWorldWidget,
            'COMMENT',
            'TAG'
          ]
        });
        
      })();
    </script>
  </body>
</html>

Full project available on GitHub.