Microphone picker

A dropdown for choosing the input device, with a level meter so people can check they are being heard.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/mic-picker.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/mic-picker.json

Usage & API

Example

mic-picker.tsx
import { LevelMeter } from "@/components/ai/mic-picker"

<LevelMeter
  level={1}
/>

Props LevelMeter

PropType & descriptionRequired
levelnumberRequired
labelstringOptional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

Dropdown with meter is the only variant. The trigger is a 48-pixel row with a listbox popup. The popup is absolutely positioned under the field, so the parent needs room or overflow visible, which the preview card provides. Options are not buttons. They are listbox options, and the active one follows both the pointer and the keyboard. The check renders only on the selected id, not on the highlighted row. The meter caption and LevelMeter always show, even while the menu is open. The preview wraps this in a bordered card and adds the sample-device note plus Use my microphone, which is absent from MicPicker. Reduced motion shortens the menu's open and close animation. The simulated levels keep running until a real device is connected, and reduced motion holds a static level for the samples instead of the speech curve.

Choosing a layout

Use it on the way into a call, or in settings, wherever the person must confirm they are heard before they depend on it. The meter is the point. A menu of names does not tell you the chosen mic is dead. Put it near Voice session rather than inside that bar. The bar is for mute and hang up during the call. This stack is taller: label, control, list, caption, and meter. Voice picker is the sibling for output voices, and it previews with a play button instead of an input meter. Do not conflate the two. One chooses where sound comes from, the other chooses how the assistant speaks.

Skip it if the product has a single fixed input and no level to show. An empty devices array leaves the control without a sensible label, because the selected row falls off the end of the list. Skip the live permission button if you are embedding only MicPicker. That button is preview chrome around the component. You can still use LevelMeter alone, next to a custom device list, because it is exported on its own and only needs a level. The meter does not identify which device. The dropdown does that.

Does opening the menu turn the microphone on?

No. MicPicker never requests a device. It renders the array you pass and the level you pass. The preview's Use my microphone button is the only place that calls getUserMedia, and it does so after the click. Denying permission leaves the sample list in place and shows an error string under the card.

What do the meter colours mean?

They are position, not a calibration. Segments start cyan, shift through violet and peach, and the last stretch is red. The lit count is the level times 28. A peak marker holds about seven tenths of a second, then eases down. The caption says Picking you up above a small threshold and Say something to test at or below it. The meter exposes the percent as its value.