mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Merge pull request #7423 from lurunze1226/feat-nested-select-overflow
feat: NestedSelect组件支持最大展示标签数量
This commit is contained in:
commit
6d2dd47a9f
@ -686,29 +686,92 @@ order: 31
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 限制标签最大展示数量
|
||||||
|
|
||||||
|
> 3.3.0 及以上版本
|
||||||
|
|
||||||
|
`maxTagCount`可以限制标签的最大展示数量,超出数量的部分会收纳到 Popover 中,可以通过`overflowTagPopover`配置 Popover 相关的[属性](../tooltip#属性表),注意该属性仅在多选模式开启后生效。
|
||||||
|
|
||||||
|
```schema: scope="body"
|
||||||
|
{
|
||||||
|
"type": "form",
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "nested-select",
|
||||||
|
"name": "nestedSelect",
|
||||||
|
"label": "级联选择器",
|
||||||
|
"multiple": true,
|
||||||
|
"maxTagCount": 3,
|
||||||
|
"overflowTagPopover": {
|
||||||
|
"title": "已选项"
|
||||||
|
},
|
||||||
|
"value": "Apple,Banana,Blackberry,Blueberry,Cherry,Carambola,Coconut,Kiwifruit,Lemon,Pineapple,Vegetables,Wheat,Rice",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"label": "水果",
|
||||||
|
"value": "Fruits",
|
||||||
|
"children" : [
|
||||||
|
{"label": "苹果", "value": "Apple"},
|
||||||
|
{"label": "香蕉", "value": "Banana"},
|
||||||
|
{"label": "黑莓", "value": "Blackberry"},
|
||||||
|
{"label": "蓝莓", "value": "Blueberry"},
|
||||||
|
{"label": "樱桃", "value": "Cherry"},
|
||||||
|
{"label": "杨桃", "value": "Carambola"},
|
||||||
|
{"label": "椰子", "value": "Coconut"},
|
||||||
|
{"label": "猕猴桃", "value": "Kiwifruit"},
|
||||||
|
{"label": "柠檬", "value": "Lemon"},
|
||||||
|
{"label": "菠萝", "value": "Pineapple"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "蔬菜",
|
||||||
|
"value": "Vegetables",
|
||||||
|
"children": [
|
||||||
|
{"label": "西兰花", "value": "Broccoli"},
|
||||||
|
{"label": "菠菜", "value": "Spinach"},
|
||||||
|
{"label": "南瓜", "value": "Pumpkin"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "谷物",
|
||||||
|
"value": "Grain",
|
||||||
|
"children": [
|
||||||
|
{"label": "小麦", "value": "Wheat"},
|
||||||
|
{"label": "水稻", "value": "Rice"},
|
||||||
|
{"label": "燕麦", "value": "Oats"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 属性表
|
## 属性表
|
||||||
|
|
||||||
当做选择器表单项使用时,除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
当做选择器表单项使用时,除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
|
||||||
| ----------------- | ----------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------- |
|
| ------------------ | ----------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --- |
|
||||||
| options | `Array<object>`或`Array<string>` | | [选项组](./options#%E9%9D%99%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-options) |
|
| options | `Array<object>`或`Array<string>` | | [选项组](./options#%E9%9D%99%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-options) |
|
||||||
| source | `string`或 [API](../../../docs/types/api) | | [动态选项组](./options#%E5%8A%A8%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-source) |
|
| source | `string`或 [API](../../../docs/types/api) | | [动态选项组](./options#%E5%8A%A8%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-source) |
|
||||||
| delimiter | `boolean` | `false` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) |
|
| delimiter | `boolean` | `false` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) |
|
||||||
| labelField | `boolean` | `"label"` | [选项标签字段](./options#%E9%80%89%E9%A1%B9%E6%A0%87%E7%AD%BE%E5%AD%97%E6%AE%B5-labelfield) |
|
| labelField | `boolean` | `"label"` | [选项标签字段](./options#%E9%80%89%E9%A1%B9%E6%A0%87%E7%AD%BE%E5%AD%97%E6%AE%B5-labelfield) |
|
||||||
| valueField | `boolean` | `"value"` | [选项值字段](./options#%E9%80%89%E9%A1%B9%E5%80%BC%E5%AD%97%E6%AE%B5-valuefield) |
|
| valueField | `boolean` | `"value"` | [选项值字段](./options#%E9%80%89%E9%A1%B9%E5%80%BC%E5%AD%97%E6%AE%B5-valuefield) |
|
||||||
| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) |
|
| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) |
|
||||||
| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) |
|
| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) |
|
||||||
| autoFill | `object` | | [自动填充](./options#%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85-autofill) |
|
| autoFill | `object` | | [自动填充](./options#%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85-autofill) |
|
||||||
| cascade | `boolean` | `false` | 设置 `true`时,当选中父节点时不自动选择子节点。 |
|
| cascade | `boolean` | `false` | 设置 `true`时,当选中父节点时不自动选择子节点。 |
|
||||||
| withChildren | `boolean` | `false` | 设置 `true`时,选中父节点时,值里面将包含子节点的值,否则只会保留父节点的值。 |
|
| withChildren | `boolean` | `false` | 设置 `true`时,选中父节点时,值里面将包含子节点的值,否则只会保留父节点的值。 |
|
||||||
| onlyChildren | `boolean` | `false` | 多选时,选中父节点时,是否只将其子节点加入到值中。 |
|
| onlyChildren | `boolean` | `false` | 多选时,选中父节点时,是否只将其子节点加入到值中。 |
|
||||||
| searchable | `boolean` | `false` | 可否搜索 |
|
| searchable | `boolean` | `false` | 可否搜索 |
|
||||||
| searchPromptText | `string` | `"输入内容进行检索"` | 搜索框占位文本 |
|
| searchPromptText | `string` | `"输入内容进行检索"` | 搜索框占位文本 |
|
||||||
| noResultsText | `string` | `"未找到任何结果"` | 无结果时的文本 |
|
| noResultsText | `string` | `"未找到任何结果"` | 无结果时的文本 |
|
||||||
| multiple | `boolean` | `false` | 可否多选 |
|
| multiple | `boolean` | `false` | 可否多选 |
|
||||||
| hideNodePathLabel | `boolean` | `false` | 是否隐藏选择框中已选择节点的路径 label 信息 |
|
| hideNodePathLabel | `boolean` | `false` | 是否隐藏选择框中已选择节点的路径 label 信息 |
|
||||||
| onlyLeaf | `boolean` | `false` | 只允许选择叶子节点 |
|
| onlyLeaf | `boolean` | `false` | 只允许选择叶子节点 |
|
||||||
|
| maxTagCount | `number` | | 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效 | `3.3.0` |
|
||||||
|
| overflowTagPopover | `TooltipObject` | `{"placement": "top", "trigger": "hover", "showArrow": false, "offset": [0, -10]}` | 收纳浮层的配置属性,详细配置参考[Tooltip](../tooltip#属性表) | `3.3.0` |
|
||||||
|
|
||||||
## 事件表
|
## 事件表
|
||||||
|
|
||||||
|
@ -0,0 +1,151 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Renderer:NestedSelect with maxTagLength 3 1`] = `
|
||||||
|
<div>
|
||||||
|
<form
|
||||||
|
class="cxd-Form cxd-Form--normal"
|
||||||
|
novalidate=""
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
style="display: none;"
|
||||||
|
type="submit"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="cxd-Form-item cxd-Form-item--normal"
|
||||||
|
data-role="form-item"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="cxd-Form-label"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<span
|
||||||
|
class="cxd-TplField"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
NestedSelect
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="cxd-NestedSelectControl cxd-Form-control"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox cxd-NestedSelect cxd-NestedSelect--multi is-clickable is-group"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-value-wrap"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-value"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-ResultBox-valueLabel"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-Select-valueLabel"
|
||||||
|
title="水果 / 苹果"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
水果
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
苹果
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
data-index="0"
|
||||||
|
>
|
||||||
|
<icon-mock
|
||||||
|
classname="icon icon-close"
|
||||||
|
icon="close"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-value"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-ResultBox-valueLabel"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-Select-valueLabel"
|
||||||
|
title="水果 / 香蕉"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
水果
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
香蕉
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
data-index="1"
|
||||||
|
>
|
||||||
|
<icon-mock
|
||||||
|
classname="icon icon-close"
|
||||||
|
icon="close"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-value"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-ResultBox-valueLabel"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-Select-valueLabel"
|
||||||
|
title="水果 / 黑莓"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
水果
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
黑莓
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
data-index="2"
|
||||||
|
>
|
||||||
|
<icon-mock
|
||||||
|
classname="icon icon-close"
|
||||||
|
icon="close"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-value"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-ResultBox-valueLabel"
|
||||||
|
>
|
||||||
|
+ 10 ...
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="cxd-ResultBox-actions"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="cxd-ResultBox-pc-arrow"
|
||||||
|
>
|
||||||
|
<icon-mock
|
||||||
|
classname="icon icon-right-arrow-bold"
|
||||||
|
icon="right-arrow-bold"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
`;
|
115
packages/amis/__tests__/renderers/Form/nestedSelect.test.tsx
Normal file
115
packages/amis/__tests__/renderers/Form/nestedSelect.test.tsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/**
|
||||||
|
* 组件名称:NestedSelect 级联选择器
|
||||||
|
* 单测内容:
|
||||||
|
* 01. maxTagLength
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {render, cleanup, waitFor} from '@testing-library/react';
|
||||||
|
import '../../../src';
|
||||||
|
import {render as amisRender} from '../../../src';
|
||||||
|
import {makeEnv} from '../../helper';
|
||||||
|
import {clearStoresCache} from '../../../src';
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
cleanup();
|
||||||
|
clearStoresCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
const setupNestedSelect = async (
|
||||||
|
schema: any = {},
|
||||||
|
props: any = {},
|
||||||
|
env: any = {}
|
||||||
|
) => {
|
||||||
|
const renderResult = render(
|
||||||
|
amisRender(
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
wrapWithPanel: false,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'nested-select',
|
||||||
|
name: 'nestedSelect',
|
||||||
|
label: 'NestedSelect',
|
||||||
|
...schema
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{...props},
|
||||||
|
makeEnv({...env})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
renderResult.container.querySelector('.cxd-NestedSelectControl')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const cmpt = renderResult.container.querySelector(
|
||||||
|
'.cxd-ResultBox .cxd-NestedSelect'
|
||||||
|
) as HTMLDivElement;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...renderResult,
|
||||||
|
cmpt
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Renderer:NestedSelect', () => {
|
||||||
|
test('with maxTagLength 3', async () => {
|
||||||
|
const {container, cmpt, queryByText} = await setupNestedSelect({
|
||||||
|
multiple: true,
|
||||||
|
maxTagCount: 3,
|
||||||
|
overflowTagPopover: {
|
||||||
|
title: '已选项'
|
||||||
|
},
|
||||||
|
value:
|
||||||
|
'Apple,Banana,Blackberry,Blueberry,Cherry,Carambola,Coconut,Kiwifruit,Lemon,Pineapple,Vegetables,Wheat,Rice',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '水果',
|
||||||
|
value: 'Fruits',
|
||||||
|
children: [
|
||||||
|
{label: '苹果', value: 'Apple'},
|
||||||
|
{label: '香蕉', value: 'Banana'},
|
||||||
|
{label: '黑莓', value: 'Blackberry'},
|
||||||
|
{label: '蓝莓', value: 'Blueberry'},
|
||||||
|
{label: '樱桃', value: 'Cherry'},
|
||||||
|
{label: '杨桃', value: 'Carambola'},
|
||||||
|
{label: '椰子', value: 'Coconut'},
|
||||||
|
{label: '猕猴桃', value: 'Kiwifruit'},
|
||||||
|
{label: '柠檬', value: 'Lemon'},
|
||||||
|
{label: '菠萝', value: 'Pineapple'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '蔬菜',
|
||||||
|
value: 'Vegetables',
|
||||||
|
children: [
|
||||||
|
{label: '西兰花', value: 'Broccoli'},
|
||||||
|
{label: '菠菜', value: 'Spinach'},
|
||||||
|
{label: '南瓜', value: 'Pumpkin'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '谷物',
|
||||||
|
value: 'Grain',
|
||||||
|
children: [
|
||||||
|
{label: '小麦', value: 'Wheat'},
|
||||||
|
{label: '水稻', value: 'Rice'},
|
||||||
|
{label: '燕麦', value: 'Oats'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = container.querySelectorAll('.cxd-ResultBox-value-wrap')[0];
|
||||||
|
/** Tag 数量正确 */
|
||||||
|
expect(list.childNodes.length).toBe(4);
|
||||||
|
|
||||||
|
const overflowText = '+ 10 ...';
|
||||||
|
/** 收纳 Tag 可见 */
|
||||||
|
expect(queryByText(overflowText)).toBeVisible();
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
@ -37,6 +37,8 @@ import {FormOptionsSchema} from '../../Schema';
|
|||||||
import {supportStatic} from './StaticHoc';
|
import {supportStatic} from './StaticHoc';
|
||||||
import {matchSorter} from 'match-sorter';
|
import {matchSorter} from 'match-sorter';
|
||||||
|
|
||||||
|
import type {TooltipObject} from 'amis-ui/lib/components/TooltipWrapper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nested Select
|
* Nested Select
|
||||||
* 文档:https://aisuda.bce.baidu.com/amis/zh-CN/components/form/nested-select
|
* 文档:https://aisuda.bce.baidu.com/amis/zh-CN/components/form/nested-select
|
||||||
@ -77,6 +79,16 @@ export interface NestedSelectControlSchema extends FormOptionsSchema {
|
|||||||
* 是否隐藏选择框中已选中节点的祖先节点的文本信息
|
* 是否隐藏选择框中已选中节点的祖先节点的文本信息
|
||||||
*/
|
*/
|
||||||
hideNodePathLabel?: boolean;
|
hideNodePathLabel?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效
|
||||||
|
*/
|
||||||
|
maxTagCount?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收纳标签的Popover配置
|
||||||
|
*/
|
||||||
|
overflowTagPopover?: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NestedSelectProps
|
export interface NestedSelectProps
|
||||||
@ -88,6 +100,8 @@ export interface NestedSelectProps
|
|||||||
onlyChildren?: boolean;
|
onlyChildren?: boolean;
|
||||||
hideNodePathLabel?: boolean;
|
hideNodePathLabel?: boolean;
|
||||||
useMobileUI?: boolean;
|
useMobileUI?: boolean;
|
||||||
|
maxTagCount?: number;
|
||||||
|
overflowTagPopover?: TooltipObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NestedSelectState {
|
export interface NestedSelectState {
|
||||||
@ -914,7 +928,9 @@ export default class NestedSelectControl extends React.Component<
|
|||||||
useMobileUI,
|
useMobileUI,
|
||||||
popOverContainer,
|
popOverContainer,
|
||||||
env,
|
env,
|
||||||
loadingConfig
|
loadingConfig,
|
||||||
|
maxTagCount,
|
||||||
|
overflowTagPopover
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const mobileUI = useMobileUI && isMobile();
|
const mobileUI = useMobileUI && isMobile();
|
||||||
@ -925,6 +941,8 @@ export default class NestedSelectControl extends React.Component<
|
|||||||
>
|
>
|
||||||
<ResultBox
|
<ResultBox
|
||||||
useMobileUI={useMobileUI}
|
useMobileUI={useMobileUI}
|
||||||
|
maxTagCount={maxTagCount}
|
||||||
|
overflowTagPopover={overflowTagPopover}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
ref={this.domRef}
|
ref={this.domRef}
|
||||||
placeholder={__(placeholder ?? 'placeholder.empty')}
|
placeholder={__(placeholder ?? 'placeholder.empty')}
|
||||||
|
Loading…
Reference in New Issue
Block a user