Hooks
Chín hook dùng chung mà chính các component của Yugen UI dùng — trạng thái, màn hình, lưu trữ, phím tắt, đo đạc.
Import
Cài từ npm, chép mã nguồn vào dự án bằng @yugen-ui/cli hoặc shadcn CLI, hoặc import thẳng khi làm việc trong repo này.
// npm install yugen-uiimport { useControllableState, useDisclosure, useMediaQuery, useLocalStorage, useClipboard, useHotkeys, useDebouncedValue, useIntersection, useElementSize,} from "yugen-ui";Biến thể
Mỗi ô là một mẫu độc lập: hover để Copy, hoặc bấm Code để xem mã nguồn.
Bảng đang đóng.
useDisclosure
Mở / đóng / đảo cho dialog, menu, panel. Các hàm có identity ổn định nên truyền thẳng vào onClick.
useMediaQuery
Theo dõi một CSS media query. Đổi cỡ cửa sổ hoặc chế độ sáng / tối của hệ điều hành để thấy đổi ngay, không nháy khi render lại.
useLocalStorage
Lưu JSON vào localStorage, đồng bộ giữa các hook cùng khoá và giữa các tab. Server và lần hydrate đầu dùng giá trị ban đầu nên HTML không lệch.
yugen_live_4f9a2c71useClipboard
Chép chữ vào bộ nhớ tạm; copied tự tắt sau timeout. Đã có sẵn đường lui cho ngữ cảnh không an toàn.
Bấm vào khung này rồi nhấn Ctrl / ⌘ + K, ? hoặc mũi tên. Gõ trong ô dưới: phím thường bị bỏ qua, phím có Ctrl / ⌘ vẫn chạy.
useHotkeys
Khoá là tổ hợp phím, mod là ⌘ trên Mac và Ctrl ở nơi khác. Phím thường không chạy khi đang gõ trong ô nhập; start / end đảo theo RTL.
Đang gõ: “”
Sau 400ms: “” — đã “gọi API” 0 lần
useDebouncedValue
Giá trị chỉ đổi khi người dùng ngừng gõ đủ delay — gọi API theo giá trị đã debounce thay vì mỗi phím.
useIntersection
Biết phần tử có đang trong khung nhìn không. Dùng once để tải lười hoặc chạy hiệu ứng đúng một lần.
0 × 0 px
Bố cục gọn— kéo góc dưới phải để đổi cỡ.
useElementSize
Đo phần tử theo ResizeObserver, để đổi bố cục theo chỗ chứa thay vì theo cỡ cửa sổ.
Cách dùng
- Dùng useControllableState cho mọi component có cặp x / defaultX / onXChange để hành vi controlled và uncontrolled giống nhau.
- Dùng useMediaQuery cho logic (đổi component, đổi số cột); dùng breakpoint của Tailwind cho thay đổi thuần giao diện.
- Đặt tên khoá useLocalStorage có tiền tố của ứng dụng, và chỉ lưu dữ liệu nhỏ, không nhạy cảm.
- Đặt phím tắt toàn cục ở vài chỗ cấp cao; để useHotkeys bỏ qua ô nhập thay vì tự lọc.
- Không đọc giá trị useLocalStorage khi render để quyết định HTML ở server — lần render đầu luôn là giá trị ban đầu.
- Không lưu token hay dữ liệu cá nhân vào localStorage.
- Không dùng
left/rightcho phím tắt điều hướng theo chiều chữ — dùngstart/endđể RTL đúng. - Không debounce giá trị mà người dùng cần thấy phản hồi ngay (ô nhập vẫn bind giá trị gốc).
Props
| Prop · Kiểu | Mặc định | Mô tả |
|---|---|---|
| useControllableState | Mặc định: — | Hàm set có identity ổn định, bỏ qua khi giá trị không đổi. value === undefined nghĩa là uncontrolled. |
| useDisclosure | Mặc định: defaultOpen: false | Trạng thái mở / đóng, cũng dùng được ở chế độ controlled. |
| useMediaQuery | Mặc định: false | Giá trị khi chưa có window (server, test). Dựa trên useSyncExternalStore nên không nháy. |
| useLocalStorage | Mặc định: — | set nhận giá trị hoặc hàm cập nhật; remove() xoá khoá và về giá trị ban đầu. Dữ liệu hỏng hoặc localStorage bị chặn vẫn không gây lỗi. Mặc định lưu JSON; serialize / deserialize để đọc khoá có sẵn ở dạng khác. |
| useClipboard | Mặc định: 1600 | timeout (ms) là thời gian giữ copied = true. |
| useHotkeys | Mặc định: — | options: target (mặc định document), enabled (true), enableOnFormTags (false), preventDefault (true), repeat (false: giữ phím chỉ tính một lần). Khoá hợp lệ: mod / ctrl / meta / alt / shift + phím, cùng alias esc, space, up, down, left, right, start, end. |
| useDebouncedValue | Mặc định: 300 | Trả giá trị ngay lần đầu; sau đó chỉ đổi khi value đứng yên delay ms. |
| useIntersection | Mặc định: — | Gắn ref vào phần tử. Không có IntersectionObserver thì luôn false. |
| useElementSize | Mặc định: box: "content-box", enabled: true | Chưa đo được (server, lần render đầu) thì là 0 × 0. Đo lần đầu trước khi trình duyệt vẽ nên không nháy. Dùng được cả với chữ viết dọc. enabled: false khi kích thước đã biết trước (vd. độ rộng cố định): không đo, không ResizeObserver, không render thêm, luôn 0 × 0. |