aporia
v0.3.1
Published
A small React UI kit for your little tools — a polished, draggable Panel with sliders, toggles, colors, and gradient controls.
Maintainers
Readme
aporia
aporia is a small React UI kit for your little tools.
Built for designers and visual builders who make lots of tiny branding tools, config panels, AI apps, and experiments, then need a fast way to tune values and make things feel right.
Install
npm i aporiaImport styles once in your app entry:
import 'aporia/styles.css'Prompt an LLM
You can use Aporia with any LLM by just asking naturally, like:
Install the aporia npm package and add it to this configurator - hook up all sliders, toggles, colors, and other adjustable values to the right state and actions so everything actually controls the app.Quick start
import { useState } from 'react'
import Panel, { Category, SliderRow, ColorRow, ToggleRow } from 'aporia'
import 'aporia/styles.css'
export default function App() {
const [size, setSize] = useState(40)
const [color, setColor] = useState('#E8470C')
const [enabled, setEnabled] = useState(true)
return (
<Panel>
<Category title="Basics">
<SliderRow label="Size" value={size} min={0} max={100} step={1} onChange={setSize} />
<ColorRow label="Color" value={color} onChange={setColor} />
<ToggleRow label="Enabled" checked={enabled} onChange={setEnabled} />
</Category>
</Panel>
)
}What you get
Panel+Categorylayout primitivesSliderRow,NumberRow,TextRow,ColorRow,ToggleRow,SelectRow,GradientRow,ButtonRowGradientPicker+ gradient utils (parseGradient,stopsToGradient)usePresets+PresetRow— save, load, and delete named value presetsDriverProvider+useDriverClock— driveSliderRow/NumberRowvalues from time-based generators- Keyboard accessible controls and polished defaults
Presets
Save and restore sets of values. You stay in control of your state — usePresets
just snapshots the values you give it and applies them back. Pass a storageKey to
persist to localStorage.
import Panel, { Category, SliderRow, PresetRow, usePresets } from 'aporia'
function App() {
const [size, setSize] = useState(40)
const [color, setColor] = useState('#E8470C')
const presets = usePresets({
values: { size, color },
onApply: (v) => { setSize(v.size); setColor(v.color) },
storageKey: 'my-tool',
})
return (
<Panel>
<Category title="Presets">
<PresetRow presets={presets} />
</Category>
<Category title="Controls">
<SliderRow label="Size" value={size} min={0} max={100} onChange={setSize} />
<ColorRow label="Color" value={color} onChange={setColor} />
</Category>
</Panel>
)
}Driven values
Give a SliderRow or NumberRow a stable id inside a DriverProvider, and a small dot
appears on the row that opens a generator editor — sine, triangle, ramp, pulse, or noise — so a
value can animate itself over time. Grabbing the control hands the live value back and turns the
driver off.
Aporia never runs its own animation loop. You feed it time from your existing render loop with
useDriverClock().tick(t) and read the live values back with getValue(id) — one clock, no drift.
import Panel, { Category, SliderRow, DriverProvider, useDriverClock } from 'aporia'
function Clock() {
const { tick, getValue } = useDriverClock()
useEffect(() => {
let raf = 0
const start = performance.now()
const loop = (now: number) => {
tick((now - start) / 1000) // feed absolute seconds
const spread = getValue('spread') // live value, or undefined when not driven
// ...apply `spread` to your scene
raf = requestAnimationFrame(loop)
}
raf = requestAnimationFrame(loop)
return () => cancelAnimationFrame(raf)
}, [tick, getValue])
return null
}
function App() {
const [spread, setSpread] = useState(0.5)
return (
<DriverProvider>
<Clock />
<Panel>
<Category title="Motion">
<SliderRow id="spread" label="Spread" value={spread} min={0} max={1} step={0.01} onChange={setSpread} />
</Category>
</Panel>
</DriverProvider>
)
}The id must be stable for the row's lifetime — it's the key the clock reads values back by. You
can also seed a driver in code with defaultDriver={{ kind: 'sin', rate: 0.25, amplitude: 0.35, center: 0.5 }}.
Notes
- The UI theme is dark by default.
- Peer deps:
react,react-dom,motion,@base-ui/react.
License
MIT
