Skip to the content.

Historical UI

A small utility that allows you to control one or more mutually-exclusive popup UIs using the history stack. For example, if you have two potential popups, then open the first one, then open the second one, the first one would get closed first. Then, if you use the browser's back button, the second one gets closed as well. Then, the forward button would make it reopen.

Example:

import { HistoricalUI } from "@travisspomer/tidbits"

const popupController = HistoricalUI.add({
	onStateChange: (ev) => {
		if (ev.state)
			myPopup.style.removeProperty("display")
		else
			myPopup.style.display = "none"
	}
})

myButton.addEventListener("click", () => popupController.state = !popupController.state)

In this example, the popup is visible when popupController.state is true, and hidden when it's false or null. A button click event toggles the popup's visibility manually. In addition, HistoricalUI sets the state to null when the user presses the Back button, or another UI that was registered with add() is opened.

HistoricalUI

import { HistoricalUI } from "@travisspomer/tidbits"

add

HistoricalUI.add({
	onStateChange: (ev: StateChangeEvent) => void,
	key?: string
}): HistoricalUIElement

Tip: In TypeScript, you can supply a state type to get a strongly-typed object in return. For example, add<number>() returns a HistoricalUIElement<number> which stores its state as a number instead of any.

If you supply a key, HistoricalUI will attempt to "rehydrate" the state of that element if the page is refreshed, or if the user navigates away and then back.

remove

HistoricalUI.remove(
	controller: HistoricalUIElement
): void

Removes an object from being managed by HistoricalUI. In a single-page application, you can use this to stop managing the state of a component when the component is about to be destroyed and you'll no longer have the reference to the HistoricalUIElement.

StateChangeEvent

A StateChangeEvent object is passed to your onStateChange handler.

interface StateChangeEvent<StateType>
{
	readonly state: StateType
	readonly controller: HistoricalUIElement
}

state

The new state of your UI element.

controller

The same object that was returned from add().

HistoricalUIElement

A HistoricalUIElement object is returned from add().

interface HistoricalUIElement<StateType>
{
	state: StateType | null
	readonly key: string
}

state

The current state of your UI element. You can change this property to trigger a state change. In TypeScript, if you supplied a type to add(), this property will be that same type or null.

Important: Setting any UI element's state to a non-falsy value will set all other registered UI elements to null. All falsy state values are treated as null.

key

Read-only. The key supplied to add(), or a randomly-generated one.

Using it from React

You could use HistoricalUI from React too, but it's a bit more complicated, especially if you're using server-side rendering such as with Next.js.

Keep in mind that the router that your JavaScript framework uses may limit some or all of the functionality of Historical UI—it may not have been written to support other libraries accessing the history API.