decue
v1.1.0
Published
Declarative Custom Elements. Create simple web components with just HTML, parameterized with slots and attributes. With or without shadow-dom.
Maintainers
Readme
DecuE
Declarative Custom Elements
DeCuE is a lightweight framework for defining custom elements declaratively using HTML <template> tags.
It supports Shadow DOM, slotting, attribute observation, and form-associated custom elements.
Based on ideas in https://github.com/kgscialdone/facet (Thank you very much!) though with a bit different mindset.
Features
- Automatically registers all
<template decue="...">as custom elements at DOMContentLoaded.- also from inside
<object>s, thus supporting elements defined in external files.
- also from inside
- Supports Shadow DOM modes:
none,open,closed(default isnone). - Allows giving parameter data to elements.
- as slots for structured data: named and unnamed, also without shadow DOM (though mind the differences to native slots).
- as attributes for textual data: referenced by {placeholders} in template content.
- Supports function and method piping in placeholders, e.g.
{name.toUpperCase|someRegisteredFunction}. - Supports form-associated custom elements.
- I currently don't have actual use cases. Please let me know if you need some functionality!
- Allows event handler binding via
decue-on:eventnameattributes. - No dependencies. Rather small.
Installation
Download from https://unpkg.com/decue/dist/decue.min.js and include in your HTML:
<script src="decue.min.js"></script>You can add defer unless you want to use predefined elements.
Usage
By default, all templates having the attribute decue are automatically defined as custom elements at DOMContentLoaded. The template content is automatically searched for placeholder references, which are then included as observedAttributes to monitor for changes.
By default, all elements are defined without a shadow DOM. You can choose the shadow mode (none, open or closed) by the following ways:
<!-- global default shadow DOM mode -->
<script shadow="...">
<!-- my-element default shadow DOM mode -->
<template decue="my-element" shadow="...">
<!-- specific my-element instance shadow DOM mode -->
<my-element shadow="...">
<!-- make my-element form-associated -->
<template decue="my-element" form-associated>Predefined elements
If you want to have elements already defined when the DOM is parsed to remove flicker, you can use the script tag with the attribute elements (or form-associated for form associated elements). In this case the template is not available yet, so attributes will be monitored for changes using a MutationObserver. You can declare attributes explicitly to make them observed as observedAttributes instead. Make sure the template appears before the using elements in the DOM.
<!-- predefined custom element names, separated by spaces, -->
<!-- can include attributes to observe, separated by a comma -->
<script elements="my-element my-other-element[observed1,observed2]">Functions for piping
You can invoke object properties and methods in the pipes, but you can only include explicitly registered functions. They can be registered with the functions attribute, separated by spaces. Non-global functions can be given an alias as a simple name:
<script>
function myLowercase(str) {
return str.toLowerCase();
}
</script>
<script functions="myLowercase myAlias:window.someModule.someFunction"></script>External elements
You can include elements defined in external files using an <object> tag:
<object data="external.html" type="text/html" style="position:absolute; left: -99999px"></object>or by including them into the DOM as you wish and calling decue.processTemplate(...) for each of them.
Events
Fires connect, disconnect, adopt, attributechange, formassociate, formdisable, formreset, formstaterestore and checkvalidity custom events.
Allows binding global functions as event handlers via decue-on:eventname attributes:
<script>
function validateme(ev) {
...
}
</script>
<form-associated-element decue-on:checkvalidity="validateme">...</form-associated-element>This form doesn't require using eval. Please let me know if you need the old fashioned (and not recommended) inline-javascript way.
Examples
See https://lahteenmaki.net/decue/examples.html for some examples.
