Tweakit v0.7.2

The two builds

One source tree, two builds, one API. The only observable difference is when heavy controls exist.

EntrySizeLoading
tweakit~25 KB gzipcode-split; color engine and heavy controls dynamic-import on first use
tweakit/single~64 KB gzipthe single-file build; every control inlined, fully synchronous
tweakit/auto~25 KB gzipthe code-split entry, plus enhance(document) once the page has parsed, for a page of [data-twk] markup
tweakit/css~10 KB gzipthe 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, and gradient and shadow (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: monitor and fpsgraph share a module
  • motion: motion, which also loads spring and cubicbezier (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";