Mic Selector

A searchable popover for picking an audio input — permission-aware labels, live device updates, and width-matched content.

Default

Popover list of audio inputs. Opening requests mic permission so device names resolve.

Loading…

Installation

CLI
npx @sonojs/ui@latest add mic-selector
Also needsnpx @sonojs/ui@latest add button command popover && npm i lucide-react

Usage

mic-selector.tsx
import {
  MicSelector,
  MicSelectorContent,
  MicSelectorEmpty,
  MicSelectorInput,
  MicSelectorItem,
  MicSelectorLabel,
  MicSelectorList,
  MicSelectorTrigger,
  MicSelectorValue,
} from "@/components/sonojs/mic-selector"

export function Example() {
  return (
    <MicSelector>
      <MicSelectorTrigger className="w-full max-w-sm">
        <MicSelectorValue />
      </MicSelectorTrigger>
      <MicSelectorContent>
        <MicSelectorInput />
        <MicSelectorEmpty />
        <MicSelectorList>
          {(devices) =>
            devices.map((device) => (
              <MicSelectorItem key={device.deviceId} value={device.deviceId}>
                <MicSelectorLabel device={device} />
              </MicSelectorItem>
            ))
          }
        </MicSelectorList>
      </MicSelectorContent>
    </MicSelector>
  )
}

Props

PropTypeDefaultDescription
value / defaultValuestring—Selected device ID (controlled or uncontrolled).
onValueChange(deviceId?: string) => void—Fires when the selected microphone changes.
open / onOpenChangeboolean / (open: boolean) => void—Popover open state. Opening without permission requests mic access.
MicSelectorList children(devices: MediaDeviceInfo[]) => ReactNode—Render prop with the current audioinput devices.
MicSelectorLabel deviceMediaDeviceInfo—Splits hardware IDs like `(1a2b:3c4d)` into muted suffix text.
useAudioDevices()hook—Standalone hook: `devices`, `loading`, `error`, `hasPermission`, `loadDevices`.