4.22.3 • Published 5 months ago

@uiw/react-tree v4.22.3

Weekly downloads
235
License
MIT
Repository
github
Last release
5 months ago

Tree 树形控件

Buy me a coffee Open in unpkg NPM Downloads npm version

使用树控件可以完整展现其中的层级关系,并具有展开收起选择等交互功能。

import { Tree } from 'uiw';
// or
import Tree from '@uiw/react-tree';

基础用法

import React from 'react';
import { Tree, Card, Row, Col, } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
      {
        label: '崇文区',
        key: '2-3-0',
        children:[
          { label: '东花市街道', key: '2-3-1' },
          { label: '体育馆路街道', key: '2-3-2' },
          { label: '前门街道', key: '2-3-3' },
        ]
      },
    ]
  }
];

const Demo = () => (
  <div>
    <Row gutter={10}>
      <Col fixed>
        <Card title="单选">
          <Tree
            defaultExpandAll={true}
            data={data}
            onExpand={(key, expanded, data, node) => {
              console.log('onExpand',key, expanded, data, node);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log('onSelected',key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="多选,子节点不受控">
          <Tree
          autoExpandParent={true}
            data={data}
            multiple
            onExpand={(key, expanded, data, node) => {
              console.log(key, expanded, data, node);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="多选,子节点受控">
          <Tree
            data={data}
            multiple
            checkStrictly
            onExpand={(key, expanded, data, node) => {
              console.log(key, expanded, data, node);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
    </Row>
  </div>
)
export default Demo;

自定义图标

import React from 'react';
import { Tree, Card, Row, Col, Icon } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
      {
        label: '崇文区',
        key: '2-3-0',
        children:[
          { label: '东花市街道', key: '2-3-1' },
          { label: '体育馆路街道', key: '2-3-2' },
          { label: '前门街道', key: '2-3-3' },
        ]
      },
    ]
  }
];

const Demo = () => (
  <div>
    <Row gutter={10}>
      <Col fixed>
        <Card title="标题中添加图标">
          <Tree
            data={data}
            renderTitle={(item, { selected, noChild }) => (
              <>
                <Icon style={{ display: '-webkit-inline-box' }} type={noChild ? 'smile-o' : 'apple'} />
                <span>{item.label}</span>
              </>
            )}
            onExpand={(key, expanded, data, node) => {
              console.log(key, expanded, data, node);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="替换默认折叠图标">
          <Tree
            data={data}
            icon="right-circle-o"
            onExpand={(key, expanded, data, node) => {
              console.log(key, expanded, data, node);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="自定义展开图标">
          <Tree
            data={data}
            iconAnimation={false}
            icon={(data, { isOpen, noChild }) => {
              if(isOpen && !noChild) {
                return 'folder-open';
              } else if (!noChild) {
                return 'folder';
              }
              return 'file-text';
            }}
            onExpand={(key, expanded, data) => {
              console.log(key, expanded, data);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
    </Row>
  </div>
)
export default Demo;

自定义选中效果

通过设置 checkStrictly 父节点受子节点控制,设置 multiple 为多选,设置 isSelected 取消选中效果,也可以使用 TreeChecked 组件。

import React from 'react';
import { Tree, Card, Row, Col, Icon } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1', disabled: true },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
      {
        label: '崇文区',
        key: '2-3-0',
        children:[
          { label: '东花市街道', key: '2-3-1' },
          { label: '体育馆路街道', key: '2-3-2' },
          { label: '前门街道', key: '2-3-3' },
        ]
      },
    ]
  },
  { label: '澳门', key: '3' },
];

const Demo = () => (
  <div>
    <Tree
      data={data}
      selectedKeys={['0-1-1']}
      multiple
      isSelected={false}
      checkStrictly
      renderTitle={(item, { selected, isHalfChecked }) => {
        if(isHalfChecked) {
          return (
            <><Icon type="minus-square-o" style={{ color: 'green' }} /> <span>{item.label}</span></>
          );
        }
        if (selected) {
          return (
            <><Icon type="check-square-o" style={{ color: 'green' }} /> <span>{item.label}</span></>
          );
        }
        return (
          <><Icon type="square-o" style={{ color: '#b6b6b6' }} /> <span>{item.label}</span></>
        );
      }}
      onExpand={(key, expanded, data, node) => {
        console.log(key, expanded, data, node);
      }}
      onSelected={(key, selected, item, evn) => {
        console.log(key, selected, item, evn);
      }}
    />
  </div>
)
export default Demo;

禁用选项

import React from 'react';
import { Tree, Card, Row, Col, Icon } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        disabled: true,
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
      {
        label: '崇文区',
        key: '2-3-0',
        children:[
          { label: '东花市街道', key: '2-3-1' },
          { label: '体育馆路街道', key: '2-3-2' },
          { label: '前门街道', key: '2-3-3' },
        ]
      },
    ]
  }
];

const Demo = () => (
  <div>
    <Row gutter={10}>
      <Col fixed>
        <Card title="基础使用">
          <Tree data={data} />
        </Card>
      </Col>
      <Col fixed>
        <Card title="自定义图标">
          <Tree
            data={data}
            renderTitle={(item, { selected, noChild, disabledStyle }) => (
              <>
                <Icon style={{ display: '-webkit-inline-box', ...disabledStyle }} type={noChild ? 'smile-o' : 'apple'} />
                <span style={disabledStyle}>{item.label}</span>
              </>
            )}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="自定义选中效果">
          <Tree
            data={data}
            renderTitle={(item, { selected, isHalfChecked, disabledStyle, disabledClass }) => {
              if(isHalfChecked) {
                return (
                  <><Icon type="minus-square-o" style={{ color: 'green', ...disabledStyle }} /> <span className={disabledClass} >{item.label}</span></>
                );
              }
              if (selected) {
                return (
                  <><Icon type="check-square-o" style={{ color: 'green', ...disabledStyle }} /> <span className={disabledClass} >{item.label}</span></>
                );
              }
              return (
                <><Icon type="square-o" style={{ color: '#b6b6b6',...disabledStyle }} /> <span className={disabledClass} >{item.label}</span></>
              );
            }}
          />
        </Card>
      </Col>
    </Row>
  </div>
)
export default Demo;

连接线

带连接线的树,通过设置 showLine

import React from 'react';
import { Tree, Card, Row, Col } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
      {
        label: '崇文区',
        key: '2-3-0',
        children:[
          { label: '东花市街道', key: '2-3-1' },
          { label: '体育馆路街道', key: '2-3-2' },
          { label: '前门街道', key: '2-3-3' },
        ]
      },
    ]
  }
];

const Demo = () => (
  <div>
    <Row gutter={10}>
      <Col fixed>
        <Card title="自定义展开图标">
          <Tree
            data={data}
            showLine
            iconAnimation={false}
            icon={(data, {isOpen, noChild}) => {
              if(isOpen && !noChild) {
                return 'folder-open';
              } else if (!noChild) {
                return 'folder';
              }
              return 'file-text';
            }}
            onExpand={(key, expanded, data) => {
              console.log(key, expanded, data);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="自定义展开图标">
          <Tree
            data={data}
            showLine
            icon={(data, {isOpen, noChild}) => {
              if(noChild) {
                return 'file-text';
              }
            }}
            onExpand={(key, expanded, data) => {
              console.log(key, expanded, data);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
    </Row>
  </div>
)
export default Demo;

默认展开树

import React from 'react';
import { Tree, Card, Row, Col } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
    ]
  }
];

const Demo = () => (
  <div>
    <Row gutter={10}>
      <Col fixed>
        <Card title="默认展开部分">
          <Tree
            data={data}
            showLine
            openKeys={['0-0-0', '0-1-0']}
            iconAnimation={false}
            icon={(data, {isOpen, noChild}) => {
              if(isOpen && !noChild) {
                return 'folder-open';
              } else if (!noChild) {
                return 'folder';
              }
              return 'file-text';
            }}
            onExpand={(key, expanded, data) => {
              console.log(key, expanded, data);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
      <Col fixed>
        <Card title="展开所有">
          <Tree
            data={data}
            showLine
            defaultExpandAll
            icon={(data, {isOpen, noChild}) => {
              if(noChild) {
                return 'file-text';
              }
            }}
            onExpand={(key, expanded, data) => {
              console.log(key, expanded, data);
            }}
            onSelected={(key, selected, item, evn) => {
              console.log(key, selected, item, evn);
            }}
          />
        </Card>
      </Col>
    </Row>
  </div>
)
export default Demo;

Form中使用

import React from 'react';
import { Tree, Row, Col, Form, Button } from 'uiw';

const data = [
  {
    label: '湖北省',
    key: '0-0-0',
    children:[
      {
        label: '武汉市',
        key: '0-1-0',
        children:[
          { label: '新洲区', key: '0-1-1' },
          { label: '武昌区', key: '0-1-2' },
          {
            label: '汉南区',
            key: '0-1-3',
            children:[
              { label: '汉南区1', key: '0-1-3-1' },
              { label: '汉南区2', key: '0-1-3-2' },
              { label: '汉南区3', key: '0-1-3-3' },
            ]
          },
        ]
      },
      { label: '黄冈市', key: '0-2-0' },
      {
        label: '黄石市',
        key: '0-3-0',
        children:[
          { label: '青山区', key: '0-3-1' },
          { label: '黄陂区', key: '0-3-2' },
          { label: '青山区', key: '0-3-3' },
        ]
      },
    ]
  },
  {
    label: '上海市',
    key: '1-0-0',
    children:[
      { label: '黄浦区', key: '1-0-1' },
      { label: '卢湾区', key: '1-0-2' },
      {
        label: '徐汇区',
        key: '1-0-3',
        children:[
          { label: '半淞园路街道', key: '1-1-0' },
          { label: '南京东路街道', key: '1-2-0' },
          { label: '外滩街道', key: '1-3-0' },
        ]
      },
    ]
  },
  {
    label: '北京市',
    key: '2-0-0',
    children:[
      { label: '东城区', key: '2-1-0' },
      { label: '西城区', key: '2-2-0' },
    ]
  }
];

const Demo = () => {
  return (
    <Form
      onChange={({ initial, current }) => {}}
      resetOnSubmit={false}
      onSubmitError={(error) => error && error.filed ? { ...error.filed } : null}
      onSubmit={({initial, current}) => {
        console.log('current: ', current);
        const ErrObj = {};
        if (current.tree === 'unknown') {
          ErrObj.radioGroup = '请选择性别!';
        }
        if(Object.keys(ErrObj).length > 0) {
          const err = new Error();
          err.filed = ErrObj;
          throw err;
        }
        Notify.success({
          title: '提交成功!', description: `填写:【填写成功】!`
        });
      }}
      fields={{
        tree: {
          value: 'region',
          label: '请输入内容',
          help: '必须选择地区!',
          initialValue: ['0-1-1'],
          children: <Tree
            // multiple 
            checkStrictly
            data={data}
          />,
        },
      }}
    >
      {({ fields, state, canSubmit }) => {
        return (
          <div>
            <Row>
              <Col>{fields.tree}</Col>
            </Row>
            <Row>
              <Col>
                <Button disabled={!canSubmit()} type="primary" htmlType="submit">提交</Button>
              </Col>
            </Row>
            <Row>
              <Col>
                <pre style={{ padding: 10, marginTop: 10 }}>
                  {JSON.stringify(state.current, null, 2)}
                </pre>
              </Col>
            </Row>
          </div>
        );
      }}
    </Form>
  )
}
export default Demo;

Props

参数说明类型默认值
data展示数据ArrayTreeData[]
openKeys节点展开 keyArray[]
selectedKeys设置选中的树节点Array[]
autoExpandParent是否自动展开父节点Booleantrue
defaultExpandAll默认展开所有树节点Booleanfalse
iconAnimation展开收缩图标,参数设为 false 禁用动画Booleantrue
isSelected是否选中当前节点样式。Booleantrue
showLine是否展示连接线Booleanfalse
checkStrictly子节点受父节点控制设置 true,需要配合 multiple 参数使用。Booleanfalse
multiple支持点选多个节点Booleanfalse
icon重新定义,展开收缩图标,当为函数时视为自定义图标,并展示非折叠项的图标。Function(data: object, noChild: bool)/String/Node @3.4.0+ Function(data: object, { selected: bool, noChild: bool })/String/Node-
renderTitle重新定义每个标题节点的显示Function(item, selected: bool, noChild: bool) @3.4.0+ Function(item: TreeData, node?: Node) => React.ReactElement;-
onSelected点击选择树节点触发Function(selectedKeys: array, key, selected: bool, data, e)-
onExpand展开/收起节点时触发Function(key, expanded: bool, data, evn)-

Node Type

参数类型版本
selectedboolean-
noChildboolean-
isHalfCheckedboolean@3.4.0+
openKeysProps'openKeys'@3.4.0+
selectedKeysProps'selectedKeys'@3.4.0+
disabledboolean@4.20.0+
disabledClassstring@4.20.0+
disabledStyleReact.CSSProperties@4.20.0+

data

[
  {
    "label": "湖北省",
    "key": "0-0-0",
    "disabled": false,
    "children":[]
  }
  ...
]
4.22.0

8 months ago

4.22.1

6 months ago

4.22.2

6 months ago

4.22.3

5 months ago

4.21.26

1 year ago

4.21.25

1 year ago

4.21.28

1 year ago

4.21.27

1 year ago

5.0.0-bate.2.1

1 year ago

5.0.0-bate.2.0

1 year ago

4.21.24

1 year ago

5.0.0-bate-19

1 year ago

4.21.22

1 year ago

4.21.21

1 year ago

4.21.23

1 year ago

5.0.0-bate-18

1 year ago

5.0.0-bate-14

1 year ago

5.0.0-bate-17

1 year ago

5.0.0-bate-10

1 year ago

5.0.0-bate-11

1 year ago

5.0.0-bate-12

1 year ago

5.0.0-bate-9

1 year ago

5.0.0-bate-7

1 year ago

5.0.0-bate-8

1 year ago

5.0.0-bate-6

1 year ago

4.21.20

1 year ago

4.21.19

2 years ago

4.21.18

2 years ago

4.21.15

2 years ago

4.21.17

2 years ago

4.21.16

2 years ago

5.0.0-bate-5

2 years ago

5.0.0-bate-3

2 years ago

5.0.0-bate-4

2 years ago

5.0.0-bate-1

2 years ago

5.0.0-bate-2

2 years ago

5.0.0-bate-0

2 years ago

4.21.13

2 years ago

4.21.14

2 years ago

4.21.11

2 years ago

4.21.12

2 years ago

4.21.10

2 years ago

4.21.1

2 years ago

4.21.2

2 years ago

4.21.3

2 years ago

4.21.4

2 years ago

4.21.0

2 years ago

4.20.0

2 years ago

4.21.9

2 years ago

4.21.5

2 years ago

4.21.6

2 years ago

4.21.7

2 years ago

4.21.8

2 years ago

4.18.1

2 years ago

4.18.0

2 years ago

4.17.0

2 years ago

4.16.0

2 years ago

4.16.1

2 years ago

4.16.2

2 years ago

4.19.0

2 years ago

4.15.1

2 years ago

4.14.1

2 years ago

4.14.2

2 years ago

4.14.0

2 years ago

4.13.7

2 years ago

4.13.8

2 years ago

4.13.9

2 years ago

4.13.11

2 years ago

4.13.12

2 years ago

4.13.10

2 years ago

4.15.0

2 years ago

4.10.5

2 years ago

4.10.6

2 years ago

4.10.7

2 years ago

4.9.9

2 years ago

4.10.1

2 years ago

4.10.2

2 years ago

4.10.3

2 years ago

4.10.4

2 years ago

4.10.0

2 years ago

4.13.6

2 years ago

4.13.2

2 years ago

4.13.3

2 years ago

4.13.4

2 years ago

4.13.5

2 years ago

4.13.0

2 years ago

4.13.1

2 years ago

4.12.0

2 years ago

4.12.1

2 years ago

4.12.2

2 years ago

4.11.4

2 years ago

4.11.5

2 years ago

4.11.6

2 years ago

4.9.11

2 years ago

4.9.10

2 years ago

4.11.0

2 years ago

4.11.1

2 years ago

4.11.2

2 years ago

4.11.3

2 years ago

4.9.7

3 years ago

4.9.6

3 years ago

4.9.4

3 years ago

4.9.3

3 years ago

4.9.2

3 years ago

4.9.1

3 years ago

4.9.0

3 years ago

4.8.9

3 years ago

4.8.8

3 years ago

4.7.16

3 years ago

4.8.5

3 years ago

4.8.4

3 years ago

4.8.7

3 years ago

4.8.6

3 years ago

4.8.1

3 years ago

4.8.0

3 years ago

4.8.3

3 years ago

4.8.2

3 years ago

4.7.13

3 years ago

4.7.14

3 years ago

4.7.15

3 years ago

4.7.12

3 years ago

4.7.10

3 years ago

4.7.11

3 years ago

4.7.9

3 years ago

4.7.8

3 years ago

4.7.6

3 years ago

4.7.7

3 years ago

4.7.5

3 years ago

4.7.4

3 years ago

4.7.3

3 years ago

4.7.2

3 years ago

4.7.0

3 years ago

4.6.19

3 years ago

4.6.15

3 years ago

4.6.16

3 years ago

4.6.17

3 years ago

4.6.18

3 years ago

4.6.14

4 years ago

4.6.13

4 years ago

4.6.12

4 years ago

4.6.11

4 years ago

4.6.10

4 years ago

4.6.9

4 years ago

4.6.8

4 years ago

4.6.7

4 years ago

4.6.6

4 years ago

4.6.3

4 years ago

4.6.4

4 years ago

4.6.2

4 years ago

4.6.1

4 years ago

4.6.0

4 years ago

4.5.0

4 years ago

4.4.1

4 years ago

4.4.0

4 years ago

4.3.1

4 years ago

4.2.3

4 years ago

4.2.5

4 years ago

4.3.0

4 years ago

4.2.14

4 years ago

4.2.1

4 years ago

4.2.0

4 years ago

4.1.2

4 years ago

4.1.0

4 years ago

4.1.1

4 years ago

4.0.0

4 years ago

4.0.0-alpha.7

4 years ago

4.0.0-alpha.8

4 years ago

4.0.0-alpha.6

4 years ago

4.0.0-alpha.3

4 years ago

4.0.0-alpha.2

4 years ago

4.0.0-alpha.1

4 years ago

4.0.0-alpha.0

4 years ago