Bỏ qua tới nội dung
Component / 011 / NEXOFRAME

RadioGroup

Mẫu chuẩn

Chọn đúng một giá trị trong một tập loại trừ nhau, khi mọi lựa chọn nên hiện ra cùng lúc trước mắt người dùng.

Radix RadioGroupVòng 16 pxKhông dựng layoutLight & dark

Playground

Đổi cấu hình để xem cùng một nhóm RadioGroup thích ứng với nhận diện và ngữ cảnh.

LIVE PREVIEW

Đang chọn: Tiêu chuẩn

import { RadioGroup, RadioGroupItem, Label } from "@nexobox/ui";

<RadioGroup defaultValue="standard" aria-label="Gói cước">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="standard" id="standard" />
    <Label htmlFor="standard">Tiêu chuẩn</Label>
  </div>
</RadioGroup>

Khi nào sử dụng

Nên dùng

Chọn đúng một giá trị trong một tập loại trừ nhau, khi tất cả lựa chọn nên hiện ra cùng lúc — thường 2 đến 5 lựa chọn.

Tránh dùng

Nhiều lựa chọn không loại trừ nhau — dùng Checkbox. Bật/tắt một hiệu lực đang chạy — dùng Switch. Danh sách dài cần thu gọn — dùng Select.

Anatomy

RadioGroup là tái xuất trần của RadioGroupPrimitive.Root — không class, không layout, không khoảng cách giữa các item. Trang này tự bọc mỗi RadioGroupItem cùng Label trong một hàng flex và tự đặt gap-3; đó chính là bằng chứng cho việc primitive không dựng layout — nếu bỏ lớp bọc này, các vòng tròn sẽ dính sát nhau. Mỗi Item là một vòng tròn 16 px; khi được chọn, một chấm 8 px hiện ra bên trong qua RadioGroupPrimitive.Indicator.

Variants & states

variant: không có. size: không có.

UNCHECKED

Nền field, viền control, không có chấm.

CHECKED

Viền đổi màu nhấn, nền vòng ngoài giữ nguyên, chấm 8 px hiện ra.

HOVER

Di chuột vào vòng. Nền của vòng không đổi. Vầng hover là bóng 4px bám đúng hình tròn, đọc --nf-component-radio-hover.

PRESSED

Giữ chuột xuống. Cùng state layer đọc --nf-component-radio-pressed, cộng viền vòng thật đổi sang --nf-component-radio-border-pressed. Không co scale.

FOCUS-VISIBLE

Outline theo token focus, offset dương.

DISABLED

Nền và viền chuyển sang màu disabled, con trỏ not-allowed.

DISABLED + CHECKED

Khiếm khuyết đã biết: vòng ngoài chuyển màu disabled nhưng chấm bên trong vẫn giữ màu nhấn chính — hai màu không ăn nhau. Chưa sửa trong radio-group.tsx.

Design tokens

Giá trị theo NexoCrew / light đang chọn trong playground. Item đọc --nf-component-field-background, --nf-semantic-border-control, --nf-semantic-action-primary-border khi checked; chấm đọc --nf-semantic-action-primary-background. Token --nf-component-radio-radius tồn tại nhưng code dùng rounded-full — một alias chưa được nối, giá trị trùng nên không lệch thị giác. State layer (::before) đọc --nf-component-radio-hover và --nf-component-radio-pressed; viền vòng thật đổi sang --nf-component-radio-border-pressed khi nhấn.

API & triển khai

PropMặc địnhQuy ước
value / defaultValue—Chế độ controlled / uncontrolled cho cả nhóm.
onValueChange—Phát khi giá trị đổi.
disabledfalseVô hiệu hoá cả nhóm; item cũng nhận riêng disabled.
orientationundefinedChỉ đổi chiều mũi tên, không tự dựng layout.
looptrueMũi tên ở item cuối quay vòng về item đầu.
RadioGroupItem value—Bắt buộc, giá trị của item đó.

Accessibility & nội dung

Tab vào cả nhóm là một điểm dừng duy nhất (roving tabindex), focus rơi vào item đang chọn hoặc item đầu.
Mũi tên di chuyển và chọn luôn item kế tiếp, không cần Space.
Ghép Label bằng htmlFor cho từng item; đặt aria-label hoặc aria-labelledby trên RadioGroup để nhóm có tên truy cập.
size, variant, loading, error, density: không có. Hover và pressed có, qua state layer — không tự tăng vùng chạm dưới 44 px ở con trỏ mịn.