Dependent Ranges
Change one control's valid range in response to another, using atomic configure() to avoid ever passing through an invalid state.
A control's valid range can depend on the value of another control. Here, the
maximum a threshold slider can reach depends on the selected bitDepth. This
is a case where configure() being atomic
really matters — the range and the (possibly clamped) value are applied together,
so threshold never briefly holds a value above its new max.
Source
const bitDepth = pp.select({
label: "Bit depth",
value: 8,
options: [
{ label: "8-bit", value: 8 },
{ label: "10-bit", value: 10 },
{ label: "12-bit", value: 12 },
],
});
const threshold = pp.slider({
label: "Threshold",
value: 128,
min: 0,
max: 255,
step: 1,
});
bitDepth.subscribe((depth, details) => {
const max = 2 ** depth - 1;
const current = threshold.get();
// New max and clamped value applied together — never invalid in between.
threshold.configure({
max,
value: Math.min(current, max),
});
if (details.final) {
rebuildProcessingPipeline();
}
});Notable details
- Switching
bitDepthfrom 12-bit (max = 4095) to 8-bit (max = 255) whilethresholdsits at1000would be invalid ifmaxandvaluewere set separately —threshold.configure({ max: 255 })alone would momentarily leave the control at a value above its new maximum. Passing both fields in the sameconfigure()call means validation happens against the whole proposed configuration before anything is applied. bitDepth's own subscriber usesdetails.finalto gaterebuildProcessingPipeline(), the same intermediate/final pattern used throughout the library.