TouchStrip Hooks
React hooks for the Stream Deck+ shared touch strip -- geometry, tap events, dial rotation, and dial press within a touchStrip component.
TouchStrip hooks are available inside a touchStrip component registered via defineAction. They provide geometry info, tap coordinates, and per-dial events with column identification.
These hooks are only available inside a
touchStripcomponent. For per-encoder hooks (one React root per dial), see Event Hooks.
useTouchStrip
Returns the current touch strip geometry and configuration.
function useTouchStrip(): TouchStripInfo;interface TouchStripInfo {
/** Full strip width in pixels (e.g. 800 for 4 encoders). */
width: number;
/** Strip height in pixels (always 100). */
height: number;
/** Sorted list of active encoder columns, e.g. [0, 1, 3]. */
columns: number[];
/** Width of each encoder segment in pixels (always 200). */
segmentWidth: number;
/** Target FPS from the action definition. */
fps: number;
}function MyTouchStrip() {
const { width, height, fps, columns, segmentWidth } = useTouchStrip();
return (
<div style={{ width, height, background: "#1a1a2e" }}>
<span style={{ color: "white", fontSize: 14 }}>
{columns.length} dials active — {width}x{height}
</span>
</div>
);
}useTouchStripTap
Fires when the touch strip is tapped. Coordinates are absolute across the full strip width.
function useTouchStripTap(callback: (payload: TouchStripTapPayload) => void): void;interface TouchStripTapPayload {
/** Absolute tap position across the full strip. */
tapPos: [x: number, y: number];
/** Whether it was a long press. */
hold: boolean;
/** The encoder column that was touched. */
column: number;
}function MyTouchStrip() {
const { width, height } = useTouchStrip();
const [marker, setMarker] = useState(0);
useTouchStripTap(({ tapPos }) => {
setMarker(tapPos[0]);
});
return (
<div style={{ width, height, position: "relative", background: "#1a1a2e" }}>
<div
style={{
position: "absolute",
left: marker,
top: 0,
width: 2,
height,
background: "#ff3366",
}}
/>
</div>
);
}Tap coordinates are translated from per-segment local coordinates to absolute strip coordinates automatically. A tap at local [50, 30] on column 2 becomes [450, 30].
useTouchStripDialRotate
Fires when any dial is rotated. The column field identifies which dial.
function useTouchStripDialRotate(callback: (payload: TouchStripDialRotatePayload) => void): void;interface TouchStripDialRotatePayload {
/** Which encoder column was rotated (0-indexed). */
column: number;
/** Signed rotation amount. Positive = clockwise. */
ticks: number;
/** Whether the dial was pressed while rotating. */
pressed: boolean;
}useTouchStripDialRotate(({ column, ticks }) => {
if (column === 0) {
// Dial 0: steer
setDirection((d) => (ticks > 0 ? turnRight(d) : turnLeft(d)));
} else if (column === 1) {
// Dial 1: speed
setSpeed((s) => Math.max(1, s + ticks));
}
});useTouchStripDialDown
Fires when a dial is pressed down.
function useTouchStripDialDown(callback: (payload: TouchStripDialPressPayload) => void): void;interface TouchStripDialPressPayload {
/** Which encoder column was pressed (0-indexed). */
column: number;
}useTouchStripDialUp
Fires when a dial is released.
function useTouchStripDialUp(callback: (payload: TouchStripDialPressPayload) => void): void;Same payload as useTouchStripDialDown.
TouchStrip vs Per-Encoder Hooks
| TouchStrip hooks | Per-encoder hooks | |
|---|---|---|
| Component | touchStrip in defineAction | dial in defineAction |
| React roots | One shared tree for the full strip | One root per encoder slot |
| Event routing | All events arrive in one component; use column to distinguish | Each component only receives its own dial's events |
| Canvas size | Full strip (e.g. 800x100) | Single segment (200x100) |
| Hooks | useTouchStrip* family | useDialRotate, useDialDown, useTouchTap, etc. |