The two builds
One source tree, two builds, one API. The only observable difference is when heavy controls exist.
| Entry | Size | Loading |
|---|---|---|
tweakit | ~25 KB gzip | code-split; color engine and heavy controls dynamic-import on first use |
tweakit/single | ~64 KB gzip | the single-file build; every control inlined, fully synchronous |
tweakit/auto | ~25 KB gzip | the code-split entry, plus enhance(document) once the page has parsed, for a page of [data-twk] markup |
tweakit/css | ~10 KB gzip | the stylesheet, the same for both builds; add it to either figure for the full weight on the wire |
The default suits an app: users who never open a picker never download the color
engine. Pick /single for one file you can drop in, or when you want every control
built the moment tweaks() returns. Only tweakit/auto and the
stylesheet act on the page when imported, so a bundler drops an import of the kit that your
production code never calls.
panel.ready
tweaks() returns synchronously on both builds: the panel
element, params and methods are live at once. On the split build, a panel whose
schema needs lazy modules builds all of its controls when panel.ready
resolves (until then the shell is an empty frame); on the single-file build,
ready resolves immediately. On either build, a panel that persists an image
control builds without its stored images and resolves ready once they're back. This page runs the split build; the stamp
shows how long the lazy path took (the docs preload the chunks, so this is the
import, not a network round trip).
…const stamp = target.querySelector(".im-stamp");
const t0 = performance.now();
const panel = tweaks("Ready", {
motion: { type: "spring", stiffness: 220, damping: 18, mass: 1 }, // lazy here
speed: [1, 0, 3, 0.1], // built-in
});
mount.append(panel.el); // the shell mounts now; controls build at ready
panel.ready.then(() => {
stamp.textContent = `panel.ready resolved in ${Math.round(performance.now() - t0)} ms`;
});mount is the panel's slot inside the stage; target is the demo surface it controls. In your own page you'd just document.body.append(panel.el).
What loads when
On the split build, these schema types trigger a dynamic import the first
time any panel (or [data-twk] host) uses them; once loaded, they're
synchronous for the rest of the session:
- color engine:
color, andgradientandshadow(which build on it) - numeric field engine:
number(the boxed fields of spring, point, cubicbezier, motion, shadow and the color channels reuse it) - one module each:
interval,sides,spring,cubicbezier,point,plot,image,tabs - monitors:
monitorandfpsgraphshare a module - motion:
motion, which also loadsspringandcubicbezier(its two editors)
Everything else (slider, text, checkbox, list,
radiogrid, button, buttongroup, folder,
separator) ships in core and is always synchronous.
The exports map
Everything the package ships, by import path. Types ride along with every entry.
import { tweaks, enhance, mountControl, createColorPicker, gradientCss, gradientStops } from "tweakit"; // code-split
import { tweaks, enhance, mountControl, createColorPicker, gradientCss, gradientStops } from "tweakit/single"; // single-file build
import { tweaks, enhance, mountControl, createColorPicker, gradientCss, gradientStops } from "tweakit/auto"; // code-split, binds [data-twk] on load
import "tweakit/css"; // panel styles
import type { Schema, Panel, PanelState, Theme, TweaksOptions, GradientValue, MotionValue, ShadowValue } from "tweakit";