Skip to content

Commit 83214cb

Browse files
fix(collapse): fix the behavior of the defaultExpandAll prop (#775)
* fix(collapse): fix the behavior of the defaultExpandAll prop - Fix the abnormal opening issue caused by the defaultExpandAll prop - Fix the conflict issue when defaultExpandAll and expandMutex are passed together * test(collapse): supplement test cases for the collapse component fix #697 * chore: update demo --------- Co-authored-by: novlan1 <[email protected]>
1 parent a86e3cd commit 83214cb

File tree

14 files changed

+4622
-14667
lines changed

14 files changed

+4622
-14667
lines changed

site/test-coverage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module.exports = {
88
cascader: { statements: '4.3%', branches: '0%', functions: '0%', lines: '4.59%' },
99
cell: { statements: '100%', branches: '100%', functions: '100%', lines: '100%' },
1010
checkbox: { statements: '99.12%', branches: '98.27%', functions: '100%', lines: '100%' },
11-
collapse: { statements: '69.09%', branches: '36.66%', functions: '72.72%', lines: '72.54%' },
11+
collapse: { statements: '100%', branches: '100%', functions: '100%', lines: '100%' },
1212
colorPicker: { statements: '3.03%', branches: '0%', functions: '0%', lines: '3.03%' },
1313
common: { statements: '82.75%', branches: '66.66%', functions: '83.33%', lines: '92%' },
1414
configProvider: { statements: '54.54%', branches: '0%', functions: '0%', lines: '54.54%' },

src/collapse/Collapse.tsx

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { forwardRef, memo, useCallback, useMemo } from 'react';
1+
import React, { forwardRef, memo, useCallback, useMemo, useRef } from 'react';
2+
import { debounce } from 'lodash-es';
23
import type { StyledProps } from '../common';
34
import type { TdCollapseProps, CollapseValue } from './type';
45
import { collapseDefaultProps } from './defaultProps';
@@ -29,25 +30,59 @@ const Collapse = forwardRef<HTMLDivElement, CollapseProps>((originProps, ref) =>
2930
} = props;
3031

3132
const [activeValue, setActiveValue] = useDefault<CollapseValue, any[]>(value, defaultValue, onChange);
33+
const firstNewValRef = useRef<any[] | null>(null);
34+
const collectedValuesRef = useRef<(string | number)[]>([]);
35+
36+
const debouncedUpdate = useMemo(
37+
() =>
38+
debounce((values: (string | number)[], args: { e: React.MouseEvent<HTMLDivElement> }) => {
39+
const uniqueValues = [...new Set(values)];
40+
setActiveValue(uniqueValues);
41+
onChange?.(uniqueValues, args);
42+
collectedValuesRef.current = [];
43+
}, 100),
44+
[onChange, setActiveValue],
45+
);
3246

3347
const onPanelChange = useCallback(
34-
(panelValue: string | number, args: { e: React.MouseEvent<HTMLDivElement> }) => {
35-
if (Array.isArray(activeValue)) {
36-
const hit = activeValue.indexOf(panelValue);
48+
(panelValue: string | number, args: { e: React.MouseEvent<HTMLDivElement> }, isDefaultExpandAll: boolean) => {
49+
if (!Array.isArray(activeValue)) {
50+
return;
51+
}
52+
53+
const isPanelActive = activeValue.includes(panelValue);
54+
55+
if (isPanelActive) {
56+
const newActiveValues = activeValue.filter((item) => item !== panelValue);
57+
setActiveValue(newActiveValues);
58+
onChange?.(newActiveValues, args);
59+
return;
60+
}
3761

38-
if (hit > -1) {
39-
const newVal = activeValue.filter((item) => item !== panelValue);
40-
setActiveValue(newVal);
41-
onChange?.(newVal, args);
42-
} else {
43-
const newVal = expandMutex ? [panelValue] : activeValue.concat(panelValue);
44-
setActiveValue(newVal);
45-
onChange?.(newVal, args);
62+
if (isDefaultExpandAll && expandMutex) {
63+
if (firstNewValRef.current === null) {
64+
firstNewValRef.current = [panelValue];
65+
setActiveValue([panelValue]);
66+
onChange?.([panelValue], args);
4667
}
68+
return;
4769
}
70+
71+
if (isDefaultExpandAll && !expandMutex) {
72+
if (!collectedValuesRef.current.includes(panelValue)) {
73+
collectedValuesRef.current.push(panelValue);
74+
}
75+
const finalValues = [...activeValue, ...collectedValuesRef.current];
76+
debouncedUpdate(finalValues, args);
77+
return;
78+
}
79+
80+
const newActiveValues = expandMutex ? [panelValue] : [...activeValue, panelValue];
81+
setActiveValue(newActiveValues);
82+
onChange?.(newActiveValues, args);
4883
},
4984
// eslint-disable-next-line react-hooks/exhaustive-deps
50-
[activeValue, onChange, expandMutex],
85+
[activeValue, onChange, expandMutex, debouncedUpdate],
5186
);
5287

5388
const memoProviderValues = useMemo(

src/collapse/CollapseContext.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ export interface CollapseContextValue {
66
activeValue: CollapseValue | undefined;
77
disabled: boolean;
88
expandIcon: TNode;
9-
onPanelChange: (name: string | number, args: { e: React.MouseEvent<HTMLDivElement> }) => void;
9+
onPanelChange: (
10+
name: string | number,
11+
args: { e: React.MouseEvent<HTMLDivElement> },
12+
isDefaultExpandAll?: boolean,
13+
) => void;
1014
defaultExpandAll: boolean;
1115
}
1216

src/collapse/CollapsePanel.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ const CollapsePanel = forwardRef<HTMLDivElement, CollapsePanelProps>((originProp
4646

4747
useEffect(() => {
4848
if (parent?.defaultExpandAll) {
49-
parent.onPanelChange(value, { e: null });
49+
parent.onPanelChange(value, { e: null }, true);
5050
}
51-
}, [parent, value]);
51+
// eslint-disable-next-line react-hooks/exhaustive-deps
52+
}, []);
5253

5354
const renderDefaultIcon = () => {
5455
if (placement === 'bottom') {

0 commit comments

Comments
 (0)