<Cthuvien:nhom> - <BSSList>
Mô tả
BSSList là component React thay thế cho <Cthuvien:nhom> cũ. Nó hiển thị danh sách chọn dạng dropdown (<select>) cho phép người dùng chọn nhanh một giá trị từ mảng cấu hình lke.
Điểm nổi bật của BSSList:
- Chống giật Grid (Local State): Giá trị đang chọn được lưu nội bộ. Chỉ khi
onBlur,Tab, hoặcEnter, component mới bắn giá trị ra ngoài (onChange), tránh render lại toàn bộ form/grid khi người dùng đang lướt qua các option. - Dữ liệu linh hoạt: Mảng
lkehỗ trợ nhiều cấu trúc tên trường (value/ma/MAcho giá trị,label/ten/TEN/name/NAMEcho hiển thị), giúp tương thích với dữ liệu từ nhiều nguồn API khác nhau mà không cần mapping thủ công. - Dòng trống (dongChon): Hỗ trợ thêm option rỗng đầu danh sách cho phép bỏ chọn, thay vì bắt buộc lúc nào cũng phải có giá trị mặc định.
- Phím tắt:
Spacemở popup dropdown (native),Enternhảy sang ô tiếp theo trong form#dt_ct.
Thuộc tính
So sánh thuộc tính cũ và mới
| <Cthuvien:nhom> | <BSSList> | Kiểu | Mô tả / Chú ý khi chuyển đổi |
|---|---|---|---|
ten | label | string | Tên nhãn hiển thị bên trái (tự động dịch đa ngôn ngữ). |
nhap | disabled | bool | Cũ: nhap="K". Mới: Dùng thuộc tính HTML chuẩn disabled={true}. |
lke (chuỗi) | lke (mảng) | Array | Cũ: Chuỗi lke="Xem,Sửa,Xóa" phẩy phân cách. Mới: Mảng Object [{ value: 'V', label: 'Xem' }]. |
tra (chuỗi) | (gộp vào lke) | Cũ: Chuỗi tra="V,E,D" phẩy phân cách. Mới: Gộp chung vào trường value của mỗi phần tử trong mảng lke. | |
cthich | (Không còn) | Chú thích giờ được xử lý riêng ở lớp logic ngoài component. | |
kieu_chu | (Không còn) | Tự viết hoa không áp dụng cho dropdown chọn giá trị. | |
kt_xoa | (Không còn) | Logic xóa quản lý ở lớp dữ liệu store/form. |
Các thuộc tính của <BSSList>
| Tên | Kiểu | Mặc định | Có thể có | Mục đích |
|---|---|---|---|---|
id | string | useId() | Định danh của control. Render ra HTML với prefix BSS_. | |
name | string | sinh tự động | Tên trường dữ liệu dùng làm key trong form và validation. | |
label | string | Nhãn hiển thị bên trái dropdown (tự động dịch đa ngôn ngữ). | ||
labelWidth | number / string | var(--bss-label-width) | 100, '120px' | Độ rộng của nhãn label. |
lke | Array | [] | [{ value, label }] | Danh sách option. Mỗi item hỗ trợ nhiều kiểu key: value/ma/MA (giá trị lưu) và label/ten/TEN/name/NAME (hiển thị). |
value | any | Giá trị binding hiện tại (phải khớp với value của một phần tử trong mảng lke). | ||
gtriDau | string | '' | Giá trị mặc định ban đầu nếu value là undefined. | |
dongChon | bool | false | true / false | Nếu true, thêm một dòng <option> rỗng ở đầu danh sách cho phép người dùng bỏ chọn. |
required | bool | false | true / false | Đánh dấu bắt buộc chọn (hiện sao đỏ). |
error | string | Nội dung lỗi (hoặc tự lấy từ context useValidation). Làm viền chuyển đỏ. | ||
isInGrid | bool | false | true / false | Đánh dấu control đang nằm trong lưới GridX (điều chỉnh background khi focus). |
className | string | '' | Class CSS bổ sung cho wrapper. | |
onChange | function | (e) => void | Sự kiện chính. Trả ra event giả { target: { name, value } } khi commit giá trị. | |
onChangeValue | function | (val) => void | Sự kiện phụ, nhận trực tiếp giá trị string đã chọn (tiện dùng, không cần e.target.value). |
Hoạt động phía Client
- Chọn giá trị: Khi người dùng chọn option trong dropdown, giá trị chỉ cập nhật local state. Lúc người dùng rời khỏi ô (blur) hoặc bấm
Tab/Enter, component mới so sánh giá trị local với giá trị props gốc — nếu khác nhau thì gọionChangevàonChangeValue. - Phím Space: Khi đang focus vào dropdown, bấm phím
Spacesẽ gọishowPicker()(native API) để mở danh sách dropdown của trình duyệt. - Phím Enter: Khi focus vào dropdown, nhấn
Entersẽ commit giá trị và tự động nhảy focus sang control kế tiếp (nếu trong form#dt_ct). - Dark Mode: Component tự phát hiện chế độ tối/sáng qua
useAppStore.isDarkModeđể điều chỉnh màu chữ tương ứng.
Ví dụ
1. Dropdown cơ bản (Chọn chi nhánh):
<BSSList
label="Chi nhánh"
name="chi_nhanh"
labelWidth={120}
required={true}
lke={[
{ value: 'HN', label: 'Hà Nội' },
{ value: 'HCM', label: 'Hồ Chí Minh' },
{ value: 'DN', label: 'Đà Nẵng' }
]}
value={data.chi_nhanh}
onChange={handleChange}
/>
2. Dropdown có dòng trống cho phép bỏ chọn:
<BSSList
label="Phòng ban"
name="phong_ban"
dongChon={true} // Thêm dòng trống đầu tiên
lke={danhSachPhongBan}
value={data.phong_ban}
onChange={handleChange}
onChangeValue={(val) => console.log('Đã chọn:', val)}
/>
3. Sử dụng trong lưới GridX (Không có label):
<BSSList
isInGrid={true}
dongChon={true}
lke={danhSachLoai}
value={row.loai}
onChange={(e) => updateRowField(row.id, 'loai', e.target.value)}
className="w-full"
/>