ImageSwitch

A boolean control that displays one of two images based on state, perfect for on/off switches and buttons with custom bitmap graphics.

ImageSwitch is a boolean control that displays one of two images based on the boolean value. It shares the same layout, parameter model, interaction, and accessibility as other controls (vector, raster, and control primitives); see the Raster introduction.

The image displayed is determined by the boolean value:

  • false (normalized 0.0) displays imageHrefFalse
  • true (normalized 1.0) displays imageHrefTrue

Note:

No Theming Support: This component does NOT support themable props (color, roundness, thickness) as visuals are entirely determined by the image content.

Props

NameTypeDefaultRequiredDescription
valueboolean—RequiredCurrent value of the control
onChange(event: AudioControlEvent<boolean>) => void—OptionalHandler for value changes
latchbooleanfalseOptionalWhether the button operates in latch (toggle) mode or momentary mode
labelstring—OptionalLabel displayed below the component
frameWidthnumber—RequiredWidth of the viewBox (determines viewBox width)
frameHeightnumber—RequiredHeight of the viewBox (determines viewBox height)
imageHrefFalsestring—RequiredURL to the image for false/off state
imageHrefTruestring—RequiredURL to the image for true/on state
adaptiveSizebooleanfalseOptionalWhether the component stretches to fill its container
size"xsmall" | "small" | "normal" | "large" | "xlarge"normalOptionalSize of the component
parameterBooleanParameter—OptionalAudio Parameter definition (Model). If provided, overrides label/latch from ad-hoc props

Basic Usage

ImageSwitch requires two image URLs (one for off state, one for on state) and frame dimensions:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function BasicImageSwitchExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <ImageSwitch
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Modes of Operation

Latch Mode (Toggle)

In latch mode, the button toggles between pressed and released states:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function LatchImageSwitchExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <ImageSwitch
      value={isOn}
      latch={true}
      label="Favorite"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Momentary Mode

In momentary mode, the button is only active while being pressed:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function MomentaryImageSwitchExample() {
  const [isPressed, setIsPressed] = useState(false);
 
  return (
    <ImageSwitch
      value={isPressed}
      latch={false}
      label="Record"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsPressed(e.value)}
    />
  );
}

Image Selection

The component displays different images based on the boolean value:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function ImageSelectionExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <ImageSwitch
      value={isOn}
      latch={true}
      label="Switch"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Parameter Model

Use a parameter model for integration with audio parameter systems. The following example uses ad-hoc props; with the full library you would use createBooleanParameter and the parameter prop:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function ImageSwitchParameterModelExample() {
  const [value, setValue] = useState(false);
 
  return (
    <ImageSwitch
      label="Favorite"
      latch={true}
      value={value}
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setValue(e.value)}
    />
  );
}

Adaptive Sizing

The ImageSwitch component supports both fixed sizes and adaptive sizing. By default, the size of the component is driven by the Size System and their size attribute:

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function ImageSwitchSizingExample() {
  const [v1, setV1] = useState(false);
  const [v2, setV2] = useState(false);
  const [v3, setV3] = useState(false);
  const [v4, setV4] = useState(false);
 
  return (
    <div className="flex gap-4 items-center flex-wrap">
      <ImageSwitch
        value={v1}
        latch={true}
        label="Small"
        size="small"
        frameWidth={100}
        frameHeight={100}
        imageHrefFalse="/images/demo/star-off.png"
        imageHrefTrue="/images/demo/star-on.png"
        onChange={(e) => setV1(e.value)}
      />
      <ImageSwitch
        value={v2}
        latch={true}
        label="Normal"
        size="normal"
        frameWidth={100}
        frameHeight={100}
        imageHrefFalse="/images/demo/star-off.png"
        imageHrefTrue="/images/demo/star-on.png"
        onChange={(e) => setV2(e.value)}
      />
      <ImageSwitch
        value={v3}
        latch={true}
        label="Large"
        size="large"
        frameWidth={100}
        frameHeight={100}
        imageHrefFalse="/images/demo/star-off.png"
        imageHrefTrue="/images/demo/star-on.png"
        onChange={(e) => setV3(e.value)}
      />
      <ImageSwitch
        value={v4}
        latch={true}
        label="XLarge"
        size="xlarge"
        frameWidth={100}
        frameHeight={100}
        imageHrefFalse="/images/demo/star-off.png"
        imageHrefTrue="/images/demo/star-on.png"
        onChange={(e) => setV4(e.value)}
      />
    </div>
  );
}

Adaptive sizing allows the component to adapt to the size of its parent container, adjusting its dimensions intelligently without causing distortion (scaleToFit display mode). The fill display mode makes the component fill the entire container, potentially distorting it.

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function ImageSwitchAdaptiveSize() {
  const [wideVal, setWideVal] = useState(false);
  const [tallVal, setTallVal] = useState(false);
  const [distortedVal, setDistortedVal] = useState(false);
 
  return (
    <div className="flex gap-6 items-center flex-wrap">
      <div className="w-32 h-12 border rounded-lg p-2">
        <ImageSwitch
          value={wideVal}
          onChange={(e) => setWideVal(e.value)}
          latch={true}
          adaptiveSize={true}
          label="Wide"
          frameWidth={100}
          frameHeight={100}
          imageHrefFalse="/images/demo/star-off.png"
          imageHrefTrue="/images/demo/star-on.png"
        />
      </div>
      <div className="w-12 h-32 border rounded-lg p-2">
        <ImageSwitch
          value={tallVal}
          onChange={(e) => setTallVal(e.value)}
          latch={true}
          adaptiveSize={true}
          label="Tall"
          frameWidth={100}
          frameHeight={100}
          imageHrefFalse="/images/demo/star-off.png"
          imageHrefTrue="/images/demo/star-on.png"
        />
      </div>
      <div className="w-24 h-20 border rounded-lg p-2">
        <ImageSwitch
          value={distortedVal}
          onChange={(e) => setDistortedVal(e.value)}
          latch={true}
          adaptiveSize={true}
          displayMode="fill"
          label="Distorted"
          frameWidth={100}
          frameHeight={100}
          imageHrefFalse="/images/demo/star-off.png"
          imageHrefTrue="/images/demo/star-on.png"
        />
      </div>
    </div>
  );
}

Common Use Cases

Favorite/Star Button

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function FavoriteButtonExample() {
  const [isFavorite, setIsFavorite] = useState(false);
 
  return (
    <ImageSwitch
      value={isFavorite}
      latch={true}
      label="Favorite"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsFavorite(e.value)}
    />
  );
}

Power Switch

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function PowerSwitchExample() {
  const [isOn, setIsOn] = useState(false);
 
  return (
    <ImageSwitch
      value={isOn}
      latch={true}
      label="Power"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsOn(e.value)}
    />
  );
}

Momentary Record Button

import { useState } from "react";
import { ImageSwitch } from "@cutoff/audio-ui-react";
 
export default function RecordButtonExample() {
  const [isRecording, setIsRecording] = useState(false);
 
  return (
    <ImageSwitch
      value={isRecording}
      latch={false}
      label="Record"
      size="large"
      frameWidth={100}
      frameHeight={100}
      imageHrefFalse="/images/demo/star-off.png"
      imageHrefTrue="/images/demo/star-on.png"
      onChange={(e) => setIsRecording(e.value)}
    />
  );
}

Image Requirements

  • Format: Any image format supported by browsers (PNG, JPG, SVG, etc.)
  • Dimensions: The frameWidth and frameHeight props determine the viewBox dimensions
  • Aspect Ratio: Images will be scaled to fit the viewBox while preserving aspect ratio
  • States: Provide two separate images for off and on states

Image Selection Logic

The component selects images based on the boolean value:

  • value === false → Displays imageHrefFalse
  • value === true → Displays imageHrefTrue

The selection is immediate and does not animate between states.

Next Steps