Add a colour-wheel widget to the dashboard
A custom hue ring — a conic gradient, not a canvas — with saturation and brightness sliders beside or under it depending on the tile's shape, sized for a wall panel and reachable from a keyboard. It publishes [h, s, v] by default, which is what the reference installation's DMX encoders read, and `format` switches that to [r, g, b] or "#rrggbb". `usePublish` moves to its own module so a widget in a file of its own can reach it without importing `widgets.tsx` back.
This commit is contained in:
@@ -36,6 +36,7 @@ import {
|
||||
import { cn } from "@/lib/utils"
|
||||
import { MAX_SEGMENTS, type Segment, segmentsOf } from "./BarWidget"
|
||||
import { MAX_SERIES, refreshFor } from "./ChartWidget"
|
||||
import { COLOR_DTYPES, COLOR_FORMATS, colorFormatOf } from "./ColorWidget"
|
||||
import {
|
||||
CANVAS_PRESETS,
|
||||
COLUMN_CHOICES,
|
||||
@@ -435,6 +436,15 @@ export function WidgetPanel({
|
||||
value={str(cfg[isInput ? "target" : "message"])}
|
||||
label={isInput ? "Publishes to" : "Shows"}
|
||||
testId="widget-message"
|
||||
// A colour widget may bind either shape, and the format is what
|
||||
// decides which of the two — so it filters rather than the type.
|
||||
filter={
|
||||
widget.type === "color"
|
||||
? (message) =>
|
||||
message.dtype === COLOR_DTYPES[colorFormatOf(widget)] &&
|
||||
message.writable !== false
|
||||
: undefined
|
||||
}
|
||||
onPick={(message, dtype) =>
|
||||
set({ [isInput ? "target" : "message"]: message, dtype })
|
||||
}
|
||||
@@ -867,6 +877,36 @@ export function WidgetPanel({
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{widget.type === "color" ? (
|
||||
<div className="grid gap-1.5">
|
||||
<Label className="text-sm font-normal">Sends</Label>
|
||||
<Segmented
|
||||
value={colorFormatOf(widget)}
|
||||
options={COLOR_FORMATS}
|
||||
label="What this wheel publishes"
|
||||
testId="widget-format"
|
||||
onChange={(format) =>
|
||||
set({
|
||||
format,
|
||||
// Both triples are a `list` and hex is a `str`, so a change
|
||||
// between the two shapes takes the binding with it rather
|
||||
// than leaving a message this control can no longer carry.
|
||||
...(COLOR_DTYPES[format as keyof typeof COLOR_DTYPES] ===
|
||||
str(cfg.dtype)
|
||||
? {}
|
||||
: { target: "", dtype: undefined }),
|
||||
})
|
||||
}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
HSV is{" "}
|
||||
<span className="font-mono">[h 0-360, s 0-100, v 0-100]</span>,
|
||||
RGB <span className="font-mono">[r, g, b]</span> 0-255, Hex{" "}
|
||||
<span className="font-mono">"#rrggbb"</span>.
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{widget.type === "switch" || widget.type === "dropdown" ? (
|
||||
<div className="grid gap-1.5">
|
||||
<Label className="text-sm font-normal">Style</Label>
|
||||
|
||||
Reference in New Issue
Block a user