The Interactivity API - First Impressions

⚠️ Not a challenge

This is one of the occasional emails that I’ll send every now and then when I find something interesting or that I’ve learned.

Recently, I’ve learned about the Interactivity API that is being implemented with the Block Editor.

It gives me “Vue” vibes and it definitely looks like something that will enable us to build even more interactive and complex blocks.

So, what’s Interactivity API? In essence, we use custom HTML attributes on elements (as with Vue) that will perform some actions.

There’s a global and a local state. Global state is available through all the HTML of our block. Local state or context is available on the node we specific and all its children.

Do note, I am just starting to learn it so I might be 100% wrong.

I went in to try it out. Still much things to learn but I did build a simple timer with it.

The result:

Code

Editor side:

Added a simple input to enter seconds for the timer.

Front side:

On the front, I added a Start & Stop button and also rendered the seconds left.

When the timer starts, the seconds go down. Once they hit 0 or you click to stop it, it resets.

Timer not running

Timer running

Code:

edit.js for the block editor part:

import { __ } from '@wordpress/i18n';
 
import { useBlockProps } from '@wordpress/block-editor';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
 
export default function Edit( { attributes, setAttributes } ) {
  const blockProps = useBlockProps();
  const { timer } = attributes;

  return (
    <div { ...blockProps }>
      <p >
        { __(
          'Select the time from which the countdown will go', 'my-first-interactive-block'
        ) }
      </p>
      <NumberControl
        isShiftStepEnabled={ false }
        onChange={ ( time ) => setAttributes({ timer: time }) }

        value={ timer }
      />
    </div>
  );
}

render.php - where we code the HTML that will be rendered on the front with the Interactivity API attributes.

<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive='{ "namespace": "create-block" }'
	data-wp-context='{ "startTime": <?php echo $attributes['timer']; ?>, "timer": <?php echo $attributes['timer']; ?>, "running": 0 }'
	data-wp-watch="callbacks.runTimer"
>
    <span data-wp-text="context.timer"></span>
    <button data-wp-on--click="actions.startTimer" data-wp-bind--hidden="context.running">Start Timer</button>
    <button data-wp-on--click="actions.stopTimer" data-wp-bind--hidden="!context.running">Stop Timer</button>
</div>

view.js - where the store functionality is created which is used by the Interactivity API

/**
 * WordPress dependencies
 */
import { store, getContext } from '@wordpress/interactivity';

const { actions, state } = store( 'create-block', {
  actions: {
    startTimer: () => {
      const context = getContext();
      context.running = 1;
      context.interval = setInterval(function () {
        context.timer--;

        if ( context.timer <= 0 ) {
          actions.stopTimer();
        }
      }, 1000)

    },
    stopTimer:() => {
      const context = getContext();
      context.running = 0;
      context.timer = context.startTime;
      clearInterval(context.interval);
    }
  }
} );

Where does this code go? I’ve used the command line provided in the Interactivity API docs to create a new plugin for the block using this new API.

You can follow the docs there to find out how you can enable this API in your existing blocks. Although, I’d not recommend that yet as this API is only available, for now, in the Gutenberg plugin.

I couldn’t wait for January to start with the first WordPress Challenge, so I went ahead and sent these new findings of mine.

Hope you won’t mind it sending it 😅 

Join the conversation

or to participate.