This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
import * as React from 'react';
import type { InputNumberProps as RcInputNumberProps, InputNumberRef as RcInputNumberRef, ValueType } from '@rc-component/input-number';
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { InputStatus } from '../_util/statusUtils';
import type { Variant } from '../config-provider';
import type { SizeType } from '../config-provider/SizeContext';
export type InputNumberSemanticName = keyof InputNumberSemanticClassNames & keyof InputNumberSemanticStyles;
export type InputNumberSemanticClassNames = {
root?: string;
prefix?: string;
suffix?: string;
input?: string;
actions?: string;
};
export type InputNumberSemanticStyles = {
root?: React.CSSProperties;
prefix?: React.CSSProperties;
suffix?: React.CSSProperties;
input?: React.CSSProperties;
actions?: React.CSSProperties;
};
export type InputNumberClassNamesType<T extends ValueType = ValueType> = SemanticClassNamesType<InputNumberProps<T>, InputNumberSemanticClassNames>;
export type InputNumberStylesType<T extends ValueType = ValueType> = SemanticStylesType<InputNumberProps<T>, InputNumberSemanticStyles>;
export interface InputNumberProps<T extends ValueType = ValueType> extends Omit<RcInputNumberProps<T>, 'prefix' | 'size' | 'controls' | 'classNames' | 'styles'> {
prefixCls?: string;
rootClassName?: string;
classNames?: InputNumberClassNamesType;
styles?: InputNumberStylesType;
/**
* @deprecated Use `Space.Compact` instead.
*
* @example
* ```tsx
* import { Space, InputNumber } from 'antd';
*
* <Space.Compact>
* {addon}
* <InputNumber defaultValue={1} />
* </Space.Compact>
* ```
*/
addonBefore?: React.ReactNode;
/**
* @deprecated Use `Space.Compact` instead.
*
* @example
* ```tsx
* import { Space, InputNumber } from 'antd';
*
* <Space.Compact>
* <InputNumber defaultValue={1} />
* {addon}
* </Space.Compact>
* ```
*/
addonAfter?: React.ReactNode;
prefix?: React.ReactNode;
suffix?: React.ReactNode;
size?: SizeType;
disabled?: boolean;
/** @deprecated Use `variant` instead. */
bordered?: boolean;
status?: InputStatus;
controls?: boolean | {
upIcon?: React.ReactNode;
downIcon?: React.ReactNode;
};
/**
* @since 5.13.0
* @default "outlined"
*/
variant?: Variant;
}
declare const TypedInputNumber: (<T extends ValueType = ValueType>(props: React.PropsWithChildren<InputNumberProps<T>> & React.RefAttributes<RcInputNumberRef>) => React.ReactElement) & {
displayName?: string;
_InternalPanelDoNotUseOrYouWillBeFired: typeof PureInputNumber;
};
/** @private Internal Component. Do not use in your production. */
declare const PureInputNumber: React.FC<InputNumberProps>;
export default TypedInputNumber;
+212
View File
@@ -0,0 +1,212 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _DownOutlined = _interopRequireDefault(require("@ant-design/icons/DownOutlined"));
var _MinusOutlined = _interopRequireDefault(require("@ant-design/icons/MinusOutlined"));
var _PlusOutlined = _interopRequireDefault(require("@ant-design/icons/PlusOutlined"));
var _UpOutlined = _interopRequireDefault(require("@ant-design/icons/UpOutlined"));
var _inputNumber = _interopRequireDefault(require("@rc-component/input-number"));
var _clsx = require("clsx");
var _ContextIsolator = _interopRequireDefault(require("../_util/ContextIsolator"));
var _hooks = require("../_util/hooks");
var _is = require("../_util/is");
var _statusUtils = require("../_util/statusUtils");
var _warning = require("../_util/warning");
var _configProvider = _interopRequireDefault(require("../config-provider"));
var _context = require("../config-provider/context");
var _DisabledContext = _interopRequireDefault(require("../config-provider/DisabledContext"));
var _useCSSVarCls = _interopRequireDefault(require("../config-provider/hooks/useCSSVarCls"));
var _useSize = _interopRequireDefault(require("../config-provider/hooks/useSize"));
var _context2 = require("../form/context");
var _useVariants = _interopRequireDefault(require("../form/hooks/useVariants"));
var _Addon = _interopRequireDefault(require("../space/Addon"));
var _Compact = _interopRequireWildcard(require("../space/Compact"));
var _style = _interopRequireDefault(require("./style"));
const InternalInputNumber = /*#__PURE__*/React.forwardRef((props, ref) => {
const inputRef = React.useRef(null);
React.useImperativeHandle(ref, () => inputRef.current);
const {
rootClassName,
size: customizeSize,
disabled: customDisabled,
prefixCls,
addonBefore: _addonBefore,
addonAfter: _addonAfter,
prefix,
suffix,
bordered,
readOnly,
status,
controls = true,
variant: customVariant,
className,
style,
classNames,
styles,
mode,
...others
} = props;
const {
direction,
className: contextClassName,
style: contextStyle,
styles: contextStyles,
classNames: contextClassNames
} = (0, _context.useComponentConfig)('inputNumber');
// ===================== Disabled =====================
const disabled = React.useContext(_DisabledContext.default);
const mergedDisabled = customDisabled ?? disabled;
// controls && !mergedDisabled && !readOnly;
const mergedControls = React.useMemo(() => {
if (!controls || mergedDisabled || readOnly) {
return false;
}
return controls;
}, [controls, mergedDisabled, readOnly]);
const {
compactSize,
compactItemClassnames
} = (0, _Compact.useCompactItemContext)(prefixCls, direction);
let upIcon = mode === 'spinner' ? /*#__PURE__*/React.createElement(_PlusOutlined.default, null) : /*#__PURE__*/React.createElement(_UpOutlined.default, null);
let downIcon = mode === 'spinner' ? /*#__PURE__*/React.createElement(_MinusOutlined.default, null) : /*#__PURE__*/React.createElement(_DownOutlined.default, null);
const controlsTemp = typeof mergedControls === 'boolean' ? mergedControls : undefined;
if ((0, _is.isPlainObject)(mergedControls)) {
upIcon = mergedControls.upIcon || upIcon;
downIcon = mergedControls.downIcon || downIcon;
}
const {
hasFeedback,
isFormItemInput,
feedbackIcon
} = React.useContext(_context2.FormItemInputContext);
const mergedSize = (0, _useSize.default)(ctx => customizeSize ?? compactSize ?? ctx);
const [variant, enableVariantCls] = (0, _useVariants.default)('inputNumber', customVariant, bordered);
const suffixNode = hasFeedback && /*#__PURE__*/React.createElement(React.Fragment, null, feedbackIcon);
// =========== Merged Props for Semantic ==========
const mergedProps = {
...props,
size: mergedSize,
disabled: mergedDisabled,
controls: mergedControls
};
const [mergedClassNames, mergedStyles] = (0, _hooks.useMergeSemantic)([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
});
return /*#__PURE__*/React.createElement(_inputNumber.default, {
ref: inputRef,
mode: mode,
disabled: mergedDisabled,
className: (0, _clsx.clsx)(className, rootClassName, mergedClassNames.root, contextClassName, compactItemClassnames, (0, _statusUtils.getStatusClassNames)(prefixCls, status, hasFeedback), {
[`${prefixCls}-${variant}`]: enableVariantCls,
[`${prefixCls}-lg`]: mergedSize === 'large',
[`${prefixCls}-sm`]: mergedSize === 'small',
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-in-form-item`]: isFormItemInput,
[`${prefixCls}-without-controls`]: !mergedControls
}),
style: {
...mergedStyles.root,
...contextStyle,
...style
},
upHandler: upIcon,
downHandler: downIcon,
prefixCls: prefixCls,
readOnly: readOnly,
controls: controlsTemp,
prefix: prefix,
suffix: suffixNode || suffix,
classNames: mergedClassNames,
styles: mergedStyles,
...others
});
});
// ===================================================================
// == InputNumber ==
// ===================================================================
const InputNumber = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
addonBefore,
addonAfter,
prefixCls: customizePrefixCls,
className,
status: customStatus,
rootClassName,
...rest
} = props;
const {
getPrefixCls
} = (0, _context.useComponentConfig)('inputNumber');
const prefixCls = getPrefixCls('input-number', customizePrefixCls);
const {
status: contextStatus
} = React.useContext(_context2.FormItemInputContext);
const mergedStatus = (0, _statusUtils.getMergedStatus)(contextStatus, customStatus);
const rootCls = (0, _useCSSVarCls.default)(prefixCls);
const [hashId, cssVarCls] = (0, _style.default)(prefixCls, rootCls);
const hasLegacyAddon = addonBefore || addonAfter;
// ======================= Warn =======================
if (process.env.NODE_ENV !== 'production') {
const typeWarning = (0, _warning.devUseWarning)('InputNumber');
[['bordered', 'variant'], ['addonAfter', 'Space.Compact'], ['addonBefore', 'Space.Compact']].forEach(([prop, newProp]) => {
typeWarning.deprecated(!(prop in props), prop, newProp);
});
typeWarning(!(props.type === 'number' && props.changeOnWheel), 'usage', 'When `type=number` is used together with `changeOnWheel`, changeOnWheel may not work properly. Please delete `type=number` if it is not necessary.');
}
// ====================== Render ======================
const inputNumberNode = /*#__PURE__*/React.createElement(InternalInputNumber, {
ref: ref,
...rest,
prefixCls: prefixCls,
status: mergedStatus,
className: (0, _clsx.clsx)(cssVarCls, rootCls, hashId, className),
rootClassName: !hasLegacyAddon ? rootClassName : undefined
});
if (hasLegacyAddon) {
const renderAddon = node => {
if (!node) {
return null;
}
return /*#__PURE__*/React.createElement(_Addon.default, {
className: (0, _clsx.clsx)(`${prefixCls}-addon`, cssVarCls, hashId),
variant: props.variant,
disabled: props.disabled,
status: mergedStatus
}, /*#__PURE__*/React.createElement(_ContextIsolator.default, {
form: true
}, node));
};
const addonBeforeNode = renderAddon(addonBefore);
const addonAfterNode = renderAddon(addonAfter);
return /*#__PURE__*/React.createElement(_Compact.default, {
rootClassName: rootClassName
}, addonBeforeNode, inputNumberNode, addonAfterNode);
}
return inputNumberNode;
});
const TypedInputNumber = InputNumber;
/** @private Internal Component. Do not use in your production. */
const PureInputNumber = props => (/*#__PURE__*/React.createElement(_configProvider.default, {
theme: {
components: {
InputNumber: {
handleVisible: true
}
}
}
}, /*#__PURE__*/React.createElement(InputNumber, {
...props
})));
if (process.env.NODE_ENV !== 'production') {
InternalInputNumber.displayName = 'InternalInputNumber';
TypedInputNumber.displayName = 'InputNumber';
}
TypedInputNumber._InternalPanelDoNotUseOrYouWillBeFired = PureInputNumber;
var _default = exports.default = TypedInputNumber;
+4
View File
@@ -0,0 +1,4 @@
import type { ComponentToken } from './token';
export type { ComponentToken };
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+322
View File
@@ -0,0 +1,322 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
var _style = require("../../input/style");
var _variants = require("../../input/style/variants");
var _style2 = require("../../style");
var _compactItem = require("../../style/compact-item");
var _internal = require("../../theme/internal");
var _genStyleUtils = require("../../theme/util/genStyleUtils");
var _token = require("./token");
const genInputNumberStyles = token => {
const {
componentCls,
lineWidth,
lineType,
borderRadius,
inputFontSizeSM,
inputFontSizeLG,
colorError,
paddingInlineSM,
paddingBlockSM,
paddingBlockLG,
paddingInlineLG,
colorIcon,
colorTextDisabled,
motionDurationMid,
handleHoverColor,
handleOpacity,
paddingInline,
paddingBlock,
handleBg,
handleActiveBg,
inputAffixPadding,
borderRadiusSM,
controlWidth,
handleBorderColor,
filledHandleBg,
lineHeightLG,
antCls
} = token;
const borderStyle = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${handleBorderColor}`;
const [varName, varRef] = (0, _genStyleUtils.genCssVar)(antCls, 'input-number');
return [
// ==========================================================
// == Base ==
// ==========================================================
{
[componentCls]: {
...(0, _style2.resetComponent)(token),
...(0, _style.genBasicInputStyle)(token),
[varName('input-padding-block')]: (0, _cssinjs.unit)(paddingBlock),
[varName('input-padding-inline')]: (0, _cssinjs.unit)(paddingInline),
display: 'inline-flex',
width: controlWidth,
margin: 0,
paddingBlock: 0,
borderRadius,
// ======================= Variants =======================
...(0, _variants.genOutlinedStyle)(token, {
[`${componentCls}-actions`]: {
background: handleBg,
[`${componentCls}-action-down`]: {
borderBlockStart: borderStyle
}
}
}),
...(0, _variants.genFilledStyle)(token, {
[`${componentCls}-actions`]: {
background: filledHandleBg,
[`${componentCls}-action-down`]: {
borderBlockStart: borderStyle
}
},
'&:focus-within': {
[`${componentCls}-actions`]: {
background: handleBg
}
}
}),
...(0, _variants.genUnderlinedStyle)(token, {
[`${componentCls}-actions`]: {
background: handleBg,
[`${componentCls}-action-down`]: {
borderBlockStart: borderStyle
}
}
}),
...(0, _variants.genBorderlessStyle)(token),
// InputNumber 两层结构:borderless 补偿只加在内层 input 的 CSS 变量上,避免外层+内层双重 padding 导致高度异常
[`&${componentCls}-borderless`]: {
paddingBlock: 0,
[varName('input-padding-block')]: (0, _cssinjs.unit)(token.calc(paddingBlock).add(lineWidth).equal())
},
[`&${componentCls}-borderless${componentCls}-sm`]: {
paddingBlock: 0,
[varName('input-padding-block')]: (0, _cssinjs.unit)(token.calc(paddingBlockSM).add(lineWidth).equal())
},
[`&${componentCls}-borderless${componentCls}-lg`]: {
paddingBlock: 0,
[varName('input-padding-block')]: (0, _cssinjs.unit)(token.calc(paddingBlockLG).add(lineWidth).equal())
},
// ========================= RTL ==========================
'&-rtl': {
direction: 'rtl',
[`${componentCls}-input`]: {
direction: 'rtl'
}
},
// ===================== Out Of Range =====================
[`&${componentCls}-out-of-range`]: {
[`${componentCls}-input`]: {
color: colorError
}
},
// ======================== Input =========================
[`${componentCls}-input`]: {
...(0, _style2.resetComponent)(token),
width: '100%',
paddingBlock: varRef('input-padding-block'),
textAlign: 'start',
backgroundColor: 'transparent',
border: 0,
borderRadius: 0,
outline: 0,
transition: `all ${motionDurationMid} linear`,
appearance: 'textfield',
fontSize: 'inherit',
lineHeight: 'inherit',
...(0, _style.genPlaceholderStyle)(token.colorTextPlaceholder),
'&[type="number"]::-webkit-inner-spin-button, &[type="number"]::-webkit-outer-spin-button': {
margin: 0,
appearance: 'none'
}
},
[`&:hover ${componentCls}-handler-wrap, &-focused ${componentCls}-handler-wrap`]: {
width: token.handleWidth,
opacity: 1
},
// ======================= Disabled =======================
[`&-disabled ${componentCls}-input`]: {
cursor: 'not-allowed',
color: token.colorTextDisabled
}
}
},
// ==========================================================
// == Action ==
// ==========================================================
{
[componentCls]: {
// ======================= Shared =======================
[`${componentCls}-action`]: {
...(0, _style2.resetIcon)(),
userSelect: 'none',
overflow: 'hidden',
fontWeight: 'bold',
lineHeight: 0,
textAlign: 'center',
cursor: 'pointer',
transition: `all ${motionDurationMid} linear`,
// Active: change background not disabled only;
[`&:active:not(${componentCls}-action-up-disabled):not(${componentCls}-action-down-disabled)`]: {
background: handleActiveBg
},
// Hover: change color not disabled only;
[`&:hover:not(${componentCls}-action-up-disabled):not(${componentCls}-action-down-disabled)`]: {
color: handleHoverColor
},
[`&${componentCls}-action-up-disabled, &${componentCls}-action-down-disabled`]: {
cursor: 'not-allowed',
color: colorTextDisabled
}
},
// ===================== Input Mode =====================
'&-mode-input': {
overflow: 'hidden',
[`${componentCls}-actions`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineEnd: 0,
width: token.handleVisibleWidth,
opacity: handleOpacity,
height: '100%',
borderRadius: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'stretch',
transition: `all ${motionDurationMid}`,
overflow: 'hidden',
// 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}-action`]: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flex: 'auto',
height: '40%',
marginInlineEnd: 0,
fontSize: token.handleFontSize
}
},
[`&:hover ${componentCls}-actions, &-focused ${componentCls}-actions`]: {
width: token.handleWidth,
opacity: 1
},
[`${componentCls}-action`]: {
color: colorIcon,
height: '50%',
borderInlineStart: borderStyle,
// Hover: change height not disabled only;
[`&:hover:not(${componentCls}-action-up-disabled):not(${componentCls}-action-down-disabled)`]: {
height: `60%`
}
},
[`&${componentCls}-disabled, &${componentCls}-readonly`]: {
[`${componentCls}-actions`]: {
display: 'none'
}
}
},
// ==================== Spinner Mode ====================
[`&${componentCls}-mode-spinner`]: {
padding: 0,
width: 'auto',
[`${componentCls}-action`]: {
flex: 'none',
paddingInline: varRef('input-padding-inline'),
'&-up': {
borderInlineStart: borderStyle
},
'&-down': {
borderInlineEnd: borderStyle
}
},
[`${componentCls}-input`]: {
textAlign: 'center',
paddingInline: varRef('input-padding-inline')
}
}
}
},
// ==========================================================
// == Size ==
// ==========================================================
{
[componentCls]: {
'&-lg': {
[varName('input-padding-block')]: (0, _cssinjs.unit)(paddingBlockLG),
[varName('input-padding-inline')]: (0, _cssinjs.unit)(paddingInlineLG),
paddingBlock: 0,
fontSize: inputFontSizeLG,
lineHeight: lineHeightLG
},
'&-sm': {
[varName('input-padding-block')]: (0, _cssinjs.unit)(paddingBlockSM),
[varName('input-padding-inline')]: (0, _cssinjs.unit)(paddingInlineSM),
paddingBlock: 0,
fontSize: inputFontSizeSM,
borderRadius: borderRadiusSM
}
}
},
// ==========================================================
// == Pre/Suffix ==
// ==========================================================
{
[componentCls]: {
[`${componentCls}-prefix, ${componentCls}-suffix`]: {
display: 'flex',
flex: 'none',
alignItems: 'center',
alignSelf: 'center',
pointerEvents: 'none'
},
[`${componentCls}-prefix`]: {
marginInlineEnd: inputAffixPadding
},
[`${componentCls}-suffix`]: {
height: '100%',
marginInlineStart: inputAffixPadding,
transition: `margin ${motionDurationMid}`
},
[`&:hover:not(${componentCls}-without-controls)`]: {
[`${componentCls}-suffix`]: {
marginInlineEnd: token.handleWidth
}
}
}
}];
};
const genCompatibleStyles = token => {
const {
componentCls,
antCls
} = token;
return {
[`${componentCls}-addon`]: {
[`&:has(${antCls}-select)`]: {
border: 0,
padding: 0
}
}
};
};
var _default = exports.default = (0, _internal.genStyleHooks)('InputNumber', token => {
const inputNumberToken = (0, _internal.mergeToken)(token, (0, _style.initInputToken)(token));
return [genInputNumberStyles(inputNumberToken), genCompatibleStyles(inputNumberToken),
// =====================================================
// == Space Compact ==
// =====================================================
(0, _compactItem.genCompactItemStyle)(inputNumberToken)];
}, _token.prepareComponentToken, {
unitless: {
handleOpacity: true
},
resetFont: false
});
+52
View File
@@ -0,0 +1,52 @@
import type { SharedComponentToken, SharedInputToken } from '../../input/style/token';
import type { FullToken, GetDefaultToken } from '../../theme/internal';
export interface ComponentToken extends SharedComponentToken {
/**
* @desc 输入框宽度
* @descEN Width of input
*/
controlWidth: number;
/**
* @desc 操作按钮宽度
* @descEN Width of control button
*/
handleWidth: number;
/**
* @desc 操作按钮图标大小
* @descEN Icon size of control button
*/
handleFontSize: number;
/**
* Default `auto`. Set `true` will always show the handle
* @desc 操作按钮可见性
* @descEN Handle visible
*/
handleVisible: 'auto' | true;
/**
* @desc 操作按钮背景色
* @descEN Background color of handle
*/
handleBg: string;
/**
* @desc 操作按钮激活背景色
* @descEN Active background color of handle
*/
handleActiveBg: string;
/**
* @desc 操作按钮悬浮颜色
* @descEN Hover color of handle
*/
handleHoverColor: string;
/**
* @desc 操作按钮边框颜色
* @descEN Border color of handle
*/
handleBorderColor: string;
/**
* @desc 面性变体操作按钮背景色
* @descEN Background color of handle in filled variant
*/
filledHandleBg: string;
}
export type InputNumberToken = FullToken<'InputNumber'> & SharedInputToken;
export declare const prepareComponentToken: GetDefaultToken<'InputNumber'>;
+27
View File
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.prepareComponentToken = void 0;
var _fastColor = require("@ant-design/fast-color");
var _token = require("../../input/style/token");
const prepareComponentToken = token => {
const handleVisible = token.handleVisible ?? 'auto';
const handleWidth = token.controlHeightSM - token.lineWidth * 2;
return {
...(0, _token.initComponentToken)(token),
controlWidth: 90,
handleWidth,
handleFontSize: token.fontSize / 2,
handleVisible,
handleActiveBg: token.colorFillAlter,
handleBg: token.colorBgContainer,
filledHandleBg: new _fastColor.FastColor(token.colorFillSecondary).onBackground(token.colorBgContainer).toHexString(),
handleHoverColor: token.colorPrimary,
handleBorderColor: token.colorBorder,
handleOpacity: handleVisible === true ? 1 : 0,
handleVisibleWidth: handleVisible === true ? handleWidth : 0
};
};
exports.prepareComponentToken = prepareComponentToken;