# Collapse 折叠

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/collapse/freepass)
- 平台：PC
- 维护者：王斌
- 设计稿：http://pd.e-cology.com.cn/pd/E10/interface/e10xiaoguotu/PC/E10zjys/#s53
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Collapse]

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import React from 'react';
import { Collapse, Switch } from '@weapp/ui';

export default class BasicDemo extends React.Component<{}> {
  state = {
    activeKey: '1',
    bg: true,
    accordion: false,
    iconPosition: 'right'
  };

  handleChange = (activeKey: any) => {
    this.setState({
      activeKey,
    });
  };

  handleBgChange = (bg: boolean) => {
    this.setState({ bg });
  };

  handleAccordionChange = (accordion: boolean) => {
    this.setState({ accordion, activeKey: '1' });
  };

  handlePositionChange = (v: boolean) => {
    this.setState({ iconPosition: v ? 'right' : 'left' });
  };

  render() {
    const { activeKey, bg, accordion } = this.state;
    const titleBg = bg ? 'default' : 'none';

    return (
      <div>
        <div style={{ margin: '20px 0' }}>
          <span>
            <Switch
              value={this.state.bg}
              onChange={this.handleBgChange}
            />
            <span>&nbsp;&nbsp;底色</span>
          </span>
          <span style={{ marginLeft: 20 }}>
            <Switch
              value={this.state.accordion}
              onChange={this.handleAccordionChange}
            />
            <span>&nbsp;&nbsp;手风琴</span>
          </span>
          <span style={{ marginLeft: 20 }}>
            <Switch
                    value={this.state.iconPosition === 'right'}
                    onChange={this.handlePositionChange}
            />
            <span>&nbsp;&nbsp;图标位置</span>
          </span>
        </div>
        <Collapse
          accordion={accordion}
          panelTitleBackground={titleBg}
          activeKey={activeKey}
          onChange={this.handleChange}
          bordered={false}
        >
          <Collapse.Panel title="标题一" key="1" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题一内容标题一内容标题一内容标题一内容标题一内容
          </Collapse.Panel>
          <Collapse.Panel title="标题二" key="2" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容
          </Collapse.Panel>
          <Collapse.Panel title="标题三" key="3" disabled  iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题三内容标题三内容标题三内容标题三内容标题三内容标题三内容
          </Collapse.Panel>
        </Collapse>
      </div>
    );
  }
}
```

### 分组模式

type = 'group'

```jsx
import React from 'react';
import { Collapse, Table, constants } from '@weapp/ui';

const { uiPcClsPrefix } = constants;

const prefixCls = `${uiPcClsPrefix}-demo-collapse`;

const columns = [
  {
    title: '签批文件内容',
    dataIndex: 'name',
  }, {
    title: '签批文件标题',
    dataIndex: 'title'
  }, {
    title: '签批文件标题',
    dataIndex: 'title_2'
  }, {
    title: '签批文件标题',
    dataIndex: 'title_3'
  }
];

const data = [{
  id: '1',
  name: '相关文档1',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}, {
  id: '2',
  name: '相关文档2',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}, {
  id: '3',
  name: '相关文档3',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}]

const itemStyle = {
  lineHeight: '46px',
  padding: '0 16px',
  color: '#333333',
  fontSize: '12px'
}
const itemSpanStyle = {
  width: '130px',
  display: 'inline-block',
  color: '#666666'
}

export default class GroupDemo extends React.Component<{}> {
  state = {
    activeKey: ['1', '3'],
    selectedRowKeys: [],
    data
  };

  handleChange = (activeKey: any) => {
    this.setState({ activeKey });
  };

  onSelect = (selectedRowKeys: string[], selectedRows: any, currentRow: any) => {
    console.log('onSelect', selectedRowKeys, selectedRows, currentRow)
    this.setState({
      selectedRowKeys,
    });
  }

  onDrag = (data: any) => {
    this.setState({ data })
  }

  render() {
    const { activeKey, data } = this.state;

    return (
      <div>
        <div style={{ margin: '20px 0', padding: '20px' }}>
          <Collapse
                    activeKey={activeKey}
                    onChange={this.handleChange}
                    type={'group'}
          >
            <Collapse.Panel title='分组名称1' key="1">
              <div style={{ background: '#FFFFFF', border: '1px solid #E5E5E5' }}>
                <div className={`${prefixCls}-single ${prefixCls}-single-demo3`} >
                  <span style={{ ...itemSpanStyle }}>PC端显示模板</span>
                  <span>发起节点显示模板</span>
                </div>
                <div className={`${prefixCls}-single-demo3`}>
                  <span style={{ ...itemSpanStyle }}>同步节点</span>
                  <span>需求提交</span>
                </div>
              </div>
            </Collapse.Panel>
            <Collapse.Panel title="分组名称2" key="2">
              <div style={{  lineHeight: '46px', background: '#FFFFFF', paddingLeft: '16px' }}>标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容</div>
            </Collapse.Panel>
            <Collapse.Panel title="分组名称3" key="3">
              <Table
                     columns={columns}
                     data={data}
                     sortable
                     sortableType='icon'
                     onDrag={this.onDrag}
                     selection={{
                       selectedRowKeys: this.state.selectedRowKeys,
                       getSelectionProps: (data: object, rowIndex: number | string) => {
                         return {
                           visible: true,
                           disabled: false,
                         }
                       },
                       onSelect: this.onSelect
                     }}
              />
            </Collapse.Panel>
          </Collapse>
        </div>
      </div>
    );
  }
}
```

### 自定义渲染图标

customIconRender

```jsx
import React from 'react';
import { Collapse, ICollapsePanelProps, Icon } from '@weapp/ui';

export default class CustomDemo extends React.Component<{}> {
  state = {
    activeKey: '1',
    bg: true,
    accordion: false,
    iconPosition: 'right'
  };

  handleChange = (activeKey: any) => {
    this.setState({
      activeKey,
    });
  };

  customIconRender = (props: ICollapsePanelProps) => {
    console.log('props', props)
    return (
      <Icon
       
        name={props.active? 'Icon-reduce03' : 'Icon-add-to03'}
        style={{ marginRight: '15px' }}
      />
    )
  }

  render() {
    const { activeKey, bg, accordion } = this.state;
    const titleBg = bg ? 'default' : 'none';

    return (
      <div>
        <div style={{ margin: '20px 0' }}>
          <Collapse
                    accordion={accordion}
                    panelTitleBackground={titleBg}
                    activeKey={activeKey}
                    onChange={this.handleChange}
                    customIconRender={this.customIconRender}
          >
            <Collapse.Panel title="标题一" key="1" iconPosition={this.state.iconPosition as 'left' | 'right'}>
              标题一内容标题一内容标题一内容标题一内容标题一内容
            </Collapse.Panel>
            <Collapse.Panel title="标题二" key="2" iconPosition={this.state.iconPosition as 'left' | 'right'}>
              标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容
            </Collapse.Panel>
            <Collapse.Panel title="标题三" key="3" disabled  iconPosition={this.state.iconPosition as 'left' | 'right'}>
              标题三内容标题三内容标题三内容标题三内容标题三内容标题三内容
            </Collapse.Panel>
          </Collapse>
        </div>
      </div>
    );
  }
}
```

### 展开禁用

Panel设置disabled

```jsx
import React from 'react';
import { Collapse, Switch } from '@weapp/ui';

export default class BasicDemo extends React.Component<{}> {
  state = {
    activeKey: '1',
    bg: true,
    accordion: false,
    iconPosition: 'right'
  };

  handleChange = (activeKey: any) => {
    this.setState({
      activeKey,
    });
  };

  handleBgChange = (bg: boolean) => {
    this.setState({ bg });
  };

  handleAccordionChange = (accordion: boolean) => {
    this.setState({ accordion, activeKey: '1' });
  };

  handlePositionChange = (v: boolean) => {
    this.setState({ iconPosition: v ? 'right' : 'left' });
  };

  render() {
    const { activeKey, bg, accordion } = this.state;
    const titleBg = bg ? 'default' : 'none';

    return (
      <div>
        <Collapse
          accordion={accordion}
          panelTitleBackground={titleBg}
          activeKey={activeKey}
          onChange={this.handleChange}
          bordered={false}
        >
          <Collapse.Panel title="标题一" key="1" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题一内容标题一内容标题一内容标题一内容标题一内容
          </Collapse.Panel>
          <Collapse.Panel title="标题二" key="2" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容
          </Collapse.Panel>
          <Collapse.Panel title="标题三" key="3" disabled iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题三内容标题三内容标题三内容标题三内容标题三内容标题三内容
          </Collapse.Panel>
        </Collapse>
      </div>
    );
  }
}
```

### 向下折叠

```jsx
import React from 'react';
import { Collapse,  constants , Switch, Table } from '@weapp/ui';
const { uiPcClsPrefix } = constants;

const prefixCls = `${uiPcClsPrefix}-demo-collapse`;

const columns = [
  {
    title: '签批文件内容',
    dataIndex: 'name',
  }, {
    title: '签批文件标题',
    dataIndex: 'title'
  }, {
    title: '签批文件标题',
    dataIndex: 'title_2'
  }, {
    title: '签批文件标题',
    dataIndex: 'title_3'
  }
];

const data = [{
  id: '1',
  name: '相关文档1',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}, {
  id: '2',
  name: '相关文档2',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}, {
  id: '3',
  name: '相关文档3',
  title: '相关标题',
  title_2: '相关标题',
  title_3: '相关标题',
}]

const itemSpanStyle = {
  width: '130px',
  display: 'inline-block',
  color
  : '#666666'
}
const itemStyle = {
  lineHeight: '46px',
  padding: '0 16px',
  color: '#333333',
  fontSize: '12px'
}

export default class BasicDemo extends React.Component<{}> {
  state = {
    activeKey: '1',
    bg: true,
    accordion: false,
    iconPosition: 'right',
    _activeKey: ['1', '3'],
    selectedRowKeys: [],
    data
  };

  handleChange = (activeKey: any) => {
    this.setState({
      activeKey,
    });
  };

  handleBgChange = (bg: boolean) => {
    this.setState({ bg });
  };

  handleAccordionChange = (accordion: boolean) => {
    this.setState({ accordion, activeKey: '1' });
  };

  handlePositionChange = (v: boolean) => {
    this.setState({ iconPosition: v ? 'right' : 'left' });
  };
  _handleChange = (activeKey: any) => {
    this.setState({ _activeKey:activeKey });
  };

  onSelect = (selectedRowKeys: string[], selectedRows: any, currentRow: any) => {
    console.log('onSelect', selectedRowKeys, selectedRows, currentRow)
    this.setState({
      selectedRowKeys,
    });
  }

  onDrag = (data: any) => {
    this.setState({ data })
  }

  render() {
    const { activeKey, bg, accordion,_activeKey, data } = this.state;
    const titleBg = bg ? 'default' : 'none';

    return (
      <div>
        <div style={{ margin: '20px 0' }}>
          <span>
            <Switch
              value={this.state.bg}
              onChange={this.handleBgChange}
            />
            <span>&nbsp;&nbsp;底色</span>
          </span>
          <span style={{ marginLeft: 20 }}>
            <Switch
              value={this.state.accordion}
              onChange={this.handleAccordionChange}
            />
            <span>&nbsp;&nbsp;手风琴</span>
          </span>
          <span style={{ marginLeft: 20 }}>
            <Switch
              value={this.state.iconPosition === 'right'}
              onChange={this.handlePositionChange}
            />
            <span>&nbsp;&nbsp;图标位置</span>
          </span>
        </div>
        <Collapse
          accordion={accordion}
          panelTitleBackground={titleBg}
          activeKey={activeKey}
          onChange={this.handleChange}
          bordered={false}
          direction='down'
        >
          <Collapse.Panel title="标题一" key="1" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题一内容标题一内容标题一内容标题一内容标题一内容
          </Collapse.Panel>
          <Collapse.Panel title="标题二" key="2" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容
          </Collapse.Panel>
          <Collapse.Panel title="标题三" key="3"  iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题三内容标题三内容标题三内容标题三内容标题三内容标题三内容
          </Collapse.Panel>
        </Collapse>
        

        <h3>单独使用</h3>
        <Collapse
          accordion={accordion}
          panelTitleBackground={titleBg}
          activeKey={activeKey}
          onChange={this.handleChange}
          bordered={false}
        >
          <Collapse.Panel direction='down' title="标题一" key="1" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题一内容标题一内容标题一内容标题一内容标题一内容
          </Collapse.Panel>
          <Collapse.Panel direction='up' title="标题二" key="2" iconPosition={this.state.iconPosition as 'left' | 'right'}>
            标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容
          </Collapse.Panel>
        </Collapse>

        <h3>分组模式</h3>
        <div>
        <div style={{ margin: '20px 0', padding: '20px' }}>
          <Collapse
                    activeKey={_activeKey}
                    onChange={this._handleChange}
                    type={'group'}
                    direction='down'
          >
            <Collapse.Panel title='分组名称1' key="1">
            <div style={{ background: '#FFFFFF', border: '1px solid #E5E5E5' }}>
                <div className={`${prefixCls}-single`} style={{ ...itemStyle }} >
                  <span style={{ ...itemSpanStyle }}>PC端显示模板</span>
                  <span>发起节点显示模板</span>
                </div>
                <div style={{ ...itemStyle }}>
                  <span style={{ ...itemSpanStyle }}>同步节点</span>
                  <span>需求提交</span>
                </div>
              </div>
            </Collapse.Panel>
            <Collapse.Panel title="分组名称2" key="2">
              <div style={{  lineHeight: '46px', background: '#FFFFFF', paddingLeft: '16px' }}>标题二内容标题二内容标题二内容标题二内容标题二内容标题二内容</div>
            </Collapse.Panel>
            <Collapse.Panel title="分组名称3" key="3">
              <Table
                     columns={columns}
                     data={data}
                     sortable
                     sortableType='icon'
                     onDrag={this.onDrag}
                     selection={{
                       selectedRowKeys: this.state.selectedRowKeys,
                       getSelectionProps: (data: object, rowIndex: number | string) => {
                         return {
                           visible: true,
                           disabled: false,
                         }
                       },
                       onSelect: this.onSelect
                     }}
              />
            </Collapse.Panel>
          </Collapse>
        </div>
      </div>
      </div>
    );
  }
}
```

## API

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| accordion | 手风琴模式，一次只能有一个 active 的面板 | boolean | 否 | - |
| activeKey | 当前打开的面板 id | string \| string[] | 否 | - |
| bordered | 是否有外边框 | boolean | 否 | - |
| className | 复写类名 | string | 否 | - |
| isClickOnRow | 是否点击整行折叠收缩 | boolean | 否 | true |
| panelTitleBackground | Panel 标题底色 | string | 否 | - |
| type | 展示模式 | 'normal' \| 'group' | 否 | 'normal' |
| customIconRender | 自定义渲染箭头图标 | props: ICollapsePanelProps => React.ReactNode | 否 | - |
| onChange | 切换面板的回调函数 | (value: string \| string[]) => any; | 否 | - |
| direction | 折叠方向 | 'up'\|'down' | 否 | 'up' |
## 子组件

### Collapse.Pannel

#### 参数如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| bordered | 是否有边框 | boolean | 否 | - |
| className | 复写类名 | string | 否 | - |
| disabled | 禁用 | boolean | 否 | - |
| iconPosition | 图标位置 | 'right' \| 'left' | 否 | 'right' |
| id | 面板 id | string | 否 | - |
| isMobile | 是否移动端 | boolean | 否 | - |
| showArrow | 是否显示箭头图标 | boolean | 否 | true |
| style | 复写样式 | React.CSSProperties | 否 | - |
| title | 面板标题 | React.ReactNode | 是 | - |
| customIconRender | 自定义渲染箭头图标 | props: ICollapsePanelProps => React.ReactNode | 否 | - |
| direction | 折叠方向 | 'up'\|'down' | 否 | 'up' |
#### IAnimateHeightBaseProps类型如下

```typescript
export type IAnimateHeightOverflow = 'hidden' | 'scroll' | 'auto' | 'unset';
export interface IAnimateHeightBaseProps {
  appear?: boolean;
  duration?: number;
  easing?: string;
  className?: string;
  style?: CSSProperties;
  overflow?: IAnimateHeightOverflow;
}
```
