Copy Button: xác nhận tức thì bằng state change

Copy button là một trong những interaction nhỏ nhất có thể làm — nhưng khi thiếu feedback, người dùng luôn tự hỏi: “Nó có copy chưa? Tôi có cần nhấn lại không?”

Spring easing cubic-bezier(0.34, 1.56, 0.64, 1)
Ease out cubic-bezier(0, 0, 0.58, 1)
Transition — quick 200ms
Transition — base 280ms

Click Copy để copy giá trị vào clipboard

State machine tối giản

Copy button chỉ cần hai trạng thái:

StateVisualDuration
idleIcon copy + label “Copy”Mặc định
doneIcon checkmark + label “Copied” + màu xanh1.8s

Không cần loading state vì Clipboard API gần như tức thì. Không cần error state vì failure là edge case — xử lý silent là đủ.

Tại sao 1.8 giây

Ngắn hơn (< 1s): người dùng có thể bỏ lỡ confirmation nếu không nhìn kịp.

Dài hơn (> 3s): button bị “kẹt” trạng thái quá lâu, trông như bị broken.

1.8s là đủ để mắt người nhận ra sự thay đổi và não xác nhận “đã xong”.

Label transition

Label cũ slide lên (translateY(-6px)) và label mới slide vào từ dưới — cùng direction convention với ButtonStateDemo. Consistent direction = consistent mental model.

Color semantics

rgb(34, 197, 94) (green-500) cho done state vì:

  • Green = thành công, hoàn tất — universal semantic
  • Contrast đủ tốt trên cả light và dark surface
  • Không dùng blue (primary) để tránh nhầm với interactive state

Mỗi button độc lập

Mỗi row có state riêng. Click “Copy” trên row 1 không ảnh hưởng row 2, 3, 4. Điều này quan trọng khi người dùng copy nhiều giá trị liên tiếp.