Mara
Mara is a MIT licensed, pick-n-mix style base for Custom Elements built around providing mixins with extensions and common behaviors for web components.
Creating elements
The base of Mara is a set of extensions for Custom Elements to make it easier to build both simple and advanced elements.
Mara provides HTMLCustomElement
which can be used as a base for elements:
; ;
Note: To maximize compatibility with different polyfills, use createdCallback
instead of constructor
during element creation.
HTMLCustomElement
also provides support for mixins via the static method
HTMLCustomElement.with(mixin1, mixin2, ...)
.
Attributes
A bit of extra care is needed to support attributeChangedCallback
. When
specifying attributes to observe either in an element or a mixin care
is needed to fetch the attributes of the super class and to call the callback
of the super class:
static { // Be sure to combine own observed attributes with those of the super return 'attribute1' ...superobservedAttributes ; } { // Call super to make sure super class can handle its attributes super; }
Core mixins
Initial rendering
The Custom Elements specification enforces things such as not changing attributes
during element construction and most of the initialization of an element should
be done in connectedCallback
. But connectedCallback
can be called several
times and in many cases you only want to do something the first time an element
is connected to the DOM.
The mixin InitialRender
provides a callback that will only be called once:
; ;
Children Ready
If an element needs access to its children you can use the ChildrenReady
mixin
to get a callback when the children are available.
; ;
Help wanted: This implementation of this mixin could use an overhaul. If you have ideas or fixes, feel free to open an issue or a pull request.
Templates via Shadow DOM
A component can be enhanced with a shadow root initalized from a template via
the Template
mixin:
; ;
Shadow DOM
If a component just needs access to a shadow root but no special template
handling the ShadowDOM
mixin will create a shadow root that can be used:
; ;
Polyfills
Polyfills are provided for the web site or web app that is consuming the elements, in the case your target environment needs it.
To import the standard polyfills, such as for DOM4 you can use:
;
Imported polyfill: DOM4.
To include a polyfill just for Custom Elements use:
;
Imported polyfill: Custom Elements (v1)
For Custom Elements with support for Shadow DOM use:
;
Imported polyfill: Custom Elements (v1), ShadyDOM, ShadyCSS
Creating mixins
Mixins contain limited functionality that can be composed together to help with implementation of a new custom element.
; let CustomMixin = ;
Mixins themselves can be composed with other mixins:
; let CustomMixin = ;
Basic behaviors
Mara contains a set of behaviors for creating certain components that need special attention to keyboard navigation, focus management and accessibility. These behaviors are provided as mixins and base classes.
Managing disabled state
These behaviors manage the disabled state of a component and optionally its children. When a component is disabled it is made inert both from pointer use and from keyboard use.
; ;
The attribute disabled
on the HTML element will reflect the disabled state,
so <element-name disabled>
will disable an element. An element can also
be controlled via the disabled
property:
elementdisabled = true;
Use DisableBehavior
if the element does not contain anything focusable or
clickable. DisableSubtreeBehavior
can be used to disable and maintain the
disabled state of both the element and its children.
Focusable element
FocusableBehavior
in mara/focus
can be used to make an element focusable
via keyboard and clicks:
;
Focus locking
When implementing certain components, such as dialogs, it can be useful to lock the focus to a certain component. A locked focus means that keyboard navigation via Tab and Shift-Tab will cycle through focusable children of the element.
;
The property focusLocked
is made available on the element and can be used to
control the focus lock:
elementfocusLocked = true;
A special version of this behavior is SubtreeFocus
which adds extensions
for also focusing the first focusable child in the element.
;
Two functions are available to control the focus:
element.grabFocus()
will lock the focus and move focus within the elementelement.releaseFocus()
will unlock the focus and move focus the element that was focused whengrabFocus
was called.
Component behaviors
Component behaviors are a step up from the basic behaviors and provide mixins that make elements behave as common components.
Button
The button behavior provides a button with correct keyboard control, ARIA roles
and support for disabling it. The button will emit a click
event when it is
invoked both via pointer and keyboard.
// Using as a mixin; {} // Using as a class; {}
Submit Button
SubmitButton
is a class/mixin that can be used to create a custom submit
button. This behavior creates a button that submits the form it is a child of.
To integrate properly with forms this behavior manages a hidden button, this
is needed to make forms submittable via keyboard as with a regular <button>
.
; ;
Modal Dialog
A modal dialog is a dialog that is displayed over other content and only allows interaction with its children.
; ;
The attribute open
on the HTML element will reflect if the dialog is open
or not, so <custom-dialog open>
indicates a dialog that is open. Setting
the property open
will also open the dialog: element.open = true
.
The functions show
and close
can also be used to show and close the dialog.