@@ -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
@@ -100,12 +106,14 @@ export interface InputNumberProps<T extends ValueType = ValueType>
100106 changeOnBlur ?: boolean ;
101107}
102108
103- type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > ;
109+ type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > & {
110+ domRef : React . Ref < HTMLDivElement > ;
111+ } ;
104112
105113const InternalInputNumber = React . forwardRef (
106114 ( props : InternalInputNumberProps , ref : React . Ref < HTMLInputElement > ) => {
107115 const {
108- prefixCls = 'rc-input-number' ,
116+ prefixCls,
109117 className,
110118 style,
111119 min,
@@ -136,6 +144,8 @@ const InternalInputNumber = React.forwardRef(
136144
137145 changeOnBlur = true ,
138146
147+ domRef,
148+
139149 ...inputProps
140150 } = props ;
141151
@@ -572,6 +582,7 @@ const InternalInputNumber = React.forwardRef(
572582 // ============================ Render ============================
573583 return (
574584 < div
585+ ref = { domRef }
575586 className = { clsx ( prefixCls , className , {
576587 [ `${ prefixCls } -focused` ] : focus ,
577588 [ `${ prefixCls } -disabled` ] : disabled ,
@@ -622,66 +633,76 @@ const InternalInputNumber = React.forwardRef(
622633 } ,
623634) ;
624635
625- const InputNumber = React . forwardRef (
626- ( props : InputNumberProps , ref : React . Ref < HTMLInputElement > ) => {
627- const {
628- disabled,
629- style,
630- prefixCls,
631- value,
632- prefix,
633- suffix,
634- addonBefore,
635- addonAfter,
636- className,
637- classNames,
638- ...rest
639- } = props ;
640-
641- const inputFocusRef = React . useRef < HTMLInputElement > ( null ) ;
642-
643- const focus = ( option ?: InputFocusOptions ) => {
644- if ( inputFocusRef . current ) {
645- triggerFocus ( inputFocusRef . current , option ) ;
646- }
647- } ;
636+ const InputNumber = React . forwardRef < InputNumberRef , InputNumberProps > ( ( props , ref ) => {
637+ const {
638+ disabled,
639+ style,
640+ prefixCls = 'rc-input-number' ,
641+ value,
642+ prefix,
643+ suffix,
644+ addonBefore,
645+ addonAfter,
646+ className,
647+ classNames,
648+ ...rest
649+ } = props ;
650+
651+ const holderRef = React . useRef < HolderRef > ( null ) ;
652+ const inputNumberDomRef = React . useRef < HTMLDivElement > ( null ) ;
653+ const inputFocusRef = React . useRef < HTMLInputElement > ( null ) ;
654+
655+ const focus = ( option ?: InputFocusOptions ) => {
656+ if ( inputFocusRef . current ) {
657+ triggerFocus ( inputFocusRef . current , option ) ;
658+ }
659+ } ;
648660
649- return (
650- < BaseInput
651- className = { className }
652- triggerFocus = { focus }
661+ React . useImperativeHandle ( ref , ( ) =>
662+ proxyObject ( inputFocusRef . current , {
663+ nativeElement : holderRef . current . nativeElement || inputNumberDomRef . current ,
664+ } ) ,
665+ ) ;
666+
667+ return (
668+ < BaseInput
669+ className = { className }
670+ triggerFocus = { focus }
671+ prefixCls = { prefixCls }
672+ value = { value }
673+ disabled = { disabled }
674+ style = { style }
675+ prefix = { prefix }
676+ suffix = { suffix }
677+ addonAfter = { addonAfter }
678+ addonBefore = { addonBefore }
679+ classNames = { classNames }
680+ components = { {
681+ affixWrapper : 'div' ,
682+ groupWrapper : 'div' ,
683+ wrapper : 'div' ,
684+ groupAddon : 'div' ,
685+ } }
686+ ref = { holderRef }
687+ >
688+ < InternalInputNumber
653689 prefixCls = { prefixCls }
654- value = { value }
655690 disabled = { disabled }
656- style = { style }
657- prefix = { prefix }
658- suffix = { suffix }
659- addonAfter = { addonAfter }
660- addonBefore = { addonBefore }
661- classNames = { classNames }
662- components = { {
663- affixWrapper : 'div' ,
664- groupWrapper : 'div' ,
665- wrapper : 'div' ,
666- groupAddon : 'div' ,
667- } }
668- >
669- < InternalInputNumber
670- prefixCls = { prefixCls }
671- disabled = { disabled }
672- ref = { composeRef ( inputFocusRef , ref ) }
673- className = { classNames ?. input }
674- { ...rest }
675- />
676- </ BaseInput >
677- ) ;
678- } ,
679- ) as ( < T extends ValueType = ValueType > (
691+ ref = { inputFocusRef }
692+ domRef = { inputNumberDomRef }
693+ className = { classNames ?. input }
694+ { ...rest }
695+ />
696+ </ BaseInput >
697+ ) ;
698+ } ) as ( < T extends ValueType = ValueType > (
680699 props : React . PropsWithChildren < InputNumberProps < T > > & {
681700 ref ?: React . Ref < HTMLInputElement > ;
682701 } ,
683702) => React . ReactElement ) & { displayName ?: string } ;
684703
685- InputNumber . displayName = 'InputNumber' ;
704+ if ( process . env . NODE_ENV !== 'production' ) {
705+ InputNumber . displayName = 'InputNumber' ;
706+ }
686707
687708export default InputNumber ;
0 commit comments