Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tree-select 新增TreeSelect组件 #523

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions site/mobile/mobile.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,5 +262,10 @@ export default {
name: 'table',
component: () => import('tdesign-mobile-react/table/_example/index.tsx'),
},
{
title: 'TreeSelect 树形选择',
name: 'tree-select',
component: () => import('tdesign-mobile-react/tree-select/_example/index.tsx'),
},
],
};
6 changes: 6 additions & 0 deletions site/web/site.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ export default {
path: '/mobile-react/components/upload',
component: () => import('tdesign-mobile-react/upload/upload.md'),
},
{
title: 'TreeSelect 树形选择',
name: 'tree-select',
path: '/mobile-react/components/tree-select',
component: () => import('tdesign-mobile-react/tree-select/tree-select.md'),
},
],
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export * from './drawer';
* 二期组件
*/
export * from './collapse';

export * from './tree-select';
export * from './notice-bar';

/**
Expand Down
39 changes: 39 additions & 0 deletions src/tree-select/_example/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useState } from 'react';
import { TreeSelect } from 'tdesign-mobile-react';
import { TdTreeSelectProps, TreeSelectValue } from '../type';

export default function BaseBadge() {
const chineseNumber = '一二三四五六七八九十'.split('');

const generateTree = (deep = 0, count = 10, prefix = ''): TdTreeSelectProps['options'] => {
const ans: TdTreeSelectProps['options'] = [];

for (let i = 0; i < count; i += 1) {
const value = prefix ? `${prefix}-${i}` : `${i}`;
const rect = {
label: `选项${chineseNumber[i]}`,
value,
};

if (deep > 0) {
// @ts-ignore
rect.children = generateTree(deep - 1, 10, value);
}
ans.push(rect);
}

return ans;
};
const options = generateTree(1);
const [value, setValue] = useState<TreeSelectValue>(['1', '1-0']);
const onChange: TdTreeSelectProps['onChange'] = (itemValue, level) => {
console.log(itemValue, level);
setValue(itemValue);
};

return (
<>
<TreeSelect value={value} options={options} onChange={onChange}></TreeSelect>
</>
);
}
24 changes: 24 additions & 0 deletions src/tree-select/_example/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import TDemoBlock from '../../../site/mobile/components/DemoBlock';
import TDemoHeader from '../../../site/mobile/components/DemoHeader';

import BaseDemo from './base';
import MultipleDemo from './multiple';
import NormalDemo from './normal';

export default function BadgeDemo() {
return (
<div className="tdesign-mobile-demo">
<TDemoHeader title="TreeSelect 树形选择器" summary="用于多层级数据的逐级选择。" />
<TDemoBlock title="01 组件类型" summary="基础树形选择">
<BaseDemo />
</TDemoBlock>
<TDemoBlock summary="多选树形选择">
<MultipleDemo />
</TDemoBlock>
<TDemoBlock title="02 组件状态" summary="三级树形选择">
<NormalDemo />
</TDemoBlock>
</div>
);
}
40 changes: 40 additions & 0 deletions src/tree-select/_example/multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useState } from 'react';
import { TreeSelect } from 'tdesign-mobile-react';
import { TdTreeSelectProps, TreeSelectValue } from '../type';

export default function BaseBadge() {
const chineseNumber = '一二三四五六七八九十'.split('');

const generateTree = (deep = 0, count = 10, prefix = ''): TdTreeSelectProps['options'] => {
const ans: TdTreeSelectProps['options'] = [];

for (let i = 0; i < count; i += 1) {
const value = prefix ? `${prefix}-${i}` : `${i}`;
const rect = {
label: `选项${chineseNumber[i]}`,
value,
};

if (deep > 0) {
// @ts-ignore
rect.children = generateTree(deep - 1, 10, value);
}
ans.push(rect);
}

return ans;
};
const options = generateTree(1);
const [value, setValue] = useState<TreeSelectValue>(['0', ['0-0', '0-1']]);

const onChange: TdTreeSelectProps['onChange'] = (itemValue, level) => {
console.log(itemValue, level);
setValue(itemValue);
};

return (
<>
<TreeSelect value={value} multiple options={options} onChange={onChange}></TreeSelect>
</>
);
}
142 changes: 142 additions & 0 deletions src/tree-select/_example/normal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { useState } from 'react';
import { TreeSelect } from 'tdesign-mobile-react';
import { TdTreeSelectProps, TreeSelectValue } from '../type';

export default function BaseBadge() {
const areaList = {
provinces: {
110000: '北京市',
440000: '广东省',
},
cities: {
110100: '北京市',
440100: '广州市',
440200: '韶关市',
440300: '深圳市',
440400: '珠海市',
440500: '汕头市',
440600: '佛山市',
},
counties: {
110101: '东城区',
110102: '西城区',
110105: '朝阳区',
110106: '丰台区',
110107: '石景山区',
110108: '海淀区',
110109: '门头沟区',
110111: '房山区',
110112: '通州区',
110113: '顺义区',
110114: '昌平区',
110115: '大兴区',
110116: '怀柔区',
110117: '平谷区',
110118: '密云区',
110119: '延庆区',
440103: '荔湾区',
440104: '越秀区',
440105: '海珠区',
440106: '天河区',
440111: '白云区',
440112: '黄埔区',
440113: '番禺区',
440114: '花都区',
440115: '南沙区',
440117: '从化区',
440118: '增城区',
440203: '武江区',
440204: '浈江区',
440205: '曲江区',
440222: '始兴县',
440224: '仁化县',
440229: '翁源县',
440232: '乳源瑶族自治县',
440233: '新丰县',
440281: '乐昌市',
440282: '南雄市',
440303: '罗湖区',
440304: '福田区',
440305: '南山区',
440306: '宝安区',
440307: '龙岗区',
440308: '盐田区',
440309: '龙华区',
440310: '坪山区',
440311: '光明区',
440402: '香洲区',
440403: '斗门区',
440404: '金湾区',
440507: '龙湖区',
440511: '金平区',
440512: '濠江区',
440513: '潮阳区',
440514: '潮南区',
440515: '澄海区',
440523: '南澳县',
440604: '禅城区',
440605: '南海区',
440606: '顺德区',
440607: '三水区',
440608: '高明区',
},
};

const generateTree = () => {
const { provinces, cities, counties } = areaList;
const options: TdTreeSelectProps['options'] = [];
const eachObj = (obj: Record<string, string>, cb: (item: string) => void) => Object.keys(obj).forEach(cb);
// @ts-ignore
const match = (v1, v2, base) => parseInt(v1 / base, 10) === parseInt(v2 / base, 10);

eachObj(provinces, (prov) => {
const cityList: TdTreeSelectProps['options'] = [];

eachObj(cities, (city) => {
const countyList: TdTreeSelectProps['options'] = [];

if (match(city, prov, 10000)) {
eachObj(counties, (county) => {
if (match(county, city, 100)) {
countyList.push({
label: counties[county],
value: county,
disabled: ['110102', '440104'].includes(county),
});
}
});
cityList.push({
label: cities[city],
value: city,
children: countyList,
disabled: ['110100', '440200'].includes(city),
});
}
});

const item = {
label: provinces[prov],
value: prov,
children: cityList,
};

options.push(item);
});

return options;
};

const options = generateTree();
const [value, setValue] = useState<TreeSelectValue>(['110000', '110100', '110101']);

const onChange: TdTreeSelectProps['onChange'] = (itemValue, level) => {
console.log(itemValue, level);
setValue(itemValue);
};

return (
<>
<TreeSelect value={value} options={options} onChange={onChange}></TreeSelect>
</>
);
}
12 changes: 12 additions & 0 deletions src/tree-select/defaultProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TdTreeSelectProps } from './type';

export const treeSelectDefaultProps: TdTreeSelectProps = {
filterable: false,
height: 336,
multiple: false,
options: [],
};
8 changes: 8 additions & 0 deletions src/tree-select/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import _TreeSelect from './tree-select';
import { TdTreeSelectProps } from './type';

import './style';

export * from './type';
export type TreeSelectProps = TdTreeSelectProps;
export const TreeSelect = _TreeSelect;
1 change: 1 addition & 0 deletions src/tree-select/style/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './index.css';
1 change: 1 addition & 0 deletions src/tree-select/style/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '../../_common/style/mobile/components/tree-select/_index.less';
18 changes: 18 additions & 0 deletions src/tree-select/tree-select.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
:: BASE_DOC ::

## API

### TreeSelect Props

name | type | default | description | required
-- | -- | -- | -- | --
className | String | - | className of component | N
style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N
filterable | Boolean | false | \- | N
height | String / Number | 336 | \- | N
keys | Object | - | alias filed name in data。Typescript:`TreeKeysType`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
multiple | Boolean | false | \- | N
options | Array | [] | Typescript:`Array<DataOption>` | N
value | String / Number / Array | - | Typescript:`TreeSelectValue` `type TreeSelectValue = string \| number \| Array<TreeSelectValue>`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts) | N
defaultValue | String / Number / Array | - | uncontrolled property。Typescript:`TreeSelectValue` `type TreeSelectValue = string \| number \| Array<TreeSelectValue>`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts) | N
onChange | Function | | Typescript:`(value: TreeSelectValue, level: TreeLevel) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts)。<br/>`type TreeLevel = 0 \| 1 \| 2`<br/> | N
18 changes: 18 additions & 0 deletions src/tree-select/tree-select.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
:: BASE_DOC ::

## API

### TreeSelect Props

名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
filterable | Boolean | false | 是否可搜索 | N
height | String / Number | 336 | 高度,默认单位为 px | N
keys | Object | - | 用来定义 `value / label / disabled / children` 在 `data` 数据中对应的字段别名,示例:`{ value: 'key', label: 'name', children: 'list' }`。TS 类型:`TreeKeysType`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
multiple | Boolean | false | 是否允许多选 | N
options | Array | [] | 选项。TS 类型:`Array<DataOption>` | N
value | String / Number / Array | - | 选中值。TS 类型:`TreeSelectValue` `type TreeSelectValue = string \| number \| Array<TreeSelectValue>`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts) | N
defaultValue | String / Number / Array | - | 选中值。非受控属性。TS 类型:`TreeSelectValue` `type TreeSelectValue = string \| number \| Array<TreeSelectValue>`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts) | N
onChange | Function | | TS 类型:`(value: TreeSelectValue, level: TreeLevel) => void`<br/>点击任何节点均会触发;level 代表当前点击的层级,0 代表最左侧,依次递进。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/tree-select/type.ts)。<br/>`type TreeLevel = 0 \| 1 \| 2`<br/> | N
Loading