feat: input add disabled

pull/6245/head
tangjinzhou 2023-02-08 11:04:16 +08:00
parent 4f3ce35e74
commit 8658806e3f
12 changed files with 38 additions and 36 deletions

View File

@ -62,6 +62,9 @@ export function functionType<T = () => {}>(defaultVal?: any) {
export function anyType<T = any>() {
return { validator: () => true } as unknown as { type: PropType<T> };
}
export function vNodeType<T = VueNode>() {
return { validator: () => true } as unknown as { type: PropType<T> };
}
export function stringType<T extends string = string>(defaultVal?: string) {
return { type: String as unknown as PropType<T>, default: defaultVal as T };

View File

@ -5,7 +5,7 @@ export type DisabledType = boolean | undefined;
const DisabledContextKey: InjectionKey<Ref<DisabledType>> = Symbol('DisabledContextKey');
export const useInjectDisabled = () => {
return inject(DisabledContextKey, ref(undefined));
return inject(DisabledContextKey, ref<DisabledType>(undefined));
};
export const useProviderDisabled = (disabled: Ref<DisabledType>) => {
const parentDisabled = useInjectDisabled();

View File

@ -4,7 +4,8 @@ import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode';
import type { CSSProperties, PropType, VNode } from 'vue';
import { defineComponent } from 'vue';
import { tuple } from '../_util/type';
import type { VueNode } from '../_util/type';
import { anyType, tuple } from '../_util/type';
import type { Direction, SizeType } from '../config-provider';
import type { MouseEventHandler } from '../_util/EventInterface';
import { hasAddon } from './util';
@ -12,7 +13,7 @@ import { FormItemInputContext } from '../form/FormItemContext';
import type { InputStatus } from '../_util/statusUtils';
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
const ClearableInputType = ['text', 'input'];
const ClearableInputType = ['text', 'input'] as const;
export default defineComponent({
compatConfig: { MODE: 3 },
@ -21,18 +22,18 @@ export default defineComponent({
props: {
prefixCls: String,
inputType: PropTypes.oneOf(tuple('text', 'input')),
value: PropTypes.any,
defaultValue: PropTypes.any,
value: anyType<VueNode>(),
defaultValue: anyType<VueNode>(),
allowClear: { type: Boolean, default: undefined },
element: PropTypes.any,
element: anyType<VueNode>(),
handleReset: Function as PropType<MouseEventHandler>,
disabled: { type: Boolean, default: undefined },
direction: { type: String as PropType<Direction> },
size: { type: String as PropType<SizeType> },
suffix: PropTypes.any,
prefix: PropTypes.any,
addonBefore: PropTypes.any,
addonAfter: PropTypes.any,
suffix: anyType<VueNode>(),
prefix: anyType<VueNode>(),
addonBefore: anyType<VueNode>(),
addonAfter: anyType<VueNode>(),
readonly: { type: Boolean, default: undefined },
focused: { type: Boolean, default: undefined },
bordered: { type: Boolean, default: true },
@ -114,7 +115,7 @@ export default defineComponent({
return () => {
const { prefixCls, inputType, element = slots.element?.() } = props;
if (inputType === ClearableInputType[0]) {
return renderTextAreaWithClearIcon(prefixCls, element);
return renderTextAreaWithClearIcon(prefixCls, element as VNode);
}
return null;
};

View File

@ -2,7 +2,6 @@ import type { PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import type { SizeType } from '../config-provider';
import { FormItemInputContext } from '../form/FormItemContext';
import type { FocusEventHandler, MouseEventHandler } from '../_util/EventInterface';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
@ -17,20 +16,16 @@ export default defineComponent({
prefixCls: String,
size: { type: String as PropType<SizeType> },
compact: { type: Boolean, default: undefined },
onMouseenter: { type: Function as PropType<MouseEventHandler> },
onMouseleave: { type: Function as PropType<MouseEventHandler> },
onFocus: { type: Function as PropType<FocusEventHandler> },
onBlur: { type: Function as PropType<FocusEventHandler> },
},
setup(props, { slots, attrs }) {
const { prefixCls, direction } = useConfigInject('input-group', props);
const { prefixCls, direction, getPrefixCls } = useConfigInject('input-group', props);
const formItemInputContext = FormItemInputContext.useInject();
FormItemInputContext.useProvide(formItemInputContext, {
isFormItemInput: false,
});
// style
const { prefixCls: inputPrefixCls } = useConfigInject('input', props);
const inputPrefixCls = computed(() => getPrefixCls('input'));
const [wrapSSR, hashId] = useStyle(inputPrefixCls);
const cls = computed(() => {
@ -46,14 +41,7 @@ export default defineComponent({
});
return () => {
return wrapSSR(
<span
{...attrs}
class={classNames(cls.value, attrs.class)}
onMouseenter={props.onMouseenter}
onMouseleave={props.onMouseleave}
onFocus={props.onFocus}
onBlur={props.onBlur}
>
<span {...attrs} class={classNames(cls.value, attrs.class)}>
{slots.default?.()}
</span>,
);

View File

@ -16,6 +16,7 @@ import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
// CSSINJS
import useStyle from './style';
import { useInjectDisabled } from '../config-provider/DisabledContext';
export default defineComponent({
compatConfig: { MODE: 3 },
@ -32,6 +33,8 @@ export default defineComponent({
// Style
const [wrapSSR, hashId] = useStyle(prefixCls);
const disabled = useInjectDisabled();
const focus = (option?: InputFocusOptions) => {
inputRef.value?.focus(option);
};
@ -129,6 +132,7 @@ export default defineComponent({
{...omit(rest, ['onUpdate:value', 'onChange', 'onInput'])}
onChange={triggerChange}
id={id}
disabled={props.disabled ?? disabled.value}
ref={inputRef}
prefixCls={prefixClsValue}
autocomplete={autocomplete.value}

View File

@ -64,7 +64,7 @@ export default defineComponent({
};
const onPressEnter = (e: KeyboardEvent) => {
if (composedRef.value) {
if (composedRef.value || props.loading) {
return;
}
onSearch(e);

View File

@ -23,6 +23,7 @@ import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
// CSSINJS
import useStyle from './style';
import { useInjectDisabled } from '../config-provider/DisabledContext';
function fixEmojiLength(value: string, maxLength: number) {
return [...(value || '')].slice(0, maxLength).join('');
@ -64,7 +65,7 @@ export default defineComponent({
// Style
const [wrapSSR, hashId] = useStyle(prefixCls);
const disabled = useInjectDisabled();
const showCount = computed(() => {
return (props.showCount as any) === '' || props.showCount || false;
});
@ -191,12 +192,11 @@ export default defineComponent({
setValue(triggerValue);
};
const renderTextArea = () => {
const { style, class: customClass } = attrs;
const { class: customClass } = attrs;
const { bordered = true } = props;
const resizeProps = {
...omit(props, ['allowClear']),
...attrs,
style: showCount.value ? {} : style,
class: [
{
[`${prefixCls.value}-borderless`]: !bordered,
@ -261,6 +261,7 @@ export default defineComponent({
bordered,
style: showCount.value ? undefined : style,
hashId: hashId.value,
disabled: props.disabled ?? disabled.value,
};
let textareaNode = (
@ -276,7 +277,11 @@ export default defineComponent({
const valueLength = [...mergedValue.value].length;
let dataCount: VueNode = '';
if (typeof showCount.value === 'object') {
dataCount = showCount.value.formatter({ count: valueLength, maxlength });
dataCount = showCount.value.formatter({
value: mergedValue.value,
count: valueLength,
maxlength,
});
} else {
dataCount = `${valueLength}${hasMaxLength.value ? ` / ${maxlength}` : ''}`;
}

View File

@ -2,7 +2,7 @@
category: Components
type: Data Entry
title: Input
cover: https://gw.alipayobjects.com/zos/alicdn/xS9YEJhfe/Input.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Y3R0RowXHlAAAAAAAAAAAAAADrJ8AQ/original
---
A basic widget for getting the user input is a text field. Keyboard and mouse can be used for providing or changing data.

View File

@ -3,7 +3,7 @@ category: Components
type: 数据录入
title: Input
subtitle: 输入框
cover: https://gw.alipayobjects.com/zos/alicdn/xS9YEJhfe/Input.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Y3R0RowXHlAAAAAAAAAAAAAADrJ8AQ/original
---
通过鼠标或键盘输入内容,是最基础的表单域的包装。

View File

@ -1,6 +1,7 @@
import type { ExtractPropTypes, PropType } from 'vue';
import omit from '../_util/omit';
import type { VueNode } from '../_util/type';
import { eventType } from '../_util/type';
import type { CompositionEventHandler } from '../_util/EventInterface';
import { inputProps as vcInputProps } from '../vc-input/inputProps';
@ -29,8 +30,8 @@ const textAreaProps = () => ({
autosize: { type: [Boolean, Object] as PropType<boolean | AutoSizeType>, default: undefined },
autoSize: { type: [Boolean, Object] as PropType<boolean | AutoSizeType>, default: undefined },
onResize: { type: Function as PropType<(size: { width: number; height: number }) => void> },
onCompositionstart: Function as PropType<CompositionEventHandler>,
onCompositionend: Function as PropType<CompositionEventHandler>,
onCompositionstart: eventType<CompositionEventHandler>(),
onCompositionend: eventType<CompositionEventHandler>(),
valueModifiers: Object,
});

View File

@ -107,7 +107,7 @@ export const inputProps = () => ({
export type InputProps = Partial<ExtractPropTypes<ReturnType<typeof inputProps>>>;
export interface ShowCountProps {
formatter: (args: { count: number; maxlength?: number }) => VueNode;
formatter: (args: { count: number; maxlength?: number; value?: string }) => VueNode;
}
export interface InputRef {