# Stepper Ô tăng/giảm số lượng gồm nút −, ô nhập số và nút +, dùng khi lên kế hoạch số phần mỗi món. ## Khi nào dùng - Chỉnh một số nguyên trong khoảng [min, max], ví dụ số phần Trà sữa cần chuẩn bị. - Cho phép cả bấm nút lẫn gõ trực tiếp số. ## Biến thể | Biến thể | Lớp | Dùng khi | |---|---|---| | Mặc định | `tt-stepper` | Nút 30×32, ô số rộng 46px | ## Cấu trúc ```html
``` Nút − là `.tt-stepper__btn` đầu tiên, nút + là cái cuối. ## Trạng thái | Trạng thái | Hiệu ứng | |---|---| | Chạm biên | Nút tương ứng `disabled` (opacity .4) | | Focus | Vòng `focus-ring` 3px trên nút hoặc ô số | ## Hành vi JS ```js var s = TTMU.stepper(el, { min: 0, max: 99, step: 5, onChange: function (v) {} }); s.value; // số hiện tại s.set(12); // đặt, kẹp trong [min, max] ``` - Mặc định `min = 0`, `max = ∞`, `step = 1`. Gõ số lạ khi rời ô thì quay về giá trị cũ. - Gắn một lần (`data-tt-bound`); trả về `{ value, set(n), destroy() }`. - **Quy ước `onChange`:** chỉ thao tác của người dùng mới gọi `onChange`, và chỉ khi giá trị thật sự đổi; `set()` từ code thì im lặng. ## Token sử dụng `line`, `bg`, `ink`, `radius-8`, cùng token của Button `--small`. ## Khả năng tiếp cận - Nút có `aria-label` "Bớt"/"Thêm" (nên kèm tên món ở ô số: "Số phần Trà sữa"). - `inputmode="numeric"` mở bàn phím số trên điện thoại; nút spin mặc định bị ẩn. ## Nên / Không nên | Nên | Không nên | |---|---| | Đặt `min`/`max` rõ ràng | Để người chơi nhập số âm | | Dùng `aria-label` có tên món cho ô số | Dùng "+"/"−" không có nhãn | ## Nguồn `.step5`, `.step5 .sbtn`, `.step5 input` (+ ẩn spin button) — css/style.css; markup trong js/game.js (`data-d`, `data-v`). - Nút gốc là `.sbtn` nên Stepper dùng `tt-button tt-button--small` cộng `tt-stepper__btn`. - Game cộng/trừ 5 mỗi lần bấm; ở đây là tuỳ chọn `step`.