DialKit

Josh Puckett's floating or inline tuning panel, plus individually exported controls: sliders, segmented toggles, color/image pickers, XY pads, and spring/Bézier editors wired to real UI values.

What It Does

DialKit renders a draggable floating panel that auto-generates controls from a config object. Call useDialKit("name", config) in any component and get a collapsible folder in the panel with sliders, toggles, pickers, spring/easing editors, and action buttons. Source: Obsidian-LLM-Wiki/Clippings/Josh Puckett.md; https://joshpuckett.me/dialkit

The panel is dev-only by default (productionEnabled: false). Supports popover and inline modes.

Config Types

Format Control Description
[default, min, max, step?] Slider Explicit range with optional step
number Slider Auto-inferred range
boolean Toggle On/off segmented control
"#ff5500" Color Picker Auto-detected from hex strings
"Hello" Text Input Auto-detected from non-hex strings
{ type: "spring", ... } Spring Editor Visual spring curve, Time/Physics modes
{ type: "easing", ... } Easing Editor Cubic bezier curve with duration preview
{ type: "select", ... } Select Dropdown with options array
{ type: "color", default: ... } Color Picker Explicit color; supports alpha, OKLCH, and Display P3 as well as hex/RGB/HSL
{ type: "image", options: [...] } Image Picker Labeled URL choices or a local image upload
{ type: "pad", x: [...], y: [...] } XY Pad Bounded two-axis values with snapping and keyboard adjustment
{ type: "action" } Button Triggers onAction callback
{ nested: ... } Folder Collapsible group

Keyboard Shortcuts

Assign keyboard shortcuts to controls: hold key + scroll, drag, or move mouse to adjust values without touching the panel. Interaction types: scroll, drag, move, scroll-only.

Installation

npm install dialkit motion

Add <DialRoot /> as sibling to {children} in root layout. Import dialkit/styles.css.

Use Cases

  • Tuning spring physics (visualDuration, bounce) on hover animations
  • Adjusting layout values (gap, padding, columns, radius) in real-time
  • Exploring visual variations (colors, opacity, blur) on components
  • Triggering replay of entrance animations via action buttons
  • Live-tweaking Motion transition parameters during development

Tuning Console Pattern

Soren Blank's Linear parallax-bar recreation shows the high-leverage use case: use a DialKit-like floating panel as a temporary console for spatial/motion parameters while the component updates live. The reviewed video exposes bar count, step sizes, diagonal offsets, peak nodes, peak height, falloff, and floor. The lesson is to make hard-to-see motion geometry explicit while developing, then preserve the final values as constants or design tokens. Source: X/@sorenblank and local video contact sheet, 2026-07-03

Frameworks

React (default), Solid (dialkit/solid), Svelte 5 (dialkit/svelte), Vue 3 (dialkit/vue), and imperative DOM (dialkit/vanilla). Config concepts are shared, but hooks, accessors, lifecycle, and component bindings are framework-specific; do not paste one adapter's API unchanged into another. Store and timeline entry points are also exported. Source: pinned repository package.json, docs/reference.md, and docs/timeline.md

Source-Verified Adoption Boundary

The 2026-09-05 review binds npm dialkit@2.0.0 to repository commit d408597c85b118dc497a209c5f1dc396922f8cc7. The repository's package.json still says 1.4.4, while npm has no release at that version. npm's gitHead matches the pinned commit, the tarball's SHA-512 integrity was verified, and published dist/styles.css is byte-identical to src/styles/theme.css. Treat the package metadata mismatch as a versioning hazard, not evidence of a different stylesheet. License: MIT, copyright 2026 Josh Puckett; preserve the notice when copying source or styles. Source: pinned repository, published npm metadata and tarball; outputs/2026-09-05/source-compile/dialkit.md

Controlled components, not a second settings owner

The React package exposes useful controls separately from DialRoot:

Public export Controlled contract / adoption boundary
Slider value, onChange, bounded min/max/step, optional unit; drag, keyboard, and precise numeric editing
Toggle checked, onChange; a two-button Off/On radio group, not a switch
SelectControl value, options, onChange; portal-backed, keyboard-operable menu
TextControl value, onChange, optional placeholder; autosizing text input
ColorControl Color string plus onChange; real picker, gamut/alpha controls, and format editing
ImageControl URL/string value, optional labeled choices, onChange; uploads become data URLs, not remote storage
DialPad {x,y} value and onChange; separate axis ranges; use only for a genuine two-axis relation
EasingVisualization Easing object and optional onChange; editable cubic-Bézier geometry without a registered panel
SpringVisualization Read-only curve from spring parameters and a mode flag
Folder Optional controlled open/onOpenChange; group related controls without requiring a floating root
ButtonGroup Array of {label,onClick} actions in a vertical stack, not a segmented value selector

SegmentedControl exists internally but is not a public package export. SpringControl and TransitionControl accept values and callbacks, but their Time/Physics/Easing mode uses a registered DialStore panel. With no panel, updateTransitionMode is a no-op; they are not fully store-independent standalone editors. ControlRenderer, PresetManager, and ShortcutsMenu likewise depend on the library store. Read the exported declaration rather than guessing from a component's screenshot or filename. Source: pinned src/index.ts, src/components/{Toggle,ButtonGroup,TransitionControl}.tsx, src/store/DialStore.ts, published dist/index.d.ts

For a product inspector that already has saved settings, the preferred host interpretation is to pass those settings into the real controlled exports and keep one existing persistence owner. This is an adoption decision, not an upstream requirement. If using DialRoot, its default production visibility is off, its persistence default is false, and mode="inline" avoids a second floating panel. A stable panel ID retains in-memory state across mounts; explicit local/session persistence also owns presets and values. Source: pinned docs/reference.md; Personal Website integration direction, 2026-09-05

Visual and runtime checks before shipping

  • The actual source grammar is compact: 36px rows, 6px row gaps, 13px labels, 8px control radius, 14px panel radius, and low-contrast nested surfaces. Preserve that hierarchy when fitting the host; do not reduce it to a generic collection of sliders. These measurements describe the source, not universal application spacing rules.
  • The CSS begins with a remote Google Geist Mono import. A self-hosted-font application should remove that import in an attributed scoped copy and map its existing text/value fonts deliberately. Keep .dialkit-root tokens and theme ownership consistent, including portal content.
  • Dark tertiary text is 40% white. Verify actual composited contrast and focus visibility instead of assuming the upstream alpha values satisfy the host's small-text requirements.
  • Slider release/fill springs use imperative Motion animate(). The source's reduced-motion CSS rules cover selected CSS transitions, not every imperative animation. Verify the host reduced-motion branch explicitly.
  • Image uploads are data URLs with a 10MB file cap; persisting several can exhaust browser storage. Only expose uploads if the product needs them.
  • Color parsing does not accept CSS variables, named colors, or arbitrary CSS expressions. Resolve host tokens before passing a color to the picker.
  • Root/picker menus use portals, fixed positioning, and optional browser top-layer popovers. Verify theme inheritance, clipping, scroll, touch, and keyboard focus in the actual sidebar.
  • The separate timeline clock defaults to autoplay; hiding its UI does not stop playback. Do not add it merely for appearance or replace an existing owned animation clock without an explicit lifecycle decision.

These boundaries come from the pinned source, not a general accessibility or production-readiness claim. 45 upstream pure tests passed for numeric values, keyboard helpers, color/gamut handling, XY geometry, Bézier geometry, popover measurement, image values, panel drag helpers, and copy instructions. Framework/browser interaction, host theme contrast, reduced motion, and app integration were not exercised by this source review. Source: outputs/2026-09-05/source-compile/dialkit.md


Timeline