Skip to content

Commit

Permalink
feat: support classNames and styles (#350)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
wanpan11 authored Aug 23, 2024
1 parent d753928 commit edb7a22
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 14 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ If `accordion` is true, only one panel can be open. Opening another panel will c
<thead>
<tr>
<th style="width: 100px;">name</th>
<th style="width: 50px;">type</th>
<th style="width: 200px;">type</th>
<th>default</th>
<th>description</th>
</tr>
Expand Down Expand Up @@ -160,12 +160,24 @@ If `accordion` is true, only one panel can be open. Opening another panel will c
<th></th>
<td>custom className to apply</td>
</tr>
<tr>
<td>classNames</td>
<td>{ header?: string, body?: string }</td>
<th></th>
<td>Semantic structure className</td>
</tr>
<tr>
<td>style</td>
<td>object</td>
<th></th>
<td>custom style</td>
</tr>
<tr>
<td>styles</td>
<td>{ header?: React.CSSProperties, body?: React.CSSProperties }</td>
<th></th>
<td>Semantic structure styles</td>
</tr>
<tr>
<td>openMotion</td>
<td>object</td>
Expand Down
19 changes: 14 additions & 5 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
onItemClick,
forceRender,
className,
classNames: customizeClassNames = {},
styles = {},
prefixCls,
collapsible,
accordion,
Expand Down Expand Up @@ -64,18 +66,23 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
className,
);

const headerClassName = classNames(headerClass, {
[`${prefixCls}-header`]: true,
[`${prefixCls}-header-collapsible-only`]: collapsibleHeader,
[`${prefixCls}-icon-collapsible-only`]: collapsibleIcon,
});
const headerClassName = classNames(
headerClass,
{
[`${prefixCls}-header`]: true,
[`${prefixCls}-header-collapsible-only`]: collapsibleHeader,
[`${prefixCls}-icon-collapsible-only`]: collapsibleIcon,
},
customizeClassNames.header,
);

// ======================== HeaderProps ========================
const headerProps: React.HTMLAttributes<HTMLDivElement> = {
className: headerClassName,
'aria-expanded': isActive,
'aria-disabled': disabled,
onKeyDown: handleKeyDown,
style: styles.header,
};

if (!collapsibleHeader && !collapsibleIcon) {
Expand Down Expand Up @@ -110,7 +117,9 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
ref={motionRef}
prefixCls={prefixCls}
className={motionClassName}
classNames={customizeClassNames}
style={motionStyle}
styles={styles}
isActive={isActive}
forceRender={forceRender}
role={accordion ? 'tabpanel' : void 0}
Expand Down
19 changes: 17 additions & 2 deletions src/PanelContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ const PanelContent = React.forwardRef<
HTMLDivElement,
CollapsePanelProps & { children: React.ReactNode }
>((props, ref) => {
const { prefixCls, forceRender, className, style, children, isActive, role } = props;
const {
prefixCls,
forceRender,
className,
style,
children,
isActive,
role,
classNames: customizeClassNames,
styles,
} = props;

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

Expand Down Expand Up @@ -34,7 +44,12 @@ const PanelContent = React.forwardRef<
style={style}
role={role}
>
<div className={`${prefixCls}-content-box`}>{children}</div>
<div
className={classnames(`${prefixCls}-content-box`, customizeClassNames?.body)}
style={styles?.body}
>
{children}
</div>
</div>
);
});
Expand Down
2 changes: 2 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export interface CollapsePanelProps extends React.DOMAttributes<HTMLDivElement>
headerClass?: string;
showArrow?: boolean;
className?: string;
classNames?: { header?: string; body?: string };
style?: object;
styles?: { header?: React.CSSProperties; body?: React.CSSProperties };
isActive?: boolean;
openMotion?: CSSMotionProps;
destroyInactivePanel?: boolean;
Expand Down
32 changes: 27 additions & 5 deletions tests/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('collapse', () => {
const { container } = render(element);
const header = container.querySelector('.rc-collapse-header');

expect(header.classList.contains('custom-class')).toBeTruthy();
expect(header?.classList.contains('custom-class')).toBeTruthy();
});
});

Expand Down Expand Up @@ -713,7 +713,7 @@ describe('collapse', () => {
</Panel>
</Collapse>,
);
expect(container.querySelector('.rc-collapse-item').style.color).toBe('red');
expect(container.querySelector('.rc-collapse-item')).toHaveStyle({ color: 'red' });
});

describe('props items', () => {
Expand Down Expand Up @@ -778,7 +778,7 @@ describe('collapse', () => {
]}
/>,
);
fireEvent.click(container.querySelector('.rc-collapse-header'));
fireEvent.click(container.querySelector('.rc-collapse-header')!);
expect(onItemClick).toHaveBeenCalled();
expect(onItemClick).lastCalledWith('0');
});
Expand All @@ -800,11 +800,11 @@ describe('collapse', () => {
/>,
);

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

fireEvent.click(
container.querySelector('.rc-collapse-item:nth-child(2) .rc-collapse-expand-icon'),
container.querySelector('.rc-collapse-item:nth-child(2) .rc-collapse-expand-icon')!,
);
expect(onItemClick).toHaveBeenCalled();
expect(onChangeFn).toBeCalledTimes(1);
Expand Down Expand Up @@ -859,5 +859,27 @@ describe('collapse', () => {
expect(container.querySelector('.rc-collapse')?.getAttribute('data-testid')).toBe('1234');
expect(container.querySelector('.rc-collapse')?.getAttribute('aria-label')).toBe('test');
});

it('should support styles and classNames', () => {
const { container } = render(
<Collapse
activeKey={['1']}
items={[
{
key: '1',
label: 'title',
styles: { header: { color: 'red' }, body: { color: 'blue' } },
classNames: { header: 'header-class', body: 'body-class' },
},
]}
/>,
);

expect(container.querySelector('.rc-collapse-header')).toHaveClass('header-class');
expect(container.querySelector('.rc-collapse-content-box')).toHaveClass('body-class');

expect(container.querySelector('.rc-collapse-header')).toHaveStyle({ color: 'red' });
expect(container.querySelector('.rc-collapse-content-box')).toHaveStyle({ color: 'blue' });
});
});
});
9 changes: 8 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,12 @@
"rc-collapse": ["src/index.tsx"]
}
},
"include": [".dumirc.ts", "./src/**/*.ts", "./src/**/*.tsx", "./docs/**/*.tsx"]
"include": [
".dumirc.ts",
"./src/**/*.ts",
"./src/**/*.tsx",
"./tests/**/*.ts",
"./tests/**/*.tsx",
"./docs/**/*.tsx"
]
}

0 comments on commit edb7a22

Please sign in to comment.