ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

coss Command 组件全指南:用 Base UI 构建可键盘导航的命令面板

coss Command 组件全指南:用 Base UI 构建可键盘导航的命令面板 前端UI组件设计系统【免费下载链接】cosscoss.com/ui is the official design system of Cal.com项目地址https://gitcode.com/gh_mirrors/or/coss点击查看免费下载coss是 Cal.com 官方设计系统位于本仓库apps/ui目录其Command组件基于 Base UI 的Autocomplete与Dialog原语组合而成用于实现命令面板Command Palette与键盘可导航的操作菜单。本文以 apps/ui/skills/coss/references/primitives/command.md 为骨架结合 command.tsx 源码与p-command-1、p-command-2两个粒子示例系统讲解 Command 组件的适用场景、安装方式、完整 API、最小可用模式、分组与快捷键最佳实践以及常见陷阱读完即可在你的项目中落地一个生产级的命令面板。何时该用、何时不该用 CommandCommand 组件解决的是「快速发现并执行动作」这一交互问题。官方文档给出了清晰的判定标准适用场景When to use命令面板Command palette与可键盘导航的操作菜单面向高级用户power-user的快捷动作发现以及应用级快捷键工作流。不适用场景When NOT to use列表只是一组没有搜索的简单操作 → 使用 Menu用户需要从预定义列表中选择 → 使用 Select 或 Combobox流程是一个数据表单 → 使用 Form。这条边界非常重要Command 的定位是「搜索 动作执行」而不是「选择数据」或「录入表单」。选错组件会让交互变得笨重。安装与依赖在 coss 的组件注册表中command被声明为一个registry:ui类型条目见 registry-ui.ts{ dependencies: [base-ui/react], files: [{ path: ui/command.tsx, type: registry:ui }], name: command, registryDependencies: [coss/autocomplete], type: registry:ui, }因此可以通过 shadcn CLI 一键安装npx shadcnlatest add coss/command注意command的registryDependencies声明了coss/autocomplete也就是说安装 Command 时它的 Autocomplete 底层依赖会被一并带入。如果选择手动安装Manual deps核心第三方依赖是npm install base-ui/react从源码看command.tsx通过base-ui/react/dialog的Dialog原语和/registry/default/ui/autocomplete的Autocomplete*系列组件组合而成没有直接依赖 cmdk 或其他命令面板库。Canonical imports标准导入组件拆分为 14 个可独立导入的 API官方推荐的导入方式如下import { Command, CommandCollection, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut, } from /components/ui/command import { Button } from /components/ui/button结合 command.tsx 源码可以看清这些 API 的组成对话框相关CommandDialog即 Base UIDialog.Root、CommandDialogTrigger、CommandDialogPopup、CommandDialogPortal即Dialog.Portal、CommandDialogBackdrop、CommandDialogViewport、CommandCreateHandle即Dialog.createHandle用于命令式打开对话框搜索与列表Command包装Autocomplete、CommandInput包装AutocompleteInput、CommandList、CommandEmpty、CommandPanel结果面板容器分组与条目CommandGroup、CommandGroupLabel、CommandCollection渲染函数式集合、CommandItem、CommandSeparator、CommandShortcut快捷键kbd、CommandFooter底部操作提示栏。其中Command组件值得单独说明它并不是一个独立的原语而是对Autocomplete的预设封装export function Command({ autoHighlight always, keepHighlight true, ...props }) { return Autocomplete autoHighlight{autoHighlight} inline keepHighlight{keepHighlight} open {...props} /; }这意味着Command默认强制展开open、始终高亮首个条目autoHighlightalways、保持高亮keepHighlight并使用**内联inline**过滤模式——这正是命令面板「输入即过滤、方向键即选择」体验的底层保证。最小可用模式Minimal pattern官方文档提供了一个开箱即用的最小示例完整复刻如下const items [ { value: linear, label: Linear }, { value: figma, label: Figma }, { value: slack, label: Slack }, ] CommandDialog CommandDialogTrigger render{Button variantoutline /} Open Command Palette /CommandDialogTrigger CommandDialogPopup Command items{items} CommandInput placeholderSearch... / CommandEmptyNo results found./CommandEmpty CommandList {(item) ( CommandItem key{item.value} value{item.value} {item.label} /CommandItem )} /CommandList /Command /CommandDialogPopup /CommandDialog这段代码展示了几条关键用法CommandDialogTrigger的renderprop 可以让任意组件这里是Button成为触发器这是 Base UI 的「render prop 组合」模式CommandList接收一个渲染函数函数的入参是items中的每一项CommandItem的value用于过滤匹配label用于展示CommandEmpty在过滤结果为空时展示「No results found.」组件树是「Trigger → Popup → Command含 Input/Empty/List」的三层结构。从源码看CommandInput还内置了autoFocus、sizelg与startAddon{SearchIcon /}左侧搜索图标这些是封装好的默认行为无需额外配置。分组命令面板Group / Collection 模式当命令数量较多时应当使用分组。官方文档给出了带分组的标准写法Command items{items} CommandInput placeholderType a command... / CommandEmptyNo results found./CommandEmpty CommandList CommandGroup CommandGroupLabelSuggestions/CommandGroupLabel CommandCollection {(item) ( CommandItem key{item.value} value{item.value} {item.label} /CommandItem )} /CommandCollection /CommandGroup /CommandList /Command分组模式的关键点是CommandGroupCommandGroupLabelCommandCollection三者配合CommandGroup声明一组条目的容器CommandGroupLabel渲染组标题如 Suggestions、CommandsCommandCollection接收渲染函数把组的items逐项渲染成CommandItem。在p-command-1粒子见 p-command-1.json中可以看到完整的分组数据模型Group接口包含value组名和items数组groupedItems将 Suggestions 与 Commands 两组组合后直接传入Command items{groupedItems}外层CommandList的渲染函数收到(group, index)每组渲染一个CommandGroup组间用CommandSeparator分隔。这展示了「外层按组渲染、内层按条目渲染」的完整模式。对话框模式受控 open 与快捷键唤起命令面板最常见的形态是放在对话框弹层中。官方文档明确指出UseCommandDialogCommandDialogTriggerCommandDialogPopupto wrapCommandin a dialog overlay. Use controlledopen/onOpenChangestate for keyboard-shortcut activation.即用CommandDialog三件套包裹Command并通过受控的open/onOpenChange实现快捷键唤起。p-command-1给出了完整参考实现const [open, setOpen] useState(false); useEffect(() { const down (e: KeyboardEvent) { if (e.key j (e.metaKey || e.ctrlKey)) { e.preventDefault(); setOpen((open) !open); } }; document.addEventListener(keydown, down); return () document.removeEventListener(keydown, down); }, []); CommandDialog onOpenChange{setOpen} open{open} CommandDialogTrigger render{Button variantoutline /} Open Command Palette KbdGroupKbd⌘/KbdKbdJ/Kbd/KbdGroup /CommandDialogTrigger ... /CommandDialog关键细节在useEffect中监听全局keydown捕获⌘/Ctrl JpreventDefault后切换open状态CommandDialog的onOpenChange同步状态实现 Esc 关闭时状态一致CommandDialogTrigger内部用KbdGroup/Kbd渲染快捷键提示⌘J点击条目时通过onClick回调setOpen(false)关闭面板p-command-1中的handleItemClick弹出层的布局由CommandDialogBackdropbg-black/32 backdrop-blur-sm遮罩、CommandDialogViewport全屏固定定位的居中容器、CommandDialogPopupmax-w-xl圆角卡片三级组成视觉与动效由源码中的 Tailwind 类与data-starting-style/data-ending-style数据属性驱动。进阶portalProps 与 Portal 转发官方文档在「Patterns from coss particles」一节特别提到了Portal forwardingoptionalportalPropsonCommandDialogPopup→ Base UIDialog.Portal(keepMounted,container, …)结合 command.tsx 的源码实现CommandDialogPopup的签名是export function CommandDialogPopup({ className, children, portalProps, ...props }: CommandDialogPrimitive.Popup.Props { portalProps?: CommandDialogPrimitive.Portal.Props; })它内部把portalProps展开spread到CommandDialogPortal即 Base UIDialog.Portal上同时渲染CommandDialogBackdrop与CommandDialogViewport。完整说明见 portal-props.md核心用途包括keepMounted让弹层内容在关闭后仍挂载在 DOM 中对保持输入状态、动画退场有用container把弹层内容渲染到指定 DOM 节点处理层叠上下文、微前端、Shadow DOM 场景以及其他该组件Portal.Props接受的属性。同时要注意portalProps只影响portal 节点若要调整定位placement应使用side、align、sideOffset等 positioner 属性。进阶命令式 Dialog 句柄CommandCreateHandlecommand.tsx还导出了CommandCreateHandle即 Base UIDialog.createHandle用于命令式地控制对话框。p-command-2粒子AI 助手命令面板见 p-command-2.json展示了它的用法export const commandHandle: ReturnTypetypeof CommandCreateHandle CommandCreateHandle(); ... CommandDialog handle{commandHandle} onOpenChange{handleOpenChange} open{open}CommandCreateHandle()返回一个可重用的句柄对象传入CommandDialog的handleprop 后即可在组件外部以命令式方式打开/关闭对话框该粒子中还结合AbortController处理了 AI 请求的取消与卸载清理。进阶自定义过滤与 AI 搜索filter propp-command-2展示了超越基本搜索的高级用法它通过useAutocompleteFilter构造大小写不敏感sensitivity: base的匹配器然后向Command传入自定义filterconst { contains } useAutocompleteFilter({ sensitivity: base }); const filterItem useCallback((itemValue, query) { const item itemValue as Item; return ( contains(item.label, query) || contains(item.value, query) || item.keywords?.some((keyword) contains(keyword, query)) ); }, [contains]); Command filter{filterItem} items{commandGroups} key{commandResetKeyRef.current}要点匹配逻辑可以扩展到keywords字段如 proj 匹配 Projects实现别名/模糊搜索该粒子还在输入框旁提供了 Ask AITab / Enter入口无结果时按 Enter 进入 AI 问答模式展示Skeleton加载态、mock 回答dangerouslySetInnerHTML渲染 markdown 转换结果与参考链接Button render{Link/}key{commandResetKeyRef.current}用于在状态切换时强制重建Command重置高亮与过滤状态Esc 在 AI 模式下被stopPropagation拦截为「返回搜索」而非「关闭面板」。这一示例说明Command的filterprop 是可插拔的完全可以把本地过滤替换为远程搜索或 AI 检索逻辑。用 CommandFooter 呈现键盘操作提示p-command-1与p-command-2都用CommandFooter渲染底部操作提示条↑/↓ 导航、↵ 打开、Esc 关闭通过KbdGroup/Kbd组件组合展示。源码中CommandFooter是一个带顶部边框的 flex 容器flex items-center justify-between gap-2 rounded-b-... border-t px-5 py-3 text-muted-foreground text-xs而CommandShortcut则渲染为右对齐的kbd元素ms-auto ... tracking-widest用于在条目行尾展示快捷键如 ⌘L、⌘⇧C。这是让命令面板对新手也保持「可发现、可学习」的关键 UX 细节。常见陷阱Common pitfalls官方文档总结了三条高频问题值得在实现时逐条对照命令列表缺少清晰分组与动作标签没有分组的扁平长列表会让用户难以扫读应使用CommandGroupCommandGroupLabel并为每个动作提供明确的label与value分开必要时补充shortcut。把关键破坏性操作直接绑定到命令缺少确认路径删除、清空等破坏性动作不应在面板内一键触发应弹出确认流程如 AlertDialog再执行。缺少方向键 / 选择 / Esc 的键盘可访问性检查命令面板的可用性几乎全部依赖键盘。需要验证↑/↓导航、Enter选择、Esc关闭/返回以及autoFocus是否落位到输入框p-command-2中对 Esc 的自定义拦截AI 模式返回搜索就是一个需要刻意处理的边界。更多参考与粒子示例核心粒子p-command-1p-command-1.json— 对话框 分组动作命令面板p-command-2p-command-2.json— 集成 AI 助手的进阶命令面板。相关引用p-autocomplete-1、p-select-1、p-input-group-1分别对应搜索/选择/输入分组的邻近参考模式安装命令同样是npx shadcnlatest add coss/xxx并按需选用。源码入口command.tsx组件实现、autocomplete.tsxCommand 的底层原语、registry-ui.ts注册表声明、portal-props.mdportal 转发机制说明。综上coss 的Command组件把 Base UI 的 Dialog 与 Autocomplete 能力收敛为一份开箱即用的命令面板 API从最小示例到分组、快捷键、AI 搜索、portal 定制均有官方粒子与源码可循。照着本文的模式你可以在几分钟内构建出具备完整键盘可访问性、分组导航与快捷键唤起的专业命令面板。赞分享前端UI组件设计系统【免费下载链接】cosscoss.com/ui is the official design system of Cal.com项目地址https://gitcode.com/gh_mirrors/or/coss点击查看免费下载相关推荐gpui-kit Command 命令面板完全指南构建分组过滤、Action 快捷键提示与键盘导航的 ⌘K 风格命令列表gpui kit Command 命令面板完全指南构建分组过滤、Action 快捷键提示与键盘导航的 ⌘K 风格命令列表 命令面板Command Palet桌面应用UI组件前端coss Menu 组件实战指南用 Base UI 构建可访问的 React 下拉菜单coss Menu 组件实战指南用 Base UI 构建可访问的 React 下拉菜单 在 kaneo 项目中 Menu 是 coss UI 组件库 htt企业应用后端前端gpui-kit Command 组件实战指南构建可搜索、可虚拟化的 ⌘K 命令面板gpui kit Command 组件实战指南构建可搜索、可虚拟化的 ⌘K 命令面板 本指南以 gpui kit 组件库的 Command 命令面板为核心系桌面应用UI组件前端上一篇Lucide 图标库全解析社区驱动的轻量 SVG 图标解决方案与多框架集成指南下一篇MLflow AI Gateway 接入 TogetherAICompletions、Chat 与 Embeddings 端点配置实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表