Yugen UI

Overflow

Overflow thu các item không vừa chiều rộng vào nút menu "…", theo thứ tự ưu tiên.

Bọc container (Toolbar, TabsList, Breadcrumb, TagGroup hay một div flex) bằng <Overflow> và từng item bằng <OverflowItem id priority>. Kích thước đo bằng ResizeObserver và được cache; item bị ẩn vẫn mounted nhưng gắn hidden + data-overflowing nên không focus được. Nút menu dùng useOverflowMenu() (ref + số item ẩn) và useOverflowItems() (id các item ẩn theo thứ tự) để render MenuItem tương ứng. Render đầu tiên (và SSR) luôn hiện đủ item; RTL hoạt động vì chỉ đo độ rộng, không giả định trái/phải.
Độ rộng khung (%)100

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.

TSX
// npm install yugen-uiimport { Overflow, OverflowItem, OverflowDivider, useOverflowMenu, useOverflowItems } 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.

Ưu tiên & minimumVisible

priority lớn hơn ở lại lâu hơn: Sửa (3) → Chia sẻ (2) → Xoá (1) → phần còn lại. minimumVisible={1} giữ ít nhất một nút dù khung rất hẹp.

Tabs

Tab đang chọn có priority 1 nên luôn hiển thị; chọn tab trong menu sẽ đưa nó ra ngoài. Nút menu nằm ngoài TabsList (tablist chỉ nên chứa tab).

Breadcrumb & OverflowDivider

Mỗi mục có groupId riêng; OverflowDivider ẩn cùng nhóm. Mục đầu và trang hiện tại có priority 1, phần giữa gom vào "…". Kéo góc khung để đổi độ rộng.

ReactTypeScriptTailwind CSSRadix UIFluent 2ViteVitestPlaywrightNode.js

TagGroup "+N"

Tag không vừa một dòng gom vào InteractionTag "+N" mở menu.

Cách dùng

Nên
  • Chỉ render nút menu khi isOverflowing và gắn ref của useOverflowMenu() lên phần tử ngoài cùng của nó.
  • Đặt priority cao cho item quan trọng hoặc đang chọn (tab active, trang hiện tại) để chúng không bị ẩn.
  • Cho container độ rộng không phụ thuộc nội dung (khối, w-full, flex-1) — Overflow tự thêm w-full min-w-0.
Không nên
  • Không để nút menu luôn hiển thị — Overflow chỉ chừa chỗ cho nó khi có item bị ẩn.
  • Không dùng Overflow cho nội dung đọc được dạng đoạn văn — dùng truncate hoặc xuống dòng.
  • Không đặt item có độ rộng co giãn (flex-1) bên trong: kích thước phải là kích thước tự nhiên.

Props

Prop · KiểuMặc địnhMô tả
Overflow.childrenReactElementMặc định: —Một container chuyển tiếp ref và nhận className.
overflowAxis"horizontal" | "vertical"Mặc định: "horizontal"Trục đo (vertical cần container cao cố định).
overflowDirection"end" | "start"Mặc định: "end"Cùng priority thì ẩn từ cuối hay từ đầu.
minimumVisiblenumberMặc định: 0Số item luôn hiển thị.
paddingnumberMặc định: 0Khoảng (px) chừa thêm ở cuối; nút menu đã được tự đo.
onOverflowChange({ hiddenIds, visibleIds }) => voidMặc định: —Gọi khi tập item ẩn thay đổi.
OverflowItem.id / priority / groupIdstring / number / stringMặc định: — / 0 / —Định danh, mức ưu tiên (lớn = ở lại lâu hơn), nhóm.
OverflowDivider.groupIdstringMặc định: —Divider ẩn khi mọi item của nhóm bị ẩn (không cần child chuyển tiếp ref).
useOverflowMenu<T>(){ ref, overflowCount, isOverflowing }Mặc định: —Cho nút menu "…".
useOverflowItems()string[]Mặc định: —id các item đang ẩn, theo thứ tự DOM.
useIsOverflowItemVisible(id) / useIsOverflowGroupVisible(groupId)boolean / "visible" | "overflow" | "hidden"Mặc định: —Trạng thái một item / một nhóm.
computeOverflow(input)(input) => { visibleIds, hiddenIds }Mặc định: —Thuật toán thuần (không cần DOM) — dùng để test hoặc tự dựng layout.