loadable-element
Loading / success / error state, a provision, and the three events — once, for every element that does async work.
Features
- Three states
is-loading/is-success/is-error, mutually exclusive - Stale-while-revalidate
did-loadis set on the first success, kept through a refresh, cleared on an error — keep content on screen during a refresh - One payload The result or the error lands on
provision - Three events
{tag}-loading/{tag}-success/{tag}-error, tag-prefixed automatically - Four effects
_setLoading,_setSuccess,_setError,_resetLoadState— the element decides when, the base does the bookkeeping
Installation
This package is available in the
<script src="https://unpkg.com/@excom/kit-utils@0.3.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/neutron@0.2.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/loadable-element@0.2.2/dist/index.umd.min.js"></script>npm install @excom/loadable-elementimport { /* … */ } from "@excom/loadable-element";Peer dependencies (0)
Packages a consumer must install alongside this one. Workspace deps are bundled.
| Package | Version |
|---|---|
|
Usage
Compose LoadableElement and call its effects from your own lifecycles. FetchableElement (and every element built on it) and quark-sheet compose it this way.
import { LoadableElement } from "@excom/loadable-element";
import { Neutron } from "@excom/neutron";
export const LoadJson = Neutron.compose([
LoadableElement,
Neutron({ tag: "load-json", props: { srcUrl: String, _promise: Promise } }),
])
.onPropSet("srcUrl", ({ srcUrl }) => [
{ _setLoading: [] },
{ _promise: fetch(srcUrl).then((r) => r.json()) },
])
.onPromiseResolved("_promise", (_, { _promise }) => ({ _setSuccess: [_promise] }))
.onPromiseRejected("_promise", (_, { _promise }) => ({ _setError: [_promise] }));
LoadJson.define();import { LoadableElement } from "@excom/loadable-element";
import { Neutron } from "@excom/neutron";
export const LoadJson = Neutron.compose([
LoadableElement,
Neutron({ tag: "load-json", props: { srcUrl: String, _promise: Promise } }),
])
.onPropSet("srcUrl", ({ srcUrl }) => [
{ _setLoading: [] },
{ _promise: fetch(srcUrl).then((r) => r.json()) },
])
.onPromiseResolved("_promise", (_, { _promise }) => ({ _setSuccess: [_promise] }))
.onPromiseRejected("_promise", (_, { _promise }) => ({ _setError: [_promise] }));
LoadJson.define();<load-json src-url="/api/user"></load-json><load-json src-url="/api/user"></load-json>load-json[is-success] { $user: prop("provision"); }
load-json[is-error] [bind-message] { content: prop("provision").message; }load-json[is-success] { $user: prop("provision"); }
load-json[is-error] [bind-message] { content: prop("provision").message; }Cancelled or superseded work calls _resetLoadState (no event) — pair with
API Reference
Attributes
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
Provision
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
Events
Type
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
Recognized Elements
Child or descendant elements are recognized by and relevant to its functionality.Styles
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
Attributes (4)
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
did-load
Work has succeeded and no failure followed. Stays set while a refresh loads, so content can stay on screen (stale-while-revalidate): gate it on
[did-load] rather than [is-success]. Cleared on error.
didLoad
boolean
falseis-error
The most recent work failed. Mutually exclusive with
is-loading and is-success.
isError
boolean
falseis-loading
Work is in flight.
isLoading
boolean
falseis-success
The most recent work finished successfully. Mutually exclusive with
is-loading and is-error.
isSuccess
boolean
falseProvision (1)
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
provision
The result of the most recent work on success, or the error payload on failure. Shape is defined by the composing element. Not reflected as an attribute.
provision
unknown
Events (3)
A "default action" is subsequent logic executed by the element if
e.preventDefault() is not
synchronously called on the event.
Type
{tag}-error
After
is-error is set. event.detail is the error payload (also stored as provision).
Type
LoadableErrorEvent
{tag}-loading
After
is-loading is set (work started).
Type
LoadableLoadingEvent
{tag}-success
After
is-success is set. event.detail is the new provision.
Type
LoadableSuccessEvent
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
Recognized Elements (0)
Child or descendant elements are recognized by and relevant to its functionality.Styles (0)
If you wish to opt-out of these styles on a case-to-case basis, use property
all: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
Release notes (2)
0.2.0
- Add
did-load: set on the first success, kept while a refresh loads and after a cancel, and cleared on an error, so content can stay on screen during a refresh with[did-load]instead of[is-success]
0.1.1
- Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
Release notes
A "default action" is subsequent logic executed by the element if
e.preventDefault() is not
synchronously called on the event.
If you wish to opt-out of these styles on a case-to-case basis, use property
all: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.