数政dialog

@aligov/components-dialog

数政dialog,基于 Fusion Dialog 做定制,主要是对弹层宽度做了几个尺寸的限制,默认是 medium

API

参数名 说明 必填 类型 默认值 备注
size 大小:'small' or 'medium' or 'large' string medium
hasFooterBorder 底部按钮上方是否有分隔线 boolean false
okClickableDelay 确定按钮可点击的延时,单位秒,整数 number
okRender 确定按钮的渲染函数,主要配合 okClickableDelay 使用 (remainSeconds: number) => ReactElement
className 自定义 class string
style 自定义样式 object

除了上面这些参数外,其他参数沿用 Fusion Dialog 的参数,用法也一致。

关于弹层标题以及底部按钮和主体内容之间的分隔线,组件内部不会主动添加,而是采用主题的设置。

hasFooterBorder 在主题的基础上,默认底部按钮上方分隔线会隐藏掉,只要在设为 true 后才会展示。用于主体内容有分页(如表格 + 分页)的场景。

okClickableDelayokRender 搭配用来实现确定按钮需要等待指定秒数后才能点击的效果。

开发

开发阶段,如果需要在特定主题下看,先安装依赖(不要保存到 package.json 中),然后 bash 下使用 theme=the-pkg npm start 来运行,如 theme=@alifd/theme-dev-test-only npm start

fish 下使用 env theme=the-pkg npm start

Todo

[ ] max height

DEMO 列表

普通使用

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import GovDialog from '@aligov/components-dialog';
import { Button } from '@alifd/next';

class App extends Component {
  state = {
    visible: false
  }

  show = () => {
    this.setState({
      visible: true
    });
  };

  close = () => {
    this.setState({
      visible: false
    });
  };

  render() {
    return (
      <div>
        <Button onClick={this.show}>展现弹窗</Button>
        <GovDialog
          visible={this.state.visible}
          title="南方强降雨"
          onOk={this.close}
          onClose={this.close}
          onCancel={this.close}
        >62日至7126时,中央气象台连续40天发布暴雨预警,成为2007年开展暴雨预警业务以来历时最长的一次。暴雨给长江流域防汛带来了压力,61日至79日,长江流域平均降水量达到369.9毫米,较1998年同期偏多54.8毫米,为1961年以来历史同期最多。
        </GovDialog>
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

尺寸

弹层的宽度可以通过 size 属性来改变,size 可以设置为 smallmediumlarge,默认值为 medium

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import GovDialog from '@aligov/components-dialog';
import { Button, Select } from '@alifd/next';

const sizes = [
    { label: 'small', value: 'small'},
    { label: 'medium (default)', value: 'medium'},
    { label: 'large', value: 'large'}
];

class App extends Component {
  state = {
    size: 'medium',
    visible: false
  }

  show = (size) => {
    this.setState({
      size,
      visible: true
    });
  };

  close = () => {
    this.setState({
      visible: false
    });
  };

  changeSize = (size) => {
    this.setState({
      size
    });
  }

  render() {
    const { size, visible } = this.state;

    return (
      <div>
        <Button.Group>
            {sizes.map(i => <Button key={i.value} onClick={() => this.show(i.value)}>{i.label}</Button>)}
        </Button.Group>
        <GovDialog
          visible={visible}
          title="南方强降雨"
          size={size}
          onOk={this.close}
          onClose={this.close}
          onCancel={this.close}
        >62日至7126时,中央气象台连续40天发布暴雨预警,成为2007年开展暴雨预警业务以来历时最长的一次。暴雨给长江流域防汛带来了压力,61日至79日,长江流域平均降水量达到369.9毫米,较1998年同期偏多54.8毫米,为1961年以来历史同期最多。
        </GovDialog>
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

底部分隔线

弹层默认底部没有分隔线,但如果内容是含分页的场景,如分页表格,那设置 hasFooterBordertrue 来添加分隔线。

这种场景,一般分页固定在底部位置来使用,所以需要搭配设置 table 支持内部滚动,如 fixedHeader 配合 maxBodyHeight = 400

默认情况下,弹层最大高度(640)- 标题高度(50)- 底部高度(53)- 内容上下 padding(20 * 2)- 分页高度(28)- 分页上外间距(20)- 表头高度(40)= 409。

需要主题设置了底部分隔线。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import GovDialog from '@aligov/components-dialog';
import { Button, Table, Pagination } from '@alifd/next';

class App extends Component {
  state = {
    loading: false,
    visible: false,
    dataSource: createDataSource(5)
  }

  show = () => {
    this.setState({
      visible: true
    });
  };

  close = () => {
    this.setState({
      visible: false
    });
  };

  onChange = (currentPage) => {
    this.setState({
      loading: true
    });
    setTimeout(() => {
      this.setState({
        dataSource: createDataSource(currentPage * 5),
        loading: false
      });
    }, 200);
  }

  render() {
    const {visible, dataSource, loading} = this.state;
    return (
      <div>
        <Button onClick={this.show}>展现弹窗</Button>
        <GovDialog
          visible={visible}
          title="南方强降雨"
          hasFooterBorder={true}
          onOk={this.close}
          onClose={this.close}
          onCancel={this.close}
        >
          <Table dataSource={dataSource} loading={loading} fixedHeader={true} maxBodyHeight={400}>
            <Table.Column title="Id1" dataIndex="id" width={140}/>
            <Table.Column title="Time" dataIndex="time"/>
            <Table.Column title="Action" width={200}/>
          </Table>
          <Pagination type="simple" onChange={this.onChange} totalRender={totalRender} style={{marginTop: 20}}/>
        </GovDialog>
      </div>
    );
  }
}

function totalRender(total) {
  return `总计 ${total}`;
}

function createDataSource(start) {
  const result = [];
  for (let i = 0; i < 15; i++) {
    result.push({
      title: {name: `Quotation for 1PCS Nano ${3 + i}.0 controller compatible`},
      id: 100306660940 + i + start,
      time: 2000 + start
    });
  }
  return result;
}


ReactDOM.render((
  <App/>
), mountNode);
.next-pagination .next-pagination-pages {
  float: right;
}

快捷调用

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Dialog from '@aligov/components-dialog';
import { Button } from '@alifd/next';

const popupAlert = () => {
  Dialog.alert({
    title: 'Alert',
    content: 'alert content alert content...',
    onOk: () => console.log('ok')
  });
};

const popupConfirm = () => {
  Dialog.confirm({
    title: 'Confirm',
    content: 'confirm content confirm content...',
    onOk: () => console.log('ok'),
    onCancel: () => console.log('cancel')
  });
};

const popupShow = () => {
  const dialog = Dialog.show({
    title: 'Custom',
    content: 'custom content custom content...',
    footer: (
      <Button warning type="primary" onClick={() => dialog.hide()}>
        Custom button
      </Button>
    )
  });
};


class App extends Component {

  render() {
    return (
      <div>
        <span>
          <Button onClick={popupAlert}>Alert</Button> &nbsp;
          <Button onClick={popupConfirm}>Confirm</Button> &nbsp;
          <Button onClick={popupShow}>Show</Button> &nbsp;
        </span>
      </div>
    );
  }
}

ReactDOM.render((
  <App/>
), mountNode);

内容较多的弹窗

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import GovDialog from '@aligov/components-dialog';
import { Button } from '@alifd/next';

const largeContent = new Array(30).fill(
    <p>Start your business here by searching a popular product</p>
);

class App extends Component {
  state = {
    visible: false
  }

  show = () => {
    this.setState({
      visible: true
    });
  };

  close = () => {
    this.setState({
      visible: false
    });
  };

  render() {
    return (
      <div>
        <Button onClick={this.show}>展现弹窗</Button>
        <GovDialog
          visible={this.state.visible}
          title="内容较多的弹窗"
          onOk={this.close}
          onClose={this.close}
          onCancel={this.close}
        >
          {largeContent}
        </GovDialog>
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);