Skip to content

Components

Mike Nickaloff edited this page Mar 6, 2026 · 6 revisions

QHTML v6 Components

This page explains Components in QHTML v6 in practical, beginner-friendly language, while still covering all advanced capabilities available in the current runtime :contentReference[oaicite:0]{index=0}.


What Is a Component?

A q-component is a runtime UI building block.

It creates:

  • A real custom host element in the DOM
  • A scoped execution context (this.component)
  • Internal state (q-property)
  • Methods (function)
  • Signals (q-signal)
  • Computed values (q-alias)
  • Slots for content projection (slot {})

Think of it as:

A reusable mini-application with its own state, logic, and UI.


Why Use Components?

Use q-component when you need:

  • Reusable UI widgets
  • Stateful behavior
  • Encapsulated logic
  • Events between UI pieces
  • Controlled update cycles
  • Internal methods
  • Reactive-ish binding via update()

If you do not need runtime behavior, use q-template instead.


Minimal Component Example

<q-html>

  q-component app-card {
    q-property { title }

    div {
      h3 { text { ${this.component.title} } }
      slot { body }
    }
  }

  app-card {
    title: "Welcome"
    body {
      p { text { Projected content. } }
    }
  }

</q-html>

What happens:

  • app-card becomes a real host element.
  • title is stored on this.component.title.
  • slot { body } injects projected content.
  • q-bind reads component state.

Anatomy of a Component

A component can contain:

1. Properties (q-property)

Stores internal state.

q-component my-comp {
  q-property title
  q-property selected: true
}

Access with:

this.component.title

After changing a property:

this.component.update()

2. Methods (function)

Methods attach to this.component.

q-component counter-box {

  q-property count: 0

  function increment() {
    this.component.count++;
    this.component.update();
  }

  button {
    text { Click }
    onclick { this.component.increment(); }
  }

}

3. Signals (Component Events)

Components can emit signals like function calls.

q-component sender {
  q-signal sendNotify(message)

  button {
    text { Send }
    onclick { this.component.sendNotify("Hello"); }
  }
}


Connect them using sender.signal.connect(receiver.method):

q-component sender {
  q-signal sendNotify(message)

  button {
    text { Send }
    onclick { this.component.sendNotify("Hello"); }
  }
}
sender { id: "sender" } /* instance of q-component */

q-component other-component { 
  function notify(message) { alert(message) }
  onReady {

    $("#sender").sendNotify.connect(this.component.notify);
  }


}
other-component { }

Signals support:

  • .connect(fn)
  • .disconnect(fn)
  • .emit(...)

4. Slots (Content Projection)

Slots let users pass markup inside a component.

q-component panel {
  div {
    h2 { slot { title } }
    div { slot { content } }
  }
}

panel {
  title { text { Header } }
  content { p { text { Body text } } }
}

Slots are named placeholders.


5. q-alias (Computed Properties)

Creates a computed property on this.component.

q-component mycomp {
  q-alias labelText {
    return this.querySelector("#label").textContent;
  }
}

Useful when:

  • You want computed values
  • You want derived state
  • You want DOM-backed accessors

6. Binding to Named Child Nodes (property name { ... })

You can bind a real DOM node to a component property.

q-component builder-box {
  property editor {
    div { text { hello } }
  }

  onReady {
    this.component.editor.textContent = "hello world"
  }
}

This creates:

this.component.editor  → DOM node

State + Rebinding with q-bind

q-bind evaluates expressions at render time.

q-component my-component {
  function myprop() {
    const src = new Date();
    return src;
  }
  q-property prop2: q-bind { return this.myprop() }
  slot { main }
}

my-component {
  div {
    div { text { ${this.component.prop2} } }
  }
  button { 
    text {hello world }
    onmouseover { 
      this.component.update()
    }
    onclick { this.component.update() }
  }
}

To re-evaluate:

this.component.update()

q-bind runs in a DOM-capable context.


Scoped Updates

Components can update:

Only themselves

this.component.update();

Entire <q-html> tree

this.component.root().update();

Use subtree updates for performance.


Component Instances Support Selector Shorthand

q-component card {
  div { text { Card } }
}

card#card-1.primary { }

This produces:

<card id="card-1" class="primary">

Component vs Template

Feature q-component q-template
Runtime host element
this.component
Properties
Methods
Signals
Slots
Pure HTML output

Use q-template when you only need static expansion.


When Should Beginners Use Components?

Use components when:

  • You need interaction
  • You need internal state
  • You need events between UI pieces
  • You need reusable logic
  • You want structured UI architecture

Do not use components when:

  • You just need markup reuse → use q-template
  • You need compile-time source expansion → use q-macro
  • You want pre-parse transformation → use q-rewrite

Component Lifecycle

onReady {}

Runs after mount.

q-component init-box {
  onReady {
    this.setAttribute("data-ready", "true");
  }
}

This executes after rendering.


Advanced: Combining Everything

q-component modal-box {

  q-property open: false
  q-signal closed()

  function close() {
    this.open = false;
    this.update();
    this.closed();
  }

  div {
    style {
      display: ${this.component.open ? "block" : "none"};
    }

    slot { content }

    button {
      text { Close }
      onclick { this.component.close(); }
    }
  }

}

This component:

  • Has state
  • Has a method
  • Emits a signal
  • Uses slots
  • Updates itself

Mental Model

A q-component is:

  • A DOM host element
  • With a private state object
  • With attached methods
  • With an update cycle
  • With event dispatch capability
  • With projection support

It is the core runtime building block of QHTML.


Summary

Components provide:

  • Structured UI architecture
  • Encapsulated state
  • Event systems
  • Scoped updates
  • Reusable design units
  • Declarative syntax with runtime control

They are the foundation of complex QHTML applications.