Tweaks
A floating development panel for adjusting the HUD theme live: accent hue, glow intensity and
five on/off flags. Pair it with useTweakApply to write the hue and glow into the design
tokens.
import { Tweaks } from 'jarvis-react-ui';
Warning: Development aid
Tweaks is meant for showcases, prototypes and design sessions. Do not ship it in a production UI; render it behind a dev flag such as
import.meta.env.DEV. For a permanent theme, override the tokens in CSS instead (see Theming).
Panel and useTweakApply
Tweaks is controlled: it shows tweaks and calls onChange with the complete next object.
open shows or hides it. The panel is position: fixed in the bottom-right corner (14px from the
right, 110px from the bottom); in this demo frame it stays within the frame.
useTweakApply(tweaks) sets the accent and glow variables on :root, so moving the hue slider or
picking a swatch recolors this whole page.
import { useState } from 'react';
import { Button, Tweaks, TWEAKS_DEFAULTS, useTweakApply } from 'jarvis-react-ui';
import type { TweaksState } from 'jarvis-react-ui';
export default function Panel() {
const [open, setOpen] = useState(true);
const [tweaks, setTweaks] = useState<TweaksState>(TWEAKS_DEFAULTS);
// Writes the accent + glow tokens to :root; removes them again on unmount.
useTweakApply(tweaks);
return (
<div className="flex flex-col items-start gap-3 self-start">
<Button variant={open ? 'primary' : 'secondary'} onClick={() => setOpen((v) => !v)}>
{open ? 'Close tweaks' : 'Open tweaks'}
</Button>
<span className="text-[10px] text-text-muted">
hue {tweaks.hue}° · glow {tweaks.glow}
</span>
<Tweaks open={open} tweaks={tweaks} onChange={setTweaks} />
</div>
);
}
Note: Automatic reset
When the component that calls
useTweakApplyunmounts, the hook removes every variable it set, so the stylesheet tokens apply again. Leaving this page therefore restores the default colors.
Feature flags
scan, grid, rings, particles and idleDim are plain booleans that only live in your
tweaks state. No library code reads them: neither the panel nor useTweakApply turns on
scanlines, a grid, orb rings, particles or idle dimming by itself. Your app decides what each flag
means and passes it on, for example to the rings and particles props of CssOrb, or to whether
you render scanline and grid layers at all. This demo flips two of them with switches.
import { useState } from 'react';
import { CssOrb, Switch, TWEAKS_DEFAULTS } from 'jarvis-react-ui';
import type { TweaksState } from 'jarvis-react-ui';
export default function FeatureFlags() {
const [tweaks, setTweaks] = useState<TweaksState>(TWEAKS_DEFAULTS);
return (
<div className="flex w-full flex-col items-center gap-3">
<div className="flex gap-4">
<Switch
label="Rings"
checked={tweaks.rings}
onCheckedChange={(rings) => setTweaks({ ...tweaks, rings })}
/>
<Switch
label="Particles"
checked={tweaks.particles}
onCheckedChange={(particles) => setTweaks({ ...tweaks, particles })}
/>
</div>
<div className="relative h-[260px] w-full overflow-hidden">
<CssOrb state="idle" rings={tweaks.rings} particles={tweaks.particles} />
</div>
</div>
);
}
TWEAKS_DEFAULTS
The starting values. Use them as the initial state.
import { Tweaks, TWEAKS_DEFAULTS, useTweakApply, type TweaksState } from 'jarvis-react-ui';
const [tweaks, setTweaks] = useState<TweaksState>(TWEAKS_DEFAULTS);
useTweakApply(tweaks);
<Tweaks open={open} tweaks={tweaks} onChange={setTweaks} />;
| Field | Type | Default | Description |
|---|---|---|---|
hue |
number |
215 |
Accent hue in degrees (0–360); applied by useTweakApply. |
glow |
number |
74 |
Glow intensity (0–100); applied by useTweakApply. |
scan |
boolean |
true |
Show scanlines. Read by your app. |
grid |
boolean |
true |
Show the grid background. Read by your app. |
rings |
boolean |
true |
Show the orb rings. Read by your app. |
particles |
boolean |
true |
Show the orb particles. Read by your app. |
idleDim |
boolean |
true |
Dim the HUD while idle. Read by your app. |
The hue swatches in the panel select 215, 28, 150, 280 and 0.
useTweakApply
useTweakApply(tweaks: TweaksState): void runs an effect whenever tweaks.hue or tweaks.glow
changes and sets these inline styles on document.documentElement:
| Variable | Value |
|---|---|
--tweak-hue |
hue |
--accent |
oklch(0.72 0.14 hue) |
--accent-bright |
oklch(0.82 0.16 hue) |
--accent-speak |
oklch(0.77 0.15 hue) |
--accent-dim |
oklch(0.52 0.10 hue) |
--glow |
one accent glow whose blur and opacity grow with glow |
--glow-strong |
two stacked accent glows whose blur and opacity grow with glow |
Every component that uses these tokens, including Tailwind classes such as text-accent, follows
the new color immediately. Inline styles on :root win over the token stylesheet. When the calling
component unmounts, the hook removes all seven properties again, so the stylesheet values apply.
Call the hook in one place only; two mounted callers overwrite each other, and the first one to
unmount removes the variables for both. The flags are not touched by the hook.
Sound
Hovering a hue swatch or a flag toggle plays hover_button, clicking it plays click. The two range
sliders are silent. See Sound effects.
Accessibility
- The hue and glow sliders are native
<input type="range">elements with visible labels, so arrow keys adjust them. - Each flag is a
<button>witharia-pressedand anaria-labelequal to its caption. - Hue swatches are buttons named
Hue <degrees>; the selected swatch hasaria-pressed="true". - The slider ids are generated with
useId, so the labels stay linked even with several panels on one page.
API
| Prop | Type | Default | Description |
|---|---|---|---|
onChange (required) |
(next: TweaksState) => void |
Called with the complete next settings object whenever a control changes. | |
open (required) |
boolean |
Whether the panel is visible; when false it renders with display: none. |
|
tweaks (required) |
TweaksState |
Current settings shown in the panel (controlled). | |
className |
string |
Extra classes for the root <div> element (the fixed panel). |
Type TweaksState
Theme settings edited by the Tweaks panel.
| Field | Type | Default | Description |
|---|---|---|---|
glow (required) |
number |
Glow intensity (0–100); useTweakApply scales --glow and --glow-strong with it. |
|
grid (required) |
boolean |
Whether the grid background should be shown; read by your app. | |
hue (required) |
number |
Accent hue in degrees (0–360); useTweakApply turns it into the --accent* tokens. |
|
idleDim (required) |
boolean |
Whether the HUD should dim while idle; read by your app. | |
particles (required) |
boolean |
Whether the orb particles should be shown; read by your app (e.g. CssOrb particles). |
|
rings (required) |
boolean |
Whether the orb rings should be shown; read by your app (e.g. CssOrb rings). |
|
scan (required) |
boolean |
Whether scanlines should be shown; read by your app, not applied by the library. |