feat: cascader add status & showCheckedStrategy

pull/5820/head
tangjinzhou 2022-05-14 15:40:17 +08:00
parent dbe7fe78ce
commit 5bc17f0578
7 changed files with 64 additions and 12 deletions

View File

@ -16,18 +16,32 @@ title:
Select multiple options
</docs>
<template>
<a-cascader
v-model:value="value"
style="width: 100%"
multiple
max-tag-count="responsive"
:options="options"
placeholder="Please select"
></a-cascader>
<a-space direction="vertical" style="width: 100%">
<h4>Cascader.SHOW_PARENT</h4>
<a-cascader
v-model:value="value"
style="width: 100%"
multiple
max-tag-count="responsive"
:options="options"
placeholder="Please select"
></a-cascader>
<h4>Cascader.SHOW_CHILD</h4>
<a-cascader
v-model:value="value"
style="width: 100%"
multiple
max-tag-count="responsive"
:options="options"
placeholder="Please select"
:show-checked-strategy="Cascader.SHOW_CHILD"
></a-cascader>
</a-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import type { CascaderProps } from 'ant-design-vue';
import { Cascader } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
label: 'Light',
@ -66,6 +80,7 @@ export default defineComponent({
return {
value: ref<string[]>([]),
options,
Cascader,
};
},
});

View File

@ -47,7 +47,9 @@ Cascade selection box.
| searchValue | Set search valueNeed work with `showSearch` | string | - | 3.0 |
| showSearch | Whether show search input in single mode. | boolean \| [object](#showsearch) | false | |
| size | input size | `large` \| `default` \| `small` | `default` | |
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
| suffixIcon | The custom suffix icon | string \| VNode \| slot | - | |
| showCheckedStrategy | The way show selected item in box. ** `SHOW_CHILD`: ** just show child treeNode. **`Cascader.SHOW_PARENT`:** just show parent treeNode (when all child treeNode under the parent treeNode are checked) | `Cascader.SHOW_PARENT` \| `Cascader.SHOW_CHILD` | `Cascader.SHOW_PARENT` | 3.3.0 |
| tagRender | Customize tag render when `multiple` | slot | - | 3.0 |
| value(v-model) | selected value | string\[] \| number\[] | - | |

View File

@ -1,5 +1,9 @@
import type { ShowSearchType, FieldNames, BaseOptionType, DefaultOptionType } from '../vc-cascader';
import VcCascader, { cascaderProps as vcCascaderProps } from '../vc-cascader';
import VcCascader, {
cascaderProps as vcCascaderProps,
SHOW_CHILD,
SHOW_PARENT,
} from '../vc-cascader';
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
@ -19,6 +23,9 @@ import type { SelectCommonPlacement } from '../_util/transition';
import { getTransitionDirection, getTransitionName } from '../_util/transition';
import { useInjectFormItemContext } from '../form';
import type { ValueType } from '../vc-cascader/Cascader';
import type { InputStatus } from '../_util/statusUtils';
import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
import { FormItemInputContext } from '../form/FormItemContext';
// Align the design since we use `rc-select` in root. This help:
// - List search content will show all content
@ -99,6 +106,7 @@ export function cascaderProps<DataNodeType extends CascaderOptionType = Cascader
bordered: { type: Boolean, default: undefined },
placement: { type: String as PropType<SelectCommonPlacement> },
suffixIcon: PropTypes.any,
status: String as PropType<InputStatus>,
options: Array as PropType<DataNodeType[]>,
'onUpdate:value': Function as PropType<(value: ValueType) => void>,
};
@ -121,6 +129,8 @@ const Cascader = defineComponent({
}),
setup(props, { attrs, expose, slots, emit }) {
const formItemContext = useInjectFormItemContext();
const formItemInputContext = FormItemInputContext.useInject();
const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
const {
prefixCls: cascaderPrefixCls,
rootPrefixCls,
@ -234,6 +244,8 @@ const Cascader = defineComponent({
const { suffixIcon, removeIcon, clearIcon } = getIcons(
{
...props,
hasFeedback: formItemInputContext.hasFeedback,
feedbackIcon: formItemInputContext.feedbackIcon,
multiple,
prefixCls: prefixCls.value,
showArrow: mergedShowArrow.value,
@ -253,7 +265,13 @@ const Cascader = defineComponent({
[`${prefixCls.value}-sm`]: size.value === 'small',
[`${prefixCls.value}-rtl`]: isRtl.value,
[`${prefixCls.value}-borderless`]: !bordered,
[`${prefixCls.value}-in-form-item`]: formItemInputContext.isFormItemInput,
},
getStatusClassNames(
prefixCls.value,
mergedStatus.value,
formItemInputContext.hasFeedback,
),
attrs.class,
]}
direction={direction.value}
@ -282,7 +300,7 @@ const Cascader = defineComponent({
}}
displayRender={props.displayRender || slots.displayRender}
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
showArrow={props.showArrow}
showArrow={formItemInputContext.hasFeedback || props.showArrow}
onChange={handleChange}
onBlur={handleBlur}
v-slots={slots}
@ -292,5 +310,14 @@ const Cascader = defineComponent({
};
},
});
export default withInstall(Cascader);
export default withInstall<
typeof Cascader & {
SHOW_PARENT: typeof SHOW_PARENT;
SHOW_CHILD: typeof SHOW_CHILD;
}
>(
Object.assign(Cascader, {
SHOW_CHILD,
SHOW_PARENT,
} as any),
);

View File

@ -45,9 +45,11 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
| options | 可选项数据源 | [Option](#option)\[] | - | |
| placeholder | 输入框占位文本 | string | '请选择' | |
| placement | 浮层预设位置 | `bottomLeft` \| `bottomRight` \| `topLeft` \| `topRight` | `bottomLeft` | 3.0 |
| showCheckedStrategy | 定义选中项回填的方式。`Cascader.SHOW_CHILD`: 只显示选中的子节点。`Cascader.SHOW_PARENT`: 只显示父节点(当父节点下所有子节点都选中时)。 | `Cascader.SHOW_PARENT` \| `Cascader.SHOW_CHILD` | `Cascader.SHOW_PARENT` | 3.3.0 |
| removeIcon | 自定义的多选框清除图标 | slot | - | 3.2 |
| searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 3.0 |
| showSearch | 在选择框中显示搜索框 | boolean \| [object](#showsearch) | false | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
| size | 输入框大小 | `large` \| `default` \| `small` | `default` | |
| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - | |
| tagRender | 自定义 tag 内容,多选时生效 | slot | - | 3.0 |

View File

@ -29,6 +29,7 @@
}
&-menu {
flex-grow: 1;
min-width: 111px;
height: 180px;
margin: 0;

View File

@ -4,3 +4,5 @@ import './index.less';
// style dependencies
import '../../empty/style';
import '../../select/style';
// deps-lint-skip: form

View File

@ -19,6 +19,7 @@
<formInModalVue />
<timeRelatedControlsVue />
<validateOtherVue />
<validateStaticVue />
<UseFormBasic />
<UseFormNested />
<UseFormTrigger />
@ -50,6 +51,7 @@ import UseFormMerge from './useForm-merge.vue';
import CustomizedFormControls from './customized-form-controls.vue';
import timeRelatedControlsVue from './time-related-controls.vue';
import validateOtherVue from './validate-other.vue';
import validateStaticVue from './validate-static.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
@ -57,6 +59,7 @@ export default defineComponent({
US,
CN,
components: {
validateStaticVue,
timeRelatedControlsVue,
validateOtherVue,
Basic,