-
Notifications
You must be signed in to change notification settings - Fork 140
Expand file tree
/
Copy pathPanel.tsx
More file actions
118 lines (108 loc) · 3.34 KB
/
Panel.tsx
File metadata and controls
118 lines (108 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import classNames from 'classnames';
import KeyCode from '@rc-component/util/lib/KeyCode';
import React from 'react';
import type { CollapsePanelProps } from './interface';
import PanelContent from './PanelContent';
const CollapsePanel = React.forwardRef<HTMLDetailsElement, CollapsePanelProps>((props, ref) => {
const {
showArrow = true,
headerClass,
isActive,
onItemClick,
forceRender,
className,
classNames: customizeClassNames = {},
styles = {},
prefixCls,
collapsible,
accordion,
panelKey,
extra,
header,
expandIcon,
openMotion,
destroyOnHidden,
children,
...resetProps
} = props;
const disabled = collapsible === 'disabled';
const ifExtraExist = extra !== null && extra !== undefined && typeof extra !== 'boolean';
const collapsibleProps = {
onClick: (e: React.MouseEvent) => {
onItemClick?.(panelKey);
e.stopPropagation();
},
onKeyDown: (e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.keyCode === KeyCode.ENTER || e.which === KeyCode.ENTER) {
onItemClick?.(panelKey);
}
},
role: accordion ? 'tab' : 'button',
['aria-expanded']: isActive,
['aria-disabled']: disabled,
tabIndex: disabled ? -1 : 0,
};
// ======================== Icon ========================
const iconNodeInner =
typeof expandIcon === 'function' ? expandIcon(props) : <i className="arrow" />;
const iconNode = iconNodeInner && (
<div
className={classNames(`${prefixCls}-expand-icon`, customizeClassNames?.icon)}
style={styles?.icon}
{...(['header', 'icon'].includes(collapsible) ? collapsibleProps : {})}
>
{iconNodeInner}
</div>
);
const collapsePanelClassNames = classNames(
`${prefixCls}-item`,
{
[`${prefixCls}-item-active`]: isActive,
[`${prefixCls}-item-disabled`]: disabled,
},
className,
// ? 修改为details实现后动画是作用在details元素上 需要将motionName设置在details上
openMotion?.motionName,
);
const headerClassName = classNames(
headerClass,
`${prefixCls}-header`,
{
[`${prefixCls}-collapsible-${collapsible}`]: !!collapsible,
},
customizeClassNames?.header,
);
// ======================== HeaderProps ========================
const headerProps: React.HTMLAttributes<HTMLElement> = {
className: headerClassName,
style: styles?.header,
...(['header', 'icon'].includes(collapsible) ? {} : collapsibleProps),
};
// ======================== Render ========================
return (
<details {...resetProps} ref={ref} className={collapsePanelClassNames} open={isActive}>
<summary {...headerProps}>
{showArrow && iconNode}
<span
className={classNames(`${prefixCls}-title`, customizeClassNames?.title)}
style={styles?.title}
{...(collapsible === 'header' ? collapsibleProps : {})}
>
{header}
</span>
{ifExtraExist && <div className={`${prefixCls}-extra`}>{extra}</div>}
</summary>
<PanelContent
prefixCls={prefixCls}
classNames={customizeClassNames}
styles={styles}
isActive={isActive}
forceRender={forceRender}
role={accordion ? 'tabpanel' : undefined}
>
{children}
</PanelContent>
</details>
);
});
export default CollapsePanel;