Skip to content

Commit ba47b30

Browse files
authored
fix: dropdown menu missing first tab in overflow edge case (#866)
1 parent 778663d commit ba47b30

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

src/hooks/useVisibleRange.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ export default function useVisibleRange(
3838
let endIndex = len;
3939
for (let i = 0; i < len; i += 1) {
4040
const offset = tabOffsets.get(tabs[i].key) || DEFAULT_SIZE;
41-
if (Math.floor(offset[position] + offset[charUnit]) > Math.floor(transformSize + visibleTabContentValue)) {
41+
if (
42+
Math.floor(offset[position] + offset[charUnit]) >
43+
Math.floor(transformSize + visibleTabContentValue)
44+
) {
4245
endIndex = i - 1;
4346
break;
4447
}
@@ -53,7 +56,7 @@ export default function useVisibleRange(
5356
}
5457
}
5558

56-
return startIndex >= endIndex ? [0, 0] : [startIndex, endIndex];
59+
return startIndex > endIndex ? [0, -1] : [startIndex, endIndex];
5760
}, [
5861
tabOffsets,
5962
visibleTabContentValue,

tests/overflow.test.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,4 +584,65 @@ describe('Tabs.Overflow', () => {
584584

585585
jest.useRealTimers();
586586
});
587+
588+
it('should handle no visible tabs when container is too small', () => {
589+
jest.useFakeTimers();
590+
591+
// 设置极小的容器空间,无法显示任何tab
592+
// 可用空间 = container - more - add - extra - tabNode = 40 - 10 - 10 - 10 - 20 = -10
593+
hackOffsetInfo.container = 40;
594+
hackOffsetInfo.more = 10;
595+
hackOffsetInfo.add = 10;
596+
hackOffsetInfo.extra = 10;
597+
hackOffsetInfo.tabNode = 20;
598+
599+
const { container, unmount } = render(
600+
getTabs({
601+
editable: { onEdit: () => {} },
602+
tabBarExtraContent: 'Extra',
603+
}),
604+
);
605+
606+
triggerResize(container);
607+
608+
act(() => {
609+
jest.runAllTimers();
610+
});
611+
612+
// 验证关键行为:当startIndex > endIndex时(返回[0,-1]),容器太小无法显示任何tab
613+
614+
// 1. "更多"按钮存在(在operations区域,用于访问隐藏的tab)
615+
const dropdownTrigger = container.querySelector('.rc-tabs-nav-operations .rc-tabs-nav-more');
616+
expect(dropdownTrigger).toBeTruthy();
617+
618+
// 2. 验证添加按钮(operations区域的添加按钮应该可见)
619+
const operationsAddButton = container.querySelector('.rc-tabs-nav-operations .rc-tabs-nav-add');
620+
expect(operationsAddButton).toBeTruthy();
621+
622+
// 3. Extra内容存在
623+
const extraTrigger = container.querySelector('.rc-tabs-extra-content');
624+
expect(extraTrigger).toBeTruthy();
625+
626+
// 4. transform会是负值,将所有tab移出可视区域
627+
const transformX = getTransformX(container);
628+
expect(transformX).toBe(-10); // 实际测量值,说明组件正确处理了无tab可见的情况
629+
630+
// 5. 获取实际的tab数量(动态计算,不硬编码)
631+
const allTabs = container.querySelectorAll('.rc-tabs-nav-list .rc-tabs-tab');
632+
const expectedTabCount = allTabs.length;
633+
634+
// 6. 触发下拉菜单打开,验证所有tab都在dropdown中
635+
fireEvent.mouseEnter(dropdownTrigger);
636+
637+
act(() => {
638+
jest.runAllTimers();
639+
});
640+
641+
// 验证下拉菜单包含所有tab
642+
const moreDropdownItems = document.querySelectorAll('.rc-tabs-dropdown-menu-item');
643+
expect(moreDropdownItems.length).toBe(expectedTabCount);
644+
645+
unmount();
646+
jest.useRealTimers();
647+
});
587648
});

0 commit comments

Comments
 (0)