Bỏ qua tới nội dung

Nền tảng

States

Đã đặc tả

Sáu trạng thái: rest, hover, pressed, focus-visible, selected, disabled. Chúng được kể bằng màu bề mặt và ring, không bằng hình học — một control không lún, không nảy, không đổi kích thước khi bị chạm vào. Focus có ba lớp, không phải hai, và lớp thứ ba không phải focus.

Nghĩa vụ

Obligation

IDObligationNguồn
A33Trạng thái kể bằng bề mặtDS-018 clause 1
A34Không control nào câmDS-018 clause 1, 10
A35Một ring duy nhấtDS-018 clause 7, 8
A36Highlighted không phải focusDS-018 clause 9

A33

A33 Trạng thái kể bằng bề mặt

Hover, pressed, selected và disabled biểu đạt bằng màu — nền, viền, chữ. Không control nào đổi chiều cao, chiều rộng, vị trí hay scale để báo trạng thái. Ô nhập chữ là ngoại lệ duy nhất không có pressed: gõ không phải nhấn.

Ở chiều cao mặc định 36px sau DS-017 clause 3, một phép thu 2% dịch 0,7 pixel — dưới ngưỡng đọc được thành phản hồi, nhưng đủ để trình duyệt lấy mẫu lại chữ trong nhãn và làm nó rung. Đó là nhiễu phải trả giá render mà không mua được thông tin nào.

Kiểm. node infra/check-control-states.mjs — chuỗi press-scale không được xuất hiện trong packages/ui/src/**.

A34

A34 Không control nào câm

Mỗi primitive tương tác có hover, pressed và focus-visible; cộng selected nếu nó có trạng thái chọn, và disabled nếu nó vô hiệu hoá được. Trước DS-018, checkbox, radio và switch không có hover — cách duy nhất biết con trỏ đang ở trên một checkbox là con trỏ chuột đổi hình. Sáu ô dưới đây là năm trạng thái trên primitive thật, cạnh nhau — không phải mô tả, không phải ảnh chụp.

rest

Trạng thái nghỉ, không token nào áp.

hover

surface.hover — nền +1 bậc.

pressed

surface.pressed, border.strong. Không lún, không co — chỉ màu đổi.

focus-visible

Ring 2px, cách 2px. Bấm chuột vào nút này không vẽ ring — chỉ Tab mới vẽ.

selected / checked

Di chuột vào từng hộp: nền của chính hộp không đổi — hover và pressed sống trên một state layer phía sau, vì trên hộp 20px đổi nền của chính nó sẽ đọc như đổi checked.

disabled

Nền và chữ mờ, con trỏ không còn bấm được.

A35

A35 Một ring duy nhất

Ring vẽ ở :focus-visible, không ở :focus. Nó dùng --nf-component-focus-color, -width, -offset và không được tuỳ biến theo primitive.:focus-visible đã xử lý đúng sự khác biệt ở tầng trình duyệt: click vào một ô text vẫn được coi là focus-visible vì người dùng cần biết caret ở đâu, click một nút thì không. Ô nhập là chỗ duy nhất hai lớp tách nhau: :focus đổi border-color, còn :focus-visible vẽ ring.

Ring giống hệt nhau trên mọi control. Người dùng bàn phím học chỉ báo này một lần; hình học của ring — độ dày, khoảng cách — thuộc A16, trang này không lặp lại nó.

A36

A36 Highlighted không phải focus

Trong menu, select và combobox, con trỏ bàn phím hiển thị bằng nền qua data-[highlighted]. Những item đó không nhận ring — ring cộng nền highlighted đọc như hai con trỏ cùng lúc trên cùng một danh sách, và nền một mình là đủ.

Never. Đừng "sửa" dropdown-menu.tsx vì nó không có focus-visible. Con số 0 ở đó là đúng, và gate của A34 miễn trừ nó có tên kèm lý do ghi trong chính mã gate — chứ không im lặng bỏ qua.

Bảng

Sáu trạng thái

Trạng tháiCơ chếToken
rest——
hovernền +1 bậc--nf-semantic-surface-hover
pressednền +2 bậc, viền đậm hơn--nf-semantic-surface-pressed, --nf-semantic-border-strong
focus-visiblering 2px, cách 2px--nf-component-focus-color / -width / -offset
selected / checkednền và chữ riêng--nf-semantic-action-selected-background / -foreground
disablednền và chữ mờ--nf-semantic-action-disabled-background / -foreground

Mỗi primitive bind alias -hover và -pressed của chính nó ở tầng component, không bind thẳng token semantic. Giá trị thật của mười token dưới, đọc trực tiếp từ theme đang mở:

TokenGiá trị
--nf-semantic-surface-hoverUnknown
--nf-semantic-surface-pressedUnknown
--nf-semantic-border-strongUnknown
--nf-component-focus-colorUnknown
--nf-component-focus-widthUnknown
--nf-component-focus-offsetUnknown
--nf-semantic-action-selected-backgroundUnknown
--nf-semantic-action-selected-foregroundUnknown
--nf-semantic-action-disabled-backgroundUnknown
--nf-semantic-action-disabled-foregroundUnknown

Thời lượng

Thời lượng: vào tức thì, ra mượt

--nf-component-transition-duration là 120ms và chi phối chiều ra. --nf-component-transition-press-duration là 0ms và được ép lên chiều vào qua :active. Đó không phải một chi tiết cài đặt tình cờ — nó là thứ tạo cảm giác chắc tay: trạng thái nhấn xuất hiện ngay lập tức dưới ngón tay, rồi tan đi trong 120ms khi thả. Đảo chiều lại sẽ cho cảm giác control phản hồi chậm dù tổng thời gian không đổi.

prefers-reduced-motion: reduce đưa mọi thời lượng về 0ms, nên các trạng thái nhảy tức thì. Đổi màu không phải chuyển động và về nguyên tắc không cần zero hoá, nhưng kết quả vô hại và nhất quán với phần còn lại của kit.

Ranh giới

States không phải là gì

Không phải bảng màu — giá trị của surface.hover và surface.pressed thuộc màu, trang này chỉ nói chúng dùng vào việc gì.

Không phải hình học của ring — độ dày, khoảng cách và lý do ring không dán sát viền nằm ở tiêu điểm và bàn phím.

Không phải presence — dialog vào bằng đường cong nào, menu ra trong bao lâu, thuộc chuyển động. Ranh giới: trạng thái là control đang được tương tác; presence là bề mặt đang xuất hiện hay biến mất.

Không phải validation — aria-invalid, viền lỗi và thông điệp thuộc trang của từng primitive và nội dung/ngôn ngữ.

Chưa quyết

Open questions

QuestionOwnerResolves when
surface.hover và surface.subtle có nên tách giá trị không?nexoboxvn@gmail.comMột nút ghost đặt trên nền subtle cần hover nhìn thấy được. Hôm nay hai token phân giải về cùng một giá trị ở theme sáng
Có cần trạng thái loading ở tầng này không?nexoboxvn@gmail.comMột primitive thứ hai ngoài Button cần nó
pressScale quay lại cho bề mặt nào?nexoboxvn@gmail.comChủ sở hữu nêu tên một bề mặt. Token ở lại corpus chính vì câu hỏi này còn mở