Skip to content

feat(blockheader): support expand and change callname to onExpand #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/blockHeader/__tests__/blockHeader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@
test('should render BlockHeader props default in BlockHeader', () => {
const { container } = render(<BlockHeader title="测试" showBackground />);
const wrap = container.firstChild;
expect(wrap!.firstChild!.firstChild!.firstChild).toHaveClass(`${prefixCls}-before-title`);

Check warning on line 47 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion

Check warning on line 47 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion

Check warning on line 47 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
fireEvent.click(document.getElementsByClassName(`${prefixCls}-title-row`)[0]);
});
test('should render BlockHeader with different props', () => {
const { container, getByText } = render(<BlockHeader {...props2} />);
const wrap = container.firstChild;
expect(wrap).toHaveClass(`${prefixCls}`);
expect(wrap!.lastChild).toHaveClass(`${prefixCls}-content`);

Check warning on line 54 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
expect(wrap!.firstChild).toHaveClass(`test-row-className`);

Check warning on line 55 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
expect(getByText('标题2')).toHaveClass('test-title-className');
expect(getByText('说明文字')).toHaveClass(`${prefixCls}-after-title`);
expect(getByText('新增按钮')).toHaveClass(`test-button-after`);
Expand All @@ -61,7 +61,7 @@
test('should render BlockHeader test click event', () => {
const onChange = jest.fn();
const { getByText } = render(
<BlockHeader onChange={onChange} title="测试">
<BlockHeader onExpand={onChange} title="测试">
<div>1111</div>
</BlockHeader>
);
Expand All @@ -84,8 +84,8 @@
const { container, getByText } = render(<BlockHeader {...props2} />);
const wrap = container.firstChild;
expect(wrap).toHaveClass(`${prefixCls}`);
expect(wrap!.lastChild).toHaveClass(`${prefixCls}-content`);

Check warning on line 87 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
expect(wrap!.firstChild).toHaveClass(`test-row-className`);

Check warning on line 88 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
expect(getByText('标题2')).toHaveClass('test-title-className');
expect(getByText('说明文字')).toHaveClass(`${prefixCls}-after-title`);
expect(getByText('Icon')).toBeTruthy();
Expand All @@ -94,11 +94,11 @@
const props = { title: '测试1', showBackground: false };
const { container } = render(<BlockHeader {...props} />);
const wrap = container.firstChild;
expect(wrap!.firstChild).not.toHaveClass(`background`);

Check warning on line 97 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
});
test('should render BlockHeader className when isSmall is small', () => {
const { container, getByText } = render(<BlockHeader {...props2} />);
const wrap = container.firstChild!;

Check warning on line 101 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
expect(wrap).toHaveClass(`${prefixCls}`);
expect(wrap.lastChild).toHaveClass(`${prefixCls}-content`);
expect(wrap.firstChild).toHaveClass(`test-row-className`);
Expand All @@ -109,7 +109,7 @@

test('should render BlockHeader tooltip success', () => {
const { container } = render(<BlockHeader {...props3} />);
const wrap = container.firstChild!;

Check warning on line 112 in src/blockHeader/__tests__/blockHeader.test.tsx

View workflow job for this annotation

GitHub Actions / setup

Forbidden non-null assertion
const afterTitleWrap = wrap.firstChild!.firstChild!.lastChild;
expect(afterTitleWrap!.firstChild).toHaveClass('anticon-question-circle');
});
Expand Down
24 changes: 16 additions & 8 deletions src/blockHeader/demos/expand.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import React from 'react';
import React, { useState } from 'react';
import { Space } from 'antd';
import { BlockHeader } from 'dt-react-component';

export default () => {
const [expand, setExpand] = useState(false);
return (
<BlockHeader
title="分类标题"
defaultExpand={false}
onChange={(expand) => console.log(expand)}
>
Hello World!
</BlockHeader>
<Space direction="vertical" style={{ width: '100%' }}>
<BlockHeader
title="非受控标题"
defaultExpand={false}
onExpand={(expand) => console.log(expand)}
>
Hello World!
</BlockHeader>

<BlockHeader title="受控标题" expand={expand} onExpand={(expand) => setExpand(expand)}>
Hello World!
</BlockHeader>
</Space>
);
};
3 changes: 2 additions & 1 deletion src/blockHeader/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ demo:
| titleClassName | 标题的样式类名 | `string` | - |
| showBackground | 是否显示背景 | `boolean` | `true` |
| defaultExpand | 是否默认展开内容 | `boolean` | `true` |
| expand | 当前展开状态 | `boolean` | |
| hasBottom | 是否有默认下边距 16px | `boolean` | `false` |
| spaceBottom | 自定义下边距,优先级高于 hasBottom | `number` | `0` |
| children | 展开/收起的内容 | `React.ReactNode` | - |
| onChange | 展开/收起时的回调 | `(expand: boolean) => void` | - |
| onExpand | 展开/收起时的回调 | `(expand: boolean) => void` | - |
50 changes: 31 additions & 19 deletions src/blockHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,45 @@ import './style.scss';

export declare type SizeType = 'small' | 'middle' | undefined;

function isControlled(props: IBlockHeaderProps) {
return props.expand !== undefined;
}

export interface IBlockHeaderProps {
// 标题
/** 标题 */
title: string;
// 标题前的图标,默认是一个色块
/** 标题前的图标,默认是一个色块 */
beforeTitle?: ReactNode;
// 标题后的提示图标或文案
/** 标题后的提示图标或文案 */
afterTitle?: ReactNode;
// 默认展示为问号的tooltip
/** 默认展示为问号的tooltip */
tooltip?: ReactNode;
// 后缀自定义内容块
/** 后缀自定义内容块 */
addonAfter?: ReactNode;
/**
* 小标题 font-size: 12px; line-height: 32px
* 中标题 font-size: 14px; line-height: 40px
* 默认 中标题
*/
size?: SizeType;
/** 是否展示 Bottom,默认 false,Bottom 值 16px */
hasBottom?: boolean;
/** 自定义 Bottom 值 */
spaceBottom?: number;
// 标题一行的样式类名
/** 标题一行的样式类名 */
titleRowClassName?: string;
// 标题的样式类名
/** 标题的样式类名 */
titleClassName?: string;
// 是否显示背景, 默认 true
/** 是否显示背景, 默认 true */
showBackground?: boolean;
// 是否默认展开内容, 默认 true
/** 当前展开状态 */
expand?: boolean;
/** 是否默认展开内容, 默认 true */
defaultExpand?: boolean;
// 展开/收起时的回调
onChange?: (expand: boolean) => void;
/** 展开/收起的内容 */
children?: ReactNode;
/** 展开/收起时的回调 */
onExpand?: (expand: boolean) => void;
}
const BlockHeader: React.FC<IBlockHeaderProps> = function (props) {
const prefixCls = 'dtc-block-header';
Expand All @@ -52,12 +61,15 @@ const BlockHeader: React.FC<IBlockHeaderProps> = function (props) {
showBackground = true,
defaultExpand = true,
addonAfter,
expand,
children = '',
beforeTitle = <div className={`${prefixCls}__beforeTitle-${size}`}></div>,
onChange,
onExpand,
} = props;

const [expand, setExpand] = useState(defaultExpand);
const [internalExpand, setInternalExpand] = useState(defaultExpand);

const currentExpand = isControlled(props) ? expand : internalExpand;

const preTitleRowCls = `${prefixCls}-title-row`;

Expand All @@ -73,8 +85,8 @@ const BlockHeader: React.FC<IBlockHeaderProps> = function (props) {

const handleExpand = (expand: boolean) => {
if (!children) return;
setExpand(expand);
onChange?.(expand);
!isControlled(props) && setInternalExpand(expand);
onExpand?.(expand);
};

return (
Expand All @@ -89,7 +101,7 @@ const BlockHeader: React.FC<IBlockHeaderProps> = function (props) {
[`${preTitleRowCls}-pointer`]: children,
}
)}
onClick={() => handleExpand(!expand)}
onClick={() => handleExpand(!currentExpand)}
>
<div className={`${prefixCls}-title-box`}>
{beforeTitle ? (
Expand All @@ -103,13 +115,13 @@ const BlockHeader: React.FC<IBlockHeaderProps> = function (props) {
{addonAfter && <div className={`${prefixCls}-addonAfter-box`}>{addonAfter}</div>}
{children && (
<div className={`${prefixCls}-collapse-box`}>
<div className="text">{expand ? '收起' : '展开'}</div>
<UpOutlined className={`icon ${expand ? 'up' : 'down'}`} />
<div className="text">{currentExpand ? '收起' : '展开'}</div>
<UpOutlined className={`icon ${currentExpand ? 'up' : 'down'}`} />
</div>
)}
</div>

<div className={`${prefixCls}-content ${expand ? '' : 'hide'}`}>{children}</div>
<div className={`${prefixCls}-content ${currentExpand ? '' : 'hide'}`}>{children}</div>
</div>
);
};
Expand Down
Loading