refactor: input
parent
7ec6831508
commit
5543ce6add
|
@ -39,7 +39,7 @@ export default defineComponent({
|
||||||
addonAfter: PropTypes.any,
|
addonAfter: PropTypes.any,
|
||||||
readonly: PropTypes.looseBool,
|
readonly: PropTypes.looseBool,
|
||||||
focused: PropTypes.looseBool,
|
focused: PropTypes.looseBool,
|
||||||
bordered: PropTypes.looseBool,
|
bordered: PropTypes.looseBool.def(true),
|
||||||
triggerFocus: { type: Function as PropType<() => void> },
|
triggerFocus: { type: Function as PropType<() => void> },
|
||||||
},
|
},
|
||||||
setup(props, { slots, attrs }) {
|
setup(props, { slots, attrs }) {
|
||||||
|
@ -51,7 +51,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const renderClearIcon = (prefixCls: string) => {
|
const renderClearIcon = (prefixCls: string) => {
|
||||||
const { allowClear, value, disabled, readonly, handleReset } = props;
|
const { allowClear, value, disabled, readonly, handleReset, suffix = slots.suffix } = props;
|
||||||
if (!allowClear) {
|
if (!allowClear) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -60,9 +60,12 @@ export default defineComponent({
|
||||||
return (
|
return (
|
||||||
<CloseCircleFilled
|
<CloseCircleFilled
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
|
// Do not trigger onBlur when clear input
|
||||||
|
onMousedown={e => e.preventDefault()}
|
||||||
class={classNames(
|
class={classNames(
|
||||||
{
|
{
|
||||||
[`${className}-hidden`]: !needClear,
|
[`${className}-hidden`]: !needClear,
|
||||||
|
[`${className}-has-suffix`]: !!suffix,
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -29,7 +29,6 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
const {} = props;
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
class={cls.value}
|
class={cls.value}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { useInjectFormItemContext } from '../form/FormItemContext';
|
||||||
import omit from '../_util/omit';
|
import omit from '../_util/omit';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
import type { ChangeEvent, FocusEventHandler } from '../_util/EventInterface';
|
import type { ChangeEvent, FocusEventHandler } from '../_util/EventInterface';
|
||||||
import { controlDefaultValue } from '../_util/util';
|
|
||||||
|
|
||||||
export function fixControlledValue(value: string | number) {
|
export function fixControlledValue(value: string | number) {
|
||||||
if (typeof value === 'undefined' || value === null) {
|
if (typeof value === 'undefined' || value === null) {
|
||||||
|
@ -134,13 +133,21 @@ export default defineComponent({
|
||||||
let removePasswordTimeout: any;
|
let removePasswordTimeout: any;
|
||||||
const formItemContext = useInjectFormItemContext();
|
const formItemContext = useInjectFormItemContext();
|
||||||
const { direction, prefixCls, size, autocomplete } = useConfigInject('input', props);
|
const { direction, prefixCls, size, autocomplete } = useConfigInject('input', props);
|
||||||
const stateValue = ref(props.value === controlDefaultValue ? props.defaultValue : props.value);
|
const stateValue = ref(props.value === undefined ? props.defaultValue : props.value);
|
||||||
const focused = ref(false);
|
const focused = ref(false);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
() => {
|
() => {
|
||||||
if (props.value !== controlDefaultValue) {
|
if (props.value !== undefined) {
|
||||||
|
stateValue.value = props.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.disabled,
|
||||||
|
() => {
|
||||||
|
if (props.value !== undefined) {
|
||||||
stateValue.value = props.value;
|
stateValue.value = props.value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -181,7 +188,7 @@ export default defineComponent({
|
||||||
expose({
|
expose({
|
||||||
focus,
|
focus,
|
||||||
blur,
|
blur,
|
||||||
inputRef,
|
input: inputRef,
|
||||||
stateValue,
|
stateValue,
|
||||||
setSelectionRange,
|
setSelectionRange,
|
||||||
select,
|
select,
|
||||||
|
@ -217,7 +224,7 @@ export default defineComponent({
|
||||||
if (stateValue.value === value) {
|
if (stateValue.value === value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (props.value === controlDefaultValue) {
|
if (props.value === undefined) {
|
||||||
stateValue.value = value;
|
stateValue.value = value;
|
||||||
} else {
|
} else {
|
||||||
instance.update();
|
instance.update();
|
||||||
|
@ -234,9 +241,10 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (e: ChangeEvent) => {
|
const handleChange = (e: ChangeEvent) => {
|
||||||
const { value, composing, isComposing } = e.target as any;
|
const { value, composing } = e.target as any;
|
||||||
// https://github.com/vueComponent/ant-design-vue/issues/2203
|
// https://github.com/vueComponent/ant-design-vue/issues/2203
|
||||||
if (((isComposing || composing) && props.lazy) || stateValue.value === value) return;
|
if ((((e as any).isComposing || composing) && props.lazy) || stateValue.value === value)
|
||||||
|
return;
|
||||||
const newVal = e.target.value;
|
const newVal = e.target.value;
|
||||||
resolveOnChange(inputRef.value, e, triggerChange);
|
resolveOnChange(inputRef.value, e, triggerChange);
|
||||||
setValue(newVal, () => {
|
setValue(newVal, () => {
|
||||||
|
@ -270,6 +278,7 @@ export default defineComponent({
|
||||||
disabled,
|
disabled,
|
||||||
bordered = true,
|
bordered = true,
|
||||||
valueModifiers = {},
|
valueModifiers = {},
|
||||||
|
htmlSize,
|
||||||
} = props;
|
} = props;
|
||||||
const otherProps = omit(props as InputProps & { inputType: any; placeholder: string }, [
|
const otherProps = omit(props as InputProps & { inputType: any; placeholder: string }, [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
|
@ -285,9 +294,11 @@ export default defineComponent({
|
||||||
'size',
|
'size',
|
||||||
'inputType',
|
'inputType',
|
||||||
'bordered',
|
'bordered',
|
||||||
|
'htmlSize',
|
||||||
]);
|
]);
|
||||||
const inputProps = {
|
const inputProps = {
|
||||||
...otherProps,
|
...otherProps,
|
||||||
|
...attrs,
|
||||||
autocomplete: autocomplete.value,
|
autocomplete: autocomplete.value,
|
||||||
onChange: handleChange,
|
onChange: handleChange,
|
||||||
onInput: handleChange,
|
onInput: handleChange,
|
||||||
|
@ -302,6 +313,7 @@ export default defineComponent({
|
||||||
),
|
),
|
||||||
ref: inputRef,
|
ref: inputRef,
|
||||||
key: 'ant-input',
|
key: 'ant-input',
|
||||||
|
size: htmlSize,
|
||||||
};
|
};
|
||||||
if (valueModifiers.lazy) {
|
if (valueModifiers.lazy) {
|
||||||
delete inputProps.onInput;
|
delete inputProps.onInput;
|
||||||
|
@ -321,7 +333,7 @@ export default defineComponent({
|
||||||
inputType: 'input',
|
inputType: 'input',
|
||||||
value: fixControlledValue(stateValue.value),
|
value: fixControlledValue(stateValue.value),
|
||||||
handleReset,
|
handleReset,
|
||||||
focused: focused.value,
|
focused: focused.value && props.disabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,125 +1,100 @@
|
||||||
import type { PropType, VNode } from 'vue';
|
import type { CSSProperties, VNode } from 'vue';
|
||||||
import { nextTick, defineComponent, withDirectives } from 'vue';
|
import {
|
||||||
|
getCurrentInstance,
|
||||||
|
watch,
|
||||||
|
onBeforeUnmount,
|
||||||
|
ref,
|
||||||
|
nextTick,
|
||||||
|
defineComponent,
|
||||||
|
withDirectives,
|
||||||
|
} from 'vue';
|
||||||
import ResizeObserver from '../vc-resize-observer';
|
import ResizeObserver from '../vc-resize-observer';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import calculateNodeHeight from './calculateNodeHeight';
|
import calculateNodeHeight from './calculateNodeHeight';
|
||||||
import raf from '../_util/raf';
|
import raf from '../_util/raf';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import inputProps from './inputProps';
|
|
||||||
import PropTypes from '../_util/vue-types';
|
|
||||||
import { getOptionProps } from '../_util/props-util';
|
|
||||||
import antInput from '../_util/antInputDirective';
|
import antInput from '../_util/antInputDirective';
|
||||||
import omit from '../_util/omit';
|
import omit from '../_util/omit';
|
||||||
|
import { textAreaProps } from './inputProps';
|
||||||
|
|
||||||
const RESIZE_STATUS_NONE = 0;
|
const RESIZE_STATUS_NONE = 0;
|
||||||
const RESIZE_STATUS_RESIZING = 1;
|
const RESIZE_STATUS_RESIZING = 1;
|
||||||
const RESIZE_STATUS_RESIZED = 2;
|
const RESIZE_STATUS_RESIZED = 2;
|
||||||
|
|
||||||
export interface AutoSizeType {
|
|
||||||
minRows?: number;
|
|
||||||
maxRows?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TextAreaProps = {
|
|
||||||
...inputProps,
|
|
||||||
autosize: { type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined },
|
|
||||||
autoSize: { type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined },
|
|
||||||
onResize: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ResizableTextArea = defineComponent({
|
const ResizableTextArea = defineComponent({
|
||||||
name: 'ResizableTextArea',
|
name: 'ResizableTextArea',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: TextAreaProps,
|
props: textAreaProps,
|
||||||
setup() {
|
setup(props, { attrs, emit, expose }) {
|
||||||
return {
|
let nextFrameActionId: any;
|
||||||
nextFrameActionId: undefined,
|
let resizeFrameId: any;
|
||||||
textArea: null,
|
const textAreaRef = ref();
|
||||||
resizeFrameId: undefined,
|
const textareaStyles = ref({});
|
||||||
};
|
const resizeStatus = ref(RESIZE_STATUS_NONE);
|
||||||
},
|
onBeforeUnmount(() => {
|
||||||
data() {
|
raf.cancel(nextFrameActionId);
|
||||||
return {
|
raf.cancel(resizeFrameId);
|
||||||
textareaStyles: {},
|
|
||||||
resizeStatus: RESIZE_STATUS_NONE,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value() {
|
|
||||||
nextTick(() => {
|
|
||||||
this.resizeTextarea();
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.resizeTextarea();
|
|
||||||
},
|
|
||||||
beforeUnmount() {
|
|
||||||
raf.cancel(this.nextFrameActionId);
|
|
||||||
raf.cancel(this.resizeFrameId);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
saveTextArea(textArea: HTMLTextAreaElement) {
|
|
||||||
this.textArea = textArea;
|
|
||||||
},
|
|
||||||
handleResize(size: { width: number; height: number }) {
|
|
||||||
const { resizeStatus } = this.$data;
|
|
||||||
|
|
||||||
if (resizeStatus !== RESIZE_STATUS_NONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$emit('resize', size);
|
|
||||||
},
|
|
||||||
resizeOnNextFrame() {
|
|
||||||
raf.cancel(this.nextFrameActionId);
|
|
||||||
this.nextFrameActionId = raf(this.resizeTextarea);
|
|
||||||
},
|
|
||||||
|
|
||||||
resizeTextarea() {
|
|
||||||
const autoSize = this.$props.autoSize || this.$props.autosize;
|
|
||||||
if (!autoSize || !this.textArea) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { minRows, maxRows } = autoSize;
|
|
||||||
const textareaStyles = calculateNodeHeight(this.textArea, false, minRows, maxRows);
|
|
||||||
this.setState({ textareaStyles, resizeStatus: RESIZE_STATUS_RESIZING }, () => {
|
|
||||||
raf.cancel(this.resizeFrameId);
|
|
||||||
this.resizeFrameId = raf(() => {
|
|
||||||
this.setState({ resizeStatus: RESIZE_STATUS_RESIZED }, () => {
|
|
||||||
this.resizeFrameId = raf(() => {
|
|
||||||
this.setState({ resizeStatus: RESIZE_STATUS_NONE });
|
|
||||||
this.fixFirefoxAutoScroll();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// https://github.com/ant-design/ant-design/issues/21870
|
// https://github.com/ant-design/ant-design/issues/21870
|
||||||
fixFirefoxAutoScroll() {
|
const fixFirefoxAutoScroll = () => {
|
||||||
try {
|
try {
|
||||||
if (document.activeElement === this.textArea) {
|
if (document.activeElement === textAreaRef.value) {
|
||||||
const currentStart = this.textArea.selectionStart;
|
const currentStart = textAreaRef.value.selectionStart;
|
||||||
const currentEnd = this.textArea.selectionEnd;
|
const currentEnd = textAreaRef.value.selectionEnd;
|
||||||
this.textArea.setSelectionRange(currentStart, currentEnd);
|
textAreaRef.value.setSelectionRange(currentStart, currentEnd);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Fix error in Chrome:
|
// Fix error in Chrome:
|
||||||
// Failed to read the 'selectionStart' property from 'HTMLInputElement'
|
// Failed to read the 'selectionStart' property from 'HTMLInputElement'
|
||||||
// http://stackoverflow.com/q/21177489/3040605
|
// http://stackoverflow.com/q/21177489/3040605
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
renderTextArea() {
|
const resizeTextarea = () => {
|
||||||
const props: any = { ...getOptionProps(this), ...this.$attrs };
|
const autoSize = props.autoSize || props.autosize;
|
||||||
const { prefixCls, autoSize, autosize, disabled, class: className } = props;
|
if (!autoSize || !textAreaRef.value) {
|
||||||
const { textareaStyles, resizeStatus } = this.$data;
|
return;
|
||||||
|
}
|
||||||
|
const { minRows, maxRows } = autoSize;
|
||||||
|
textareaStyles.value = calculateNodeHeight(textAreaRef.value, false, minRows, maxRows);
|
||||||
|
resizeStatus.value = RESIZE_STATUS_RESIZING;
|
||||||
|
raf.cancel(resizeFrameId);
|
||||||
|
resizeFrameId = raf(() => {
|
||||||
|
resizeStatus.value = RESIZE_STATUS_RESIZED;
|
||||||
|
resizeFrameId = raf(() => {
|
||||||
|
resizeStatus.value = RESIZE_STATUS_NONE;
|
||||||
|
fixFirefoxAutoScroll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const resizeOnNextFrame = () => {
|
||||||
|
raf.cancel(nextFrameActionId);
|
||||||
|
nextFrameActionId = raf(resizeTextarea);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResize = (size: { width: number; height: number }) => {
|
||||||
|
if (resizeStatus.value !== RESIZE_STATUS_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit('resize', size);
|
||||||
|
|
||||||
|
const autoSize = props.autoSize || props.autosize;
|
||||||
|
if (autoSize) {
|
||||||
|
resizeOnNextFrame();
|
||||||
|
}
|
||||||
|
};
|
||||||
warning(
|
warning(
|
||||||
autosize === undefined,
|
props.autosize === undefined,
|
||||||
'Input.TextArea',
|
'Input.TextArea',
|
||||||
'autosize is deprecated, please use autoSize instead.',
|
'autosize is deprecated, please use autoSize instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const renderTextArea = () => {
|
||||||
|
const { prefixCls, autoSize, autosize, disabled } = props;
|
||||||
const otherProps = omit(props, [
|
const otherProps = omit(props, [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
'onPressEnter',
|
'onPressEnter',
|
||||||
|
@ -130,23 +105,19 @@ const ResizableTextArea = defineComponent({
|
||||||
'type',
|
'type',
|
||||||
'lazy',
|
'lazy',
|
||||||
]);
|
]);
|
||||||
const cls = classNames(prefixCls, className, {
|
const cls = classNames(prefixCls, attrs.class, {
|
||||||
[`${prefixCls}-disabled`]: disabled,
|
[`${prefixCls}-disabled`]: disabled,
|
||||||
});
|
});
|
||||||
// Fix https://github.com/ant-design/ant-design/issues/6776
|
|
||||||
// Make sure it could be reset when using form.getFieldDecorator
|
|
||||||
if ('value' in otherProps) {
|
|
||||||
otherProps.value = otherProps.value || '';
|
|
||||||
}
|
|
||||||
const style = {
|
const style = {
|
||||||
...props.style,
|
...(attrs.style as CSSProperties),
|
||||||
...textareaStyles,
|
...textareaStyles.value,
|
||||||
...(resizeStatus === RESIZE_STATUS_RESIZING
|
...(resizeStatus.value === RESIZE_STATUS_RESIZING
|
||||||
? { overflowX: 'hidden', overflowY: 'hidden' }
|
? { overflowX: 'hidden', overflowY: 'hidden' }
|
||||||
: null),
|
: null),
|
||||||
};
|
};
|
||||||
const textareaProps: any = {
|
const textareaProps: any = {
|
||||||
...otherProps,
|
...otherProps,
|
||||||
|
...attrs,
|
||||||
style,
|
style,
|
||||||
class: cls,
|
class: cls,
|
||||||
};
|
};
|
||||||
|
@ -154,17 +125,32 @@ const ResizableTextArea = defineComponent({
|
||||||
delete textareaProps.autofocus;
|
delete textareaProps.autofocus;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ResizeObserver onResize={this.handleResize} disabled={!(autoSize || autosize)}>
|
<ResizeObserver onResize={handleResize} disabled={!(autoSize || autosize)}>
|
||||||
{withDirectives((<textarea {...textareaProps} ref={this.saveTextArea} />) as VNode, [
|
{withDirectives((<textarea {...textareaProps} ref={textAreaRef} />) as VNode, [
|
||||||
[antInput],
|
[antInput],
|
||||||
])}
|
])}
|
||||||
</ResizeObserver>
|
</ResizeObserver>
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
watch(
|
||||||
return this.renderTextArea();
|
() => props.value,
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
resizeTextarea();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
expose({
|
||||||
|
resizeTextarea,
|
||||||
|
textArea: textAreaRef,
|
||||||
|
instance,
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return renderTextArea();
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMousedown: MouseEventHandler = e => {
|
const onMousedown: MouseEventHandler = e => {
|
||||||
if (document.activeElement === inputRef.value?.inputRef.value) {
|
if (document.activeElement === inputRef.value?.input) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -84,7 +84,9 @@ export default defineComponent({
|
||||||
enterButtonAsElement.type.__ANT_BUTTON;
|
enterButtonAsElement.type.__ANT_BUTTON;
|
||||||
|
|
||||||
if (isAntdButton || enterButtonAsElement.tagName === 'button') {
|
if (isAntdButton || enterButtonAsElement.tagName === 'button') {
|
||||||
button = cloneElement(enterButtonAsElement, {
|
button = cloneElement(
|
||||||
|
enterButtonAsElement,
|
||||||
|
{
|
||||||
onMousedown,
|
onMousedown,
|
||||||
onClick: onSearch,
|
onClick: onSearch,
|
||||||
key: 'enterButton',
|
key: 'enterButton',
|
||||||
|
@ -94,7 +96,9 @@ export default defineComponent({
|
||||||
size: size.value,
|
size: size.value,
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
});
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
button = (
|
button = (
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -1,175 +1,209 @@
|
||||||
import { defineComponent, inject, nextTick } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
defineComponent,
|
||||||
|
getCurrentInstance,
|
||||||
|
nextTick,
|
||||||
|
onMounted,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
watchEffect,
|
||||||
|
} from 'vue';
|
||||||
import ClearableLabeledInput from './ClearableLabeledInput';
|
import ClearableLabeledInput from './ClearableLabeledInput';
|
||||||
import ResizableTextArea from './ResizableTextArea';
|
import ResizableTextArea from './ResizableTextArea';
|
||||||
import inputProps from './inputProps';
|
import { textAreaProps } from './inputProps';
|
||||||
import { hasProp, getOptionProps } from '../_util/props-util';
|
import type { InputFocusOptions } from './Input';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { fixControlledValue, resolveOnChange, triggerFocus } from './Input';
|
||||||
import { fixControlledValue, resolveOnChange } from './Input';
|
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
|
||||||
import { useInjectFormItemContext } from '../form/FormItemContext';
|
import { useInjectFormItemContext } from '../form/FormItemContext';
|
||||||
|
import type { FocusEventHandler } from '../_util/EventInterface';
|
||||||
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
import omit from '../_util/omit';
|
||||||
|
|
||||||
const TextAreaProps = {
|
function fixEmojiLength(value: string, maxLength: number) {
|
||||||
...inputProps,
|
return [...(value || '')].slice(0, maxLength).join('');
|
||||||
autosize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
}
|
||||||
autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
|
|
||||||
showCount: PropTypes.looseBool,
|
|
||||||
onCompositionstart: PropTypes.func,
|
|
||||||
onCompositionend: PropTypes.func,
|
|
||||||
valueModifiers: Object,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ATextarea',
|
name: 'ATextarea',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: textAreaProps,
|
||||||
...TextAreaProps,
|
setup(props, { attrs, expose, emit }) {
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const formItemContext = useInjectFormItemContext();
|
const formItemContext = useInjectFormItemContext();
|
||||||
return {
|
const stateValue = ref(props.value === undefined ? props.defaultValue : props.value);
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
const resizableTextArea = ref();
|
||||||
resizableTextArea: null,
|
const { prefixCls, size, direction } = useConfigInject('input', props);
|
||||||
clearableInput: null,
|
const showCount = computed(() => {
|
||||||
formItemContext,
|
return (props.showCount as any) === '' || props.showCount || false;
|
||||||
};
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
const value = typeof this.value === 'undefined' ? this.defaultValue : this.value;
|
|
||||||
return {
|
|
||||||
stateValue: typeof value === 'undefined' ? '' : value,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
value(val: string) {
|
|
||||||
this.stateValue = val;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
nextTick(() => {
|
|
||||||
if (process.env.NODE_ENV === 'test') {
|
|
||||||
if (this.autofocus) {
|
|
||||||
this.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
// Max length value
|
||||||
|
const hasMaxLength = computed(() => Number(props.maxlength) > 0);
|
||||||
|
const compositing = ref(false);
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
() => {
|
||||||
|
if ('value' in instance.vnode.props || {}) {
|
||||||
|
stateValue.value = props.value ?? '';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
);
|
||||||
setValue(value: string, callback?: Function) {
|
|
||||||
if (!hasProp(this, 'value')) {
|
const focus = (option?: InputFocusOptions) => {
|
||||||
this.stateValue = value;
|
triggerFocus(resizableTextArea.value?.textArea, option);
|
||||||
|
};
|
||||||
|
|
||||||
|
const blur = () => {
|
||||||
|
resizableTextArea.value?.textArea?.blur();
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = (value: string | number, callback?: Function) => {
|
||||||
|
if (stateValue.value === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (props.value === undefined) {
|
||||||
|
stateValue.value = value;
|
||||||
} else {
|
} else {
|
||||||
(this as any).$forceUpdate();
|
resizableTextArea.value?.instance.update?.();
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
callback && callback();
|
callback && callback();
|
||||||
});
|
});
|
||||||
},
|
|
||||||
handleKeyDown(e: KeyboardEvent) {
|
|
||||||
if (e.keyCode === 13) {
|
|
||||||
this.$emit('pressEnter', e);
|
|
||||||
}
|
|
||||||
this.$emit('keydown', e);
|
|
||||||
},
|
|
||||||
triggerChange(e: Event) {
|
|
||||||
this.$emit('update:value', (e.target as any).value);
|
|
||||||
this.$emit('change', e);
|
|
||||||
this.$emit('input', e);
|
|
||||||
this.formItemContext.onFieldChange();
|
|
||||||
},
|
|
||||||
handleChange(e: Event) {
|
|
||||||
const { value, composing, isComposing } = e.target as any;
|
|
||||||
if (((isComposing || composing) && this.lazy) || this.stateValue === value) return;
|
|
||||||
|
|
||||||
this.setValue((e.target as HTMLTextAreaElement).value, () => {
|
|
||||||
this.resizableTextArea?.resizeTextarea();
|
|
||||||
});
|
|
||||||
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
|
||||||
},
|
|
||||||
|
|
||||||
focus() {
|
|
||||||
this.resizableTextArea.textArea.focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
blur() {
|
|
||||||
this.resizableTextArea.textArea.blur();
|
|
||||||
},
|
|
||||||
saveTextArea(resizableTextArea: any) {
|
|
||||||
this.resizableTextArea = resizableTextArea;
|
|
||||||
},
|
|
||||||
|
|
||||||
saveClearableInput(clearableInput: HTMLTextAreaElement) {
|
|
||||||
this.clearableInput = clearableInput;
|
|
||||||
},
|
|
||||||
handleReset(e: Event) {
|
|
||||||
this.setValue('', () => {
|
|
||||||
this.resizableTextArea.renderTextArea();
|
|
||||||
this.focus();
|
|
||||||
});
|
|
||||||
resolveOnChange(this.resizableTextArea.textArea, e, this.triggerChange);
|
|
||||||
},
|
|
||||||
handleBlur(e: Event) {
|
|
||||||
this.$emit('blur', e);
|
|
||||||
this.formItemContext.onFieldBlur();
|
|
||||||
},
|
|
||||||
|
|
||||||
renderTextArea(prefixCls: string) {
|
|
||||||
const props = getOptionProps(this);
|
|
||||||
const { style, class: customClass } = this.$attrs;
|
|
||||||
const resizeProps = {
|
|
||||||
...props,
|
|
||||||
...this.$attrs,
|
|
||||||
style: !props.showCount && style,
|
|
||||||
class: !props.showCount && customClass,
|
|
||||||
showCount: null,
|
|
||||||
prefixCls,
|
|
||||||
onInput: this.handleChange,
|
|
||||||
onBlur: this.handleBlur,
|
|
||||||
onChange: this.handleChange,
|
|
||||||
onKeydown: this.handleKeyDown,
|
|
||||||
};
|
};
|
||||||
if (this.valueModifiers?.lazy) {
|
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
emit('pressEnter', e);
|
||||||
|
}
|
||||||
|
emit('keydown', e);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onBlur: FocusEventHandler = e => {
|
||||||
|
const { onBlur } = props;
|
||||||
|
onBlur?.(e);
|
||||||
|
formItemContext.onFieldBlur();
|
||||||
|
};
|
||||||
|
const triggerChange = (e: Event) => {
|
||||||
|
emit('update:value', (e.target as HTMLInputElement).value);
|
||||||
|
emit('change', e);
|
||||||
|
emit('input', e);
|
||||||
|
formItemContext.onFieldChange();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (e: MouseEvent) => {
|
||||||
|
resolveOnChange(resizableTextArea.value.textArea, e, triggerChange);
|
||||||
|
setValue('', () => {
|
||||||
|
focus();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (e: Event) => {
|
||||||
|
const { value, composing } = e.target as any;
|
||||||
|
compositing.value = (e as any).isComposing || composing;
|
||||||
|
if ((compositing.value && props.lazy) || stateValue.value === value) return;
|
||||||
|
let triggerValue = (e.currentTarget as any).value;
|
||||||
|
if (hasMaxLength.value) {
|
||||||
|
triggerValue = fixEmojiLength(triggerValue, props.maxlength!);
|
||||||
|
}
|
||||||
|
resolveOnChange(e.currentTarget as any, e, triggerChange, triggerValue);
|
||||||
|
setValue(triggerValue);
|
||||||
|
};
|
||||||
|
const renderTextArea = () => {
|
||||||
|
const { style, class: customClass } = attrs;
|
||||||
|
const { bordered = true } = props;
|
||||||
|
const resizeProps = {
|
||||||
|
...omit(props, ['allowClear']),
|
||||||
|
...attrs,
|
||||||
|
style: showCount.value && style,
|
||||||
|
class: {
|
||||||
|
[`${prefixCls.value}-borderless`]: !bordered,
|
||||||
|
[`${customClass}`]: customClass && !showCount.value,
|
||||||
|
[`${prefixCls.value}-sm`]: size.value === 'small',
|
||||||
|
[`${prefixCls.value}-lg`]: size.value === 'large',
|
||||||
|
},
|
||||||
|
showCount: null,
|
||||||
|
prefixCls: prefixCls.value,
|
||||||
|
onInput: handleChange,
|
||||||
|
onChange: handleChange,
|
||||||
|
onBlur,
|
||||||
|
onKeydown: handleKeyDown,
|
||||||
|
};
|
||||||
|
if (props.valueModifiers?.lazy) {
|
||||||
delete resizeProps.onInput;
|
delete resizeProps.onInput;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ResizableTextArea
|
<ResizableTextArea
|
||||||
{...resizeProps}
|
{...resizeProps}
|
||||||
id={resizeProps.id ?? this.formItemContext.id.value}
|
id={resizeProps.id ?? formItemContext.id.value}
|
||||||
ref={this.saveTextArea}
|
ref={resizableTextArea}
|
||||||
|
maxlength={props.maxlength}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
},
|
|
||||||
render() {
|
onMounted(() => {
|
||||||
const { stateValue, prefixCls: customizePrefixCls, maxlength, showCount } = this;
|
if (process.env.NODE_ENV === 'test') {
|
||||||
const { style, class: customClass } = this.$attrs;
|
if (props.autofocus) {
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
focus();
|
||||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
}
|
||||||
let value = fixControlledValue(stateValue) as string;
|
}
|
||||||
// Max length value
|
});
|
||||||
const hasMaxlength = Number(maxlength) > 0;
|
expose({
|
||||||
value = hasMaxlength ? value.slice(0, maxlength) : value;
|
focus,
|
||||||
const props: any = {
|
blur,
|
||||||
...getOptionProps(this),
|
resizableTextArea,
|
||||||
...this.$attrs,
|
});
|
||||||
prefixCls,
|
const mergedValue = ref('');
|
||||||
|
watchEffect(() => {
|
||||||
|
let val = fixControlledValue(stateValue.value) as string;
|
||||||
|
if (
|
||||||
|
!compositing.value &&
|
||||||
|
hasMaxLength.value &&
|
||||||
|
(props.value === null || props.value === undefined)
|
||||||
|
) {
|
||||||
|
// fix #27612 将value转为数组进行截取,解决 '😂'.length === 2 等emoji表情导致的截取乱码的问题
|
||||||
|
val = fixEmojiLength(val, props.maxlength);
|
||||||
|
}
|
||||||
|
mergedValue.value = val;
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
const { maxlength, bordered = true } = props;
|
||||||
|
const { style, class: customClass } = attrs;
|
||||||
|
|
||||||
|
const inputProps: any = {
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
prefixCls: prefixCls.value,
|
||||||
inputType: 'text',
|
inputType: 'text',
|
||||||
element: this.renderTextArea(prefixCls),
|
handleReset,
|
||||||
handleReset: this.handleReset,
|
direction: direction.value,
|
||||||
|
bordered,
|
||||||
|
style: showCount.value ? undefined : style,
|
||||||
};
|
};
|
||||||
|
|
||||||
let textareaNode = (
|
let textareaNode = (
|
||||||
<ClearableLabeledInput {...props} value={value} ref={this.saveClearableInput} />
|
<ClearableLabeledInput
|
||||||
|
{...inputProps}
|
||||||
|
value={mergedValue.value}
|
||||||
|
v-slots={{ element: renderTextArea }}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (showCount) {
|
if (showCount.value) {
|
||||||
const valueLength = [...value].length;
|
const valueLength = [...mergedValue.value].length;
|
||||||
const dataCount = `${valueLength}${hasMaxlength ? ` / ${maxlength}` : ''}`;
|
let dataCount = '';
|
||||||
|
if (typeof showCount.value === 'object') {
|
||||||
|
dataCount = showCount.value.formatter({ count: valueLength, maxlength });
|
||||||
|
} else {
|
||||||
|
dataCount = `${valueLength}${hasMaxLength.value ? ` / ${maxlength}` : ''}`;
|
||||||
|
}
|
||||||
textareaNode = (
|
textareaNode = (
|
||||||
<div
|
<div
|
||||||
class={classNames(
|
class={classNames(
|
||||||
`${prefixCls}-textarea`,
|
`${prefixCls.value}-textarea`,
|
||||||
`${prefixCls}-textarea-show-count`,
|
{
|
||||||
|
[`${prefixCls.value}-textarea-rtl`]: direction.value === 'rtl',
|
||||||
|
},
|
||||||
|
`${prefixCls.value}-textarea-show-count`,
|
||||||
customClass,
|
customClass,
|
||||||
)}
|
)}
|
||||||
style={style}
|
style={style}
|
||||||
|
@ -180,5 +214,6 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return textareaNode;
|
return textareaNode;
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// Thanks to https://github.com/andreypopp/react-textarea-autosize/
|
// Thanks to https://github.com/andreypopp/react-textarea-autosize/
|
||||||
|
|
||||||
|
import type { CSSProperties } from 'vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculateNodeHeight(uiTextNode, useCache = false)
|
* calculateNodeHeight(uiTextNode, useCache = false)
|
||||||
*/
|
*/
|
||||||
|
@ -33,6 +35,7 @@ const SIZING_STYLE = [
|
||||||
'padding-right',
|
'padding-right',
|
||||||
'border-width',
|
'border-width',
|
||||||
'box-sizing',
|
'box-sizing',
|
||||||
|
'word-break',
|
||||||
];
|
];
|
||||||
|
|
||||||
export interface NodeType {
|
export interface NodeType {
|
||||||
|
@ -90,9 +93,11 @@ export default function calculateNodeHeight(
|
||||||
useCache = false,
|
useCache = false,
|
||||||
minRows: number | null = null,
|
minRows: number | null = null,
|
||||||
maxRows: number | null = null,
|
maxRows: number | null = null,
|
||||||
) {
|
): CSSProperties {
|
||||||
if (!hiddenTextarea) {
|
if (!hiddenTextarea) {
|
||||||
hiddenTextarea = document.createElement('textarea');
|
hiddenTextarea = document.createElement('textarea');
|
||||||
|
hiddenTextarea.setAttribute('tab-index', '-1');
|
||||||
|
hiddenTextarea.setAttribute('aria-hidden', 'true');
|
||||||
document.body.appendChild(hiddenTextarea);
|
document.body.appendChild(hiddenTextarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +125,7 @@ export default function calculateNodeHeight(
|
||||||
let minHeight = Number.MIN_SAFE_INTEGER;
|
let minHeight = Number.MIN_SAFE_INTEGER;
|
||||||
let maxHeight = Number.MAX_SAFE_INTEGER;
|
let maxHeight = Number.MAX_SAFE_INTEGER;
|
||||||
let height = hiddenTextarea.scrollHeight;
|
let height = hiddenTextarea.scrollHeight;
|
||||||
let overflowY: string;
|
let overflowY: any;
|
||||||
|
|
||||||
if (boxSizing === 'border-box') {
|
if (boxSizing === 'border-box') {
|
||||||
// border-box: add border, since height = content + padding + border
|
// border-box: add border, since height = content + padding + border
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { ExtractPropTypes, PropType } from 'vue';
|
import type { ExtractPropTypes, PropType } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import type { SizeType } from '../config-provider';
|
import type { SizeType } from '../config-provider';
|
||||||
import { controlDefaultValue } from '../_util/util';
|
import omit from '../_util/omit';
|
||||||
export const inputDefaultValue = Symbol() as unknown as string;
|
export const inputDefaultValue = Symbol() as unknown as string;
|
||||||
const inputProps = {
|
const inputProps = {
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
|
@ -10,7 +10,7 @@ const inputProps = {
|
||||||
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
value: {
|
value: {
|
||||||
type: [String, Number, Symbol] as PropType<string | number>,
|
type: [String, Number, Symbol] as PropType<string | number>,
|
||||||
default: controlDefaultValue,
|
default: undefined,
|
||||||
},
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: [String, Number] as PropType<string | number>,
|
type: [String, Number] as PropType<string | number>,
|
||||||
|
@ -57,6 +57,7 @@ const inputProps = {
|
||||||
maxlength: PropTypes.number,
|
maxlength: PropTypes.number,
|
||||||
loading: PropTypes.looseBool,
|
loading: PropTypes.looseBool,
|
||||||
bordered: PropTypes.looseBool,
|
bordered: PropTypes.looseBool,
|
||||||
|
htmlSize: Number,
|
||||||
onPressEnter: PropTypes.func,
|
onPressEnter: PropTypes.func,
|
||||||
onKeydown: PropTypes.func,
|
onKeydown: PropTypes.func,
|
||||||
onKeyup: PropTypes.func,
|
onKeyup: PropTypes.func,
|
||||||
|
@ -69,3 +70,25 @@ const inputProps = {
|
||||||
};
|
};
|
||||||
export default inputProps;
|
export default inputProps;
|
||||||
export type InputProps = Partial<ExtractPropTypes<typeof inputProps>>;
|
export type InputProps = Partial<ExtractPropTypes<typeof inputProps>>;
|
||||||
|
|
||||||
|
export interface AutoSizeType {
|
||||||
|
minRows?: number;
|
||||||
|
maxRows?: number;
|
||||||
|
}
|
||||||
|
interface ShowCountProps {
|
||||||
|
formatter: (args: { count: number; maxlength?: number }) => string;
|
||||||
|
}
|
||||||
|
const textAreaProps = {
|
||||||
|
...omit(inputProps, ['prefix', 'addonBefore', 'addonAfter', 'suffix']),
|
||||||
|
autosize: { type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined },
|
||||||
|
autoSize: { type: [Boolean, Object] as PropType<AutoSizeType>, default: undefined },
|
||||||
|
showCount: { type: [Boolean, Object] as PropType<ShowCountProps> },
|
||||||
|
onResize: { type: Function as PropType<(size: { width: number; height: number }) => void> },
|
||||||
|
onCompositionstart: PropTypes.func,
|
||||||
|
onCompositionend: PropTypes.func,
|
||||||
|
valueModifiers: Object,
|
||||||
|
};
|
||||||
|
|
||||||
|
export { textAreaProps };
|
||||||
|
|
||||||
|
export type TextAreaProps = Partial<ExtractPropTypes<typeof textAreaProps>>;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Fix Input component height issue in IE11
|
||||||
|
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||||
|
.@{ant-prefix}-input {
|
||||||
|
height: @input-height-base;
|
||||||
|
|
||||||
|
&-lg {
|
||||||
|
height: @input-height-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-sm {
|
||||||
|
height: @input-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-affix-wrapper {
|
||||||
|
> input.@{ant-prefix}-input {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
@import './index';
|
|
||||||
@import './mixin';
|
@import './mixin';
|
||||||
|
@import (reference) '../../style/themes/index';
|
||||||
|
@input-prefix-cls: ~'@{ant-prefix}-input';
|
||||||
|
|
||||||
@input-affix-margin: 4px;
|
@input-affix-margin: 4px;
|
||||||
|
|
||||||
|
@ -8,6 +9,19 @@
|
||||||
.input();
|
.input();
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
||||||
|
&:not(&-disabled):hover {
|
||||||
|
.hover();
|
||||||
|
z-index: 1;
|
||||||
|
.@{ant-prefix}-input-search-with-button & {
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-focused,
|
||||||
|
&:focus {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&-disabled {
|
&-disabled {
|
||||||
.@{ant-prefix}-input[disabled] {
|
.@{ant-prefix}-input[disabled] {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -20,7 +34,7 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: none;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
@import (reference) '../../style/themes/index';
|
||||||
|
@input-prefix-cls: ~'@{ant-prefix}-input';
|
||||||
|
|
||||||
|
// ========================= Input =========================
|
||||||
|
.@{iconfont-css-prefix}.@{ant-prefix}-input-clear-icon {
|
||||||
|
margin: 0;
|
||||||
|
color: @disabled-color;
|
||||||
|
font-size: @font-size-sm;
|
||||||
|
vertical-align: -1px;
|
||||||
|
// https://github.com/ant-design/ant-design/pull/18151
|
||||||
|
// https://codesandbox.io/s/wizardly-sun-u10br
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @text-color-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: @text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-has-suffix {
|
||||||
|
margin: 0 @input-affix-margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================= TextArea ========================
|
||||||
|
.@{ant-prefix}-input-affix-wrapper-textarea-with-clear-btn {
|
||||||
|
padding: 0 !important;
|
||||||
|
border: 0 !important;
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-clear-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,21 @@
|
||||||
@import '../../style/themes/index';
|
@import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
@import '../../style/mixins/index';
|
||||||
@import './affix';
|
|
||||||
@import './mixin';
|
@import './mixin';
|
||||||
|
@import './affix';
|
||||||
|
@import './allow-clear';
|
||||||
|
|
||||||
|
@input-prefix-cls: ~'@{ant-prefix}-input';
|
||||||
|
|
||||||
// Input styles
|
// Input styles
|
||||||
.@{ant-prefix}-input {
|
.@{input-prefix-cls} {
|
||||||
.reset-component();
|
.reset-component();
|
||||||
.input();
|
.input();
|
||||||
}
|
|
||||||
|
|
||||||
//== Style for input-group: input with label, with button or dropdown...
|
//== Style for input-group: input with label, with button or dropdown...
|
||||||
.@{ant-prefix}-input-group {
|
&-group {
|
||||||
.reset-component();
|
.reset-component();
|
||||||
.input-group(~'@{ant-prefix}-input');
|
.input-group(~'@{input-prefix-cls}');
|
||||||
|
|
||||||
&-wrapper {
|
&-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -21,13 +24,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input with affix: prefix or suffix
|
&-password-icon {
|
||||||
.@{ant-prefix}-input-affix-wrapper {
|
|
||||||
.reset-component();
|
|
||||||
.input-affix-wrapper(~'@{ant-prefix}-input');
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{ant-prefix}-input-password-icon {
|
|
||||||
color: @text-color-secondary;
|
color: @text-color-secondary;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
|
@ -37,41 +34,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{ant-prefix}-input-clear-icon {
|
&[type='color'] {
|
||||||
.clear-icon();
|
height: @input-height-base;
|
||||||
vertical-align: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{ant-prefix}-input-clear-icon-hidden {
|
&.@{input-prefix-cls}-lg {
|
||||||
visibility: hidden;
|
height: @input-height-lg;
|
||||||
}
|
}
|
||||||
|
&.@{input-prefix-cls}-sm {
|
||||||
.@{ant-prefix}-input-textarea-clear-icon-hidden {
|
height: @input-height-sm;
|
||||||
visibility: hidden;
|
padding-top: 3px;
|
||||||
}
|
padding-bottom: 3px;
|
||||||
|
|
||||||
.@{ant-prefix}-input-affix-wrapper-textarea-with-clear-btn {
|
|
||||||
padding: 0 !important;
|
|
||||||
.@{ant-prefix}-input {
|
|
||||||
padding: @input-padding-vertical-base @input-padding-horizontal-base;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{ant-prefix}-input-textarea-clear-icon {
|
&-textarea-show-count {
|
||||||
.clear-icon();
|
// https://github.com/ant-design/ant-design/issues/33049
|
||||||
position: absolute;
|
> .@{input-prefix-cls} {
|
||||||
top: 0;
|
height: 100%;
|
||||||
right: 0;
|
|
||||||
margin: 8px 8px 0 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{ant-prefix}-input-textarea {
|
&::after {
|
||||||
&-show-count::after {
|
float: right;
|
||||||
display: block;
|
|
||||||
color: @text-color-secondary;
|
color: @text-color-secondary;
|
||||||
text-align: right;
|
white-space: nowrap;
|
||||||
content: attr(data-count);
|
content: attr(data-count);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './search-input';
|
@import './search-input';
|
||||||
|
@import './rtl';
|
||||||
|
@import './IE11';
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
@import '../../style/themes/index';
|
@import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
@input-affix-margin: 4px;
|
|
||||||
@input-affix-width: 19px;
|
|
||||||
@input-affix-with-clear-btn-width: 38px;
|
@input-affix-with-clear-btn-width: 38px;
|
||||||
|
|
||||||
// size mixins for input
|
// size mixins for input
|
||||||
|
@ -16,23 +14,37 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// input status
|
// input status
|
||||||
// == when focus or actived
|
// == when focus or active
|
||||||
.active(@color: @outline-color) {
|
.active(@borderColor: @primary-color; @hoverBorderColor: @primary-color-hover; @outlineColor: @primary-color-outline) {
|
||||||
border-color: ~`colorPalette('@{color}', 5) `;
|
& when (@theme = dark) {
|
||||||
|
border-color: @borderColor;
|
||||||
|
}
|
||||||
|
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||||
|
border-color: @hoverBorderColor;
|
||||||
|
}
|
||||||
|
& when not (@theme = variable) {
|
||||||
|
box-shadow: @input-outline-offset @outline-blur-size @outline-width
|
||||||
|
fade(@borderColor, @outline-fade);
|
||||||
|
}
|
||||||
|
& when (@theme = variable) {
|
||||||
|
border-color: @hoverBorderColor;
|
||||||
|
box-shadow: @input-outline-offset @outline-blur-size @outline-width @outlineColor;
|
||||||
|
}
|
||||||
border-right-width: @border-width-base !important;
|
border-right-width: @border-width-base !important;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
box-shadow: @input-outline-offset @outline-blur-size @outline-width fade(@color, 20%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// == when hoverd
|
// == when hover
|
||||||
.hover(@color: @input-hover-border-color) {
|
.hover(@color: @input-hover-border-color) {
|
||||||
border-color: @color;
|
border-color: @color;
|
||||||
border-right-width: @border-width-base !important;
|
border-right-width: @border-width-base !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled() {
|
.disabled() {
|
||||||
color: @disabled-color;
|
color: @input-disabled-color;
|
||||||
background-color: @input-disabled-bg;
|
background-color: @input-disabled-bg;
|
||||||
|
border-color: @input-border-color;
|
||||||
|
box-shadow: none;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
|
@ -46,6 +58,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
padding: @input-padding-vertical-base @input-padding-horizontal-base;
|
padding: @input-padding-vertical-base @input-padding-horizontal-base;
|
||||||
color: @input-color;
|
color: @input-color;
|
||||||
font-size: @font-size-base;
|
font-size: @font-size-base;
|
||||||
|
@ -61,7 +74,8 @@
|
||||||
.hover();
|
.hover();
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus,
|
||||||
|
&-focused {
|
||||||
.active();
|
.active();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +87,19 @@
|
||||||
.disabled();
|
.disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-borderless {
|
||||||
|
&,
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&-focused,
|
||||||
|
&-disabled,
|
||||||
|
&[disabled] {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reset height for `textarea`s
|
// Reset height for `textarea`s
|
||||||
textarea& {
|
textarea& {
|
||||||
max-width: 100%; // prevent textearea resize from coming out of its container
|
max-width: 100%; // prevent textearea resize from coming out of its container
|
||||||
|
@ -151,6 +178,9 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
border-right-width: 1px;
|
border-right-width: 1px;
|
||||||
|
.@{ant-prefix}-input-search-with-button & {
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,15 +215,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand addon icon click area
|
// https://github.com/ant-design/ant-design/issues/31333
|
||||||
// https://github.com/ant-design/ant-design/issues/3714
|
.@{ant-prefix}-cascader-picker {
|
||||||
> i:only-child::after {
|
margin: -9px (-@control-padding-horizontal);
|
||||||
position: absolute;
|
background-color: transparent;
|
||||||
top: 0;
|
.@{ant-prefix}-cascader-input {
|
||||||
right: 0;
|
text-align: left;
|
||||||
bottom: 0;
|
border: 0;
|
||||||
left: 0;
|
box-shadow: none;
|
||||||
content: '';
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +292,23 @@
|
||||||
height: @input-height-sm;
|
height: @input-height-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{inputClass}-affix-wrapper {
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
.@{ant-prefix}-input-search & {
|
||||||
|
border-top-left-radius: @border-radius-base;
|
||||||
|
border-bottom-left-radius: @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:first-child),
|
||||||
|
.@{ant-prefix}-input-search &:not(:first-child) {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&&-compact {
|
&&-compact {
|
||||||
display: block;
|
display: block;
|
||||||
.clearfix();
|
.clearfix();
|
||||||
|
@ -293,6 +340,10 @@
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > .@{ant-prefix}-picker-range {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
& > *:not(:last-child) {
|
& > *:not(:last-child) {
|
||||||
margin-right: -@border-width-base;
|
margin-right: -@border-width-base;
|
||||||
border-right-width: @border-width-base;
|
border-right-width: @border-width-base;
|
||||||
|
@ -305,11 +356,8 @@
|
||||||
|
|
||||||
// reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker, Input
|
// reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker, Input
|
||||||
& > .@{ant-prefix}-select > .@{ant-prefix}-select-selector,
|
& > .@{ant-prefix}-select > .@{ant-prefix}-select-selector,
|
||||||
& > .@{ant-prefix}-calendar-picker .@{ant-prefix}-input,
|
|
||||||
& > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input,
|
& > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input,
|
||||||
& > .@{ant-prefix}-cascader-picker .@{ant-prefix}-input,
|
& > .@{ant-prefix}-cascader-picker .@{ant-prefix}-input,
|
||||||
& > .@{ant-prefix}-mention-wrapper .@{ant-prefix}-mention-editor,
|
|
||||||
& > .@{ant-prefix}-time-picker .@{ant-prefix}-time-picker-input,
|
|
||||||
& > .@{ant-prefix}-input-group-wrapper .@{ant-prefix}-input {
|
& > .@{ant-prefix}-input-group-wrapper .@{ant-prefix}-input {
|
||||||
border-right-width: @border-width-base;
|
border-right-width: @border-width-base;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
@ -327,25 +375,23 @@
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update z-index for arrow icon
|
||||||
|
& > .@{ant-prefix}-select > .@{ant-prefix}-select-arrow {
|
||||||
|
z-index: 1; // https://github.com/ant-design/ant-design/issues/20371
|
||||||
|
}
|
||||||
|
|
||||||
& > *:first-child,
|
& > *:first-child,
|
||||||
& > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selector,
|
& > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selector,
|
||||||
& > .@{ant-prefix}-calendar-picker:first-child .@{ant-prefix}-input,
|
|
||||||
& > .@{ant-prefix}-select-auto-complete:first-child .@{ant-prefix}-input,
|
& > .@{ant-prefix}-select-auto-complete:first-child .@{ant-prefix}-input,
|
||||||
& > .@{ant-prefix}-cascader-picker:first-child .@{ant-prefix}-input,
|
& > .@{ant-prefix}-cascader-picker:first-child .@{ant-prefix}-input {
|
||||||
& > .@{ant-prefix}-mention-wrapper:first-child .@{ant-prefix}-mention-editor,
|
|
||||||
& > .@{ant-prefix}-time-picker:first-child .@{ant-prefix}-time-picker-input {
|
|
||||||
border-top-left-radius: @border-radius-base;
|
border-top-left-radius: @border-radius-base;
|
||||||
border-bottom-left-radius: @border-radius-base;
|
border-bottom-left-radius: @border-radius-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > *:last-child,
|
& > *:last-child,
|
||||||
& > .@{ant-prefix}-select:last-child > .@{ant-prefix}-select-selector,
|
& > .@{ant-prefix}-select:last-child > .@{ant-prefix}-select-selector,
|
||||||
& > .@{ant-prefix}-calendar-picker:last-child .@{ant-prefix}-input,
|
|
||||||
& > .@{ant-prefix}-select-auto-complete:last-child .@{ant-prefix}-input,
|
|
||||||
& > .@{ant-prefix}-cascader-picker:last-child .@{ant-prefix}-input,
|
& > .@{ant-prefix}-cascader-picker:last-child .@{ant-prefix}-input,
|
||||||
& > .@{ant-prefix}-cascader-picker-focused:last-child .@{ant-prefix}-input,
|
& > .@{ant-prefix}-cascader-picker-focused:last-child .@{ant-prefix}-input {
|
||||||
& > .@{ant-prefix}-mention-wrapper:last-child .@{ant-prefix}-mention-editor,
|
|
||||||
& > .@{ant-prefix}-time-picker:last-child .@{ant-prefix}-time-picker-input {
|
|
||||||
border-right-width: @border-width-base;
|
border-right-width: @border-width-base;
|
||||||
border-top-right-radius: @border-radius-base;
|
border-top-right-radius: @border-radius-base;
|
||||||
border-bottom-right-radius: @border-radius-base;
|
border-bottom-right-radius: @border-radius-base;
|
||||||
|
@ -355,107 +401,24 @@
|
||||||
& > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input {
|
& > .@{ant-prefix}-select-auto-complete .@{ant-prefix}-input {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-group-wrapper + .@{ant-prefix}-input-group-wrapper {
|
||||||
|
margin-left: -1px;
|
||||||
|
.@{ant-prefix}-input-affix-wrapper {
|
||||||
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-affix-wrapper(@inputClass) {
|
.@{ant-prefix}-input-group-wrapper:not(:last-child) {
|
||||||
position: relative;
|
&.@{ant-prefix}-input-search > .@{ant-prefix}-input-group {
|
||||||
display: inline-flex;
|
& > .@{ant-prefix}-input-group-addon > .@{ant-prefix}-input-search-button {
|
||||||
border: @border-width-base @border-style-base @input-border-color;
|
border-radius: 0;
|
||||||
border-radius: @border-radius-base;
|
|
||||||
padding: @input-padding-vertical-base @input-padding-horizontal-base;
|
|
||||||
width: 100%;
|
|
||||||
text-align: start;
|
|
||||||
background-color: @input-bg;
|
|
||||||
background-image: none;
|
|
||||||
color: @input-color;
|
|
||||||
font-size: @font-size-base;
|
|
||||||
line-height: @line-height-base;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.hover();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-disabled {
|
& > .@{ant-prefix}-input {
|
||||||
.disabled();
|
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||||
}
|
|
||||||
|
|
||||||
&-focused {
|
|
||||||
.active();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size
|
|
||||||
&-lg {
|
|
||||||
.input-lg();
|
|
||||||
}
|
|
||||||
|
|
||||||
&-sm {
|
|
||||||
.input-sm();
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{inputClass} {
|
|
||||||
position: relative;
|
|
||||||
text-align: inherit;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
&:focus {
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should not break align of icon & text
|
|
||||||
// https://github.com/ant-design/ant-design/issues/18087
|
|
||||||
// https://github.com/ant-design/ant-design/issues/17414
|
|
||||||
// https://github.com/ant-design/ant-design/pull/17684
|
|
||||||
// https://codesandbox.io/embed/pensive-paper-di2wk
|
|
||||||
// https://codesandbox.io/embed/nifty-benz-gb7ml
|
|
||||||
.@{inputClass}-prefix,
|
|
||||||
.@{inputClass}-suffix {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: @input-color;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
:not(.anticon) {
|
|
||||||
line-height: @line-height-base;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{inputClass}-disabled ~ .@{inputClass}-suffix {
|
|
||||||
.anticon {
|
|
||||||
color: @disabled-color;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{inputClass}-prefix {
|
|
||||||
margin-right: @input-affix-margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{inputClass}-suffix {
|
|
||||||
margin-left: @input-affix-margin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear-icon() {
|
|
||||||
color: @disabled-color;
|
|
||||||
font-size: @font-size-sm;
|
|
||||||
// https://github.com/ant-design/ant-design/pull/18151
|
|
||||||
// https://codesandbox.io/s/wizardly-sun-u10br
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.3s;
|
|
||||||
margin: 0 @input-affix-margin;
|
|
||||||
&:hover {
|
|
||||||
color: @text-color-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
color: @text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ i {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
@import '../../style/themes/index';
|
||||||
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
|
//== Style for input-group: input with label, with button or dropdown...
|
||||||
|
.@{ant-prefix}-input-group {
|
||||||
|
&-wrapper {
|
||||||
|
&-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// affix
|
||||||
|
@input-affix-margin: 4px;
|
||||||
|
|
||||||
|
.@{ant-prefix}-input {
|
||||||
|
&-affix-wrapper&-affix-wrapper-rtl {
|
||||||
|
> input.@{ant-prefix}-input {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-affix-wrapper-rtl {
|
||||||
|
.@{ant-prefix}-input-prefix {
|
||||||
|
margin: 0 0 0 @input-affix-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-suffix {
|
||||||
|
margin: 0 @input-affix-margin 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-textarea {
|
||||||
|
&-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rtl&-show-count::after {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow-clear
|
||||||
|
.@{ant-prefix}-input-clear-icon {
|
||||||
|
&-has-suffix {
|
||||||
|
.@{ant-prefix}-input-affix-wrapper-rtl & {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: @input-affix-margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-affix-wrapper-rtl & {
|
||||||
|
right: auto;
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mixin
|
||||||
|
@input-rtl-cls: ~'@{ant-prefix}-input-rtl';
|
||||||
|
|
||||||
|
.active() {
|
||||||
|
.@{input-rtl-cls} & {
|
||||||
|
border-right-width: 0;
|
||||||
|
border-left-width: @border-width-base !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover() {
|
||||||
|
.@{input-rtl-cls} & {
|
||||||
|
border-right-width: 0;
|
||||||
|
border-left-width: @border-width-base !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input() {
|
||||||
|
&-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// label input
|
||||||
|
.input-group(@inputClass) {
|
||||||
|
> .@{inputClass}-rtl:first-child,
|
||||||
|
&-rtl &-addon:first-child {
|
||||||
|
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-addon:first-child {
|
||||||
|
.@{inputClass}-group-rtl & {
|
||||||
|
border-right: @border-width-base @border-style-base @input-border-color;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-addon:last-child {
|
||||||
|
.@{inputClass}-group-rtl & {
|
||||||
|
border-right: 0;
|
||||||
|
border-left: @border-width-base @border-style-base @input-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .@{inputClass}:last-child,
|
||||||
|
&-addon:last-child {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{inputClass}-affix-wrapper {
|
||||||
|
&:not(:first-child) {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&&-compact {
|
||||||
|
& > *:not(:last-child) {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: -@border-width-base;
|
||||||
|
border-left-width: @border-width-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > *:first-child,
|
||||||
|
& > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selector,
|
||||||
|
& > .@{ant-prefix}-select-auto-complete:first-child .@{ant-prefix}-input,
|
||||||
|
& > .@{ant-prefix}-cascader-picker:first-child .@{ant-prefix}-input {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > *:last-child,
|
||||||
|
& > .@{ant-prefix}-select:last-child > .@{ant-prefix}-select-selector,
|
||||||
|
& > .@{ant-prefix}-select-auto-complete:last-child .@{ant-prefix}-input,
|
||||||
|
& > .@{ant-prefix}-cascader-picker:last-child .@{ant-prefix}-input,
|
||||||
|
& > .@{ant-prefix}-cascader-picker-focused:last-child .@{ant-prefix}-input {
|
||||||
|
.@{inputClass}-group-rtl& {
|
||||||
|
border-left-width: @border-width-base;
|
||||||
|
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-group-wrapper-rtl + .@{ant-prefix}-input-group-wrapper-rtl {
|
||||||
|
margin-right: -1px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-input-group-wrapper-rtl:not(:last-child) {
|
||||||
|
&.@{ant-prefix}-input-search > .@{ant-prefix}-input-group {
|
||||||
|
& > .@{ant-prefix}-input {
|
||||||
|
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search-input
|
||||||
|
@search-prefix: ~'@{ant-prefix}-input-search';
|
||||||
|
@search-rtl-cls: ~'@{search-prefix}-rtl';
|
||||||
|
|
||||||
|
.@{search-prefix}-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
|
||||||
|
.@{ant-prefix}-input {
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
+ .@{ant-prefix}-input-group-addon .@{search-prefix}-button:not(.@{ant-prefix}-btn-primary) {
|
||||||
|
border-right-color: @input-hover-border-color;
|
||||||
|
border-left-color: @border-color-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .@{ant-prefix}-input-group {
|
||||||
|
> .@{ant-prefix}-input-affix-wrapper {
|
||||||
|
&:hover,
|
||||||
|
&-focused {
|
||||||
|
border-right-color: @input-hover-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .@{ant-prefix}-input-group-addon {
|
||||||
|
right: -1px;
|
||||||
|
left: auto;
|
||||||
|
.@{search-prefix}-button {
|
||||||
|
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
// -------- Colors -----------
|
// -------- Colors -----------
|
||||||
@primary-color: @blue-6;
|
@primary-color: @blue-6;
|
||||||
|
@primary-color-hover: color(~`colorPalette('@{primary-color}', 5) `);
|
||||||
|
@primary-color-active: color(~`colorPalette('@{primary-color}', 7) `);
|
||||||
|
@primary-color-outline: fade(@primary-color, @outline-fade);
|
||||||
@info-color: @primary-color;
|
@info-color: @primary-color;
|
||||||
@success-color: @green-6;
|
@success-color: @green-6;
|
||||||
@processing-color: @blue-6;
|
@processing-color: @blue-6;
|
||||||
|
@ -141,6 +144,7 @@
|
||||||
@outline-blur-size: 0;
|
@outline-blur-size: 0;
|
||||||
@outline-width: 2px;
|
@outline-width: 2px;
|
||||||
@outline-color: @primary-color;
|
@outline-color: @primary-color;
|
||||||
|
@outline-fade: 20%;
|
||||||
|
|
||||||
@background-color-light: hsv(0, 0, 98%); // background of header and selected item
|
@background-color-light: hsv(0, 0, 98%); // background of header and selected item
|
||||||
@background-color-base: hsv(0, 0, 96%); // Default grey background color
|
@background-color-base: hsv(0, 0, 96%); // Default grey background color
|
||||||
|
@ -377,16 +381,26 @@
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
// ---
|
// ---
|
||||||
@input-height-base: 32px;
|
@input-height-base: @height-base;
|
||||||
@input-height-lg: 40px;
|
@input-height-lg: @height-lg;
|
||||||
@input-height-sm: 24px;
|
@input-height-sm: @height-sm;
|
||||||
@input-padding-horizontal: @control-padding-horizontal - 1px;
|
@input-padding-horizontal: @control-padding-horizontal - 1px;
|
||||||
@input-padding-horizontal-base: @input-padding-horizontal;
|
@input-padding-horizontal-base: @input-padding-horizontal;
|
||||||
@input-padding-horizontal-sm: @control-padding-horizontal-sm - 1px;
|
@input-padding-horizontal-sm: @control-padding-horizontal-sm - 1px;
|
||||||
@input-padding-horizontal-lg: @input-padding-horizontal;
|
@input-padding-horizontal-lg: @input-padding-horizontal;
|
||||||
@input-padding-vertical-base: 4px;
|
@input-padding-vertical-base: max(
|
||||||
@input-padding-vertical-sm: 0px;
|
(round(((@input-height-base - @font-size-base * @line-height-base) / 2) * 10) / 10) -
|
||||||
@input-padding-vertical-lg: 6.5px;
|
@border-width-base,
|
||||||
|
3px
|
||||||
|
);
|
||||||
|
@input-padding-vertical-sm: max(
|
||||||
|
(round(((@input-height-sm - @font-size-base * @line-height-base) / 2) * 10) / 10) -
|
||||||
|
@border-width-base,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
@input-padding-vertical-lg: (
|
||||||
|
ceil(((@input-height-lg - @font-size-lg * @line-height-base) / 2) * 10) / 10
|
||||||
|
) - @border-width-base;
|
||||||
@input-placeholder-color: hsv(0, 0, 75%);
|
@input-placeholder-color: hsv(0, 0, 75%);
|
||||||
@input-color: @text-color;
|
@input-color: @text-color;
|
||||||
@input-icon-color: @input-color;
|
@input-icon-color: @input-color;
|
||||||
|
@ -402,6 +416,7 @@
|
||||||
@input-disabled-bg: @disabled-bg;
|
@input-disabled-bg: @disabled-bg;
|
||||||
@input-outline-offset: 0 0;
|
@input-outline-offset: 0 0;
|
||||||
@input-icon-hover-color: fade(@black, 85%);
|
@input-icon-hover-color: fade(@black, 85%);
|
||||||
|
@input-disabled-color: @disabled-color;
|
||||||
|
|
||||||
// Mentions
|
// Mentions
|
||||||
// ---
|
// ---
|
||||||
|
|
Loading…
Reference in New Issue