Skip to content

Commit edb7a22

Browse files
authored
feat: support classNames and styles (#350)
* feat: support classNames and styles * feat: content to body * feat: Modifying the DOM structure * feat: add default value * fix: Animation does not meet expectations * fix: update
1 parent d753928 commit edb7a22

File tree

6 files changed

+81
-14
lines changed

6 files changed

+81
-14
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ If `accordion` is true, only one panel can be open. Opening another panel will c
130130
<thead>
131131
<tr>
132132
<th style="width: 100px;">name</th>
133-
<th style="width: 50px;">type</th>
133+
<th style="width: 200px;">type</th>
134134
<th>default</th>
135135
<th>description</th>
136136
</tr>
@@ -160,12 +160,24 @@ If `accordion` is true, only one panel can be open. Opening another panel will c
160160
<th></th>
161161
<td>custom className to apply</td>
162162
</tr>
163+
<tr>
164+
<td>classNames</td>
165+
<td>{ header?: string, body?: string }</td>
166+
<th></th>
167+
<td>Semantic structure className</td>
168+
</tr>
163169
<tr>
164170
<td>style</td>
165171
<td>object</td>
166172
<th></th>
167173
<td>custom style</td>
168174
</tr>
175+
<tr>
176+
<td>styles</td>
177+
<td>{ header?: React.CSSProperties, body?: React.CSSProperties }</td>
178+
<th></th>
179+
<td>Semantic structure styles</td>
180+
</tr>
169181
<tr>
170182
<td>openMotion</td>
171183
<td>object</td>

src/Panel.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
1313
onItemClick,
1414
forceRender,
1515
className,
16+
classNames: customizeClassNames = {},
17+
styles = {},
1618
prefixCls,
1719
collapsible,
1820
accordion,
@@ -64,18 +66,23 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
6466
className,
6567
);
6668

67-
const headerClassName = classNames(headerClass, {
68-
[`${prefixCls}-header`]: true,
69-
[`${prefixCls}-header-collapsible-only`]: collapsibleHeader,
70-
[`${prefixCls}-icon-collapsible-only`]: collapsibleIcon,
71-
});
69+
const headerClassName = classNames(
70+
headerClass,
71+
{
72+
[`${prefixCls}-header`]: true,
73+
[`${prefixCls}-header-collapsible-only`]: collapsibleHeader,
74+
[`${prefixCls}-icon-collapsible-only`]: collapsibleIcon,
75+
},
76+
customizeClassNames.header,
77+
);
7278

7379
// ======================== HeaderProps ========================
7480
const headerProps: React.HTMLAttributes<HTMLDivElement> = {
7581
className: headerClassName,
7682
'aria-expanded': isActive,
7783
'aria-disabled': disabled,
7884
onKeyDown: handleKeyDown,
85+
style: styles.header,
7986
};
8087

8188
if (!collapsibleHeader && !collapsibleIcon) {
@@ -110,7 +117,9 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
110117
ref={motionRef}
111118
prefixCls={prefixCls}
112119
className={motionClassName}
120+
classNames={customizeClassNames}
113121
style={motionStyle}
122+
styles={styles}
114123
isActive={isActive}
115124
forceRender={forceRender}
116125
role={accordion ? 'tabpanel' : void 0}

src/PanelContent.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,17 @@ const PanelContent = React.forwardRef<
66
HTMLDivElement,
77
CollapsePanelProps & { children: React.ReactNode }
88
>((props, ref) => {
9-
const { prefixCls, forceRender, className, style, children, isActive, role } = props;
9+
const {
10+
prefixCls,
11+
forceRender,
12+
className,
13+
style,
14+
children,
15+
isActive,
16+
role,
17+
classNames: customizeClassNames,
18+
styles,
19+
} = props;
1020

1121
const [rendered, setRendered] = React.useState(isActive || forceRender);
1222

@@ -34,7 +44,12 @@ const PanelContent = React.forwardRef<
3444
style={style}
3545
role={role}
3646
>
37-
<div className={`${prefixCls}-content-box`}>{children}</div>
47+
<div
48+
className={classnames(`${prefixCls}-content-box`, customizeClassNames?.body)}
49+
style={styles?.body}
50+
>
51+
{children}
52+
</div>
3853
</div>
3954
);
4055
});

src/interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ export interface CollapsePanelProps extends React.DOMAttributes<HTMLDivElement>
4646
headerClass?: string;
4747
showArrow?: boolean;
4848
className?: string;
49+
classNames?: { header?: string; body?: string };
4950
style?: object;
51+
styles?: { header?: React.CSSProperties; body?: React.CSSProperties };
5052
isActive?: boolean;
5153
openMotion?: CSSMotionProps;
5254
destroyInactivePanel?: boolean;

tests/index.spec.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ describe('collapse', () => {
201201
const { container } = render(element);
202202
const header = container.querySelector('.rc-collapse-header');
203203

204-
expect(header.classList.contains('custom-class')).toBeTruthy();
204+
expect(header?.classList.contains('custom-class')).toBeTruthy();
205205
});
206206
});
207207

@@ -713,7 +713,7 @@ describe('collapse', () => {
713713
</Panel>
714714
</Collapse>,
715715
);
716-
expect(container.querySelector('.rc-collapse-item').style.color).toBe('red');
716+
expect(container.querySelector('.rc-collapse-item')).toHaveStyle({ color: 'red' });
717717
});
718718

719719
describe('props items', () => {
@@ -778,7 +778,7 @@ describe('collapse', () => {
778778
]}
779779
/>,
780780
);
781-
fireEvent.click(container.querySelector('.rc-collapse-header'));
781+
fireEvent.click(container.querySelector('.rc-collapse-header')!);
782782
expect(onItemClick).toHaveBeenCalled();
783783
expect(onItemClick).lastCalledWith('0');
784784
});
@@ -800,11 +800,11 @@ describe('collapse', () => {
800800
/>,
801801
);
802802

803-
fireEvent.click(container.querySelector('.rc-collapse-header'));
803+
fireEvent.click(container.querySelector('.rc-collapse-header')!);
804804
expect(onItemClick).not.toHaveBeenCalled();
805805

806806
fireEvent.click(
807-
container.querySelector('.rc-collapse-item:nth-child(2) .rc-collapse-expand-icon'),
807+
container.querySelector('.rc-collapse-item:nth-child(2) .rc-collapse-expand-icon')!,
808808
);
809809
expect(onItemClick).toHaveBeenCalled();
810810
expect(onChangeFn).toBeCalledTimes(1);
@@ -859,5 +859,27 @@ describe('collapse', () => {
859859
expect(container.querySelector('.rc-collapse')?.getAttribute('data-testid')).toBe('1234');
860860
expect(container.querySelector('.rc-collapse')?.getAttribute('aria-label')).toBe('test');
861861
});
862+
863+
it('should support styles and classNames', () => {
864+
const { container } = render(
865+
<Collapse
866+
activeKey={['1']}
867+
items={[
868+
{
869+
key: '1',
870+
label: 'title',
871+
styles: { header: { color: 'red' }, body: { color: 'blue' } },
872+
classNames: { header: 'header-class', body: 'body-class' },
873+
},
874+
]}
875+
/>,
876+
);
877+
878+
expect(container.querySelector('.rc-collapse-header')).toHaveClass('header-class');
879+
expect(container.querySelector('.rc-collapse-content-box')).toHaveClass('body-class');
880+
881+
expect(container.querySelector('.rc-collapse-header')).toHaveStyle({ color: 'red' });
882+
expect(container.querySelector('.rc-collapse-content-box')).toHaveStyle({ color: 'blue' });
883+
});
862884
});
863885
});

tsconfig.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,12 @@
1313
"rc-collapse": ["src/index.tsx"]
1414
}
1515
},
16-
"include": [".dumirc.ts", "./src/**/*.ts", "./src/**/*.tsx", "./docs/**/*.tsx"]
16+
"include": [
17+
".dumirc.ts",
18+
"./src/**/*.ts",
19+
"./src/**/*.tsx",
20+
"./tests/**/*.ts",
21+
"./tests/**/*.tsx",
22+
"./docs/**/*.tsx"
23+
]
1724
}

0 commit comments

Comments
 (0)