mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-23 18:50:06 +08:00
fix: fix the issue about throw a warning when Splitter nested in a hidden tab panel (#51109)
This commit is contained in:
parent
1a8b252606
commit
e17d7c9a85
@ -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 =========================
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 =============================
|
||||
|
7
components/splitter/demo/nested-in-tabs.md
Normal file
7
components/splitter/demo/nested-in-tabs.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
嵌套在标签页中。
|
||||
|
||||
## en-US
|
||||
|
||||
Nested in tabs.
|
54
components/splitter/demo/nested-in-tabs.tsx
Normal file
54
components/splitter/demo/nested-in-tabs.tsx
Normal 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;
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user