fix: fix the issue about throw a warning when Splitter nested in a hidden tab panel (#51109)

This commit is contained in:
kiner-tang 2024-10-04 11:57:15 +08:00 committed by GitHub
parent 1a8b252606
commit e17d7c9a85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 319 additions and 1 deletions

View File

@ -71,7 +71,14 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
const [containerSize, setContainerSize] = useState<number>(100);
const onContainerResize: GetProp<typeof ResizeObserver, 'onResize'> = (size) => {
setContainerSize(isVertical ? size.offsetHeight : size.offsetWidth);
const { offsetWidth, offsetHeight } = size;
const containerSize = isVertical ? offsetHeight : offsetWidth;
// Skip when container has no size, Such as nested in a hidden tab panel
// to fix: https://github.com/ant-design/ant-design/issues/51106
if (containerSize === 0) {
return;
}
setContainerSize(containerSize);
};
// ========================= Size =========================

View File

@ -810,6 +810,132 @@ exports[`renders components/splitter/demo/multiple.tsx extend context correctly
exports[`renders components/splitter/demo/multiple.tsx extend context correctly 2`] = `[]`;
exports[`renders components/splitter/demo/nested-in-tabs.tsx extend context correctly 1`] = `
<div
class="ant-tabs ant-tabs-top"
>
<div
class="ant-tabs-nav"
role="tablist"
>
<div
class="ant-tabs-nav-wrap"
>
<div
class="ant-tabs-nav-list"
style="transform: translate(0px, 0px);"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-controls="rc-tabs-test-panel-1"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-1"
role="tab"
tabindex="0"
>
General
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-controls="rc-tabs-test-panel-2"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-2"
role="tab"
tabindex="0"
>
Splitter Tab
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="rc-tabs-test-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="rc-tabs-test-more"
style="visibility: hidden; order: 1;"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
<div
class="ant-tabs-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-tabs-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
aria-label="expanded dropdown"
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
data-menu-list="true"
id="rc-tabs-test-more-popup"
role="listbox"
tabindex="-1"
/>
<div
aria-hidden="true"
style="display: none;"
/>
</div>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
aria-labelledby="rc-tabs-test-tab-1"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-1"
role="tabpanel"
tabindex="0"
>
Content of Tab Pane 1
</div>
</div>
</div>
</div>
`;
exports[`renders components/splitter/demo/nested-in-tabs.tsx extend context correctly 2`] = `[]`;
exports[`renders components/splitter/demo/size.tsx extend context correctly 1`] = `
<div
class="ant-splitter ant-splitter-horizontal"

View File

@ -826,6 +826,107 @@ exports[`renders components/splitter/demo/multiple.tsx correctly 1`] = `
</div>
`;
exports[`renders components/splitter/demo/nested-in-tabs.tsx correctly 1`] = `
<div
class="ant-tabs ant-tabs-top"
>
<div
class="ant-tabs-nav"
role="tablist"
>
<div
class="ant-tabs-nav-wrap"
>
<div
class="ant-tabs-nav-list"
style="transform:translate(0px, 0px)"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
General
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Splitter Tab
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="null-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="null-more"
style="visibility:hidden;order:1"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
role="tabpanel"
tabindex="0"
>
Content of Tab Pane 1
</div>
</div>
</div>
</div>
`;
exports[`renders components/splitter/demo/size.tsx correctly 1`] = `
<div
class="ant-splitter ant-splitter-horizontal"

View File

@ -270,6 +270,27 @@ describe('Splitter', () => {
expect(onResize).toHaveBeenCalledWith([50, 0, 50]);
expect(onResizeEnd).toHaveBeenCalledWith([50, 0, 50]);
});
it("aria-valuemin/aria-valuemax should not set NaN When container's width be setting zero", async () => {
containerSize = 0;
const App: React.FC = () => {
return <SplitterDemo items={[{}, {}, {}]} />;
};
const { container } = render(<App />);
mockDrag(container.querySelectorAll<HTMLDivElement>('.ant-splitter-bar-dragger')[1], -100);
triggerResize(container.querySelector('.ant-splitter')!);
await act(async () => {
await waitFakeTimer();
});
expect(errSpy).not.toHaveBeenCalled();
expect(container.querySelector('[aria-valuemin]')?.getAttribute('aria-valuemin')).not.toBe(
'NaN',
);
expect(container.querySelector('[aria-valuemax]')?.getAttribute('aria-valuemax')).not.toBe(
'NaN',
);
});
});
// ============================= Collapsible =============================

View File

@ -0,0 +1,7 @@
## zh-CN
嵌套在标签页中。
## en-US
Nested in tabs.

View File

@ -0,0 +1,54 @@
import React from 'react';
import { Flex, Splitter, Tabs, Typography } from 'antd';
const Desc: React.FC<Readonly<{ text?: string | number }>> = (props) => (
<Flex justify="center" align="center" style={{ height: '100%' }}>
<Typography.Title type="secondary" level={5} style={{ whiteSpace: 'nowrap' }}>
{props.text}
</Typography.Title>
</Flex>
);
const App: React.FC = () => {
const SplitterContent = (
<Splitter
style={{
height: 200,
boxShadow: '0 0 10px rgba(0, 0, 0, 0.1)',
}}
>
<Splitter.Panel collapsible>
<Desc text={1} />
</Splitter.Panel>
<Splitter.Panel
collapsible={{
start: true,
}}
>
<Desc text={2} />
</Splitter.Panel>
<Splitter.Panel>
<Desc text={3} />
</Splitter.Panel>
</Splitter>
);
return (
<Tabs
defaultActiveKey="1"
items={[
{
key: '1',
label: 'General',
children: 'Content of Tab Pane 1',
},
{
key: '2',
label: 'Splitter Tab',
children: SplitterContent,
},
]}
/>
);
};
export default App;

View File

@ -23,6 +23,7 @@ Can be used to separate areas horizontally or vertically. When you need to freel
<code src="./demo/collapsible.tsx">Collapsible</code>
<code src="./demo/multiple.tsx">Multiple panels</code>
<code src="./demo/group.tsx">Complex combination</code>
<code src="./demo/nested-in-tabs.tsx" debug>Nested in tabs</code>
<code src="./demo/debug.tsx" debug>Debug</code>
## API

View File

@ -26,6 +26,7 @@ tag: 5.21.0
<code src="./demo/collapsible.tsx">可折叠</code>
<code src="./demo/multiple.tsx">多面板</code>
<code src="./demo/group.tsx">复杂组合</code>
<code src="./demo/nested-in-tabs.tsx" debug>标签页中嵌套</code>
<code src="./demo/debug.tsx" debug>调试</code>
## API