@@ -9,18 +9,24 @@ import getMiniDecimal, {
9
9
import clsx from 'classnames' ;
10
10
import { BaseInput } from 'rc-input' ;
11
11
import { useLayoutUpdateEffect } from 'rc-util/lib/hooks/useLayoutEffect' ;
12
+ import proxyObject from 'rc-util/lib/proxyObject' ;
12
13
import { composeRef } from 'rc-util/lib/ref' ;
13
14
import * as React from 'react' ;
14
15
import useCursor from './hooks/useCursor' ;
15
16
import StepHandler from './StepHandler' ;
16
17
import { getDecupleSteps } from './utils/numberUtil' ;
17
18
19
+ import type { HolderRef } from 'rc-input/lib/BaseInput' ;
20
+ import { BaseInputProps } from 'rc-input/lib/interface' ;
18
21
import { InputFocusOptions , triggerFocus } from 'rc-input/lib/utils/commonUtils' ;
19
22
import useFrame from './hooks/useFrame' ;
20
- import { BaseInputProps } from 'rc-input/lib/interface' ;
21
23
22
24
export type { ValueType } ;
23
25
26
+ export interface InputNumberRef extends HTMLInputElement {
27
+ nativeElement : HTMLElement ;
28
+ }
29
+
24
30
/**
25
31
* We support `stringMode` which need handle correct type when user call in onChange
26
32
* format max or min value
@@ -100,12 +106,14 @@ export interface InputNumberProps<T extends ValueType = ValueType>
100
106
changeOnBlur ?: boolean ;
101
107
}
102
108
103
- type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > ;
109
+ type InternalInputNumberProps = Omit < InputNumberProps , 'prefix' | 'suffix' > & {
110
+ domRef : React . Ref < HTMLDivElement > ;
111
+ } ;
104
112
105
113
const InternalInputNumber = React . forwardRef (
106
114
( props : InternalInputNumberProps , ref : React . Ref < HTMLInputElement > ) => {
107
115
const {
108
- prefixCls = 'rc-input-number' ,
116
+ prefixCls,
109
117
className,
110
118
style,
111
119
min,
@@ -136,6 +144,8 @@ const InternalInputNumber = React.forwardRef(
136
144
137
145
changeOnBlur = true ,
138
146
147
+ domRef,
148
+
139
149
...inputProps
140
150
} = props ;
141
151
@@ -572,6 +582,7 @@ const InternalInputNumber = React.forwardRef(
572
582
// ============================ Render ============================
573
583
return (
574
584
< div
585
+ ref = { domRef }
575
586
className = { clsx ( prefixCls , className , {
576
587
[ `${ prefixCls } -focused` ] : focus ,
577
588
[ `${ prefixCls } -disabled` ] : disabled ,
@@ -622,66 +633,76 @@ const InternalInputNumber = React.forwardRef(
622
633
} ,
623
634
) ;
624
635
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
+ } ;
648
660
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
653
689
prefixCls = { prefixCls }
654
- value = { value }
655
690
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 > (
680
699
props : React . PropsWithChildren < InputNumberProps < T > > & {
681
700
ref ?: React . Ref < HTMLInputElement > ;
682
701
} ,
683
702
) => React . ReactElement ) & { displayName ?: string } ;
684
703
685
- InputNumber . displayName = 'InputNumber' ;
704
+ if ( process . env . NODE_ENV !== 'production' ) {
705
+ InputNumber . displayName = 'InputNumber' ;
706
+ }
686
707
687
708
export default InputNumber ;
0 commit comments