Markup
The second way in: write [data-twk] markup and enhance()
upgrades each host into a live control in place. Importing tweakit binds
nothing by itself. Import tweakit/auto instead, the same API, and it runs
enhance(document) once the page has parsed; this page does, so the first three
examples are plain HTML, no page script at all. Or call enhance() yourself, for
the whole page or for DOM added later.
A static panel shell
A .twk-panel shell with [data-twk] hosts inside
becomes the real thing: collapsible header, copy + reset toolbar operating over
its controls, the works. Each control writes its live value back onto its host's
data-value attribute. A data-key names the control in
the toolbar's copied JSON (and stands in for a missing data-label);
without one, the label is the key.
<div class="twk-panel" data-mode="inline" style="max-width: 300px">
<div class="twk-header"><span class="twk-title">Static</span></div>
<div class="twk-controls">
<div data-twk="slider" data-label="Blur" data-value="12" data-min="0" data-max="40" data-unit="px"></div>
<div data-twk="checkbox" data-label="Visible" data-checked="true"></div>
<div data-twk="list" data-label="Blend" data-options="normal, multiply, screen" data-value="normal"></div>
</div>
</div>Heavy controls from markup
Most controls work declaratively: their config flattens into
data-* attributes, and the lazy ones load on demand exactly as they
do from a schema. Markup understands slider, number,
checkbox (with data-options it becomes a radio grid),
radiogrid (or segmented), list, text, color,
gradient, image, button, buttongroup,
separator, interval, spring,
cubicbezier, motion, shadow, sides, point, plot,
monitor and fpsgraph, plus the folder wrapper below.
An image with data-options, a comma list of URLs, is the gallery.
tabs is panel-only; a host naming it is left untouched.
<div class="twk-panel" data-mode="inline" style="max-width: 300px">
<div class="twk-header"><span class="twk-title">Heavy</span></div>
<div class="twk-controls">
<div data-twk="color" data-label="Tint" data-value="#7C5CFF"></div>
<div data-twk="spring" data-label="Motion" data-stiffness="220" data-damping="18" data-mass="1"></div>
<div data-twk="point" data-label="Offset" data-components="X,Y" data-value="0,0" data-min="-50" data-max="50" data-pad="true"></div>
<div data-twk="interval" data-label="Band" data-value="30,70" data-min="0" data-max="100" data-step="1"></div>
</div>
</div>Bare hosts, anywhere
Hosts don't need a panel shell: a [data-twk] div in any
layout enhances in place (a data-hint rides along as the ⓘ tooltip).
A data-twk="folder" wraps its children in a collapsible group.
<div style="max-width: 300px">
<div data-twk="folder" data-label="Inline anywhere">
<div data-twk="slider" data-label="Speed" data-value="1.5" data-min="0" data-max="3" data-step="0.1"
data-hint="Just a div in the page"></div>
<div data-twk="radiogrid" data-label="Size" data-options="S, M, L, XL" data-cols="2" data-value="M"></div>
</div>
</div>Listening for changes
Every edit on a host writes its data-value and dispatches a
bubbling twk:change event with { key, value } in
detail (key is the host's data-key, or its
label), so one listener on an ancestor hears every control under it. The host also
keeps its handle at host._tw.ctrl: get() reads the value
and set(v) applies one and runs the same change path (data-value
+ event). Drag the slider, then hit the button.
Change something
const log = target.querySelector(".mk-log");
target.addEventListener("twk:change", (e) => {
log.textContent = e.detail.key + " → " + JSON.stringify(e.detail.value) + " (data-value=" + e.target.dataset.value + ")";
});
enhance(target).then(() => {
const host = target.querySelector("[data-twk]");
target.querySelector(".mk-set").addEventListener("click", () => host._tw.ctrl.set(Math.round(Math.random() * 40)));
});Binding on load, or yourself
tweakit/auto covers the document as it parsed. Without it,
call enhance(), which binds the whole document by default. For markup you
inject later (a modal, a CMS block, a partial render), call it on the new root, which
counts too when it is itself a [data-twk] host. Hosts that are already live
are skipped, so re-running is safe. With the single-file build and no bundler, the same
call goes in your module script: import { enhance } from "./tweaks.js"; enhance();
import "tweakit/auto"; // binds the page's [data-twk] hosts once it has parsed
// or, from tweakit or tweakit/single:
import { enhance } from "tweakit";
await enhance(); // the whole document
modal.innerHTML = controlsMarkup;
await enhance(modal); // resolves once any lazy modules have loaded