diff --git a/examples/custom-collapse-header.tsx b/examples/custom-collapse-header.tsx new file mode 100644 index 0000000..af12edd --- /dev/null +++ b/examples/custom-collapse-header.tsx @@ -0,0 +1,158 @@ +import * as React from 'react'; +import Collapse, { Panel } from '../src'; +import motion from './_util/motionUtil'; +import '../assets/index.less'; + +const text = ` + A dog is a type of domesticated animal. + Known for its loyalty and faithfulness, + it can be found as a welcome guest in many households across the world. +`; + +function random() { + return parseInt((Math.random() * 10).toString(), 10) + 1; +} + +function customHeaderRender({ header, isActive, extra }) { + return ( +
+
+ {header} + {isActive ? '收起' : '展开'} +
+
{extra}
+
+ ); +} + +class Test extends React.Component { + state = { + time: random(), + accordion: false, + activeKey: ['4'], + collapsible: undefined, + }; + + onChange = (activeKey: string) => { + this.setState({ + activeKey, + }); + }; + + getItems() { + const items = []; + // eslint-disable-next-line no-plusplus + for (let i = 0, len = 3; i < len; i++) { + const key = i + 1; + items.push( + +

{text.repeat(this.state.time)}

+
, + ); + } + items.push( + + + +

{text}

+
+
+
, + ); + + items.push( + + + +
+ + +
+
+
+
, + ); + + items.push( + Extra Node}> +

Panel with extra

+
, + ); + + return items; + } + + setActivityKey = () => { + this.setState({ + activeKey: ['2'], + }); + }; + + reRender = () => { + this.setState({ + time: random(), + }); + }; + + toggle = () => { + const { accordion } = this.state; + this.setState({ + accordion: !accordion, + }); + }; + + handleCollapsibleChange = (e: any) => { + const values = [undefined, 'header', 'disabled']; + this.setState({ + collapsible: values[e.target.value], + }); + }; + + render() { + const { accordion, activeKey, collapsible } = this.state; + const btn = accordion ? 'Mode: accordion' : 'Mode: collapse'; + return ( +
+ + +

+ collapsible: + +

+
+
+ +
+
+ + {this.getItems()} + +
+ ); + } +} + +export default Test; diff --git a/src/Collapse.tsx b/src/Collapse.tsx index 81d6615..fee65a5 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -84,6 +84,7 @@ class Collapse extends React.Component { accordion, destroyInactivePanel: rootDestroyInactivePanel, expandIcon, + headerRender, collapsible, } = this.props; // If there is no key provide, use the panel order as default key @@ -116,6 +117,7 @@ class Collapse extends React.Component { children: child.props.children, onItemClick: mergeCollapsible === 'disabled' ? null : this.onClickItem, expandIcon, + headerRender, collapsible: mergeCollapsible, }; diff --git a/src/Panel.tsx b/src/Panel.tsx index 11cae85..2fdf689 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -80,6 +80,7 @@ class CollapsePanel extends React.Component { accordion, forceRender, openMotion, + headerRender, extra, collapsible, ...rest @@ -121,9 +122,15 @@ class CollapsePanel extends React.Component { return (
- {this.renderIcon()} - {this.renderTitle()} - {ifExtraExist &&
{extra}
} + {headerRender && typeof headerRender === 'function' ? ( + headerRender(this.props) + ) : ( + <> + {this.renderIcon()} + {this.renderTitle()} + {ifExtraExist &&
{extra}
} + + )}
React.ReactNode; collapsible?: CollapsibleType; children?: React.ReactNode; + headerRender?: (props: object) => React.ReactNode; } export interface CollapsePanelProps extends React.DOMAttributes { @@ -34,6 +35,7 @@ export interface CollapsePanelProps extends React.DOMAttributes extra?: string | React.ReactNode; onItemClick?: (panelKey: string | number) => void; expandIcon?: (props: object) => React.ReactNode; + headerRender?: (props: object) => React.ReactNode; panelKey?: string | number; role?: string; collapsible?: CollapsibleType; diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index 255b6de..66481a9 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -612,4 +612,49 @@ describe('collapse', () => { wrapper.find('.target').simulate('click'); expect(clickHandler).toHaveBeenCalled(); }); + + describe('customHeader', () => { + const customHeaderRender = ({ header, isActive, extra }) => { + return ( +
+
+ {header} + {isActive ? '收起' : '展开'} +
+
{extra}
+
+ ); + }; + + let collapse: ReactWrapper; + beforeEach(() => { + collapse = mount( + + + first + + ExtraSpan}> + second + + + third + + , + ); + }); + + it('should toggle show on panel', () => { + let header = collapse.find('.rc-collapse-header').at(1); + header.simulate('click'); + jest.runAllTimers(); + collapse.update(); + expect(collapse.find('.rc-collapse-content-active').length).toBe(1); + expect(collapse.find('.rc-collapse-item-active').length).toBe(1); + header = collapse.find('.rc-collapse-header').at(1); + header.simulate('click'); + jest.runAllTimers(); + collapse.update(); + expect(collapse.find('.rc-collapse-content-active').exists()).toBeFalsy(); + expect(collapse.find('.rc-collapse-item-active').exists()).toBeFalsy(); + }); });