enhance: auto layout hasSider (#45361)

* enhance: auto layout hasSider

* test: update snapshot
This commit is contained in:
二货爱吃白萝卜 2023-10-16 14:49:01 +08:00 committed by GitHub
parent dce878233f
commit 7f9aff2cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 26 deletions

View File

@ -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',

View File

@ -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"

View File

@ -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');
});
});

View 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,
},
});

View 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);
}

View File

@ -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,