Package Exports
- hyper-element
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (hyper-element) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
hyper-element
A combining the best of hyperHTML and Custom Elements!
Your new custom-elements are built with hyperHTML and will be re-rendered on attribute and store change.
Live Demo
Define a Custom Element
document.registerElement("my-elem", class extends hyperElement{
render(Html){
Html`hello ${this.attrs.who}`
}
})To use your element
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/hyperhtml@latest/min.js"></script>
<script src="https://unpkg.com/hyper-element@latest/source/bundle.js"></script>
</head>
<body>
<my-elem who="world"></my-elem>
</body>
<html>Output
<my-elem who="world">
hello world
</my-elem>Api
Define your element
There are 2 functions. render is required and setup is optional
render
This is what will be displayed with in your element. Use the Html to define your content
render(Html,store){
Html`
<h1>
Lasted updated at ${new Date().toLocaleTimeString()}
</h1>
`
}setup
The setup function wires up an external data-source
Connent a data source
Example to re-rendering when the mouse moves and pass current mouse values to render
// getMouseValues(){ ... }
setup(onNext){
onMouseMove(onNext(getMouseValues))
}re-rendering with out a data source
Example of re-rendering every second
setup(onNext){
setInterval(onNext(), 1000);
}Set initial values to pass to every render
Example of attach an object that will be used on evey render
setup(onNext){
onNext({max_levels:3})
}How to cleanup
Any logic you wish to run when the element is removed from the page should be returned as a function from the setup call
setup(onNext){
const next = onNext(user);
socket.addEventListener('message', next);
const teardown = function(){
socket.removeEventListener('message', next);
}
return teardown
}Returning a "teardown function" from setup address the problem of needing a reference to the resource you what to release. If the "teardown function" was a public function. We would need to store the reference to the resource some, that the teardown can access it when call.
With this approach there is no leaking of references.
✎ To subscribe to 2 events
setup(onNext){
const next = onNext(user);
mobx.autorun(next); // update when changed (real-time feedback)
setInterval(next, 1000); // update every second (update "the time is now ...")
}
this
- this.attrs : the attributes on the tage
<my-elem min="0" max="10" />={ min:0, max:10 }- Attributes will be parsed to try and cast them to Javascript types
- Casting types supported:
Boolean&Number
- this.store : the value returned from the store function. !only update before each render
- this.wrappedContent : the text content embedded between your tag
<my-elem>Hi!</my-elem>="Hi!"
Templates
You can declare markup to be used as a template within the custom element
To enable templates
- Add an attribute "templates" to you custom element
- Define the template markup within your element
<my-list template data-json='[{"name":"ann","url":""},{"name":"bob","url":""}]' >
<div><a href="{url}">{name}</a></div>
</my-list>document.registerElement("my-list",class extends hyperElement{
render(Html){
Html`
${this.attrs["data-json"].map(user => Html.template(user))}
`
}
})Output:
<my-list template data-json='[{"name":"ann","url":""},{"name":"bob","url":""}]' >
<div>
<a href="">ann</a>
</div>
<div>
<a href="">bob</a>
</div>
</my-list>Render to string
You can use the innerShadow property to get the innerHTML of the shadow-dom
// create an element
const elem = document.createElement("profile-elem")
elem.setAttribute('name', 'ashlyn');
// view hidden markup
console.log(elem,elem.innerShadow)Styling
Supports objects as style attribute, fully compatible with Preact implementation.
Example of centering an element
render(Html){
const style= {
position: "absolute",
top: "50%", left: "50%",
marginRight: "-50%",
transform: "translate(-50%, -50%)"
}
Html`<div style=${style}> center </div>`
}
Example of connecting to a data store
backbone
var user = new (Backbone.Model.extend({
defaults: {
name: 'Guest User',
}
}));
document.registerElement("my-profile", class extends hyperElement{
setup(onNext){
user.on("change",onNext(user.toJSON.bind(user)));
// OR user.on("change",onNext(()=>user.toJSON()));
}
render(Html,{name}){
Html`Profile: ${name}`
}
})mobx
const user = observable({
name: 'Guest User'
})
document.registerElement("my-profile", class extends hyperElement{
setup(onNext){
mobx.autorun(onNext(user));
}
render(Html,{name}){
Html`Profile: ${name}`
}
})redux
document.registerElement("my-profile", class extends hyperElement{
setup(onNext){
store.subcribe(onNext(store.getState)
}
render(Html,{user}){
Html`Profile: ${user.name}`
}
})