leva
leva copied to clipboard
Feature Request: Reactive constants inside control panel derived from inputs
I think it would be nice to display a reactive value derived from the values in the control panel itself. It can leverage the get
hook used in the render
option already.
Of course I can take the values and display the computed value in a div somewhere, but it would be nice to contain the computed value to the control panel since the values are related.
Technically it's not an input, more like an embellishment to the control panel.
Example:
const { width, height, depth, volume } = useControls({
width: {
value: 1,
min: 1,
max: 10,
step: 1,
},
height: {
value: 1,
min: 1,
max: 6,
step: 1,
},
depth: {
value: 1,
min: 1,
max: 10,
step: 1,
},
volume: {
derivedValue: (get) => get('width') * get('height') * get('depth'),
},
});
found this issue - kind of related: https://github.com/pmndrs/leva/issues/305
also found this -- https://github.com/pmndrs/leva/issues/112 which is asking almost the same thing.
I can begin to look into making a plug in. Feel free to close this issue if you think it's better served as a plug in vs. an update to api that I proposed above.
Here's a work around using a disabled input and the set
method. Link to repro for the work around: https://stackblitz.com/edit/vitejs-vite-o5b1yc?file=src%2FApp.jsx
const [w, setW] = useState(1);
const [h, setH] = useState(1);
const [d, setD] = useState(1);
let v = w * h * d;
const [, set] = useControls(
() => ({
width: {
value: w,
min: 1,
max: 10,
step: 1,
onChange: (v) => setW(v),
},
height: {
value: h,
min: 1,
max: 6,
step: 1,
onChange: (v) => setH(v),
},
depth: {
value: d,
min: 1,
max: 10,
step: 1,
onChange: (v) => setD(v),
},
volume: {
value: v,
disabled: true,
},
}),
[w, h, d],
);
useEffect(() => {
v = w * h * d;
set({ volume: v });
}, [w, h, d]);
Do you want to attempt a contribution for this?
Hey if you think it's a valuable feature I will give it a shot @gsimone -- I can find time beginning in September.
Wanted to see if others will find it useful before jumping in.