@warmjs/ui
v1.0.0
Published
WarmJS UI primitives and panels (header, slider, tabs, toggle, knob, color, modals, editors). Zero-dependency, no virtual DOM.
Readme
@warmjs/ui
WarmJS UI primitives + one demo panel, built on @warmjs/core (direct-DOM JSX) and @warmjs/signals (fine-grained reactivity). Zero-dependency. Drop-in trial replacement for the equivalent Preact components in Pixorig.
Contents
WarmPanelHeader— same UX asPreactPanelHeader(Back + Reset).WarmSliderControlGroup— reactive slider. Only the value label + thumb position update via effects; no whole-component re-render.WarmOpacityPanel/mountWarmOpacityPanel— full port of Pixorig's PreactOpacityPanel, decoupled from Pixorig services via callbacks.
Trial in Pixorig (opacity only)
Replace one import in the file that opens the opacity panel:
// before (Preact)
import { mountOpacityPanel } from "./panels/common/opacity-panel";
// trial (WarmJS, vendored or npm-linked)
import { mountWarmOpacityPanel } from "@warmjs/ui";
import { OpacityService } from "./core/layer/opacity-service";
const dispose = mountWarmOpacityPanel(subSidebar, {
initialOpacity: OpacityService.getOpacityPercent(layer),
onOpacityChange: (v) => OpacityService.setOpacity(layer, v, { layerManager }),
onResetRequest: () => OpacityService.resetOpacity(layer, { layerManager }),
onBack: restoreSubSidebar,
onUnmount: () => {},
});dispose() removes the wrapper (replaces Preact's render(null, root)).
Why the slider is different
Preact version: useState re-renders the whole slider subtree on every % change.
WarmJS version:
valueaccepts a plainnumber(static) or a signalGetter<number>(reactive).- The
%label is a liveTextnode frombindText(). - The
<input type="range">position is patched in acreateEffect(), guarded bydocument.activeElementso dragging is not interrupted.
License
MIT.
