-
Notifications
You must be signed in to change notification settings - Fork 131
/
Collapse.tsx
97 lines (86 loc) · 2.51 KB
/
Collapse.tsx
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
import classNames from 'classnames';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import warning from 'rc-util/lib/warning';
import React from 'react';
import useItems from './hooks/useItems';
import type { CollapseProps } from './interface';
import CollapsePanel from './Panel';
import pickAttrs from 'rc-util/lib/pickAttrs';
function getActiveKeysArray(activeKey: React.Key | React.Key[]) {
let currentActiveKey = activeKey;
if (!Array.isArray(currentActiveKey)) {
const activeKeyType = typeof currentActiveKey;
currentActiveKey =
activeKeyType === 'number' || activeKeyType === 'string' ? [currentActiveKey] : [];
}
return currentActiveKey.map((key) => String(key));
}
const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) => {
const {
prefixCls = 'rc-collapse',
destroyInactivePanel = false,
style,
accordion,
className,
children,
collapsible,
openMotion,
expandIcon,
activeKey: rawActiveKey,
defaultActiveKey,
onChange,
items,
} = props;
const collapseClassName = classNames(prefixCls, className);
const [activeKey, setActiveKey] = useMergedState<React.Key | React.Key[], React.Key[]>([], {
value: rawActiveKey,
onChange: (v) => onChange?.(v),
defaultValue: defaultActiveKey,
postState: getActiveKeysArray,
});
const onItemClick = (key: React.Key) =>
setActiveKey(() => {
if (accordion) {
return activeKey[0] === key ? [] : [key];
}
const index = activeKey.indexOf(key);
const isActive = index > -1;
if (isActive) {
return activeKey.filter((item) => item !== key);
}
return [...activeKey, key];
});
// ======================== Children ========================
warning(
!children,
'[rc-collapse] `children` will be removed in next major version. Please use `items` instead.',
);
const mergedChildren = useItems(items, children, {
prefixCls,
accordion,
openMotion,
expandIcon,
collapsible,
destroyInactivePanel,
onItemClick,
activeKey,
});
// ======================== Render ========================
return (
<div
ref={ref}
className={collapseClassName}
style={style}
role={accordion ? 'tablist' : undefined}
{...pickAttrs(props, { aria: true, data: true })}
>
{mergedChildren}
</div>
);
});
export default Object.assign(Collapse, {
/**
* @deprecated use `items` instead, will be removed in `v4.0.0`
*/
Panel: CollapsePanel,
});