hydrofoil-shell: # hydrofoil-shell
UI-agnostic base element which can be used to build hypermedia-driven
single page applications.
Implemented using lit-element
Installation
yarn add @hydrofoil/hydrofoil-shell
Usage
<hydrofoil-shell>
The core element, which manages a state (single resource representation).
This element is abstract. It does not:
- handle of client-server interaction (doesn’t load the resource)
- does not render any shell UI
- delegates the rending of resource representations to
<lit-view>element
Using the element
In order to actually deploy a shell element simple steps are required:
- inherit from the base
- implement
loadResourceInternal - override
renderMainto create some core app UI
Here’s an example of how this would be done
import HydrofoilShell from '@hydrofoil-shell/hydrofoil-shell/hydrofoil-shell'
import {customElement, html} from 'lit-element'
@customElement('my-app-shell')
export default class MyAppShell extends HydrofoilShell {
renderMain () {
// call base to keep using <lit-view> to render the actual resource
return html`
<nav>Some static menu</nav>
<section class=main>
${base.renderMain()}
</section>
<footer>Footer element</footer>
`
}
loadResourceInternal (uri) {
return fetch(uri)
}
}
The base shell element does not implement the actual loading so that it’s not
being coupled with a single client library or API implementation. Still, instead of
repeating the load method every time you should build a hydrofoil application,
a mixin can be used instead to reuse the logic for loading the resources.
For example, Hydra APIs can be consumed by mixing in alcaeus-loader
+import AlcaeusLoader from '@hydrofoil-shell/alcaeus-loader`
@customElement('my-app-shell')
-export default class MyAppShell extends HydrofoilShell {
+export default class MyAppShell extends AlcaeusLoader(HydrofoilShell) {
- loadResourceInternal (uri) {
- return fetch(uri)
- }
}
<hydrofoil-multi-resource-view>
A helper element, which helps manage multiple resource. Just as the base shell
element, it only serves as a skeleton and needs to be inherited to actually serve
as a presentation layer.
For examples check out the material design implementations hydrofoil-resource-tabs
and hydrofoil-resource-accordion.
Usage
The element is controlled by standard DOM events. To add a resource to the ones displayed
dispatch hydrofoil-append-resource from any child element.
child.dispatchEvent(new CustomEvent('hydrofoil-append-resource', {
bubbles: true,
composed: true,
detail: {
parent: currentResource,
resource: nextResource,
},
}))
Both parent and resource are mandatory. If parent is not the topmost resource on the stack
all its current children will be replaced with nextResource.
To remove an element from the stack, dispatch hydrofoil-close-resource. This will also remove
any other resources higher on the stack.
child.dispatchEvent(new CustomEvent('hydrofoil-append-resource', {
bubbles: true,
composed: true,
detail: {
resource: removedResource,
},
}))
Examples
| Before | event | After | Note |
|---|---|---|---|
| 1. resA | hydrofoil-append-resource - parent: resA - resource: resB |
1. resA 2. resB |
Add resB to stack |
| 1. resA 2. resB |
hydrofoil-append-resource - parent: resA - resource: resC |
1. resA 2. resC |
Replace resB with resC |
| 1. resA 2. resC |
hydrofoil-append-resource - parent: resC - resource: resD |
1. resA 2. resC 3. resD |
Further append resD |
| 1. resA 2. resC 3. resD |
hydrofoil-close-resource - resource: resC |
1. resA | Remove resC which also discards resD |