mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
enhance: auto layout hasSider (#45361)
* enhance: auto layout hasSider * test: update snapshot
This commit is contained in:
parent
dce878233f
commit
7f9aff2cfb
@ -1,14 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
import BarsOutlined from '@ant-design/icons/BarsOutlined';
|
||||
import LeftOutlined from '@ant-design/icons/LeftOutlined';
|
||||
import RightOutlined from '@ant-design/icons/RightOutlined';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import isNumeric from '../_util/isNumeric';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { LayoutContext } from './layout';
|
||||
import { LayoutContext } from './context';
|
||||
|
||||
const dimensionMaxMap = {
|
||||
xs: '479.98px',
|
||||
|
@ -115,7 +115,7 @@ exports[`renders components/layout/demo/basic.tsx correctly 1`] = `
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
>
|
||||
<aside
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
@ -172,7 +172,7 @@ exports[`renders components/layout/demo/component-token.tsx correctly 1`] = `
|
||||
</div>
|
||||
</header>
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
>
|
||||
<aside
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
@ -429,7 +429,7 @@ exports[`renders components/layout/demo/component-token.tsx correctly 1`] = `
|
||||
|
||||
exports[`renders components/layout/demo/custom-trigger.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
>
|
||||
<aside
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
@ -1256,7 +1256,7 @@ exports[`renders components/layout/demo/fixed-sider.tsx correctly 1`] = `
|
||||
|
||||
exports[`renders components/layout/demo/responsive.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
>
|
||||
<aside
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
@ -1434,7 +1434,7 @@ exports[`renders components/layout/demo/responsive.tsx correctly 1`] = `
|
||||
|
||||
exports[`renders components/layout/demo/side.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
style="min-height:100vh"
|
||||
>
|
||||
<aside
|
||||
@ -2154,7 +2154,7 @@ exports[`renders components/layout/demo/top-side.tsx correctly 1`] = `
|
||||
</ol>
|
||||
</nav>
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
style="padding:24px 0;background:#ffffff"
|
||||
>
|
||||
<aside
|
||||
@ -2469,7 +2469,7 @@ exports[`renders components/layout/demo/top-side-2.tsx correctly 1`] = `
|
||||
/>
|
||||
</header>
|
||||
<div
|
||||
class="ant-layout"
|
||||
class="ant-layout ant-layout-has-sider"
|
||||
>
|
||||
<aside
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import React, { useState } from 'react';
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import Layout from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
@ -332,4 +334,16 @@ describe('Sider', () => {
|
||||
expect(ref.current instanceof HTMLElement).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('auto check hasSider', () => {
|
||||
const htmlContent = renderToString(
|
||||
<Layout>
|
||||
<div />
|
||||
<Sider />
|
||||
<div />
|
||||
</Layout>,
|
||||
);
|
||||
|
||||
expect(htmlContent).toContain('ant-layout-has-sider');
|
||||
});
|
||||
});
|
||||
|
15
components/layout/context.ts
Normal file
15
components/layout/context.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface LayoutContextProps {
|
||||
siderHook: {
|
||||
addSider: (id: string) => void;
|
||||
removeSider: (id: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const LayoutContext = React.createContext<LayoutContextProps>({
|
||||
siderHook: {
|
||||
addSider: () => null,
|
||||
removeSider: () => null,
|
||||
},
|
||||
});
|
22
components/layout/hooks/useHasSider.ts
Normal file
22
components/layout/hooks/useHasSider.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import type * as React from 'react';
|
||||
import toArray from 'rc-util/lib/Children/toArray';
|
||||
|
||||
import Sider from '../Sider';
|
||||
|
||||
export default function useHasSider(
|
||||
siders: string[],
|
||||
children?: React.ReactNode,
|
||||
hasSider?: boolean,
|
||||
) {
|
||||
if (typeof hasSider === 'boolean') {
|
||||
return hasSider;
|
||||
}
|
||||
|
||||
if (siders.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const childNodes = toArray(children);
|
||||
|
||||
return childNodes.some((node) => node.type === Sider);
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { LayoutContext } from './context';
|
||||
import useHasSider from './hooks/useHasSider';
|
||||
import useStyle from './style';
|
||||
|
||||
export interface GeneratorProps {
|
||||
@ -16,19 +19,6 @@ export interface BasicProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
hasSider?: boolean;
|
||||
}
|
||||
|
||||
export interface LayoutContextProps {
|
||||
siderHook: {
|
||||
addSider: (id: string) => void;
|
||||
removeSider: (id: string) => void;
|
||||
};
|
||||
}
|
||||
export const LayoutContext = React.createContext<LayoutContextProps>({
|
||||
siderHook: {
|
||||
addSider: () => null,
|
||||
removeSider: () => null,
|
||||
},
|
||||
});
|
||||
|
||||
interface BasicPropsWithTagName extends BasicProps {
|
||||
tagName: 'header' | 'footer' | 'main' | 'div';
|
||||
}
|
||||
@ -91,11 +81,13 @@ const BasicLayout = React.forwardRef<HTMLDivElement, BasicPropsWithTagName>((pro
|
||||
const { getPrefixCls, layout } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('layout', customizePrefixCls);
|
||||
|
||||
const mergedHasSider = useHasSider(siders, children, hasSider);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
const classString = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-has-sider`]: typeof hasSider === 'boolean' ? hasSider : siders.length > 0,
|
||||
[`${prefixCls}-has-sider`]: mergedHasSider,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
layout?.className,
|
||||
|
Loading…
Reference in New Issue
Block a user