Component

A component, here intended as a reusable part of a web page, consists of a View, that is implemented as HTML template with its own CSS, and a Controller that is the Javascript code that controls the view, its presentation and interaction logic.

Component's files are placed in the same path location and their base name is the same, and it represents itself the component's name:

The unique component's identifier is then its full path, formed by the component's <path> plus the <component_name>, without any extension.

<component_id> :== [<path>/]<component_name>

Components can be loaded by adding the z-load attribute to a host element, with its value containing a valid component identifier:

<div z-load="<component_id>"></div> 

The <path> of the component, can be either relative to the page requesting the component, or an absolute path, even if pointing to a different server. In the latter case, CORS must be enabled on the server end in order to allow fetching of components from the remote server.

As an example, consider this time-clock component with its view and controller files placed inside a widgets folder:

the <component_id> is widgets/time-clock, and the component can be loaded using the following code in the HTML page:

<div z-load="widgets/time-clock"></div>
Loading widgets/time-clock...

so, basically, the component's view template's files (time-clock.html + time-clock.css) are rendered inside the host element div, and the controller code (time-clock.js) is activated and begins to animate the clock's digits.

Custom element

It is possible to define a custom element for a zuix.js component by using the zuix.loadComponent(..) method:

customElements.define('component-name', class extends HTMLElement {
connectedCallback() {
zuix.loadComponent(this, 'path/of/component-name');
}
});

After defining a custom element, the component can be added to the page by using the custom element tag:

<component-name></component-name>

which has the same effect of using the z-load attribute on a host element:

<div z-load="path/of/component-name"></div>

Defining a custom element for a Material Design button component.

customElements.define('mdl-button', class extends HTMLElement {
connectedCallback() {
zuix.loadComponent(this, '@lib/controllers/mdl-button', 'ctrl');
}
});

The third parameter <type> can be supplied to the zuix.loadComponent(..) in case we are loading only a controller (ctrl) or only a view template (view), rather than a complete component (.html + .css + .js).

Using the mdl-button element in the page:

<mdl-button :class="'primary'">
Hello
</mdl-button>

<mdl-button :type="'flat'">
Web
</mdl-button>

<mdl-button :class="'accent'">
Components
</mdl-button>

HelloWebComponents

Shadow DOM

With custom elements it is also possible to enable the shadow DOM.
zuix.js will auto-detect if a custom element is using shadow DOM when the attachShadow method is called with the mode option set to open. If the mode is otherwise set to closed, then the shadow DOM must be passed explicitly as a container with the zuix.loadComponent(..) options as shown in the following example:

JS

customElements.define('time-clock', class extends HTMLElement {
connectedCallback() {
zuix.loadComponent(this, 'widgets/time-clock', '', {
container: this.attachShadow({mode: 'closed'})
});
}
});

HTML

<time-clock></time-clock>

Standalone components

Standalone components can be easily implemented as JavaScript modules. The name of the module will have the same base name of the widget but ending with .module.js.

File: widgets/time-clock.module.js

import 'https://cdn.jsdelivr.net/npm/zuix-dist@1.1.13/js/zuix.module.min.js';
customElements.define('time-clock', class extends HTMLElement {
connectedCallback() {
zuix.loadComponent(this, 'widgets/time-clock');
}
});

Then the component module can be imported in the head section of the page

...
<head>
...
<script type="module" src="/app/widgets/time-clock.module.js"></script>
...
</head>
...

or using the import statement, or the dynamic import() function, inside another module

import "/app/widgets/time-clock.module.js"

then, the component, can be added inside the page's body using the defined tag

<time-clock></time-clock>

Since the component module is already loading zuix.js library with the import at line #1, there's no need to include zuix.min.js in the head section of the page and so, the component can be loaded with just one line of JavaScript import and the relative HTML tag.
The URL of the component's module can also be an absolute URL pointing to a different server.

try Example on CodePen

View-only component

It's also possible to load just a view without the controller and so consisting of the two files:

To load a view, the type-attribute view is added to the host element.

<div view z-load="<component_id>">
<!-- loaded view content will be rendered here -->
</div>

In the example below the view template named links is loaded using an absolute URL path:

<div view z-load="https://zuixjs.org/app/content/docs/examples/links"></div>

Loading component examples/links...

Controller-only component

A controller-only component, or simply controller, is basically a component whose view is the host element itself. To load a controller the type-attribute ctrl is added to the host element.

<div ctrl z-load="<component_id>">
<!-- host element content -->
</div>

A controller consists only of a Javascript file:

In the following example the Gesture Helper controller is added to a div container in order to detect swipe left and swipe right gestures over it.

<div ctrl z-load="@lib/controllers/gesture-helper"
:on:gesture:swipe="handleSwipeGesture">

<strong>
Gesture detection area
</strong>
<p>
Try swiping left or right.
</p>
</div>

<script>
function handleSwipeGesture(e, tp) {
switch (tp.direction) {

case 'left':
this.playAnimation('animate__fadeOutLeft');
break;

case 'right':
this.playAnimation('animate__fadeOutRight');
break;

}
}
}
</script>

Gesture detection area

Try swiping left or right.

The default component

By using the internal default component it's possible to get advantage of zuix.js components' features also on standard HTML elements.
For instance, adding the attribute z-load="default" to a div, will turn that div into a zuix.js component's view, where it will be possible to use all templating and scripting capabilities of zuix.js components:

<div z-load="default"
:model:number="0">


<mdl-button :type="'fab'"
(pointerdown)="model.number--">

remove
</mdl-button>

<strong #number></strong>

<mdl-button :type="'fab'"
(pointerdown)="model.number++">

add
</mdl-button>

<style media="#">
:host {text-align: center}
strong {margin: 12px}
</style>
</div>

removeadd

The z-load="default" attribute can be omitted if any of the other z-* option attributes are in place (z-context, z-options, z-model, z-behavior, z-on).

Getting started
Context Options
GitHub logo
JavaScript library for component-based websites and applications.