@@ -9,18 +9,24 @@ import getMiniDecimal, {
99import clsx from 'classnames' ;
1010import { BaseInput } from 'rc-input' ;
1111import { useLayoutUpdateEffect } from 'rc-util/lib/hooks/useLayoutEffect' ;
12+ import proxyObject from 'rc-util/lib/proxyObject' ;
1213import { composeRef } from 'rc-util/lib/ref' ;
1314import * as React from 'react' ;
1415import useCursor from './hooks/useCursor' ;
1516import StepHandler from './StepHandler' ;
1617import { getDecupleSteps } from './utils/numberUtil' ;
1718
19+ import type { HolderRef } from 'rc-input/lib/BaseInput' ;
20+ import { BaseInputProps } from 'rc-input/lib/interface' ;
1821import { InputFocusOptions , triggerFocus } from 'rc-input/lib/utils/commonUtils' ;
1922import useFrame from './hooks/useFrame' ;
20- import { BaseInputProps } from 'rc-input/lib/interface' ;
2123
2224export type { ValueType } ;
2325
26+ export interface InputNumberRef extends HTMLInputElement {
27+ nativeElement : HTMLElement ;
28+ }
29+
2430/**
2531 * We support `stringMode` which need handle correct type when user call in onChange
2632 * format max or min value
@@ -105,12 +111,14 @@ export interface InputNumberProps<T extends ValueType = ValueType>
105111 changeOnBlur ?: boolean ;
106112}
107113
108- type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > ;
114+ type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > & {
115+ domRef : React . Ref < HTMLDivElement > ;
116+ } ;
109117
110118const InternalInputNumber = React . forwardRef (
111119 ( props : InternalInputNumberProps , ref : React . Ref < HTMLInputElement > ) => {
112120 const {
113- prefixCls = 'rc-input-number' ,
121+ prefixCls,
114122 className,
115123 style,
116124 min,
@@ -142,6 +150,8 @@ const InternalInputNumber = React.forwardRef(
142150
143151 changeOnBlur = true ,
144152
153+ domRef,
154+
145155 ...inputProps
146156 } = props ;
147157
@@ -478,7 +488,7 @@ const InternalInputNumber = React.forwardRef(
478488 */
479489 const flushInputValue = ( userTyping : boolean ) => {
480490 const parsedValue = getMiniDecimal ( mergedParser ( inputValue ) ) ;
481- let formatValue : DecimalClass = parsedValue ;
491+ let formatValue : DecimalClass ;
482492
483493 if ( ! parsedValue . isNaN ( ) ) {
484494 // Only validate value or empty value can be re-fill to inputValue
@@ -595,6 +605,7 @@ const InternalInputNumber = React.forwardRef(
595605 // ============================ Render ============================
596606 return (
597607 < div
608+ ref = { domRef }
598609 className = { clsx ( prefixCls , className , {
599610 [ `${ prefixCls } -focused` ] : focus ,
600611 [ `${ prefixCls } -disabled` ] : disabled ,
@@ -645,66 +656,76 @@ const InternalInputNumber = React.forwardRef(
645656 } ,
646657) ;
647658
648- const InputNumber = React . forwardRef (
649- ( props : InputNumberProps , ref : React . Ref < HTMLInputElement > ) => {
650- const {
651- disabled,
652- style,
653- prefixCls,
654- value,
655- prefix,
656- suffix,
657- addonBefore,
658- addonAfter,
659- className,
660- classNames,
661- ...rest
662- } = props ;
663-
664- const inputFocusRef = React . useRef < HTMLInputElement > ( null ) ;
665-
666- const focus = ( option ?: InputFocusOptions ) => {
667- if ( inputFocusRef . current ) {
668- triggerFocus ( inputFocusRef . current , option ) ;
669- }
670- } ;
659+ const InputNumber = React . forwardRef < InputNumberRef , InputNumberProps > ( ( props , ref ) => {
660+ const {
661+ disabled,
662+ style,
663+ prefixCls = 'rc-input-number' ,
664+ value,
665+ prefix,
666+ suffix,
667+ addonBefore,
668+ addonAfter,
669+ className,
670+ classNames,
671+ ...rest
672+ } = props ;
673+
674+ const holderRef = React . useRef < HolderRef > ( null ) ;
675+ const inputNumberDomRef = React . useRef < HTMLDivElement > ( null ) ;
676+ const inputFocusRef = React . useRef < HTMLInputElement > ( null ) ;
677+
678+ const focus = ( option ?: InputFocusOptions ) => {
679+ if ( inputFocusRef . current ) {
680+ triggerFocus ( inputFocusRef . current , option ) ;
681+ }
682+ } ;
671683
672- return (
673- < BaseInput
674- className = { className }
675- triggerFocus = { focus }
684+ React . useImperativeHandle ( ref , ( ) =>
685+ proxyObject ( inputFocusRef . current , {
686+ nativeElement : holderRef . current . nativeElement || inputNumberDomRef . current ,
687+ } ) ,
688+ ) ;
689+
690+ return (
691+ < BaseInput
692+ className = { className }
693+ triggerFocus = { focus }
694+ prefixCls = { prefixCls }
695+ value = { value }
696+ disabled = { disabled }
697+ style = { style }
698+ prefix = { prefix }
699+ suffix = { suffix }
700+ addonAfter = { addonAfter }
701+ addonBefore = { addonBefore }
702+ classNames = { classNames }
703+ components = { {
704+ affixWrapper : 'div' ,
705+ groupWrapper : 'div' ,
706+ wrapper : 'div' ,
707+ groupAddon : 'div' ,
708+ } }
709+ ref = { holderRef }
710+ >
711+ < InternalInputNumber
676712 prefixCls = { prefixCls }
677- value = { value }
678713 disabled = { disabled }
679- style = { style }
680- prefix = { prefix }
681- suffix = { suffix }
682- addonAfter = { addonAfter }
683- addonBefore = { addonBefore }
684- classNames = { classNames }
685- components = { {
686- affixWrapper : 'div' ,
687- groupWrapper : 'div' ,
688- wrapper : 'div' ,
689- groupAddon : 'div' ,
690- } }
691- >
692- < InternalInputNumber
693- prefixCls = { prefixCls }
694- disabled = { disabled }
695- ref = { composeRef ( inputFocusRef , ref ) }
696- className = { classNames ?. input }
697- { ...rest }
698- />
699- </ BaseInput >
700- ) ;
701- } ,
702- ) as ( < T extends ValueType = ValueType > (
714+ ref = { inputFocusRef }
715+ domRef = { inputNumberDomRef }
716+ className = { classNames ?. input }
717+ { ...rest }
718+ />
719+ </ BaseInput >
720+ ) ;
721+ } ) as ( < T extends ValueType = ValueType > (
703722 props : React . PropsWithChildren < InputNumberProps < T > > & {
704723 ref ?: React . Ref < HTMLInputElement > ;
705724 } ,
706725) => React . ReactElement ) & { displayName ?: string } ;
707726
708- InputNumber . displayName = 'InputNumber' ;
727+ if ( process . env . NODE_ENV !== 'production' ) {
728+ InputNumber . displayName = 'InputNumber' ;
729+ }
709730
710731export default InputNumber ;
0 commit comments