Settings panel for tweaking apps, demos or tests. Pass values, get controls.
import settings from 'settings-panel'
const state = settings({
enabled: true,
volume: 0.8,
color: '#4a90d9',
quality: ['auto', 'low', 'high'],
reset: () => location.reload()
})
state.volume = 0.5 // UI updatesTypes are inferred from values.
| Type | Inferred from |
|---|---|
boolean |
true, false |
number |
123 |
slider |
0.5 (normalized 0-1), or { min, max } |
text |
'hello' |
textarea |
'line one\nline two' (multiline) |
color |
'#hex', 'rgb()', 'hsl()' |
select |
['a', 'b', 'c'] or { options: [] } |
button |
() => {} |
folder |
'group.key' dot-notation |
settings({
// Inferred
debug: false,
gain: 0.5,
// Explicit
frequency: { type: 'slider', min: 20, max: 20000, scale: 'log' },
palette: { type: 'color', variant: 'swatches' }
})Two themes today: default (browser baseline) and skeu (tactile, textured).
import settings from 'settings-panel'
import skeu from 'settings-panel/theme/skeu'
settings(schema, {
theme: skeu({ shade: '#1a1a1a', accent: '#8855cc', spacing: 0.3 })
})Themes are functions: axes in, CSS out. Default axes: shade, accent, spacing, size, weight, roundness. Skeu adds: contrast, depth, relief, bevel, grid. See axes.
settings(schema, {
container: '#app',
title: 'Settings',
theme: skeu({ shade: '#2a2a2a' }),
collapsed: false,
persist: 'my-app',
onChange: (state) => console.log(state)
})State is a signals store. Subscribe via effect, swap signal implementation via use().
import settings, { effect } from 'settings-panel'
const state = settings({ volume: 0.8 })
effect(() => audio.gain.value = state.volume)// Use @preact/signals instead of built-in
import { use } from 'settings-panel'
import * as signals from '@preact/signals'
use(signals)tweakpane · leva · lil-gui · uil · dat.gui · control-panel · oui
