feat: mentions add status

pull/5820/head
tangjinzhou 2022-05-19 17:34:41 +08:00
parent c6f692222d
commit d716421745
8 changed files with 124 additions and 10 deletions

View File

@ -6,6 +6,7 @@
<readonly />
<placement />
<FormMentions />
<statusVue />
</demo-sort>
</template>
<script>
@ -15,6 +16,7 @@ import FormMentions from './form.vue';
import Prefix from './prefix.vue';
import Readonly from './readonly.vue';
import Placement from './placement.vue';
import statusVue from './status.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
import { defineComponent } from 'vue';
@ -23,6 +25,7 @@ export default defineComponent({
CN,
US,
components: {
statusVue,
Basic,
Async,
Prefix,

View File

@ -0,0 +1,50 @@
<docs>
---
order: 8
title:
zh-CN: 自定义状态
en-US: Status
---
## zh-CN
使用 `status` Mentions 添加状态可选 `error` 或者 `warning`
## en-US
Add status to Mentions with `status`, which could be `error` or `warning`
</docs>
<template>
<a-space direction="vertical">
<a-mentions v-model:value="value" autofocus status="error" @select="onSelect">
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
<a-mentions v-model:value="value" autofocus status="warning" @select="onSelect">
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
</a-space>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
export default defineComponent({
setup() {
const value = ref<string>('@afc163');
watch(value, () => {
console.log('value', value);
});
const onSelect = (option: { value: string }) => {
console.log('select', option);
};
return {
value,
onSelect,
};
},
});
</script>

View File

@ -16,7 +16,7 @@ When you need to mention someone or something.
### Mention
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| --- | --- | --- | --- | --- |
| autofocus | Auto get focus when component mounted | boolean | `false` |
| defaultValue | Default value | string | |
| filterOption | Customize filter option logic | false \| (input: string, option: OptionProps) => boolean | |
@ -25,6 +25,7 @@ When you need to mention someone or something.
| placement | Set popup placement | `top` \| `bottom` | `bottom` |
| prefix | Set trigger prefix keyword | string \| string\[] | '@' |
| split | Set split string before and after selected mention | string | ' ' |
| status | Set validation status | 'error' \| 'warning' \| 'success' \| 'validating' | - | 3.3.0 |
| validateSearch | Customize trigger search logic | (text: string, props: MentionsProps) => void | |
| value(v-model) | Set value of mentions | string | |

View File

@ -1,15 +1,17 @@
import type { App, PropType, ExtractPropTypes } from 'vue';
import { watch, ref, onMounted, defineComponent, nextTick } from 'vue';
import { computed, watch, ref, onMounted, defineComponent, nextTick } from 'vue';
import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import VcMentions, { Option } from '../vc-mentions';
import { mentionsProps as baseMentionsProps } from '../vc-mentions/src/mentionsProps';
import useConfigInject from '../_util/hooks/useConfigInject';
import { flattenChildren, getOptionProps } from '../_util/props-util';
import { useInjectFormItemContext } from '../form/FormItemContext';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import omit from '../_util/omit';
import { optionProps } from '../vc-mentions/src/Option';
import type { KeyboardEventHandler } from '../_util/EventInterface';
import type { InputStatus } from '../_util/statusUtils';
import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
interface MentionsConfig {
prefix?: string | string[];
@ -83,6 +85,7 @@ export const mentionsProps = () => ({
notFoundContent: PropTypes.any,
defaultValue: String,
id: String,
status: String as PropType<InputStatus>,
});
export type MentionsProps = Partial<ExtractPropTypes<ReturnType<typeof mentionsProps>>>;
@ -98,6 +101,8 @@ const Mentions = defineComponent({
const vcMentions = ref(null);
const value = ref(props.value ?? props.defaultValue ?? '');
const formItemContext = useInjectFormItemContext();
const formItemInputContext = FormItemInputContext.useInject();
const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
watch(
() => props.value,
val => {
@ -174,14 +179,19 @@ const Mentions = defineComponent({
id = formItemContext.id.value,
...restProps
} = props;
const { hasFeedback, feedbackIcon } = formItemInputContext;
const { class: className, ...otherAttrs } = attrs;
const otherProps = omit(restProps, ['defaultValue', 'onUpdate:value', 'prefixCls']);
const mergedClassName = classNames(className, {
[`${prefixCls.value}-disabled`]: disabled,
[`${prefixCls.value}-focused`]: focused.value,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
});
const mergedClassName = classNames(
{
[`${prefixCls.value}-disabled`]: disabled,
[`${prefixCls.value}-focused`]: focused.value,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
},
getStatusClassNames(prefixCls.value, mergedStatus.value),
!hasFeedback && className,
);
const mentionsProps = {
prefixCls: prefixCls.value,
@ -202,12 +212,31 @@ const Mentions = defineComponent({
value: value.value,
id,
};
return (
const mentions = (
<VcMentions
{...mentionsProps}
v-slots={{ notFoundContent: getNotFoundContent, option: slots.option }}
></VcMentions>
);
if (hasFeedback) {
return (
<div
class={classNames(
`${prefixCls.value}-affix-wrapper`,
getStatusClassNames(
`${prefixCls.value}-affix-wrapper`,
mergedStatus.value,
hasFeedback,
),
className,
)}
>
{mentions}
<span class={`${prefixCls.value}-suffix`}>{feedbackIcon}</span>
</div>
);
}
return mentions;
};
},
});

View File

@ -17,7 +17,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/jPE-itMFM/Mentions.svg
### Mentions
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| --- | --- | --- | --- | --- |
| autofocus | 自动获得焦点 | boolean | `false` |
| defaultValue | 默认值 | string | |
| filterOption | 自定义过滤逻辑 | false \| (input: string, option: OptionProps) => boolean | |
@ -26,6 +26,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/jPE-itMFM/Mentions.svg
| placement | 弹出层展示位置 | `top` \| `bottom` | `bottom` |
| prefix | 设置触发关键字 | string \| string\[] | '@' |
| split | 设置选中项前后分隔符 | string | ' ' |
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
| validateSearch | 自定义触发验证逻辑 | (text: string, props: MentionsProps) => void | |
| value(v-model) | 设置值 | string | |

View File

@ -1,6 +1,7 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import '../../input/style/mixin';
@import './status';
@mention-prefix-cls: ~'@{ant-prefix}-mentions';
@ -162,6 +163,17 @@
}
}
}
&-suffix {
position: absolute;
top: 0;
right: @input-padding-horizontal-base;
bottom: 0;
z-index: 1;
display: inline-flex;
align-items: center;
margin: auto;
}
}
@import './rtl';

View File

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

View File

@ -0,0 +1,16 @@
@import '../../input/style/mixin';
@mention-prefix-cls: ~'@{ant-prefix}-mentions';
@input-prefix-cls: ~'@{ant-prefix}-input';
.@{mention-prefix-cls} {
&-status-error {
.status-color(@mention-prefix-cls, @error-color, @error-color, @input-bg, @error-color-hover, @error-color-outline);
.status-color-common(@input-prefix-cls, @error-color, @error-color, @input-bg, @error-color-hover, @error-color-outline);
}
&-status-warning {
.status-color(@mention-prefix-cls, @warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline);
.status-color-common(@input-prefix-cls, @warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline);
}
}