ZCode 中的 MicSelector 组件构建带权限处理与设备热插拔检测的麦克风选择器【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址: https://gitcode.com/gh_mirrors/zco/ZCode导读MicSelector是一个基于 shadcn/ui 的 Command 与 Popover 组合式下拉组件用于在 React 应用中完成音频输入设备的选取。它以细粒度的子组件拼装为核心内置设备自动枚举、麦克风权限请求、devicechange实时监听与设备名智能解析能力非常适合语音输入、语音笔记、AI 语音对话等需要先授权再选麦的交互场景。读完本文你将掌握该组件的全部子组件与 Props 语义、useAudioDevices独立 Hook 的用法以及它处理权限、热插拔和宽高同步的底层行为。组件概览与适用场景MicSelector提供了一套完全可组合的接口根组件MicSelector负责状态与上下文其余 8 个颗粒化子组件分别承担触发按钮、值展示、弹层容器、搜索输入、设备列表、空态、可选项和标签渲染。整体构建在 shadcn/ui 的Popover、Button与Command含CommandInput、CommandList、CommandEmpty、CommandItem之上因此天然继承了 Command 的键盘导航与可搜索能力。在本仓库中该组件与配套文档以 ai-elements 技能的形式收纳在 .agents/skills/ai-elements/ 目录下参考文档位于 references/mic-selector.md完整可运行示例位于 scripts/mic-selector.tsx。根据 third-party/copied-components.json 的记录该组件源自 vercel/ai-elementsApache-2.0 许可由 ZCode 在本地完成导入路径、样式与 Agent 工作流的适配原始许可证信息见仓库根目录的 THIRD-PARTY-NOTICES.md。安装与 ai-elements 家族其他组件一致MicSelector通过 ai-elements CLI 以代码入项目的方式安装安装后组件源码会直接落入你的项目组件目录默认是/components/ai-elements/而不是被封装在隐形的库里npx ai-elementslatest add mic-selector根据 SKILL.md 的说明请优先使用与项目packageManager匹配的包运行器npx、pnpm dlx或bunx --bun并满足以下前置条件Node.js 18 及以上一个已安装 AI SDK 的 Next.js 项目项目已接入 shadcn/ui若尚未安装执行安装命令时会自动补齐若遇到模块找不到错误请检查tsconfig.json中是否配置了/*路径别名baseUrl: .且paths: { /*: [./*] }。需要特别说明的是本仓库 packages/ui/src/components/ai-elements/ 目录中的组件为 ZCode 已本地化的实现集合其中并未包含mic-selector.tsx该组件在本仓库中的可参考实现示例即技能目录下的 scripts/mic-selector.tsx它展示了本地化后的导入方式与组装范式。组合式子组件与 Props 详解MicSelector的全部子组件都遵循透传原生 Props的扩展约定任意其他属性都会展开spread到底层 shadcn/ui 组件上因此你可以像使用原生组件一样注入className、事件回调等。MicSelector /— 根组件作为 Popover 的根容器为所有子组件提供上下文。它管理两类状态选中的设备 ID以及弹层的开合状态并且开合状态与权限请求联动。Prop类型默认值说明defaultValuestring-默认选中的设备 ID非受控。valuestring-选中的设备 ID受控。onValueChange(deviceId: string) void-选中设备变化时的回调。defaultOpenbooleanfalse默认展开状态非受控。openboolean-展开状态受控。onOpenChange(open: boolean) void-展开状态变化时的回调当无权限时打开弹层会自动请求麦克风权限。...propsReact.ComponentPropstypeof Popover-其余属性透传给 Popover。在 scripts/mic-selector.tsx 的示例中onOpenChange与onValueChange被用来在控制台观测弹层开合与设备选择事件这是调试时最常用的两个钩子。MicSelectorTrigger /— 触发按钮打开弹层的按钮会自动通过ResizeObserver跟踪自身宽度并同步给弹层内容保证触发器与弹出内容等宽的视觉一致。Prop类型默认值说明...propsReact.ComponentPropstypeof Button-其余属性透传给 Button。MicSelectorValue /— 当前值展示展示当前选中麦克风的名称未选中时渲染占位符。Prop类型默认值说明...propsReact.ComponentPropsspan-其余属性透传给 span 元素。示例中它被嵌套在Trigger内部MicSelectorTrigger classNamew-full max-w-sm MicSelectorValue / /MicSelectorTriggerMicSelectorContent /— 弹层内容容器包裹 Command 组件的容器渲染在 Popover 内容层。Prop类型默认值说明popoverOptionsReact.ComponentPropstypeof PopoverContent-传给底层 PopoverContent 的属性。...propsReact.ComponentPropstypeof Command-其余属性透传给 Command 组件。MicSelectorInput /— 搜索输入用于过滤麦克风的搜索框基于CommandInput实现支持按设备名实时筛选。Prop类型默认值说明...propsReact.ComponentPropstypeof CommandInput-其余属性透传给 CommandInput。MicSelectorList /— 设备列表设备列表的包装容器采用 render props 模式把设备数组交给调用方渲染实现 UI 的完全自定义Prop类型默认值说明children(devices: MediaDeviceInfo[]) ReactNode-接收可用设备数组的渲染函数。...propsOmitReact.ComponentPropstypeof CommandList, children-其余属性透传给 CommandList。典型用法如下来自 scripts/mic-selector.tsxMicSelectorList {(devices) devices.map((device) ( MicSelectorItem key{device.deviceId} value{device.deviceId} MicSelectorLabel device{device} / /MicSelectorItem )) } /MicSelectorListMicSelectorEmpty /— 空态提示当搜索无匹配结果时显示的提示信息。Prop类型默认值说明childrenReactNode-要展示的提示文案。...propsReact.ComponentPropstypeof CommandEmpty-其余属性透传给 CommandEmpty。MicSelectorItem /— 可选项代表单个麦克风的可选中条目Prop类型默认值说明valuestring-该条目的设备 ID。...propsReact.ComponentPropstypeof CommandItem-其余属性透传给 CommandItem。MicSelectorLabel /— 智能标签展示格式化后的麦克风名称并自动解析形如(XXXX:XXXX)的设备 ID——将设备名与 ID 拆分开ID 部分以弱化muted颜色呈现提升可读性。Prop类型默认值说明deviceMediaDeviceInfo-该设备对应的 MediaDeviceInfo 对象。...propsReact.ComponentPropsspan-其余属性透传给 span 元素。例如MacBook Pro Microphone (1a2b:3c4d)会被解析为设备名MacBook Pro Microphone设备 ID(1a2b:3c4d)以弱化颜色样式展示useAudioDevices()HookuseAudioDevices是组件内部使用的设备管理 Hook也可以脱离MicSelector独立使用比如做自定义的设备管理面板或权限引导页。其导入路径遵循组件所在位置示例中为repo/elements/mic-selector。import { useAudioDevices } from repo/elements/mic-selector; export default function Example() { const { devices, loading, error, hasPermission, loadDevices } useAudioDevices(); return ( div {loading pLoading devices.../p} {error pError: {error}/p} {devices.map((device) ( div key{device.deviceId}{device.label}/div ))} {!hasPermission button onClick{loadDevices}Grant Permission/button} /div ); }返回值Prop类型默认值说明devicesMediaDeviceInfo[]-当前可用的音频输入设备数组。loadingboolean-设备是否正在加载。errorstring \| null-设备加载失败时的错误信息。hasPermissionboolean-麦克风权限是否已授予。loadDevices() Promisevoid-请求麦克风权限并加载设备名称的函数。这个 Hook 的返回值覆盖了设备数据 加载态 错误态 权限态 触发加载的完整状态机是构建自定义设备 UI 的基础。组件内部正是利用它完成首屏无权限加载、弹层打开时二次授权加载的两阶段流程。核心行为机制两阶段权限处理组件采用两阶段权限策略兼顾不给浏览器施加不必要的授权弹窗与拿到真实设备名两个目标无权限阶段初始加载设备时不请求权限此时device.label通常只能拿到通用名称例如Microphone 1有权限阶段当弹层被打开且尚未授权时自动请求麦克风访问权限随后显示真实设备名称。从实现角度推断这一步通过navigator.mediaDevices.getUserMedia()或等效的临时媒体流触发授权并在授权完成后立即清理临时媒体流避免设备指示灯常亮或资源占用——组件文档的 Notes 部分明确提到组件会在权限请求过程中处理临时媒体流的清理。设备标签解析MicSelectorLabel对包含硬件 ID 的设备名做名称 ID拆分匹配(XXXX:XXXX)格式的 ID 段将设备名与弱化样式的 ID 分段渲染兼顾信息完整性与视觉层级。宽度同步MicSelectorTrigger通过ResizeObserver持续跟踪自身宽度并将其同步到MicSelectorContent的弹层宽度上使得触发按钮与下拉内容宽度一致、外观连贯且在窗口缩放或布局变化时实时跟随。设备热插拔检测组件监听devicechange事件例如插入或拔出麦克风一旦发生即自动刷新设备列表无需用户手动刷新或重新打开弹层。这在演示场景临时插拔 USB 麦克风蓝牙耳机断开重连等场景下非常实用。可访问性通过 shadcn/ui 组件使用语义化 HTML 并携带正确的 ARIA 属性借助 Command 组件获得完整的键盘导航支持方向键选择、回车确认对屏幕阅读器友好具备正确的标签与角色支持搜索过滤方便快速定位设备。使用注意事项麦克风访问要求安全上下文HTTPS 或 localhost在 HTTP 内网环境部署时需注意首次打开弹层时浏览器可能弹出麦克风授权询问设备标签只有在授权之后才具有完整描述性未授权前可能只显示通用名称组件基于 Radix UI 的useControllableState实现受控/非受控双模式defaultValue/value与defaultOpen/open可灵活组合。参考资源组件参考文档.agents/skills/ai-elements/references/mic-selector.md完整示例.agents/skills/ai-elements/scripts/mic-selector.tsx技能总览与安装/排障说明.agents/skills/ai-elements/SKILL.md同族参考语音选择器 .agents/skills/ai-elements/references/voice-selector.mdDialog 风格的可组合选择器可与 MicSelector 对照理解组合范式许可证与来源说明THIRD-PARTY-NOTICES.md 及 third-party/copied-components.json【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址: https://gitcode.com/gh_mirrors/zco/ZCode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
