The action-history element

Overview

The <action-history> element provides an interface with interactive controls for a "History" system.

When developing something like an "Undo" feature, user actions are maintained in memory so that their effects can be reversed. This element is a helper for that kind of functionality. The term "History system" is used to describe the abstract version of an "Undo" feature which includes "Redo" functionality as well as direct-point-in-history access.

The <action-history> element is intended to facilitate history functionality by both providing an interactive, timestamped ledger of the actions taken, and dispatching events to indicate the user's intention to undo or redo their actions.

Basic Examples

The <action-history> element maintains a full list of actions by treating each of its child elements that has a data-entry attribute as an entry in the history log.

Any child element with the data-entry attribute will be "managed" by the action history, which means it will respond to click and selection events to set the history system's state.

For layout and styling convenience, all child elements that do not have the data-entry attribute are unaffected by the <action-history> element.

Static Entries

In this example the <action-history> element has been given three children, each with the data-entry attribute.

Each element can be clicked to "activate" the entry. When an entry is activated, all subsequent entries (if any) are "reversed", if they have not already been reversed, and all prior entries are un-reversed.

Entry 1 Entry 2 Entry 3

Customization

To facilitate styling and support any representation of arbitrary history functionality, the <action-history> element does not dictate any type of content restrictions on its entry elements. Any element, including <button>s or <input>s can be used as entries.

This example uses buttons as entries so they can be activated using keypresses:

Reverse Chronological Order

History items are often listed in reverse-chronological order, meaning that the latest action would be at the top of the list, and the earliest action would be at the bottom.

The <action-history> element is already styled as a flex display, so setting the flex-direction style property to column-reverse provides a visual solution for reversing the items.

Unfortunately, this causes an issue with key-based navigation. For users using tabs to navigate through entries, the entries would be iterated through in their chronological order, rather than the way they are visually presented: in reverse.

To prevent this unexpected behavior, the <action-history> element can have its entries reversed by including a reverse attribute.

Compare how tabs navigate through each of the examples below:

Attribute

In this example, the style is set using the reverse attribute:

Style

In this example, the style is set using only the style:

Events and Functions

The <action-history> element's functionality is mostly abstract so this is a practical example with actions that are being managed by the <action-history> element, and their effects being managed by handlers for the element's events and functions.

Each input's change event is handled to add a new <action-history> entry. The activation and reverse events each have handlers that read the entries' data and apply that back to the input elements.

The following methods of history navigation are available:

Actions
Previous Action: [none]
Log

    Nested Slots

    The <action-history> element can use entries passed through from a parent element's <slot>. If the <action-history> element needs to be nested in another element, it can be populated using that element's slot functionality, rather than by writing code to handle passing the entries through to the <action-history> element.

    This example places an <action-history> element inside of the custom <shadow-wrapper> element. Events are managed on the <shadow-wrapper> element, as well, via event bubbling.

    Actions
    Previous Action: [none]
    Log