refactor:inputnumber (#6265)
* refactor:inputnumber * docs:update & refactor: inputnumber type --------- Co-authored-by: tangjinzhou <415800467@qq.com>pull/6267/head^2
parent
321989b9c2
commit
df6a1fdb71
|
@ -2,7 +2,7 @@
|
|||
category: Components
|
||||
type: Data Entry
|
||||
title: InputNumber
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*JvWbSYhuNlIAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
Enter a number within certain range with the mouse or keyboard.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { PropType, ExtractPropTypes, HTMLAttributes, App } from 'vue';
|
||||
import type { ExtractPropTypes, HTMLAttributes, App } from 'vue';
|
||||
import { watch, defineComponent, ref, computed } from 'vue';
|
||||
import classNames from '../_util/classNames';
|
||||
import UpOutlined from '@ant-design/icons-vue/UpOutlined';
|
||||
|
@ -17,11 +17,16 @@ import PropTypes from '../_util/vue-types';
|
|||
import isValidValue from '../_util/isValidValue';
|
||||
import type { InputStatus } from '../_util/statusUtils';
|
||||
import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
|
||||
import { booleanType, stringType } from '../_util/type';
|
||||
|
||||
// CSSINJS
|
||||
import useStyle from './style';
|
||||
|
||||
const baseProps = baseInputNumberProps();
|
||||
export const inputNumberProps = () => ({
|
||||
...baseProps,
|
||||
size: { type: String as PropType<SizeType> },
|
||||
bordered: { type: Boolean, default: true },
|
||||
size: stringType<SizeType>(),
|
||||
bordered: booleanType(true),
|
||||
placeholder: String,
|
||||
name: String,
|
||||
id: String,
|
||||
|
@ -31,7 +36,7 @@ export const inputNumberProps = () => ({
|
|||
prefix: PropTypes.any,
|
||||
'onUpdate:value': baseProps.onChange,
|
||||
valueModifiers: Object,
|
||||
status: String as PropType<InputStatus>,
|
||||
status: stringType<InputStatus>(),
|
||||
});
|
||||
|
||||
export type InputNumberProps = Partial<ExtractPropTypes<ReturnType<typeof inputNumberProps>>>;
|
||||
|
@ -48,6 +53,10 @@ const InputNumber = defineComponent({
|
|||
const formItemInputContext = FormItemInputContext.useInject();
|
||||
const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
|
||||
const { prefixCls, size, direction } = useConfigInject('input-number', props);
|
||||
|
||||
// Style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
const mergedValue = ref(props.value === undefined ? props.defaultValue : props.value);
|
||||
const focused = ref(false);
|
||||
watch(
|
||||
|
@ -112,6 +121,7 @@ const InputNumber = defineComponent({
|
|||
},
|
||||
getStatusClassNames(preCls, mergedStatus.value),
|
||||
className,
|
||||
hashId.value,
|
||||
);
|
||||
|
||||
let element = (
|
||||
|
@ -153,6 +163,7 @@ const InputNumber = defineComponent({
|
|||
// className will go to addon wrapper
|
||||
[`${className}`]: !hasAddon && className,
|
||||
},
|
||||
hashId.value,
|
||||
);
|
||||
element = (
|
||||
<div
|
||||
|
@ -175,9 +186,14 @@ const InputNumber = defineComponent({
|
|||
) : null;
|
||||
const addonAfterNode = addonAfter ? <div class={addonClassName}>{addonAfter}</div> : null;
|
||||
|
||||
const mergedWrapperClassName = classNames(`${preCls}-wrapper`, wrapperClassName, {
|
||||
[`${wrapperClassName}-rtl`]: direction.value === 'rtl',
|
||||
});
|
||||
const mergedWrapperClassName = classNames(
|
||||
`${preCls}-wrapper`,
|
||||
wrapperClassName,
|
||||
{
|
||||
[`${wrapperClassName}-rtl`]: direction.value === 'rtl',
|
||||
},
|
||||
hashId.value,
|
||||
);
|
||||
|
||||
const mergedGroupClassName = classNames(
|
||||
`${preCls}-group-wrapper`,
|
||||
|
@ -188,6 +204,7 @@ const InputNumber = defineComponent({
|
|||
},
|
||||
getStatusClassNames(`${prefixCls}-group-wrapper`, mergedStatus.value, hasFeedback),
|
||||
className,
|
||||
hashId.value,
|
||||
);
|
||||
element = (
|
||||
<div class={mergedGroupClassName} style={style}>
|
||||
|
@ -199,7 +216,7 @@ const InputNumber = defineComponent({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
return cloneElement(element, { style });
|
||||
return wrapSSR(cloneElement(element, { style }));
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ category: Components
|
|||
type: 数据录入
|
||||
title: InputNumber
|
||||
subtitle: 数字输入框
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*JvWbSYhuNlIAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
通过鼠标或键盘,输入范围内的数值。
|
||||
|
|
|
@ -5,11 +5,12 @@ import StepHandler from './StepHandler';
|
|||
import { getNumberPrecision, num2str, validateNumber } from './utils/numberUtil';
|
||||
import useCursor from './hooks/useCursor';
|
||||
import useFrame from './hooks/useFrame';
|
||||
import type { HTMLAttributes, PropType } from 'vue';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
import { watch, computed, ref, defineComponent } from 'vue';
|
||||
import type { ChangeEvent, KeyboardEventHandler } from '../../_util/EventInterface';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
import classNames from '../../_util/classNames';
|
||||
import { booleanType, stringType, someType, functionType } from '../../_util/type';
|
||||
|
||||
/**
|
||||
* We support `stringMode` which need handle correct type when user call in onChange
|
||||
|
@ -36,46 +37,42 @@ const getDecimalIfValidate = (value: ValueType) => {
|
|||
|
||||
export const inputNumberProps = () => ({
|
||||
/** value will show as string */
|
||||
stringMode: { type: Boolean as PropType<boolean> },
|
||||
stringMode: booleanType(),
|
||||
|
||||
defaultValue: { type: [String, Number] as PropType<ValueType> },
|
||||
value: { type: [String, Number] as PropType<ValueType> },
|
||||
defaultValue: someType<ValueType>([String, Number]),
|
||||
value: someType<ValueType>([String, Number]),
|
||||
|
||||
prefixCls: { type: String as PropType<string> },
|
||||
min: { type: [String, Number] as PropType<ValueType> },
|
||||
max: { type: [String, Number] as PropType<ValueType> },
|
||||
step: { type: [String, Number] as PropType<ValueType>, default: 1 },
|
||||
tabindex: { type: Number as PropType<number> },
|
||||
controls: { type: Boolean as PropType<boolean>, default: true },
|
||||
readonly: { type: Boolean as PropType<boolean> },
|
||||
disabled: { type: Boolean as PropType<boolean> },
|
||||
autofocus: { type: Boolean as PropType<boolean> },
|
||||
keyboard: { type: Boolean as PropType<boolean>, default: true },
|
||||
prefixCls: stringType<string>(),
|
||||
min: someType<ValueType>([String, Number]),
|
||||
max: someType<ValueType>([String, Number]),
|
||||
step: someType<ValueType>([String, Number], 1),
|
||||
tabindex: Number,
|
||||
controls: booleanType(true),
|
||||
readonly: booleanType(),
|
||||
disabled: booleanType(),
|
||||
autofocus: booleanType(),
|
||||
keyboard: booleanType(true),
|
||||
|
||||
/** Parse display value to validate number */
|
||||
parser: { type: Function as PropType<(displayValue: string | undefined) => ValueType> },
|
||||
parser: functionType<(displayValue: string | undefined) => ValueType>(),
|
||||
/** Transform `value` to display value show in input */
|
||||
formatter: {
|
||||
type: Function as PropType<
|
||||
formatter:
|
||||
functionType<
|
||||
(value: ValueType | undefined, info: { userTyping: boolean; input: string }) => string
|
||||
>,
|
||||
},
|
||||
>(),
|
||||
/** Syntactic sugar of `formatter`. Config precision of display. */
|
||||
precision: { type: Number as PropType<number> },
|
||||
precision: Number,
|
||||
/** Syntactic sugar of `formatter`. Config decimal separator of display. */
|
||||
decimalSeparator: { type: String as PropType<string> },
|
||||
decimalSeparator: String,
|
||||
|
||||
onInput: { type: Function as PropType<(text: string) => void> },
|
||||
onChange: { type: Function as PropType<(value: ValueType) => void> },
|
||||
onPressEnter: { type: Function as PropType<KeyboardEventHandler> },
|
||||
onInput: functionType<(text: string) => void>(),
|
||||
onChange: functionType<(value: ValueType) => void>(),
|
||||
onPressEnter: functionType<KeyboardEventHandler>(),
|
||||
|
||||
onStep: {
|
||||
type: Function as PropType<
|
||||
(value: ValueType, info: { offset: ValueType; type: 'up' | 'down' }) => void
|
||||
>,
|
||||
},
|
||||
onBlur: { type: Function as PropType<(e: FocusEvent) => void> },
|
||||
onFocus: { type: Function as PropType<(e: FocusEvent) => void> },
|
||||
onStep:
|
||||
functionType<(value: ValueType, info: { offset: ValueType; type: 'up' | 'down' }) => void>(),
|
||||
onBlur: functionType<(e: FocusEvent) => void>(),
|
||||
onFocus: functionType<(e: FocusEvent) => void>(),
|
||||
});
|
||||
|
||||
export default defineComponent({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import isMobile from '../../vc-util/isMobile';
|
||||
import type { PropType } from 'vue';
|
||||
import { onBeforeUnmount, ref, defineComponent } from 'vue';
|
||||
import classNames from '../../_util/classNames';
|
||||
import { functionType } from '../../_util/type';
|
||||
|
||||
/**
|
||||
* When click and hold on a button - the speed of auto changing the value.
|
||||
|
@ -21,7 +21,7 @@ export default defineComponent({
|
|||
prefixCls: String,
|
||||
upDisabled: Boolean,
|
||||
downDisabled: Boolean,
|
||||
onStep: { type: Function as PropType<(up: boolean) => void> },
|
||||
onStep: functionType<(up: boolean) => void>(),
|
||||
},
|
||||
slots: ['upNode', 'downNode'],
|
||||
setup(props, { slots, emit }) {
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
@import '../../input/style/mixin';
|
||||
@import (reference) '../../style/themes/index';
|
||||
@input-prefix-cls: ~'@{ant-prefix}-input';
|
||||
|
||||
@input-affix-margin: 4px;
|
||||
|
||||
.@{ant-prefix}-input-number {
|
||||
&-affix-wrapper {
|
||||
.input();
|
||||
// or number handler will cover form status
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
width: 90px;
|
||||
padding: 0;
|
||||
padding-inline-start: @input-padding-horizontal-base;
|
||||
|
||||
&:not(&-disabled):hover {
|
||||
.hover();
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&-focused,
|
||||
&:focus {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
.@{ant-prefix}-input-number[disabled] {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
> div.@{ant-prefix}-input-number {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
||||
&.@{ant-prefix}-input-number-focused {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
input.@{ant-prefix}-input-number-input {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
content: '\a0';
|
||||
}
|
||||
|
||||
.@{ant-prefix}-input-number-handler-wrap {
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
&-prefix,
|
||||
&-suffix {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&-prefix {
|
||||
margin-inline-end: @input-affix-margin;
|
||||
}
|
||||
|
||||
&-suffix {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
margin-right: @input-padding-horizontal-base;
|
||||
margin-left: @input-affix-margin;
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-input-number-group-wrapper .@{ant-prefix}-input-number-affix-wrapper {
|
||||
width: 100%;
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
@import './affix';
|
||||
@import './status';
|
||||
|
||||
@input-number-prefix-cls: ~'@{ant-prefix}-input-number';
|
||||
@form-item-prefix-cls: ~'@{ant-prefix}-form-item';
|
||||
|
||||
.@{input-number-prefix-cls} {
|
||||
.reset-component();
|
||||
.input();
|
||||
|
||||
//== Style for input-group: input with label, with button or dropdown...
|
||||
&-group {
|
||||
.reset-component();
|
||||
.input-group(~'@{input-number-prefix-cls}');
|
||||
|
||||
&-wrapper {
|
||||
display: inline-block;
|
||||
text-align: start;
|
||||
vertical-align: top; // https://github.com/ant-design/ant-design/issues/6403
|
||||
}
|
||||
}
|
||||
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: @border-width-base @border-style-base @border-color-base;
|
||||
border-radius: @border-radius-base;
|
||||
|
||||
&-handler {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
overflow: hidden;
|
||||
color: @text-color-secondary;
|
||||
font-weight: bold;
|
||||
line-height: 0;
|
||||
text-align: center;
|
||||
border-left: @border-width-base @border-style-base @input-number-handler-border-color;
|
||||
transition: all 0.1s linear;
|
||||
|
||||
&:active {
|
||||
background: @input-number-handler-active-bg;
|
||||
}
|
||||
|
||||
&:hover &-up-inner,
|
||||
&:hover &-down-inner {
|
||||
color: @input-number-handler-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&-handler-up-inner,
|
||||
&-handler-down-inner {
|
||||
.iconfont-mixin();
|
||||
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
color: @text-color-secondary;
|
||||
line-height: 12px;
|
||||
transition: all 0.1s linear;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.hover(@input-number-hover-border-color);
|
||||
& + .@{form-item-prefix-cls}-children-icon {
|
||||
opacity: 0;
|
||||
transition: opacity 0.24s linear 0.24s;
|
||||
}
|
||||
}
|
||||
|
||||
&-focused {
|
||||
.active();
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
.disabled();
|
||||
.@{input-number-prefix-cls}-input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.@{input-number-prefix-cls}-handler-wrap {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-readonly {
|
||||
.@{input-number-prefix-cls}-handler-wrap {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-input {
|
||||
width: 100%;
|
||||
height: @input-height-base - 2px;
|
||||
padding: 0 @control-padding-horizontal - 1px;
|
||||
text-align: left;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-radius: @border-radius-base;
|
||||
outline: 0;
|
||||
transition: all 0.3s linear;
|
||||
appearance: textfield !important;
|
||||
.placeholder();
|
||||
|
||||
&[type='number']::-webkit-inner-spin-button,
|
||||
&[type='number']::-webkit-outer-spin-button {
|
||||
margin: 0;
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-lg {
|
||||
padding: 0;
|
||||
font-size: @font-size-lg;
|
||||
|
||||
input {
|
||||
height: @input-height-lg - 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
padding: 0;
|
||||
|
||||
input {
|
||||
height: @input-height-sm - 2px;
|
||||
padding: 0 @control-padding-horizontal-sm - 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&-handler-wrap {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 22px;
|
||||
height: 100%;
|
||||
background: @input-number-handler-bg;
|
||||
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||
opacity: 0;
|
||||
transition: opacity 0.24s linear 0.1s;
|
||||
|
||||
// Fix input number inside Menu makes icon too large
|
||||
// We arise the selector priority by nest selector here
|
||||
// https://github.com/ant-design/ant-design/issues/14367
|
||||
.@{input-number-prefix-cls}-handler {
|
||||
.@{input-number-prefix-cls}-handler-up-inner,
|
||||
.@{input-number-prefix-cls}-handler-down-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: auto;
|
||||
margin-right: 0;
|
||||
font-size: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.@{input-number-prefix-cls}-borderless & {
|
||||
border-left-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-handler-wrap:hover &-handler {
|
||||
height: 40%;
|
||||
}
|
||||
|
||||
&:hover &-handler-wrap,
|
||||
&-focused &-handler-wrap {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&-handler-up {
|
||||
border-top-right-radius: @border-radius-base;
|
||||
cursor: pointer;
|
||||
|
||||
&-inner {
|
||||
top: 50%;
|
||||
margin-top: -5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
height: 60% !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-handler-down {
|
||||
top: 0;
|
||||
border-top: @border-width-base @border-style-base @border-color-base;
|
||||
border-bottom-right-radius: @border-radius-base;
|
||||
cursor: pointer;
|
||||
|
||||
&-inner {
|
||||
top: 50%;
|
||||
text-align: center;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
height: 60% !important;
|
||||
}
|
||||
.@{input-number-prefix-cls}-borderless & {
|
||||
border-top-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-handler-up-disabled,
|
||||
&-handler-down-disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&-handler-up-disabled:hover &-handler-up-inner,
|
||||
&-handler-down-disabled:hover &-handler-down-inner {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&-borderless {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
// ===================== Out Of Range =====================
|
||||
&-out-of-range {
|
||||
input {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './rtl';
|
|
@ -1,2 +1,412 @@
|
|||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
import type { InputToken } from '../../input/style';
|
||||
import {
|
||||
genActiveStyle,
|
||||
genBasicInputStyle,
|
||||
genDisabledStyle,
|
||||
genHoverStyle,
|
||||
genInputGroupStyle,
|
||||
genPlaceholderStyle,
|
||||
genStatusStyle,
|
||||
initInputToken,
|
||||
} from '../../input/style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook } from '../../theme/internal';
|
||||
import { resetComponent, resetIcon } from '../../_style';
|
||||
import { genCompactItemStyle } from '../../_style/compact-item';
|
||||
|
||||
export interface ComponentToken {
|
||||
controlWidth: number;
|
||||
handleWidth: number;
|
||||
handleFontSize: number;
|
||||
/** Default `auto`. Set `true` will always show the handle */
|
||||
handleVisible: 'auto' | true;
|
||||
}
|
||||
|
||||
type InputNumberToken = InputToken<FullToken<'InputNumber'>>;
|
||||
|
||||
const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumberToken) => {
|
||||
const {
|
||||
componentCls,
|
||||
lineWidth,
|
||||
lineType,
|
||||
colorBorder,
|
||||
borderRadius,
|
||||
fontSizeLG,
|
||||
controlHeightLG,
|
||||
controlHeightSM,
|
||||
colorError,
|
||||
inputPaddingHorizontalSM,
|
||||
colorTextDescription,
|
||||
motionDurationMid,
|
||||
colorPrimary,
|
||||
controlHeight,
|
||||
inputPaddingHorizontal,
|
||||
colorBgContainer,
|
||||
colorTextDisabled,
|
||||
borderRadiusSM,
|
||||
borderRadiusLG,
|
||||
controlWidth,
|
||||
handleVisible,
|
||||
} = token;
|
||||
|
||||
return [
|
||||
{
|
||||
[componentCls]: {
|
||||
...resetComponent(token),
|
||||
...genBasicInputStyle(token),
|
||||
...genStatusStyle(token, componentCls),
|
||||
|
||||
display: 'inline-block',
|
||||
width: controlWidth,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
border: `${lineWidth}px ${lineType} ${colorBorder}`,
|
||||
borderRadius,
|
||||
|
||||
'&-rtl': {
|
||||
direction: 'rtl',
|
||||
|
||||
[`${componentCls}-input`]: {
|
||||
direction: 'rtl',
|
||||
},
|
||||
},
|
||||
|
||||
'&-lg': {
|
||||
padding: 0,
|
||||
fontSize: fontSizeLG,
|
||||
borderRadius: borderRadiusLG,
|
||||
|
||||
[`input${componentCls}-input`]: {
|
||||
height: controlHeightLG - 2 * lineWidth,
|
||||
},
|
||||
},
|
||||
|
||||
'&-sm': {
|
||||
padding: 0,
|
||||
borderRadius: borderRadiusSM,
|
||||
|
||||
[`input${componentCls}-input`]: {
|
||||
height: controlHeightSM - 2 * lineWidth,
|
||||
padding: `0 ${inputPaddingHorizontalSM}px`,
|
||||
},
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
...genHoverStyle(token),
|
||||
},
|
||||
|
||||
'&-focused': {
|
||||
...genActiveStyle(token),
|
||||
},
|
||||
|
||||
'&-disabled': {
|
||||
...genDisabledStyle(token),
|
||||
[`${componentCls}-input`]: {
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
},
|
||||
|
||||
// ===================== Out Of Range =====================
|
||||
'&-out-of-range': {
|
||||
input: {
|
||||
color: colorError,
|
||||
},
|
||||
},
|
||||
|
||||
// Style for input-group: input with label, with button or dropdown...
|
||||
'&-group': {
|
||||
...resetComponent(token),
|
||||
...genInputGroupStyle(token),
|
||||
|
||||
'&-wrapper': {
|
||||
display: 'inline-block',
|
||||
textAlign: 'start',
|
||||
verticalAlign: 'top', // https://github.com/ant-design/ant-design/issues/6403
|
||||
|
||||
[`${componentCls}-affix-wrapper`]: {
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
// Size
|
||||
'&-lg': {
|
||||
[`${componentCls}-group-addon`]: {
|
||||
borderRadius: borderRadiusLG,
|
||||
},
|
||||
},
|
||||
'&-sm': {
|
||||
[`${componentCls}-group-addon`]: {
|
||||
borderRadius: borderRadiusSM,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[componentCls]: {
|
||||
'&-input': {
|
||||
width: '100%',
|
||||
height: controlHeight - 2 * lineWidth,
|
||||
padding: `0 ${inputPaddingHorizontal}px`,
|
||||
textAlign: 'start',
|
||||
backgroundColor: 'transparent',
|
||||
border: 0,
|
||||
borderRadius,
|
||||
outline: 0,
|
||||
transition: `all ${motionDurationMid} linear`,
|
||||
appearance: 'textfield',
|
||||
color: token.colorText,
|
||||
fontSize: 'inherit',
|
||||
verticalAlign: 'top',
|
||||
...genPlaceholderStyle(token.colorTextPlaceholder),
|
||||
|
||||
'&[type="number"]::-webkit-inner-spin-button, &[type="number"]::-webkit-outer-spin-button':
|
||||
{
|
||||
margin: 0,
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
webkitAppearance: 'none',
|
||||
appearance: 'none',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Handler
|
||||
{
|
||||
[componentCls]: {
|
||||
[`&:hover ${componentCls}-handler-wrap, &-focused ${componentCls}-handler-wrap`]: {
|
||||
opacity: 1,
|
||||
},
|
||||
|
||||
[`${componentCls}-handler-wrap`]: {
|
||||
position: 'absolute',
|
||||
insetBlockStart: 0,
|
||||
insetInlineEnd: 0,
|
||||
width: token.handleWidth,
|
||||
height: '100%',
|
||||
background: colorBgContainer,
|
||||
borderStartStartRadius: 0,
|
||||
borderStartEndRadius: borderRadius,
|
||||
borderEndEndRadius: borderRadius,
|
||||
borderEndStartRadius: 0,
|
||||
opacity: handleVisible === true ? 1 : 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch',
|
||||
transition: `opacity ${motionDurationMid} linear ${motionDurationMid}`,
|
||||
|
||||
// Fix input number inside Menu makes icon too large
|
||||
// We arise the selector priority by nest selector here
|
||||
// https://github.com/ant-design/ant-design/issues/14367
|
||||
[`${componentCls}-handler`]: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flex: 'auto',
|
||||
height: '40%',
|
||||
|
||||
[`
|
||||
${componentCls}-handler-up-inner,
|
||||
${componentCls}-handler-down-inner
|
||||
`]: {
|
||||
marginInlineEnd: 0,
|
||||
fontSize: token.handleFontSize,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-handler`]: {
|
||||
height: '50%',
|
||||
overflow: 'hidden',
|
||||
color: colorTextDescription,
|
||||
fontWeight: 'bold',
|
||||
lineHeight: 0,
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer',
|
||||
borderInlineStart: `${lineWidth}px ${lineType} ${colorBorder}`,
|
||||
transition: `all ${motionDurationMid} linear`,
|
||||
'&:active': {
|
||||
background: token.colorFillAlter,
|
||||
},
|
||||
|
||||
// Hover
|
||||
'&:hover': {
|
||||
height: `60%`,
|
||||
|
||||
[`
|
||||
${componentCls}-handler-up-inner,
|
||||
${componentCls}-handler-down-inner
|
||||
`]: {
|
||||
color: colorPrimary,
|
||||
},
|
||||
},
|
||||
|
||||
'&-up-inner, &-down-inner': {
|
||||
...resetIcon(),
|
||||
|
||||
color: colorTextDescription,
|
||||
transition: `all ${motionDurationMid} linear`,
|
||||
userSelect: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-handler-up`]: {
|
||||
borderStartEndRadius: borderRadius,
|
||||
},
|
||||
|
||||
[`${componentCls}-handler-down`]: {
|
||||
borderBlockStart: `${lineWidth}px ${lineType} ${colorBorder}`,
|
||||
borderEndEndRadius: borderRadius,
|
||||
},
|
||||
|
||||
// Disabled
|
||||
'&-disabled, &-readonly': {
|
||||
[`${componentCls}-handler-wrap`]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
[`
|
||||
${componentCls}-handler-up-disabled,
|
||||
${componentCls}-handler-down-disabled
|
||||
`]: {
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
|
||||
[`
|
||||
${componentCls}-handler-up-disabled:hover &-handler-up-inner,
|
||||
${componentCls}-handler-down-disabled:hover &-handler-down-inner
|
||||
`]: {
|
||||
color: colorTextDisabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Border-less
|
||||
{
|
||||
[`${componentCls}-borderless`]: {
|
||||
borderColor: 'transparent',
|
||||
boxShadow: 'none',
|
||||
|
||||
[`${componentCls}-handler-down`]: {
|
||||
borderBlockStartWidth: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const genAffixWrapperStyles: GenerateStyle<InputNumberToken> = (token: InputNumberToken) => {
|
||||
const {
|
||||
componentCls,
|
||||
inputPaddingHorizontal,
|
||||
inputAffixPadding,
|
||||
controlWidth,
|
||||
borderRadiusLG,
|
||||
borderRadiusSM,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
[`${componentCls}-affix-wrapper`]: {
|
||||
...genBasicInputStyle(token),
|
||||
...genStatusStyle(token, `${componentCls}-affix-wrapper`),
|
||||
// or number handler will cover form status
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
width: controlWidth,
|
||||
padding: 0,
|
||||
paddingInlineStart: inputPaddingHorizontal,
|
||||
|
||||
'&-lg': {
|
||||
borderRadius: borderRadiusLG,
|
||||
},
|
||||
|
||||
'&-sm': {
|
||||
borderRadius: borderRadiusSM,
|
||||
},
|
||||
|
||||
[`&:not(${componentCls}-affix-wrapper-disabled):hover`]: {
|
||||
...genHoverStyle(token),
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
'&-focused, &:focus': {
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
'&-disabled': {
|
||||
[`${componentCls}[disabled]`]: {
|
||||
background: 'transparent',
|
||||
},
|
||||
},
|
||||
|
||||
[`> div${componentCls}`]: {
|
||||
width: '100%',
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
|
||||
[`&${componentCls}-focused`]: {
|
||||
boxShadow: 'none !important',
|
||||
},
|
||||
},
|
||||
|
||||
[`input${componentCls}-input`]: {
|
||||
padding: 0,
|
||||
},
|
||||
|
||||
'&::before': {
|
||||
width: 0,
|
||||
visibility: 'hidden',
|
||||
content: '"\\a0"',
|
||||
},
|
||||
|
||||
[`${componentCls}-handler-wrap`]: {
|
||||
zIndex: 2,
|
||||
},
|
||||
|
||||
[componentCls]: {
|
||||
'&-prefix, &-suffix': {
|
||||
display: 'flex',
|
||||
flex: 'none',
|
||||
alignItems: 'center',
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
|
||||
'&-prefix': {
|
||||
marginInlineEnd: inputAffixPadding,
|
||||
},
|
||||
|
||||
'&-suffix': {
|
||||
position: 'absolute',
|
||||
insetBlockStart: 0,
|
||||
insetInlineEnd: 0,
|
||||
zIndex: 1,
|
||||
height: '100%',
|
||||
marginInlineEnd: inputPaddingHorizontal,
|
||||
marginInlineStart: inputAffixPadding,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genComponentStyleHook(
|
||||
'InputNumber',
|
||||
token => {
|
||||
const inputNumberToken = initInputToken<FullToken<'InputNumber'>>(token);
|
||||
return [
|
||||
genInputNumberStyles(inputNumberToken),
|
||||
genAffixWrapperStyles(inputNumberToken),
|
||||
// =====================================================
|
||||
// == Space Compact ==
|
||||
// =====================================================
|
||||
genCompactItemStyle(inputNumberToken),
|
||||
];
|
||||
},
|
||||
token => ({
|
||||
controlWidth: 90,
|
||||
handleWidth: token.controlHeightSM - token.lineWidth * 2,
|
||||
handleFontSize: token.fontSize / 2,
|
||||
handleVisible: 'auto',
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
|
||||
@input-number-prefix-cls: ~'@{ant-prefix}-input-number';
|
||||
|
||||
.@{input-number-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
&-handler {
|
||||
.@{input-number-prefix-cls}-rtl & {
|
||||
border-right: @border-width-base @border-style-base @input-number-handler-border-color;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
&-wrap {
|
||||
.@{input-number-prefix-cls}-rtl & {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.@{input-number-prefix-cls}-rtl.@{input-number-prefix-cls}-borderless & {
|
||||
border-right-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-up {
|
||||
.@{input-number-prefix-cls}-rtl & {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-down {
|
||||
.@{input-number-prefix-cls}-rtl & {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-input {
|
||||
.@{input-number-prefix-cls}-rtl & {
|
||||
direction: ltr;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
@import '../../input/style/mixin';
|
||||
|
||||
@input-number-prefix-cls: ~'@{ant-prefix}-input-number';
|
||||
|
||||
@input-number-wrapper-cls: @input-number-prefix-cls, ~'@{input-number-prefix-cls}-affix-wrapper';
|
||||
|
||||
each(@input-number-wrapper-cls, {
|
||||
.@{value} {
|
||||
&-status-error {
|
||||
.status-color(@value, @error-color, @error-color, @input-bg, @error-color-hover, @error-color-outline);
|
||||
.status-color-common(@input-number-prefix-cls, @error-color, @error-color, @input-bg, @error-color-hover, @error-color-outline)
|
||||
}
|
||||
|
||||
&-status-warning {
|
||||
.status-color(@value, @warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline);
|
||||
.status-color-common(@input-number-prefix-cls, @warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
.@{input-number-prefix-cls}-group-wrapper {
|
||||
&-status-error {
|
||||
.group-status-color(@input-number-prefix-cls, @error-color, @error-color);
|
||||
}
|
||||
|
||||
&-status-warning {
|
||||
.group-status-color(@input-number-prefix-cls, @warning-color, @warning-color);
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ import './calendar/style';
|
|||
import './table/style';
|
||||
// import './progress/style';
|
||||
// import './timeline/style';
|
||||
import './input-number/style';
|
||||
// import './input-number/style';
|
||||
// import './transfer/style';
|
||||
import './tree/style';
|
||||
// import './upload/style';
|
||||
|
|
|
@ -16,7 +16,7 @@ import type { ComponentToken as DropdownComponentToken } from '../../dropdown/st
|
|||
// import type { ComponentToken as DrawerComponentToken } from '../../drawer/style';
|
||||
import type { ComponentToken as EmptyComponentToken } from '../../empty/style';
|
||||
// import type { ComponentToken as ImageComponentToken } from '../../image/style';
|
||||
// import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
|
||||
import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
|
||||
import type { ComponentToken as LayoutComponentToken } from '../../layout/style';
|
||||
import type { ComponentToken as ListComponentToken } from '../../list/style';
|
||||
import type { ComponentToken as MentionsComponentToken } from '../../mentions/style';
|
||||
|
@ -76,7 +76,7 @@ export interface ComponentTokenMap {
|
|||
Grid?: {};
|
||||
// Image?: ImageComponentToken;
|
||||
Input?: {};
|
||||
// InputNumber?: InputNumberComponentToken;
|
||||
InputNumber?: InputNumberComponentToken;
|
||||
Layout?: LayoutComponentToken;
|
||||
List?: ListComponentToken;
|
||||
Mentions?: MentionsComponentToken;
|
||||
|
|
Loading…
Reference in New Issue