mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-11-30 11:08:00 +08:00
update input
This commit is contained in:
parent
ca7a4becbc
commit
22b051f0a5
@ -1,9 +1,10 @@
|
||||
import { filterEmpty } from '../_util/props-util';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
export default {
|
||||
name: 'AInputGroup',
|
||||
props: {
|
||||
prefixCls: {
|
||||
default: 'ant-input-group',
|
||||
type: String,
|
||||
},
|
||||
size: {
|
||||
@ -13,9 +14,15 @@ export default {
|
||||
},
|
||||
compact: Boolean,
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ({}) },
|
||||
},
|
||||
computed: {
|
||||
classes() {
|
||||
const { prefixCls, size, compact = false } = this;
|
||||
const { prefixCls: customizePrefixCls, size, compact = false } = this;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
||||
|
||||
return {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
|
@ -4,6 +4,10 @@ import omit from 'omit.js';
|
||||
import inputProps from './inputProps';
|
||||
import { hasProp, getComponentFromProp } from '../_util/props-util';
|
||||
import { isIE, isIE9 } from '../_util/env';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
import Password from './Password';
|
||||
import Icon from '../icon';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
function noop() {}
|
||||
|
||||
@ -14,6 +18,10 @@ function fixControlledValue(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function hasPrefixSuffix(props) {
|
||||
return 'prefix' in props || props.suffix || props.allowClear;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'AInput',
|
||||
inheritAttrs: false,
|
||||
@ -24,6 +32,9 @@ export default {
|
||||
props: {
|
||||
...inputProps,
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ({}) },
|
||||
},
|
||||
data() {
|
||||
const { value, defaultValue } = this.$props;
|
||||
return {
|
||||
@ -49,22 +60,6 @@ export default {
|
||||
}
|
||||
this.$emit('keydown', e);
|
||||
},
|
||||
handleChange(e) {
|
||||
// https://github.com/vueComponent/ant-design-vue/issues/92
|
||||
if (isIE && !isIE9 && this.stateValue === e.target.value) {
|
||||
return;
|
||||
}
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.stateValue = e.target.value;
|
||||
} else {
|
||||
this.$forceUpdate();
|
||||
}
|
||||
if (!e.target.composing) {
|
||||
this.$emit('change.value', e.target.value);
|
||||
}
|
||||
this.$emit('change', e);
|
||||
this.$emit('input', e);
|
||||
},
|
||||
|
||||
focus() {
|
||||
this.$refs.input.focus();
|
||||
@ -77,8 +72,8 @@ export default {
|
||||
this.$refs.input.select();
|
||||
},
|
||||
|
||||
getInputClassName() {
|
||||
const { prefixCls, size, disabled } = this.$props;
|
||||
getInputClassName(prefixCls) {
|
||||
const { size, disabled } = this.$props;
|
||||
return {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
@ -86,7 +81,64 @@ export default {
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
};
|
||||
},
|
||||
renderLabeledInput(children) {
|
||||
|
||||
setValue(value, e) {
|
||||
// https://github.com/vueComponent/ant-design-vue/issues/92
|
||||
if (isIE && !isIE9 && this.stateValue === value) {
|
||||
return;
|
||||
}
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.stateValue = value;
|
||||
} else {
|
||||
this.$forceUpdate();
|
||||
}
|
||||
if (!e.target.composing) {
|
||||
this.$emit('change.value', value);
|
||||
}
|
||||
this.$emit('change', e);
|
||||
this.$emit('input', e);
|
||||
},
|
||||
|
||||
handleReset(e) {
|
||||
this.setValue('', e);
|
||||
},
|
||||
|
||||
handleChange(e) {
|
||||
this.setValue(e.target.value, e);
|
||||
},
|
||||
|
||||
renderClearIcon(prefixCls) {
|
||||
const { allowClear } = this.$props;
|
||||
const { stateValue } = this;
|
||||
if (!allowClear || stateValue === undefined || stateValue === null || stateValue === '') {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Icon
|
||||
type="close-circle"
|
||||
theme="filled"
|
||||
onClick={this.handleReset}
|
||||
class={`${prefixCls}-clear-icon`}
|
||||
role="button"
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
renderSuffix(prefixCls) {
|
||||
const { allowClear } = this.$props;
|
||||
let suffix = getComponentFromProp(this, 'suffix');
|
||||
if (suffix || allowClear) {
|
||||
return (
|
||||
<span class={`${prefixCls}-suffix`}>
|
||||
{this.renderClearIcon(prefixCls)}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
renderLabeledInput(prefixCls, children) {
|
||||
const props = this.$props;
|
||||
let addonAfter = getComponentFromProp(this, 'addonAfter');
|
||||
let addonBefore = getComponentFromProp(this, 'addonBefore');
|
||||
@ -95,24 +147,24 @@ export default {
|
||||
return children;
|
||||
}
|
||||
|
||||
const wrapperClassName = `${props.prefixCls}-group`;
|
||||
const wrapperClassName = `${prefixCls}-group`;
|
||||
const addonClassName = `${wrapperClassName}-addon`;
|
||||
addonBefore = addonBefore ? <span class={addonClassName}>{addonBefore}</span> : null;
|
||||
|
||||
addonAfter = addonAfter ? <span class={addonClassName}>{addonAfter}</span> : null;
|
||||
|
||||
const className = {
|
||||
[`${props.prefixCls}-wrapper`]: true,
|
||||
const mergedWrapperClassName = {
|
||||
[`${prefixCls}-wrapper`]: true,
|
||||
[wrapperClassName]: addonBefore || addonAfter,
|
||||
};
|
||||
|
||||
const groupClassName = classNames(`${props.prefixCls}-group-wrapper`, {
|
||||
[`${props.prefixCls}-group-wrapper-sm`]: props.size === 'small',
|
||||
[`${props.prefixCls}-group-wrapper-lg`]: props.size === 'large',
|
||||
const mergedGroupClassName = classNames(`${prefixCls}-group-wrapper`, {
|
||||
[`${prefixCls}-group-wrapper-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-group-wrapper-lg`]: props.size === 'large',
|
||||
});
|
||||
return (
|
||||
<span class={groupClassName}>
|
||||
<span class={className}>
|
||||
<span class={mergedGroupClassName}>
|
||||
<span class={mergedWrapperClassName}>
|
||||
{addonBefore}
|
||||
{children}
|
||||
{addonAfter}
|
||||
@ -120,17 +172,15 @@ export default {
|
||||
</span>
|
||||
);
|
||||
},
|
||||
renderLabeledIcon(children) {
|
||||
const { prefixCls, size } = this.$props;
|
||||
let prefix = getComponentFromProp(this, 'prefix');
|
||||
let suffix = getComponentFromProp(this, 'suffix');
|
||||
if (!prefix && !suffix) {
|
||||
renderLabeledIcon(prefixCls, children) {
|
||||
const { size } = this.$props;
|
||||
let suffix = this.renderSuffix(prefixCls);
|
||||
if (!hasPrefixSuffix(this.$props)) {
|
||||
return children;
|
||||
}
|
||||
|
||||
let prefix = getComponentFromProp(this, 'prefix');
|
||||
prefix = prefix ? <span class={`${prefixCls}-prefix`}>{prefix}</span> : null;
|
||||
|
||||
suffix = suffix ? <span class={`${prefixCls}-suffix`}>{suffix}</span> : null;
|
||||
const affixWrapperCls = classNames(`${prefixCls}-affix-wrapper`, {
|
||||
[`${prefixCls}-affix-wrapper-sm`]: size === 'small',
|
||||
[`${prefixCls}-affix-wrapper-lg`]: size === 'large',
|
||||
@ -144,7 +194,7 @@ export default {
|
||||
);
|
||||
},
|
||||
|
||||
renderInput() {
|
||||
renderInput(prefixCls) {
|
||||
const otherProps = omit(this.$props, [
|
||||
'prefixCls',
|
||||
'addonBefore',
|
||||
@ -166,13 +216,13 @@ export default {
|
||||
input: handleChange,
|
||||
change: noop,
|
||||
},
|
||||
class: getInputClassName(),
|
||||
class: getInputClassName(prefixCls),
|
||||
ref: 'input',
|
||||
};
|
||||
if ($listeners['change.value']) {
|
||||
inputProps.directives = [{ name: 'ant-input' }];
|
||||
}
|
||||
return this.renderLabeledIcon(<input {...inputProps} />);
|
||||
return this.renderLabeledIcon(prefixCls,<input {...inputProps} />);
|
||||
},
|
||||
},
|
||||
render() {
|
||||
@ -194,6 +244,9 @@ export default {
|
||||
};
|
||||
return <TextArea {...textareaProps} ref="input" />;
|
||||
}
|
||||
return this.renderLabeledInput(this.renderInput());
|
||||
const { prefixCls: customizePrefixCls } = this.$props;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
return this.renderLabeledInput(prefixCls, this.renderInput(prefixCls));
|
||||
},
|
||||
};
|
||||
|
86
components/input/Password.js
Normal file
86
components/input/Password.js
Normal file
@ -0,0 +1,86 @@
|
||||
import classNames from 'classnames';
|
||||
import Input from './Input';
|
||||
import Icon from '../icon';
|
||||
import inputProps from './inputProps';
|
||||
import Button from '../button';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import { getOptionProps, getComponentFromProp, isValidElement } from '../_util/props-util';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
|
||||
const ActionMap = {
|
||||
click: 'click',
|
||||
hover: 'mouseover',
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'AInputPassword',
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change.value',
|
||||
},
|
||||
props: {
|
||||
...inputProps,
|
||||
prefixCls: PropTypes.string.def('ant-input-password'),
|
||||
inputPrefixCls: PropTypes.string.def('ant-input'),
|
||||
action: PropTypes.string.def('click'),
|
||||
visibilityToggle: PropTypes.bool.def(true),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
mixins: [BaseMixin],
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.setState({
|
||||
visible: !this.visible,
|
||||
});
|
||||
},
|
||||
getIcon() {
|
||||
const { prefixCls, action } = this.$props;
|
||||
const iconTrigger = ActionMap[action] || '';
|
||||
const iconProps = {
|
||||
props: {
|
||||
type: this.visible ? 'eye' : 'eye-invisible',
|
||||
},
|
||||
on: {
|
||||
[iconTrigger]: this.onChange,
|
||||
onMouseDown: (e) => {
|
||||
// Prevent focused state lost
|
||||
// https://github.com/ant-design/ant-design/issues/15173
|
||||
e.preventDefault();
|
||||
},
|
||||
},
|
||||
class: `${prefixCls}-icon`,
|
||||
key: 'passwordIcon',
|
||||
};
|
||||
return <Icon {...iconProps} />;
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
prefixCls,
|
||||
inputPrefixCls,
|
||||
size,
|
||||
suffix,
|
||||
visibilityToggle,
|
||||
...restProps
|
||||
} = this.$props;
|
||||
const suffixIcon = visibilityToggle && this.getIcon();
|
||||
const inputClassName = classNames(prefixCls, {
|
||||
[`${prefixCls}-${size}`]: !!size,
|
||||
});
|
||||
return (
|
||||
<Input
|
||||
{...restProps}
|
||||
type={this.visible ? 'text' : 'password'}
|
||||
size={size}
|
||||
class={inputClassName}
|
||||
prefixCls={inputPrefixCls}
|
||||
suffix={suffixIcon}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
@ -6,6 +6,7 @@ import Button from '../button';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import { getOptionProps, getComponentFromProp, isValidElement } from '../_util/props-util';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
export default {
|
||||
name: 'AInputSearch',
|
||||
@ -25,6 +26,9 @@ export default {
|
||||
},
|
||||
enterButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.string, PropTypes.object]),
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ({}) },
|
||||
},
|
||||
methods: {
|
||||
onSearch(e) {
|
||||
this.$emit('search', this.$refs.input.stateValue, e);
|
||||
@ -37,62 +41,96 @@ export default {
|
||||
blur() {
|
||||
this.$refs.input.blur();
|
||||
},
|
||||
getButtonOrIcon() {
|
||||
const { prefixCls, size, disabled } = this;
|
||||
renderSuffix(prefixCls) {
|
||||
const suffix = getComponentFromProp(this, 'suffix');
|
||||
const enterButton = getComponentFromProp(this, 'enterButton');
|
||||
if (enterButton) return suffix;
|
||||
|
||||
const node = (
|
||||
<Icon
|
||||
class={`${prefixCls}-icon`}
|
||||
type="search"
|
||||
key="searchIcon"
|
||||
onClick={this.onSearch}
|
||||
/>
|
||||
);
|
||||
|
||||
if (suffix) {
|
||||
let cloneSuffix = suffix;
|
||||
if (isValidElement(cloneSuffix) && !cloneSuffix.key) {
|
||||
cloneSuffix = cloneElement(cloneSuffix, {
|
||||
key: 'originSuffix',
|
||||
});
|
||||
}
|
||||
return [cloneSuffix, node];
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
renderAddonAfter(prefixCls) {
|
||||
const { size, disabled } = this;
|
||||
const enterButton = getComponentFromProp(this, 'enterButton');
|
||||
const addonAfter = getComponentFromProp(this, 'addonAfter');
|
||||
if(!enterButton) return addonAfter;
|
||||
const btnClassName = `${prefixCls}-button`;
|
||||
const enterButtonAsElement = Array.isArray(enterButton) ? enterButton[0] : enterButton;
|
||||
let node;
|
||||
if (!enterButton) {
|
||||
node = <Icon class={`${prefixCls}-icon`} type="search" key="searchIcon" />;
|
||||
} else if (
|
||||
let button;
|
||||
if (
|
||||
enterButtonAsElement.tag === 'button' ||
|
||||
(enterButtonAsElement.componentOptions &&
|
||||
enterButtonAsElement.componentOptions.Ctor.extendOptions.__ANT_BUTTON)
|
||||
) {
|
||||
node = cloneElement(enterButtonAsElement, {
|
||||
class: `${prefixCls}-button`,
|
||||
button = cloneElement(enterButtonAsElement, {
|
||||
class: btnClassName,
|
||||
props: { size },
|
||||
on: {
|
||||
click: this.onSearch,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
node = (
|
||||
button = (
|
||||
<Button
|
||||
class={`${prefixCls}-button`}
|
||||
class={btnClassName}
|
||||
type="primary"
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
key="enterButton"
|
||||
onClick={this.onSearch}
|
||||
>
|
||||
{enterButton === true ? <Icon type="search" /> : enterButton}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return cloneElement(node, {
|
||||
on: {
|
||||
click: this.onSearch,
|
||||
},
|
||||
});
|
||||
if (addonAfter) {
|
||||
return [button, addonAfter];
|
||||
}
|
||||
|
||||
return button;
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const { prefixCls, inputPrefixCls, size, ...others } = getOptionProps(this);
|
||||
const suffix = getComponentFromProp(this, 'suffix');
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
inputPrefixCls: customizeInputPrefixCls,
|
||||
size,
|
||||
...others
|
||||
} = getOptionProps(this);
|
||||
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('input-search', customizePrefixCls);
|
||||
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
|
||||
|
||||
const enterButton = getComponentFromProp(this, 'enterButton');
|
||||
const addonAfter = getComponentFromProp(this, 'addonAfter');
|
||||
const addonBefore = getComponentFromProp(this, 'addonBefore');
|
||||
const buttonOrIcon = this.getButtonOrIcon();
|
||||
let searchSuffix = suffix ? [suffix, buttonOrIcon] : buttonOrIcon;
|
||||
if (Array.isArray(searchSuffix)) {
|
||||
searchSuffix = searchSuffix.map((item, index) => {
|
||||
if (!isValidElement(item) || item.key) {
|
||||
return item;
|
||||
}
|
||||
return cloneElement(item, { key: index });
|
||||
let inputClassName;
|
||||
if(enterButton) {
|
||||
inputClassName = classNames(prefixCls, {
|
||||
[`${prefixCls}-enter-button`]: !!enterButton,
|
||||
[`${prefixCls}-${size}`]: !!size,
|
||||
});
|
||||
} else {
|
||||
inputClassName = prefixCls;
|
||||
}
|
||||
const inputClassName = classNames(prefixCls, {
|
||||
[`${prefixCls}-enter-button`]: !!enterButton,
|
||||
[`${prefixCls}-${size}`]: !!size,
|
||||
});
|
||||
|
||||
const on = { ...this.$listeners };
|
||||
delete on.search;
|
||||
const inputProps = {
|
||||
@ -100,16 +138,18 @@ export default {
|
||||
...others,
|
||||
prefixCls: inputPrefixCls,
|
||||
size,
|
||||
suffix: searchSuffix,
|
||||
addonAfter,
|
||||
suffix: this.renderSuffix(prefixCls),
|
||||
addonAfter: this.renderAddonAfter(prefixCls),
|
||||
addonBefore,
|
||||
},
|
||||
attrs: this.$attrs,
|
||||
class: inputClassName,
|
||||
ref: 'input',
|
||||
on: {
|
||||
pressEnter: this.onSearch,
|
||||
...on,
|
||||
},
|
||||
};
|
||||
return <Input {...inputProps} class={inputClassName} ref="input" />;
|
||||
return <Input {...inputProps} />;
|
||||
},
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
import inputProps from './inputProps';
|
||||
import calculateNodeHeight from './calculateNodeHeight';
|
||||
import hasProp from '../_util/props-util';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
function onNextFrame(cb) {
|
||||
if (window.requestAnimationFrame) {
|
||||
@ -36,6 +38,9 @@ export default {
|
||||
...inputProps,
|
||||
autosize: [Object, Boolean],
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ({}) },
|
||||
},
|
||||
data() {
|
||||
const { value, defaultValue } = this.$props;
|
||||
return {
|
||||
@ -105,20 +110,11 @@ export default {
|
||||
if (!autosize || !this.$refs.textArea) {
|
||||
return;
|
||||
}
|
||||
const minRows = autosize ? autosize.minRows : null;
|
||||
const maxRows = autosize ? autosize.maxRows : null;
|
||||
const { minRows, maxRows } = autosize;
|
||||
const textareaStyles = calculateNodeHeight(this.$refs.textArea, false, minRows, maxRows);
|
||||
this.textareaStyles = textareaStyles;
|
||||
},
|
||||
|
||||
getTextAreaClassName() {
|
||||
const { prefixCls, disabled } = this.$props;
|
||||
return {
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
};
|
||||
},
|
||||
|
||||
handleTextareaChange(e) {
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.stateValue = e.target.value;
|
||||
@ -144,12 +140,13 @@ export default {
|
||||
render() {
|
||||
const {
|
||||
stateValue,
|
||||
getTextAreaClassName,
|
||||
handleKeyDown,
|
||||
handleTextareaChange,
|
||||
textareaStyles,
|
||||
$attrs,
|
||||
$listeners,
|
||||
prefixCls: customizePrefixCls,
|
||||
disabled,
|
||||
} = this;
|
||||
const otherProps = omit(this.$props, [
|
||||
'prefixCls',
|
||||
@ -158,6 +155,13 @@ export default {
|
||||
'value',
|
||||
'defaultValue',
|
||||
]);
|
||||
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
|
||||
const cls = classNames(prefixCls, {
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
|
||||
const textareaProps = {
|
||||
attrs: { ...otherProps, ...$attrs },
|
||||
on: {
|
||||
@ -174,7 +178,7 @@ export default {
|
||||
<textarea
|
||||
{...textareaProps}
|
||||
value={stateValue}
|
||||
class={getTextAreaClassName()}
|
||||
class={cls}
|
||||
style={textareaStyles}
|
||||
ref="textArea"
|
||||
/>
|
||||
|
@ -24,6 +24,7 @@ const SIZING_STYLE = [
|
||||
'font-family',
|
||||
'font-weight',
|
||||
'font-size',
|
||||
'font-variant',
|
||||
'text-rendering',
|
||||
'text-transform',
|
||||
'width',
|
||||
@ -37,7 +38,7 @@ const SIZING_STYLE = [
|
||||
const computedStyleCache = {};
|
||||
let hiddenTextarea;
|
||||
|
||||
function calculateNodeStyling(node, useCache = false) {
|
||||
export function calculateNodeStyling(node, useCache = false) {
|
||||
const nodeRef =
|
||||
node.getAttribute('id') || node.getAttribute('data-reactid') || node.getAttribute('name');
|
||||
|
||||
|
24
components/input/demo/allowClear.md
Normal file
24
components/input/demo/allowClear.md
Normal file
@ -0,0 +1,24 @@
|
||||
<cn>
|
||||
#### 带移除图标
|
||||
带移除图标的输入框,点击图标删除所有内容。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### With clear icon
|
||||
Input type of password.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-input placeholder="input with clear icon" allowClear @change="onChange" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onChange(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
@ -14,12 +14,14 @@ Note: You don't need `Col` to control the width in the `compact` mode.
|
||||
<template>
|
||||
<div>
|
||||
<a-input-group size="large">
|
||||
<a-col :span="5">
|
||||
<a-input defaultValue="0571" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-input defaultValue="26888888" />
|
||||
</a-col>
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="5">
|
||||
<a-input defaultValue="0571" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-input defaultValue="26888888" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-input-group>
|
||||
<br />
|
||||
<a-input-group compact>
|
||||
@ -45,7 +47,7 @@ Note: You don't need `Col` to control the width in the `compact` mode.
|
||||
<br />
|
||||
<a-input-group compact>
|
||||
<a-input style="width: 50%" defaultValue="input content" />
|
||||
<a-date-picker />
|
||||
<a-date-picker style="width: 50%" />
|
||||
</a-input-group>
|
||||
<br />
|
||||
<a-input-group compact>
|
||||
|
@ -6,6 +6,8 @@ import SearchInput from './search-input';
|
||||
import Size from './size';
|
||||
import Group from './group';
|
||||
import TextArea from './textarea';
|
||||
import AllowClear from './allowClear';
|
||||
import PasswordInput from './password-input';
|
||||
import Addon from './addon';
|
||||
import Tooltip from './tooltip';
|
||||
import CN from '../index.zh-CN.md';
|
||||
@ -22,7 +24,7 @@ const md = {
|
||||
Keyboard and mouse can be used for providing or changing data.
|
||||
## When To Use
|
||||
- A user input in a form field is needed.
|
||||
- A search input is required.
|
||||
- A search input is required.
|
||||
## Examples `,
|
||||
};
|
||||
export default {
|
||||
@ -43,6 +45,8 @@ export default {
|
||||
<TextArea />
|
||||
<Addon />
|
||||
<Tooltip />
|
||||
<AllowClear />
|
||||
<PasswordInput />
|
||||
<api>
|
||||
<CN slot='cn' />
|
||||
<US/>
|
||||
|
15
components/input/demo/password-input.md
Normal file
15
components/input/demo/password-input.md
Normal file
@ -0,0 +1,15 @@
|
||||
<cn>
|
||||
#### 密码框
|
||||
密码框,版本 1.4.0 中新增。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Password box
|
||||
Input type of password and added in 1.4.0.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-input-password placeholder="input password" />
|
||||
</template>
|
||||
```
|
@ -11,7 +11,7 @@ For multi-line input.
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<a-button @click="() => this.autoResize = !autoResize">
|
||||
<a-button style="margin-bottom: 16px" @click="() => this.autoResize = !autoResize">
|
||||
Auto Resize: {String(autoResize)}
|
||||
</a-button>
|
||||
<a-textarea :rows="4" :autosize="autoResize" :defaultValue="defaultValue" />
|
||||
|
@ -15,6 +15,7 @@
|
||||
| suffix | The suffix icon for the Input. | string\|slot | |
|
||||
| type | The type of input, see: [MDN](https://developer.mozilla.org/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types)(use `Input.TextArea` instead of `type="textarea"`) | string | `text` |
|
||||
| value(v-model) | The input content value | string | |
|
||||
| allowClear | allow to remove input content with clear icon | boolean | |
|
||||
|
||||
### Input Events
|
||||
| Events Name | Description | Arguments |
|
||||
@ -45,7 +46,7 @@ The rest of the props of `Input.TextArea` are the same as the original [textarea
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| enterButton | to show an enter button after input | boolean\|slot | false |
|
||||
| enterButton | to show an enter button after input. This prop is conflict with addon. | boolean\|slot | false |
|
||||
|
||||
### Input.Search Events
|
||||
| Events Name | Description | Arguments |
|
||||
@ -67,3 +68,21 @@ Supports all props of `Input`.
|
||||
<a-input />
|
||||
</a-input-group>
|
||||
````
|
||||
#### Input.Password
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| visibilityToggle | Whether show toggle button | boolean | true |
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why Input lose focus when change `prefix/suffix`
|
||||
|
||||
When Input dynamic add or remove `prefix/suffix` will make Vue recreate the dom structure and new input will be not focused.
|
||||
You can set an empty `<span />` element to keep the dom structure:
|
||||
|
||||
```jsx
|
||||
const suffix = condition ? <Icon type="smile" /> : <span />;
|
||||
|
||||
<Input suffix={suffix} />
|
||||
```
|
||||
|
@ -3,6 +3,7 @@ import Input from './Input';
|
||||
import Group from './Group';
|
||||
import Search from './Search';
|
||||
import TextArea from './TextArea';
|
||||
import Password from './Password';
|
||||
import antInputDirective from '../_util/antInputDirective';
|
||||
|
||||
Vue.use(antInputDirective);
|
||||
@ -10,6 +11,7 @@ Vue.use(antInputDirective);
|
||||
Input.Group = Group;
|
||||
Input.Search = Search;
|
||||
Input.TextArea = TextArea;
|
||||
Input.Password = Password;
|
||||
|
||||
/* istanbul ignore next */
|
||||
Input.install = function(Vue) {
|
||||
@ -17,6 +19,7 @@ Input.install = function(Vue) {
|
||||
Vue.component(Input.Group.name, Input.Group);
|
||||
Vue.component(Input.Search.name, Input.Search);
|
||||
Vue.component(Input.TextArea.name, Input.TextArea);
|
||||
Vue.component(Input.Password.name, Input.Password);
|
||||
};
|
||||
|
||||
export default Input;
|
||||
|
@ -15,6 +15,7 @@
|
||||
| suffix | 带有后缀图标的 input | string\|slot | |
|
||||
| type | 声明 input 类型,同原生 input 标签的 type 属性,见:[MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input#属性)(请直接使用 `Input.TextArea` 代替 `type="textarea"`)。 | string | `text` |
|
||||
| value(v-model) | 输入框内容 | string | |
|
||||
| allowClear | 可以点击清除图标删除内容 | boolean | |
|
||||
|
||||
### Input 事件
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
@ -44,7 +45,7 @@
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| enterButton | 是否有确认按钮,可设为按钮文字 | boolean\|slot | false |
|
||||
| enterButton | 是否有确认按钮,可设为按钮文字。该属性会与 addon 冲突。 | boolean\|slot | false |
|
||||
|
||||
### Input.Search 事件
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
@ -66,3 +67,22 @@
|
||||
<a-input />
|
||||
</a-input-group>
|
||||
````
|
||||
|
||||
|
||||
#### Input.Password
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| visibilityToggle | 是否显示切换按钮 | boolean | true |
|
||||
|
||||
## FAQ
|
||||
|
||||
### 为什么我动态改变 `prefix/suffix` 时,Input 会失去焦点?
|
||||
|
||||
当 Input 动态添加或者删除 `prefix/suffix` 时,Vue 会重新创建 DOM 结构而新的 input 是没有焦点的。
|
||||
你可以预设一个空的 `<span />` 来保持 DOM 结构不变:
|
||||
|
||||
```jsx
|
||||
const suffix = condition ? <Icon type="smile" /> : <span />;
|
||||
|
||||
<Input suffix={suffix} />
|
||||
```
|
||||
|
@ -1,7 +1,6 @@
|
||||
import PropTypes from '../_util/vue-types';
|
||||
export default {
|
||||
prefixCls: {
|
||||
default: 'ant-input',
|
||||
type: String,
|
||||
},
|
||||
defaultValue: [String, Number],
|
||||
@ -34,4 +33,5 @@ export default {
|
||||
suffix: PropTypes.any,
|
||||
spellCheck: Boolean,
|
||||
autoFocus: Boolean,
|
||||
allowClear: Boolean,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user