@selfage/stateful_navigator
Version:
Navigate with observable state tracked in browser history.
41 lines (25 loc) • 2.18 kB
Markdown
# /stateful_navigator
## Install
`npm install /stateful_navigator`
## Overview
Written in TypeScript and compiled to ES6 with inline source map & source. See [/tsconfig](https://www.npmjs.com/package/@selfage/tsconfig) for full compiler options. Provides classes to manage associate observable state with browser history.
## Observable state
This library is based on `/observable` to provide an observable state, which is a data object typically generated by `@selfage/generator_cli`.
Suppose a `STATE` variable is generated and exported in a file `./state.ts`.
## Loader and updater
```TypeScript
import { createLoaderAndUpdater } from '@selfage/stateful_navigator';
import { STATE } from './state';
let queryParamKey = 'q';
let [loader, updater] = createLoaderAndUpdater(STATE, queryParamKey);
// Now build your DOM tree and add listeners on loader.state
// loader.state.on('page', ...)
// When the state is changed and you want a new history entry.
updater.push();
// When the state is changed and you don't want a new histroy entry.
updater.replace();
```
`queryParamKey` is used to compose a query param `q=...` or to read from that query param, which holds a stringified state.
`createLoaderAndUpdater()` adds a listener to `popstate` event to handle users clicking browser's back button, by parsing the query param `q=<stringified historical state>`. However, you have to add listeners to each field of `loader.state` to actually handle the state change.
`updater.push()` should be called whenever you want a new history entry with the current state, which creates a new query param `q=<stringfied current state>` in the URL. It shouldn't be called with every field change, because you may want to group several changes together as one history entry. `updater.replace()` is the same as `updater.push()` except it replace the currrent URL without creating a new history entry.
The type of `loader` is `HistoryLoader<State>` by `import {HistoryLoader} from '@selfage/stateful_navigator/history_loader'` and the type of `updater` is `HistoryUpdater` by `import {HistoryUpdater} '@selfage/stateful_navigator/history_updater'`;