q-import { wiki-common.qhtml } wiki-shell { sectionKey: "components" pageTitle: "Components" pageIntro: "q-component creates reusable custom elements. This page teaches components in a strict order so each example only depends on features that were already introduced above it." main { wiki-example-card { title: "1. Basic component structure" summary: "A q-component definition creates a reusable custom element type." note: "If you define q-component mycomponent, QHTML creates a element you can use in the current scope." details { html { q-component mycomponent { div,span { text { hello world } } } } } } wiki-example-card { title: "2. Instantiation" summary: "After defining a component, instantiate it like any other HTML element." note: "This creates a real custom element instance in the rendered output." details { html { q-component mycomponent { div,span { text { hello world } } } mycomponent { } } } } wiki-example-card { title: "3. Named instances" summary: "Give an instance a typed name when you want to reference it from other QHTML or JavaScript." note: "The typed name is the handle you use later, such as myCard.title or myCard.someMethod()." details { html { q-component mycard { div { text { hello from card } } } mycard card1 { } } } } wiki-example-card { title: "4. q-properties" summary: "Use q-property to store component state." note: "Properties are the normal place for labels, flags, counts, and other component-level values." details { html { q-component mycard { q-property title: "welcome" div { text { ${this.component.title} } } } mycard { } } } } wiki-example-card { title: "5. Accessing q-properties from JavaScript" summary: "Inside event handlers and methods, read component properties through this.component." note: "Use this.component inside JavaScript blocks. This version updates displayed state through oncountchanged instead of text interpolation." details { html { q-component mycounter { q-property count: 0 oncountchanged { $("#count-out").innerText = "count=" + String(this.component.count); } button { text { bump } onclick { this.component.count = Number(this.component.count) + 1; } } div#count-out { text { count=0 } } } mycounter { } } } } wiki-example-card { title: "6a. Scope and context" summary: "Named instances only resolve where their names are actually in scope." note: "This keeps references predictable instead of behaving like global lookups." details { html { q-component comp-a { q-property value: "hello" } comp-a rootA { } q-component comp-b { q-property fromRoot: rootA.value div { text { ${this.component.fromRoot} } } } comp-b { } } } } wiki-example-card { title: "6b. Named references declaratively" summary: "A q-property can point at another named instance declaratively." note: "This is the simple binding form for sharing values between components." details { html { q-component source-box { q-property title: "shared title" } source-box source1 { } q-component target-box { q-property copiedTitle: source1.title div { text { ${this.component.copiedTitle} } } } target-box { } } } } wiki-example-card { title: "6c. Dot walking" summary: "Use normal property paths when one named instance needs data from another named instance." note: "Dot walking is the standard component-to-component reference style in QHTML." details { html { q-component catalog-store { q-property title: "Main Catalog" q-property currency: "USD" } catalog-store store1 { } div { text { ${store1.title} (${store1.currency}) } } } } } wiki-example-card { title: "7. Dynamic components with a slot" summary: "A slot lets the caller place arbitrary content inside a reusable component shell." note: "This is the simplest way to make a component accept dynamic inner content." details { html { q-component panel-box { div { h3 { text { Panel shell } } slot { body } } } panel-box { body { ul { li { text { arbitrary content } } li { text { can go here } } } } } } } } wiki-example-card { title: "8. q-signals" summary: "q-signal declares a signal that the component can emit." note: "Think of a signal as a component-level event with arguments." details { html { q-component sender-box { q-signal sent(message) button { text { Send } onclick { this.component.sent("hello"); } } } sender-box { } } } } wiki-example-card { title: "9. on handlers" summary: "A component can handle a signal with an on hook." note: "This is the direct way to react to emitted signal values." details { html { q-component sender-box { q-signal sent(message) onsent(message) { alert("signal value: " + String(message)); } button { text { Send } onclick { this.component.sent("hello"); } } } q-component receiver-box { q-property value: "waiting" div { sender-box { } p#signal-out { text { value=waiting } } } } receiver-box { } } } } wiki-example-card { title: "10. q-connect" summary: "q-connect wires one signal to another component method declaratively." note: "Use it when both sender and receiver are already in scope and you want declarative-only wiring." details { html { q-component sender-box { q-signal sent(message) function sendNow(message) { this.sent(message); } } q-component receiver-box { q-property value: "waiting" function onMessage(message) { this.component.value = message; } div { text { ${this.component.value} } } } sender-box sender1 { } receiver-box receiver1 { } q-connect { sender1.sent receiver1.onMessage } button { text { send } onclick { sender1.sendNow("hello from q-connect"); } } } } } wiki-example-card { title: "11. onchanged { }" summary: "Each q-property automatically gets a changed hook." note: "Use this when one property update should cause another update or side effect." details { html { q-component counter-box { q-property count: 0 oncountchanged(value) { this.querySelector("#out").textContent = "count=" + String(value); } div { button { text { bump } onclick { this.component.count = Number(this.component.count) + 1; } } p#out { text { count=0 } } } } counter-box { } } } } wiki-example-card { title: "12. onready" summary: "onready runs after the component has mounted." note: "Use it for startup work that needs the rendered DOM or connected child instances." details { html { q-component ready-box { q-property label: "waiting" onready { this.component.label = "ready"; } div { text { ${this.component.label} } } } ready-box { } } } } } }