ToggleGroup
Nhóm toggle button có tên, cho một lựa chọn không bắt buộc hoặc vài lựa chọn độc lập. Phím mũi tên chuyển focus mà không đổi lựa chọn.
Xem trước
import { IconAlignCenter, IconAlignLeft, IconAlignRight } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>Cách dùng
Khi nào dùng
- Chọn một hoặc vài lựa chọn toolbar liên quan, chẳng hạn căn chỉnh hoặc định dạng chữ.
- Giữ một bộ lựa chọn gọn cùng nhau, với điều hướng bằng phím mũi tên.
Khi nào không dùng
- Phải luôn còn một lựa chọn được chọn. Dùng RadioGroup.
- Chuyển giữa các panel nội dung. Dùng Tabs.
- Một lựa chọn độc lập đơn lẻ. Dùng Toggle.
Biến thể
variant
Trong suốt khi tắt, hoặc một surface có viền trung tính cho outline.
import { IconAlignCenter, IconAlignLeft, IconAlignRight } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup variant="outline" type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>size
Chiều cao control, cỡ chữ và icon, cùng các bước với Button: sm 28px, md 32px (mặc định), lg 36px, xl 44px với chuột; trên cảm ứng md là 36px, lg 44px và xl 48px. Control nhỏ vẫn giữ vùng nhấn tối thiểu.
import { IconAlignCenter, IconAlignLeft, IconAlignRight } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup size="sm" type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-sm)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup size="lg" type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-lg)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup size="xl" type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-xl)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={20} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={20} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={20} />
Phải
</ToggleGroupItem>
</ToggleGroup>orientation
Điều khiển layout và các phím mũi tên dùng để điều hướng.
import { IconAlignCenter, IconAlignLeft, IconAlignRight } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup orientation="vertical" type="single" defaultValue="left" aria-label="Căn chỉnh văn bản" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">
<IconAlignLeft size={16} />
Trái
</ToggleGroupItem>
<ToggleGroupItem value="center">
<IconAlignCenter size={16} />
Giữa
</ToggleGroupItem>
<ToggleGroupItem value="right">
<IconAlignRight size={16} />
Phải
</ToggleGroupItem>
</ToggleGroup>Ví dụ
Căn chỉnh không bắt buộc
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" aria-label="Căn chỉnh văn bản" defaultValue="left" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left">Trái</ToggleGroupItem>
<ToggleGroupItem value="center">Giữa</ToggleGroupItem>
<ToggleGroupItem value="right">Phải</ToggleGroupItem>
</ToggleGroup>Định dạng độc lập
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="multiple" aria-label="Định dạng văn bản" defaultValue={["bold"]} className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="bold">Đậm</ToggleGroupItem>
<ToggleGroupItem value="italic">In nghiêng</ToggleGroupItem>
</ToggleGroup>Lựa chọn view theo chiều dọc
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" aria-label="Xem" orientation="vertical" variant="outline" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="grid">Lưới</ToggleGroupItem>
<ToggleGroupItem value="list">Danh sách</ToggleGroupItem>
</ToggleGroup>Căn chỉnh chỉ bằng icon
Một lựa chọn căn chỉnh không bắt buộc. Mỗi icon có tên truy cập.
import { IconAlignCenter, IconAlignLeft, IconAlignRight } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" aria-label="Căn chỉnh văn bản" defaultValue="left" className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="left" iconOnly aria-label="Căn trái">
<IconAlignLeft size={16} />
</ToggleGroupItem>
<ToggleGroupItem value="center" iconOnly aria-label="Căn giữa">
<IconAlignCenter size={16} />
</ToggleGroupItem>
<ToggleGroupItem value="right" iconOnly aria-label="Căn phải">
<IconAlignRight size={16} />
</ToggleGroupItem>
</ToggleGroup>Icon và chữ định dạng
Nhiều định dạng có thể cùng được chọn. Gạch chân không dùng được.
import { IconBold, IconItalic, IconUnderline } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="multiple" aria-label="Định dạng văn bản" variant="outline" defaultValue={["bold"]} className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="bold">
<IconBold size={16} />
Đậm
</ToggleGroupItem>
<ToggleGroupItem value="italic">
<IconItalic size={16} />
In nghiêng
</ToggleGroupItem>
<ToggleGroupItem value="underline" disabled>
<IconUnderline size={16} />
Gạch chân
</ToggleGroupItem>
</ToggleGroup>Lựa chọn icon vô hiệu
import { IconBold, IconItalic } from "@tabler/icons-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="multiple" aria-label="Định dạng văn bản đã khóa" disabled defaultValue={["bold"]} className="min-w-0 max-w-full flex-wrap gap-y-[max(var(--spacing-xs),calc(var(--size-target-min)-var(--size-element-md)))]">
<ToggleGroupItem value="bold" iconOnly aria-label="Đậm">
<IconBold size={16} />
</ToggleGroupItem>
<ToggleGroupItem value="italic" iconOnly aria-label="In nghiêng">
<IconItalic size={16} />
</ToggleGroupItem>
</ToggleGroup>Nên và không nên
Nên
- Đặt tên nhóm và giữ label của mỗi item ổn định.
- Dùng single cho lựa chọn view không bắt buộc và multiple cho các lựa chọn định dạng độc lập.
Không nên
- Đừng dùng single khi phải luôn còn đúng một lựa chọn; dùng RadioGroup.
- Đừng lặp value của item trong một nhóm.
Props
| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
|---|---|---|---|---|
| variant | enum | default | outline | default | Trong suốt khi tắt, hoặc một surface có viền trung tính cho outline. |
| size | enum | sm | md | lg | xl | md | Chiều cao control, cỡ chữ và icon, cùng các bước với Button: sm 28px, md 32px (mặc định), lg 36px, xl 44px với chuột; trên cảm ứng md là 36px, lg 44px và xl 48px. Control nhỏ vẫn giữ vùng nhấn tối thiểu. |
| disabled | boolean | - | false | Chặn focus và lựa chọn, và dùng màu disabled. |
| iconOnly | boolean | - | false | Đặt trên ToggleGroupItem. Làm item vuông. Item chỉ có icon cần aria-label. |
| type bắt buộc | enum | single | multiple | - | single nhận value string và cho phép bỏ chọn. multiple nhận mảng string. |
| value | node | - | - | Lựa chọn controlled: một string cho single hoặc một mảng string cho multiple. Mỗi item cần value riêng, không trùng. |
| defaultValue | node | - | - | Lựa chọn ban đầu khi uncontrolled: một string cho single hoặc một mảng string cho multiple. |
| onValueChange | function | - | - | Nhận một string cho single hoặc một mảng string cho multiple. Xóa lựa chọn single báo một string rỗng. |
| orientation | enum | horizontal | vertical | horizontal | Điều khiển layout và các phím mũi tên dùng để điều hướng. |
| dir | enum | ltr | rtl | ltr | Hướng chữ, được kế thừa khi bỏ qua. RTL đảo các mũi tên ngang. |
| loop | boolean | - | true | Vòng điều hướng mũi tên ở hai đầu khi true. |
Cấu tạo
| Phần | Mô tả |
|---|---|
| root | Toggle button, trong suốt theo mặc định hoặc surface có viền ở outline. Khi bật dùng cặp accent mềm. |
| icon | Icon trang trí tùy chọn, 16px ở sm, md và lg và 20px ở xl. |
| hitArea | Pseudo-element trong suốt kéo đích của button tới size-target-min. |
| wrapper | Nhóm có tên, với khoảng cách token, ngang theo mặc định và dọc khi được yêu cầu. |
Khả năng truy cập
Role: radiogroup (single), toolbar (multiple)
| Phím | Hành động |
|---|---|
| Tab | Vào nhóm tại một item, rồi rời nhóm. |
| ArrowLeft, ArrowRight | Chuyển focus trong nhóm ngang, bỏ qua item disabled, và tôn trọng hướng chữ. |
| ArrowUp, ArrowDown | Chuyển focus trong nhóm dọc và bỏ qua item disabled. |
| Home, End | Chuyển focus tới item enabled đầu hoặc cuối. |
| Space, Enter | Toggle item đang focus. |
- Nhóm cần aria-label hoặc aria-labelledby.
- Item single có role="radio" và aria-checked. Item multiple có aria-pressed.
- Nhấn một item single đang được chọn thì xóa lựa chọn. Dùng RadioGroup khi một lựa chọn phải vẫn được chọn.
- Item cần các string value không rỗng và không trùng. Item chỉ có icon cần aria-label.
- Size và variant của nhóm là mặc định của item. Một item có thể ghi đè một trong hai mặc định.
- Phím mũi tên chuyển focus; chúng không chọn. loop mặc định là true.
Cài đặt
npx werewolf-ui add toggle-groupChạ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.