Component
Command
Tìm và chạy một hành động bằng cách gõ. Dùng Command inline hoặc CommandDialog cho một palette, với kết quả theo nhóm và điều hướng bằng bàn phím.
Xem trước
import { IconPlus, IconSearch, IconSettings } from "@tabler/icons-react"
import { Command, CommandGroup, CommandItem, CommandSeparator, CommandShortcut } from "@/components/ui/command"
const selectCommand = (value: string) => { /* Chạy hành động đã chọn. */ }
<Command label="Tìm kiếm lệnh" placeholder="Tìm kiếm thao tác…" emptyText="Không tìm thấy kết quả." className="w-full max-w-md">
<CommandGroup heading="Không gian làm việc">
<CommandItem value="new-project" keywords={["create"]} leadingIcon={<IconPlus size={16} />} onSelect={selectCommand} shortcut={<CommandShortcut aria-label="Command N">⌘ N</CommandShortcut>}>Dự án mới</CommandItem>
<CommandItem value="search-projects" leadingIcon={<IconSearch size={16} />} onSelect={selectCommand}>Tìm kiếm dự án</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Tài khoản">
<CommandItem value="settings" leadingIcon={<IconSettings size={16} />} onSelect={selectCommand}>Cài đặt</CommandItem>
<CommandItem value="billing" disabled onSelect={selectCommand}>Thanh toán</CommandItem>
</CommandGroup>
</Command>Cách dùng
Khi nào dùng
- Tìm và chạy hành động từ danh sách tìm được, inline hoặc trong dialog.
- Để người dùng tới một đích bằng cách tìm tên hoặc keywords của đích đó.
Khi nào không dùng
- Chọn một giá trị form từ danh sách tìm được. Dùng Combobox.
- Menu ngắn, cố định, không có tìm kiếm. Dùng DropdownMenu.
- Đăng ký shortcut toàn cục. Thêm handler trong ứng dụng của bạn.
Ví dụ
Hành động workspace
import { Command, CommandGroup, CommandItem, CommandSeparator } from "@/components/ui/command"
const selectCommand = (value: string) => { /* Chạy hành động đã chọn. */ }
<Command label="Tìm một thao tác của không gian làm việc" placeholder="Tìm kiếm không gian làm việc…">
<CommandGroup heading="Không gian làm việc">
<CommandItem value="create" keywords={["new", "add"]} onSelect={selectCommand}>Tạo dự án</CommandItem>
<CommandItem value="archive" disabled>Lưu trữ dự án</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Tài khoản">
<CommandItem value="profile" onSelect={selectCommand}>Sửa hồ sơ</CommandItem>
</CommandGroup>
</Command>Trong dialog
Phần tử cha giữ trạng thái mở và các handler của hành động. Khi đóng, focus trở về button.
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Command, CommandDialog, CommandItem } from "@/components/ui/command"
const [commandOpen, setCommandOpen] = useState(false)
const openCommand = () => setCommandOpen(true)
const selectCommand = (value: string) => { /* Chạy hành động đã chọn. */ }
<div>
<Button variant="secondary" onClick={openCommand}>Mở lệnh</Button>
<CommandDialog title="Thao tác không gian làm việc" open={commandOpen} onOpenChange={setCommandOpen}>
<Command label="Tìm một thao tác">
<CommandItem value="create" onSelect={selectCommand}>Tạo dự án</CommandItem>
<CommandItem value="profile" onSelect={selectCommand}>Sửa hồ sơ</CommandItem>
</Command>
</CommandDialog>
</div>Từ tìm tùy chỉnh
import { Command, CommandGroup, CommandItem } from "@/components/ui/command"
const selectCommand = (value: string) => { /* Chạy hành động đã chọn. */ }
<Command label="Tìm một cài đặt" emptyText="Không có cài đặt nào khớp.">
<CommandGroup heading="Cài đặt">
<CommandItem value="appearance" textValue="Giao diện" keywords={["theme", "dark", "light"]} onSelect={selectCommand}>Giao diện</CommandItem>
<CommandItem value="notifications" onSelect={selectCommand}>Thông báo</CommandItem>
</CommandGroup>
</Command>Nên và không nên
Nên
- Dùng nhãn ngắn mở đầu bằng động từ và xếp hành động liên quan thành nhóm.
- Đưa textValue cho nhãn tùy chỉnh và keywords cho các tên khác.
- Để ứng dụng tự đăng ký shortcut toàn cục và xử lý tác dụng phụ của hành động.
Không nên
- Đừng dùng Command để gửi một giá trị form; dùng Combobox.
- Đừng dùng tìm từ xa trực tiếp hoặc trang command lồng nhau trong phiên bản này.
- Đừng hiện gợi ý shortcut cho shortcut mà ứng dụng không làm.
Props
| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
|---|---|---|---|---|
| label bắt buộc | string | - | - | Tên truy cập của ô tìm và danh sách kết quả. |
| placeholder | string | - | Search actions… | Gợi ý nhìn thấy trong ô tìm. |
| emptyText | string | - | No results found. | Trạng thái hiện khi không command nào khớp chữ đang tìm. |
| search | string | - | - | Chữ tìm được kiểm soát. Phần tử cha cập nhật nó qua onSearchChange. |
| defaultSearch | string | - | Chữ tìm ban đầu cho Command không được kiểm soát. | |
| onSearchChange | function | - | - | Được gọi với chữ tìm mới mỗi khi người dùng gõ. |
| loop | boolean | - | true | Quay vòng điều hướng mũi tên từ kết quả enabled cuối về kết quả đầu. |
| open | boolean | - | - | Trạng thái mở được kiểm soát của CommandDialog. |
| defaultOpen | boolean | - | false | Trạng thái mở ban đầu của CommandDialog không được kiểm soát. |
| onOpenChange | function | - | - | Được gọi khi CommandDialog mở hoặc đóng. |
| heading bắt buộc | string | - | - | Tiêu đề nhìn thấy và truy cập được của CommandGroup. |
| value bắt buộc | string | - | - | Định danh CommandItem duy nhất, truyền vào onSelect. Đây không phải lựa chọn form được lưu. |
| keywords | node | - | - | Một mảng các từ tìm thêm trên CommandItem. |
| leadingIcon | node | - | - | Icon trang trí của CommandItem. Dùng icon thường 16px. |
| shortcut | node | - | - | Gợi ý phím của CommandItem: chữ dùng một Kbd nhỏ; node CommandShortcut, Kbd hoặc KbdGroup giữ định dạng và tên truy cập riêng. Không đăng ký shortcut. |
| disabled | boolean | - | false | CommandItem disabled vẫn hiện nhưng không được tô sáng hoặc kích hoạt. |
| onSelect | function | - | - | Callback của CommandItem, nhận value của nó. CommandDialog đóng sau khi kích hoạt. |
| textValue | string | - | - | Nhãn tìm được của CommandItem khi children chứa node tùy chỉnh. |
| title bắt buộc | string | - | - | CommandDialog dùng prop title để đặt tên dialog của nó. Bắt buộc trên CommandDialog, không có trên Command inline. |
| description | string | - | - | CommandDialog dùng prop description cho mô tả truy cập tùy chọn. |
Cấu tạo
| Phần | Mô tả |
|---|---|
| root | Một command enabled hoặc một kết quả disabled. |
| control | Ô tìm với ngữ nghĩa combobox. |
| placeholder | Gợi ý hiện trong ô tìm đang trống. |
| list | Danh sách kết quả cuộn được. |
| icon | Icon trang trí trước nhãn của command. |
| groupLabel | Tiêu đề nhìn thấy của một nhóm kết quả. |
| separator | Đường kẻ trang trí giữa các nhóm đang hiện. |
| empty | Chữ trạng thái khi không command nào khớp. |
| shortcut | Gợi ý phím gọn ở cuối hàng. Chữ thuần dùng Kbd nhỏ; gợi ý phím hoặc nhóm phím được truyền thì render trực tiếp, không thêm keycap nữa. |
| content | Panel raised kiểu inline, chứa field tìm và kết quả của nó. |
Khả năng truy cập
Role: combobox
| Phím | Hành động |
|---|---|
| ArrowDown / ArrowUp | Đưa phần tô sáng qua các command enabled đang hiện, không rời field tìm. |
| Home / End | Tô sáng command enabled đang hiện đầu tiên hoặc cuối cùng. |
| Enter | Kích hoạt command đang tô sáng đúng một lần; không bao giờ kích hoạt khi đang soạn chữ. |
| Escape | Đóng CommandDialog và trả focus về phần tử đã mở nó. Command inline để Escape cho phần tử chủ. |
| Tab / Shift+Tab | Theo thứ tự focus bình thường khi inline; ở lại trong dialog khi modal. |
- label là bắt buộc và đặt tên cho cả field tìm lẫn listbox.
- aria-activedescendant chỉ trỏ tới một option enabled đã mount. aria-selected theo phần đang tô sáng.
- Mỗi CommandGroup được đặt tên bằng tiêu đề của nó. Các mục disabled được thông báo là disabled.
- CommandDialog bắt buộc title và focus vào field tìm khi mở. Nó đặt lại chữ tìm không kiểm soát khi đóng.
- Dùng value không trùng cho mỗi mục và nội dung thuần, không tương tác. Hành động nằm ở onSelect; đừng lồng link hoặc button bên trong một option.
Cài đặt
npx werewolf-ui add commandChạy npx werewolf-ui init một lần trong app trước khi thêm component. Init cài token, thêm CSS import và luật cho agent. Add cài component này cùng các dependency và giữ nguyên theme của bạn. Xem Cài đặt để biết yêu cầu và cách cài qua registry.