QHTML Component Examples

This page is now mostly HTML. Each example is a plain <q-editor> with inline QHTML source.

The sidebar is built with a small navigation script that links to each example section anchor.

q-keyword syntax usage

Scoped keyword remapping with direct-only alias rules.

q-keyword component { q-component } q-style tiny-card-style { q-style-class { w3-round-large w3-border } background-color: #eef4ff color: #0f172a border: 1px solid #bfd0ea } q-theme tiny-card-theme { .tiny-card-shell { tiny-card-style } } component tiny-card { tiny-card-theme { div.tiny-card-shell.w3-card.w3-padding { text { Tiny Card } } } } tiny-card { }

q-form.qhtml usage

Use form templates for quick input layouts.

q-import { q-components.qhtml } q-style form-shell-custom { background-color: #fff7ed border-color: #fdba74 color: #7c2d12 } q-style form-input-custom { background-color: #fffaf0 border-color: #fed7aa } q-style form-submit-custom { background-color: #ea580c border: 1px solid #c2410c color: #f8fafc } q-theme form-demo-theme { q-form-theme { } .q-form-shell { form-shell-custom } .q-form-input { form-input-custom } .q-form-submit { form-submit-custom } } form-demo-theme { q-form { h3 { text { Quick Form } } q-input { placeholder: "Name" } q-input { type: "email" placeholder: "Email" } q-textarea { text { Tell us what you are building... } } q-submit { text { Send } } } }

q-grid.qhtml usage

Create a simple grid with declarative columns.

q-import { q-components.qhtml } q-style cell-a-style { background-color: #eff6ff color: #1e3a8a border: 1px solid #93c5fd } q-style cell-b-style { background-color: #ecfeff color: #155e75 border: 1px solid #67e8f9 } q-style cell-c-style { background-color: #f0fdf4 color: #166534 border: 1px solid #86efac } q-theme grid-cells-theme { .cell-a { cell-a-style } .cell-b { cell-b-style } .cell-c { cell-c-style } } grid-cells-theme { q-grid { columns: 3; div.cell-a.w3-panel.w3-border { text { Cell A } } div.cell-b.w3-panel.w3-border { text { Cell B } } div.cell-c.w3-panel.w3-border { text { Cell C } } } }

q-modal.qhtml usage

Use built-in q-modal-theme defaults, then layer an external theme override.

q-import { q-components.qhtml } q-style modal-open-button-style { background-color: #16a34a color: #f8fafc border: 1px solid #15803d } q-style modal-container-override-style { background-color: #ffedd5 color: #7c2d12 } q-style modal-titlebar-override-style { background-color: #ef4444 color: #f8fafc } q-style modal-close-override-style { background-color: #7f1d1d color: #f8fafc } q-style modal-title-override-style { background-color: #fb923c color: #111827 } q-style modal-content-override-style { background-color: #dbeafe color: #1e3a8a } q-style modal-footer-override-style { background-color: #fde047 color: #713f12 } q-theme modal-demo-theme { q-modal-theme { } .modal-open-btn { modal-open-button-style } .q-modal-container { modal-container-override-style } .q-modal-titlebar { modal-titlebar-override-style } .q-modal-closebutton { modal-close-override-style } .q-modal-title { modal-title-override-style } .q-modal-content { modal-content-override-style } .q-modal-footer { modal-footer-override-style } button { modal-open-button-style } } modal-demo-theme { button.modal-open-btn.w3-button { text { Open Modal } onclick { modalUsage.show(); } } q-modal modalUsage { id: "modal-usage" title { h3 { text { q-modal Usage } } } body { p { text { Modal default colors are overridden externally via q-theme composition. } } button.w3-button { text { In-modal button override } } } footer { button.w3-button { text { Close } onclick { this.component.hide(); } } } } }

q-sidebar.qhtml usage

Use one theme: include q-sidebar-theme defaults, then apply targeted overrides.

q-import { q-components.qhtml } q-style sidebar-toggle-override-style { background-color: #16a34a color: #f8fafc border: 1px solid #15803d } q-style sidebar-panel-override-style { background-color: #ffedd5 color: #7c2d12 border-color: #fb923c } q-style sidebar-toggle-strong-style { background-color: #ef4444 color: #f8fafc border: 1px solid #7f1d1d } q-style sidebar-content-card-style { background-color: #dbeafe color: #1e3a8a border: 1px solid #60a5fa } q-style sidebar-nav-link-style { background-color: #fef3c7 color: #92400e border: 1px solid #f59e0b } q-theme sidebar-demo-theme { q-sidebar-theme { } .q-sidebar-panel { sidebar-panel-override-style } .q-sidebar-toggle { sidebar-toggle-override-style sidebar-toggle-strong-style } .sidebar-content-pane { sidebar-content-card-style } .sidebar-nav-btn { sidebar-nav-link-style } } sidebar-demo-theme { div.w3-container.w3-border.w3-round-large { style { position: relative; height: 240px; overflow: hidden; padding: 8px; } button.w3-button.w3-margin-bottom { text { Toggle Sidebar } onclick { demoSidebar.toggle(); } } q-sidebar demoSidebar { sidebarWidth: "280" collapsedWidth: "2vw" open: "1" content { div.sidebar-content-pane.w3-bar-block.w3-padding.w3-border { h4 { text { Sidebar } } a.sidebar-nav-btn.w3-bar-item.w3-button { text { Nav Item 1 } } a.sidebar-nav-btn.w3-bar-item.w3-button { text { Nav Item 2 } } } } main { div.w3-padding { h4 { text { Main Content } } p { text { q-sidebar uses an in-container grid layout (sidebar + main). } } } } } } }

lcars-sidebar.qhtml usage

LCARS-style sidebar shell with a Houdini-painted curved top, vertical rail buttons, and slotted main content.

q-import { q-components/lcars-sidebar.qhtml } lcars-sidebar { sidebar { lcars-sidebar-buttons { buttons { lcars-sidebar-button { buttonColor: "#f59a38" buttonText { text { Ops } } onclick { alert("Ops channel selected"); } } lcars-sidebar-button { buttonColor: "#d97706" buttonText { text { Sensors } } onclick { alert("Sensors selected"); } } lcars-sidebar-button { buttonColor: "#ef4444" buttonText { a { href: "https://www.google.com" target: "_blank" text { Google } } } onclick { console.log("LCARS external link button"); } } } } } main { div { style { display: grid; gap: 12px; color: #f8fafc; } h3 { text { LCARS Command Surface } } p { text { The left rail is projected through the sidebar slot. Main content remains arbitrary QHTML. } } div { style { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; } div { style { background: #172033; padding: 12px; } text { Navigation } } div { style { background: #172033; padding: 12px; } text { Telemetry } } div { style { background: #172033; padding: 12px; } text { Actions } } } } } }

q-popup-menu.qhtml usage

Minimal popup menu using popup-contents and explicit show(x, y).

q-import { q-components.qhtml } div.w3-container.w3-border.w3-round-large.w3-padding { h4 { text { Right-click inside the dashed area } } div#ctx-zone.w3-panel.w3-border-dashed.w3-round-large { style { min-height: 140px; background-color: #f8fafc; color: #0f172a; border: 1px dashed #94a3b8; } oncontextmenu { event.preventDefault(); ctxUsage.show(event.clientX + "px", event.clientY + "px"); var ctxLog = document.querySelector("#ctx-log"); if (ctxLog) { ctxLog.textContent = "Last open: " + String(event.clientX) + ", " + String(event.clientY); } } p { text { This context menu uses explicit show(event.clientX, event.clientY). } } q-popup-menu ctxUsage { id: "ctx-usage" style { position: fixed; background-color: #f8fafc; } popup-contents { ul.w3-ul.w3-small.w3-card { li { text { Rename } } li { text { Duplicate } } hr { } li { text { Archive } } li { text { Delete } } } } onready { this.closest("q-popup-menu").style.display = 'none'; } } } p#ctx-log { class: "w3-small" style { color: #334155; } text { Last open: none } } }

q-tabs.qhtml usage

Instantiate tabs and switch via showTab(index).

q-import { q-components.qhtml } q-style tabs-show-btn-style { background-color: #334155 color: #f8fafc border: 1px solid #1e293b } q-style tabs-nav-override-style { background-color: #ffedd5 } q-style tabs-content-override-style { background-color: #fffaf0 } q-theme tabs-demo-theme { .tabs-show-btn { tabs-show-btn-style } .q-tabs-nav { tabs-nav-override-style } .q-tabs-content-themed { tabs-content-override-style } } tabs-demo-theme { button.tabs-show-btn.w3-button.w3-margin-bottom { text { Show Tab 3 } onclick { tabsUsage.showTab(2); } } q-tabs tabsUsage { id: "tabs-usage" q-tab { name { text { Overview } } content { p { text { Overview content } } } } q-tab { name { text { Details } } content { p { text { Details content } } } } q-tab { name { text { Logs } } content { p { text { Logs content } } } } } }

dynamicTabWidget

Model-driven tabs using declarative composition: q-tabs + q-model-view.

q-import { q-components.qhtml } q-component dynamicTabWidget { q-tabs { q-model-view { model { q-model { q-array { q-map { name: "Tab 1", content: "hello world" }, q-map { name: "Tab 2", content: "test 123" } } } } as { tabObject } q-tab { name { div { text { ${tabObject.name} } } } content { div { text { ${tabObject.content} } } } } } } } dynamicTabWidget { }

q-tree-view quick usage

Collapsible tree using HTML5 details/summary from a q-model.

q-import { q-components.qhtml } q-model my-tree { q-map { src: q-array { "index.js", "parser.js", q-map { utils: q-array { "path.js", "net.js" } } } docs: q-array { "README.md", "MODULE-API.md" } } } q-style tree-list-style { margin: 0.25rem 0 padding-left: 1.25rem } q-style tree-item-style { display: block position: relative } q-style tree-leaf-item-style { display: flex align-items: center gap: 0.32rem position: relative margin-left: 0.2rem padding: 0.12rem 0 } q-style tree-leaf-connector-style { display: inline-block width: 0.7rem height: 0.01rem border-left: 2.0px solid #0ea5e9 border-bottom: 0.75px solid #0ea5e9 box-sizing: border-box padding-bottom: 0.25rem; } q-style tree-children-style { margin: 0.25rem 0 0.25rem 0.5rem padding-left: 1rem } q-style tree-marker-style { border-radius: 2px } q-style tree-marker-open-style { background-color: #16a34a color: #f8fafc border-color: #166534 } q-style tree-marker-closed-style { background-color: #2563eb color: #f8fafc border-color: #1d4ed8 } q-style tree-connector-style { color: #0ea5e9 border-left-style: solid border-left-width: 1.25px border-left-color: #0ea5e9 } q-style tree-connector-last-style { border-left-color: transparent } q-style tree-summary-style { color: #0f172a display: flex align-items: center gap: 0.35rem cursor: pointer } q-style tree-branch-style { display: block } q-style tree-label-style { color: #0369a1 } q-style tree-leaf-style { color: #1e3a8a } q-theme tree-demo-theme { .q-tree-list { tree-list-style } .q-tree-item { tree-item-style } .q-tree-branch-item { tree-item-style } .q-tree-leaf-item { tree-leaf-item-style } .q-tree-children { tree-children-style } .q-tree-branch { tree-branch-style } .q-tree-marker { tree-marker-style } .q-tree-marker-open { tree-marker-open-style } .q-tree-marker-closed { tree-marker-closed-style } .q-tree-connector { tree-connector-style } .q-tree-branch-item.q-tree-connector-last { tree-connector-last-style } .q-tree-summary { tree-summary-style } .q-tree-label { tree-label-style } .q-tree-leaf-connector { tree-leaf-connector-style } .q-tree-leaf-label { tree-leaf-style } } tree-demo-theme { q-tree-view#my-view { model: "my-tree" } }

q-list-view.qhtml usage

Render a simple list from a q-array model using for.

q-import { q-components.qhtml } q-component demo-list-view extends q-list-view { q-property model: q-array { "hello world", "item 2", "item 3" } } demo-list-view#my-list { }

e-store component suite demo

Integrated demo using q-estore-pricebox and q-checkout-modal.

q-import { q-components.qhtml } button.w3-button.w3-small.w3-border.w3-round { text { Load Alternate Products } onclick { demoestore.products = QArray([ { SKU: "ALT-001", name: "Travel Bottle", description: "Insulated stainless steel", price: "29.00" }, { SKU: "ALT-002", name: "Desk Mat", description: "Felt anti-slip surface", price: "22.50" }, { SKU: "ALT-003", name: "Pen Set", description: "Fine-tip gel pens", price: "12.99" }, { SKU: "ALT-004", name: "Cable Kit", description: "USB-C and Lightning pack", price: "18.75" } ]); } } q-estore demoestore { id: "demo-estore" }

q-spritesheet [alpha] usage

Declarative spritesheet player with frame range, speed, size, and interpolation controls.

q-import { q-components.qhtml } q-component sprite-demo-status { q-property textValue: "frame: 0" div.w3-small.w3-text-indigo { text { ${this.component.textValue} } } } div.w3-container.w3-border.w3-round-large.w3-padding { sprite-demo-status demoStatus { } q-spritesheet demoSheet { source: "assets/test-ss.png" frameCount: 18 frameStart: 0 frameStop: 17 frameDuration: 70 frameWidth: 32 frameHeight: 32 repeat: true running: false interpolate: true onframechanged(frameIndex) { demoStatus.textValue = "frame: " + String(frameIndex); } } div.w3-margin-top { button.w3-button.w3-border.w3-round.w3-small { text { Start } onclick { demoSheet.start(); } } button.w3-button.w3-border.w3-round.w3-small.w3-margin-left { text { Stop } onclick { demoSheet.stop(); } } button.w3-button.w3-border.w3-round.w3-small.w3-margin-left { text { Toggle Interpolate } onclick { demoSheet.interpolate = !demoSheet.interpolate; } } } }

q-painter border/background/mask demo

Three unique painters mapped to border, background, and mask using declarative q-style-painter.

q-painter painterBackground { onpaint { var w = this.width; var h = this.height; this.fillStyle = "#ff006e"; this.fillRect(0, 0, w, h); this.fillStyle = "#ffd60a"; this.fillRect(0, 0, w * 0.5, h * 0.5); this.fillStyle = "#00d1ff"; this.fillRect(w * 0.5, h * 0.5, w * 0.5, h * 0.5); this.fillStyle = "#00f5a0"; this.fillRect(0, h * 0.58, w, h * 0.16); this.fillStyle = "#111827"; this.fillRect(w * 0.46, 0, w * 0.08, h); } } q-painter painterBorder { onpaint { var w = this.width; var h = this.height; var band = Math.max(6, Math.floor(Math.min(w, h) * 0.12)); this.fillStyle = "#ff0033"; this.fillRect(0, 0, w, h); this.fillStyle = "#00e5ff"; this.fillRect(band, band, w - (band * 2), h - (band * 2)); this.fillStyle = "#000000"; this.fillRect(band * 2, band * 2, w - (band * 4), h - (band * 4)); this.fillStyle = "#f6ff00"; this.fillRect(0, h * 0.42, w, h * 0.16); this.fillRect(w * 0.42, 0, w * 0.16, h); } } q-painter painterMask { q-property topWidth: 62 q-property topHeight: 34 onpaint { var w = this.width; var h = this.height; var tw = Number(this.topWidth || 62); var th = Number(this.topHeight || 34); if (!Number.isFinite(tw) || tw < 10) { tw = 10; } if (tw > 95) { tw = 95; } if (!Number.isFinite(th) || th < 10) { th = 10; } if (th > 90) { th = 90; } var topWidth = w * tw / 100; var left = (w - topWidth) / 2; this.clearRect(0, 0, w, h); this.fillStyle = "black"; this.beginPath(); this.moveTo(left, 0); this.lineTo(w - left, 0); this.lineTo(w, h * th / 100); this.lineTo(w * 0.5, h); this.lineTo(0, h * th / 100); this.closePath(); this.fill(); } } q-style painterPanelBase { width: 220px height: 92px borderRadius: 10px display: inline-flex alignItems: center justifyContent: center marginRight: 10px marginBottom: 10px color: #0f172a fontWeight: 700 fontFamily: monospace letterSpacing: 0.02em border: 1px solid #334155 } q-style panelBackgroundStyle { width: 220px height: 92px borderRadius: 10px border: 1px solid #334155 display: inline-flex alignItems: center justifyContent: center color: #0f172a fontWeight: 700 fontFamily: monospace background-repeat: no-repeat background-size: 100% 100% q-style-painter { background { painterBackground } } } q-style panelBorderStyle { width: 220px height: 92px borderRadius: 10px border: 18px solid transparent border-image-slice: 0 backgroundColor: #f8fafc display: inline-flex alignItems: center justifyContent: center color: #0f172a fontWeight: 700 fontFamily: monospace q-style-painter { border { painterBorder } } } q-style panelMaskStyle { width: 220px height: 92px borderRadius: 10px border: 1px solid #334155 background: linear-gradient(90deg, #ff006e 0%, #ffd60a 20%, #00d1ff 40%, #00f5a0 60%, #8b5cf6 80%, #111827 100%) display: inline-flex alignItems: center justifyContent: center color: #0f172a fontWeight: 700 fontFamily: monospace mask-repeat: no-repeat mask-size: 100% 100% mask-position: center -webkit-mask-repeat: no-repeat -webkit-mask-size: 100% 100% -webkit-mask-position: center q-style-painter { mask { painterMask } } } q-theme painterTriptychTheme { .panel-background { panelBackgroundStyle } .panel-border { panelBorderStyle } .panel-mask { panelMaskStyle } } painterTriptychTheme { div.w3-container.w3-border.w3-round-large.w3-padding { div#ptri-bg.panel-background { text { background painter } } div#ptri-border.panel-border { text { border painter } } div#ptri-mask.panel-mask { text { mask painter } } p#ptri-status.w3-small.w3-text-indigo { text { painter status: checking... } } } } onready { var support = !!(CSS && CSS.paintWorklet && typeof CSS.paintWorklet.addModule === "function"); var bg = document.querySelector("#ptri-bg"); var border = document.querySelector("#ptri-border"); var mask = document.querySelector("#ptri-mask"); var out = document.querySelector("#ptri-status"); var bgStyle = bg ? String(bg.style.backgroundImage || "").trim() : ""; var borderStyle = border ? String(border.style.borderImageSource || "").trim() : ""; var maskStyle = mask ? String(mask.style.maskImage || mask.style.webkitMaskImage || "").trim() : ""; if (out) { out.textContent = "painter support=" + String(support ? 1 : 0) + " | background=" + bgStyle + " | border=" + borderStyle + " | mask=" + maskStyle; } }

q-tech-panel Houdini panel showcase

Five large direct child divs using different clipped corners, top dents, border widths, shadows, and grid patterns.

q-import { q-components.qhtml } q-style tech-panel-stage { display: grid gridTemplateColumns: repeat(auto-fit, minmax(320px, 1fr)) gap: 22px padding: 18px background: #07111f } q-style tech-panel-box { minHeight: 24vh height: 260px padding: 30px 34px color: #e6fbff fontFamily: monospace fontWeight: 700 letterSpacing: 0.04em display: flex alignItems: center justifyContent: center textAlign: center } q-theme techPanelDemoTheme { .tech-stage { tech-panel-stage } .tech-box { tech-panel-box } } techPanelDemoTheme { div.tech-stage { q-tech-panel { borderWidth: "8px" borderColor: "#6ee7ff" shadowColor: "#00ff99" topLeft: "34px" bottomRight: "42px" topDent: "30px" topDentLength: "24%" patternSize: "22px" div.tech-box { text { CYAN COMMAND PANEL } } } q-tech-panel { borderWidth: "5px" borderColor: "#ffcc66" shadowColor: "#ff7a18" topRight: "54px" bottomLeft: "48px" topDent: "46px" topDentLength: "34%" patternShift: "20px 36px" patternSize: "28px" percentage: "0.35" div.tech-box { text { AMBER REACTOR SLOT } } } q-tech-panel { borderWidth: "4px" borderColor: "#d8b4fe" shadowColor: "#a855f7" topLeft: "58px 38px" topRight: "38px 58px" bottomRight: "70px 44px" bottomLeft: "44px 70px" topDent: "26px" topDentLength: "42%" patternSize: "18px" percentage: "0.55" div.tech-box { text { VIOLET SYMMETRY FRAME } } } q-tech-panel { borderWidth: "2px" borderColor: "#86efac" shadowColor: "#22c55e" topLeft: "20px" topRight: "72px" bottomRight: "32px" bottomLeft: "86px" topDent: "54px" topDentLength: "18%" patternShift: "-18px 26px" patternSize: "34px" percentage: "0.2" div.tech-box { text { GREEN HEAVY ARMOR PANEL } } } q-tech-panel { borderWidth: "1px" borderColor: "#fca5a5" shadowColor: "#ef4444" topLeft: "46px" topRight: "18px" bottomRight: "58px" bottomLeft: "28px" topDent: "18px" topDentLength: "30%" patternShift: "12px -18px" patternSize: "20px" percentage: "0.48" div.tech-box { text { RED THIN SIGNAL PANEL } } } } }

q-toolbar + q-toolbutton usage

Floating, draggable, resizable toolbar with square toolbuttons that auto-scale from container resize events.

q-import { q-components.qhtml } div.w3-container.w3-border.w3-round-large.w3-padding { h4 { text { Toolbar Demo } } p { text { Drag from the top edge, resize from bottom-right corner, and click X to close. } } button.w3-button.w3-small.w3-border { text { Re-open toolbar } onclick { toolboxMain.showToolbar(); } } q-toolbar toolboxMain { id: "toolbox-main" title: "Quick Tools" x: 160 y: 120 width: 360 height: 72 q-toolbutton { src: "q-components/expand-collapse.svg" label: "Open File" onclick { alert("file open clicked") } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Save" onclick { alert("save clicked") } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Settings" onclick { alert("settings clicked") } } } }

Unified Commerce Ops Hub

One integrated control surface combining navigation, storefront, monitoring, and quick actions with typed named instances.

q-import { q-components/q-sidebar.qhtml?v=drawer-width } q-import { q-components/q-tabs.qhtml } q-import { q-components/q-modal.qhtml } q-import { q-components/q-popup-menu.qhtml?v=popup-redesign-6 } q-import { q-components/q-toolbar.qhtml } q-import { q-components/q-estore.qhtml } q-import { q-components/q-spritesheet.qhtml?v=6.3.2 } q-import { q-components/q-grid.qhtml } q-import { q-components/q-form.qhtml } q-import { q-components/q-list-view.qhtml } q-import { q-components/q-tree-view.qhtml?v=tree-css-28 } q-import { q-components/q-tech-tag.qhtml } q-model hubTreeModel { q-map { storefront: q-array { "catalog", "checkout", "orders" } runtime: q-array { "signals", "timers", "workers" } assets: q-array { "spritesheet", "icons", "theme" } } } q-component hub-status-pill { q-property textValue: "frame: 0" div.w3-small.w3-padding-small.w3-round.w3-border.w3-pale-blue { text { ${this.component.textValue} } } } q-component hub-activity-list extends q-list-view { q-property model: q-array { "hub initialized", "catalog loaded", "sprite ready" } } q-modal hubInfoModal { title { h4 { text { Hub Command Summary } } } body { p { text { This unified hub combines storefront controls, runtime observability, and quick command actions. } } p { text { Use the left navigation, floating toolbar, and context menu to drive one shared workspace. } } } footer { button.w3-button.w3-border.w3-round { text { Close } onclick { hubInfoModal.hide(); } } } onready { this.component.hide(); } } q-popup-menu hubContextMenu { id: "hub-context-menu" popup-contents { ul.w3-ul.w3-small.w3-card { li { text { Open Overview } onclick { hubTabs.showTab(0); } } li { text { Open Store } onclick { hubTabs.showTab(1); } } li { text { Start Sprite } onclick { hubSprite.start(); } } hr { } li { text { Open Summary Modal } onclick { hubInfoModal.show(); } } } } onready { this.closest("q-popup-menu").style.display = "none"; } } div.w3-container.w3-border.w3-round-large.w3-padding { h4 { text { Commerce Operations Hub } } p.w3-small { text { Right-click inside the workspace to open the command menu. } } hub-status-pill hubFrameStatus { } q-tech-tag.w3-tag.w3-blue.w3-round.w3-small.w3-margin-left { text { unified-demo } } q-sidebar hubSidebar { sidebarWidth: "250" collapsedWidth: "40px" open: "1" content { div.w3-padding.w3-small { h5 { text { Navigation } } button.w3-button.w3-small.w3-border.w3-round.w3-margin-bottom { text { Overview } onclick { hubTabs.showTab(0); } } button.w3-button.w3-small.w3-border.w3-round.w3-margin-bottom { text { Storefront } onclick { hubTabs.showTab(1); } } button.w3-button.w3-small.w3-border.w3-round.w3-margin-bottom { text { Runtime } onclick { hubTabs.showTab(2); } } button.w3-button.w3-small.w3-border.w3-round { text { Hub Summary } onclick { hubInfoModal.show(); } } } } main { div#hub-workspace.w3-padding.w3-round-large.w3-border { oncontextmenu { event.preventDefault(); hubContextMenu.show(event.clientX + "px", event.clientY + "px"); } q-tabs hubTabs { q-tab { name { text { Overview } } content { q-spritesheet hubSprite { source: "assets/test-ss.png" frameCount: 18 frameStart: 0 frameStop: 17 frameDuration: 90 frameWidth: 32 frameHeight: 32 repeat: true running: false interpolate: false onframechanged(frameIndex) { hubFrameStatus.textValue = "frame: " + String(frameIndex); } } div.w3-margin-top { button.w3-button.w3-small.w3-border.w3-round { text { Start Sprite } onclick { hubSprite.start(); } } button.w3-button.w3-small.w3-border.w3-round.w3-margin-left { text { Stop Sprite } onclick { hubSprite.stop(); } } } q-grid { columns: 3 div.w3-panel.w3-border.w3-round { text { active frame: ${hubSprite.currentFrame} } } div.w3-panel.w3-border.w3-round { text { frame count: ${hubSprite.frameCount} } } div.w3-panel.w3-border.w3-round { text { playback: ${hubSprite.running} } } } } } q-tab { name { text { Storefront } } content { button.w3-button.w3-small.w3-border.w3-round.w3-margin-bottom { text { Load Alternate Products } onclick { hubStore.products = QArray([ { SKU: "ALT-001", name: "Travel Bottle", description: "Insulated stainless steel", price: "29.00" }, { SKU: "ALT-002", name: "Desk Mat", description: "Felt anti-slip surface", price: "22.50" }, { SKU: "ALT-003", name: "Pen Set", description: "Fine-tip gel pens", price: "12.99" }, { SKU: "ALT-004", name: "Cable Kit", description: "USB-C and Lightning pack", price: "18.75" } ]); } } q-estore hubStore { } } } q-tab { name { text { Runtime } } content { q-tree-view { model: "hubTreeModel" } hub-activity-list hubLog { } q-form { h4 { text { Runtime Notes } } q-input { placeholder: "Operator" } q-textarea { text { Enter a runtime note... } } q-submit { text { Add Activity Entry } onclick { hubLog.model.push("note captured at frame " + String(hubSprite.currentFrame)); } } } } } } } } } q-toolbar hubTools { id: "hub-tools" title: "Hub Tools" x: 140 y: 140 width: 320 height: 70 q-toolbutton { src: "q-components/expand-collapse.svg" label: "Overview" onclick { hubTabs.showTab(0); } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Store" onclick { hubTabs.showTab(1); } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Start" onclick { hubSprite.start(); } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Stop" onclick { hubSprite.stop(); } } q-toolbutton { src: "q-components/expand-collapse.svg" label: "Summary" onclick { hubInfoModal.show(); } } } }

q-tech-tag.qhtml usage

Placeholder usage for currently empty file.

q-import { q-components/q-tech-tag.qhtml } q-style tech-note-style { background-color: #eef4ff color: #334155 border: 1px solid #c7d8ef } q-theme tech-tag-theme { .tech-note { tech-note-style } } tech-tag-theme { q-tech-tag { text { Extend this tag by adding definitions inside q-tech-tag.qhtml. } } div.tech-note.w3-panel.w3-small.w3-border { text { q-tech-tag.qhtml currently has no built-in definitions. } } }