Clone on Gitea
Introduction
Explained by ducks
FAQ
Getting Started
Components
Component Basics
Auto Initialization From DOM
Templates
Children and Parents
Roles
Strictness
Fields
What is a Field
Binding Fields to DOM
Reading and Writing Fields
Value Casting
Flags
Events
Overview
Event Handlers
DOM Events
Custom Events
Propagation and Flow
Advanced Event Control
Beyond Components
States
Overview
StateEngine
DisplayStateEngine
Field Matchers
Ordering and priority
Debugging
Advanced usage
Ajax
ComponentUI
VirtualForm
Unit Testing
Helpers
Overview
Cookies
Arrays

Getting started / Installation

As was already mentioned, Qite.js doesn't require a build step and runs directly in the browser. You include it, import the components you actually use and call Qite.init(...)

Recommended installation

The simplest way to use Qite in a real project is to add it as a git submodule:

$ git submodule add https://code.qount25.dev/qite/qite-js.git assets/vendor/qite

This keeps Qite versioned inside your repository without copying files around. You can also copy the repository into your project manually if you prefer. The important part is that browser can load Qite's files as plain ES modules.

What you must load

Qite does not auto-load every standard component and this is intentional -- you must import the files you actually use:

  • qite.js— mandatory core
  • standard Qite components you use, such as ButtonComponent
  • your own custom components

So if your page doesn't use ButtonComponent, you simply don't import it. If it does, then you do — so this explicit and small.

Typical app.js

A typical entry file looks like this:

// loads qite.js and everything mandatory
import "/assets/vendor/qite/src/qite.js";

// Components user needs, standard Qite ones or their own custom ones
import "/assets/vendor/qite/src/components/button/button_component.js";
import "/assets/js/my_form.js";

// Run qite. This attaches components to HTML.
Qite.init(document.body.querySelector("#root"));

This is the basic pattern:

  1. Import qite.js
  2. Import every component class used in the subtree you are about to initialize.
  3. Call Qite.init(...) on the root DOM element.

Minimal HTML example

Suppose your HTML looks like this:

<div id="root" data-component="MyForm">
    <button data-component="Button" data-roles="submit">
        Submit
    </button>
</div>

In this example:

  • MyForm is your custom component
  • Button is Qite's standard ButtonComponent

Because both appear in the HTML, both component classes must be loaded before Qite.init(...) runs.

A minimal custom component

Your custom component might look like this:

import BaseComponent from "/assets/vendor/qite/src/components/base_component.js";

export default class MyFormComponent extends BaseComponent {
    constructor(tree_node) {
        super(tree_node);

        this.events.add([
            ["@click", "submit", () => console.log("Submitted")]
        ]);
    }
}

Qite.components.MyForm = MyFormComponent;

There are two important things here:

  • your class extends BaseComponent
  • you register it in Qite.components

Qite scans HTML for data-component="MyForm" and then looks up Qite.components.MyForm

The loading rule

A good way to think about Qite is this:

  • HTML declares which components should exist
  • imports make those component classes available
  • Qite.init(...) matches the two and instantiates components

If HTML references a component class that hasn't been imported and registered, Qite can't create it.

A complete small example

Here is the whole thing together.

Your server-rendered HTML:

<script src="/assets/vendor/qite/src/qiteinit.js"></script>
<script type="module" src="/assets/js/app.js"></script>

<div id="root" data-component="MyForm">
    <button data-component="Button" data-roles="submit">
        Submit
    </button>
</div>

Your app.js:

import "/assets/vendor/qite/src/qite.js";
import "/assets/vendor/qite/src/components/button/button_component.js";
import "/assets/js/my_form.js";

Qite.init(document.body.querySelector("#root"));

And your custom my_form.js component:

import BaseComponent from "/assets/vendor/qite/src/components/base_component.js";

export default class MyFormComponent extends BaseComponent {
    constructor(tree_node) {
        super(tree_node);

        this.events.add([
            ["@click", "submit", () => console.log("Submitted")]
        ]);
    }
}

Qite.components.MyForm = MyFormComponent;

That is enough to get a real Qite component tree running in the browser.

Why qiteinit.js and qite.js are both there

The HTML page includes:

<script src="/assets/vendor/qite/src/qiteinit.js"></script>

This line creates the global Qite object early. Then your module imports:

import "/assets/vendor/qite/src/qite.js";

This loads Qite's core logic and mandatory internals. In normal usage, you want both:

  • qiteinit.js from HTML
  • qite.js from your module entry file

Styles

Standard Qite components often come with CSS files, but you include them manually only when you want them.

For example, if you use ButtonComponent and want its standard styling:

<link rel="stylesheet"
    href="/assets/vendor/qite/src/components/button/button.css" />

You are also free to ignore standard Qite CSS and style things yourself.

Running tests and demos

Qite itself doesn't require npm in production, however, if you want to run Qite's unit test, open Qite demo pages or work on Qite itself then you'll need Node and npm installed.

Once Node is installed, run:

$ node test/server.js

Then open:

  • https://localhost:32123 for unit tests
  • https://localhost:32123/demo/button/demo.html for a demo page

Common mistake

A very common mistake is to write HTML like this:

<button data-component="Button"></button>

but forget to import:

import "/assets/vendor/qite/src/components/button/button_component.js";

Qite will not load that component for you automatically. This is intentional and Qite stays explicit about component usage: if you use a component, you import it.