11import * as React from 'react' ;
22import { useSelectInputContext } from './context' ;
3+ import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect' ;
34
45export interface InputProps {
56 disabled ?: boolean ;
@@ -13,10 +14,12 @@ export interface InputProps {
1314 className ?: string ;
1415 style ?: React . CSSProperties ;
1516 maxLength ?: number ;
17+ /** width always match content width */
18+ syncWidth ?: boolean ;
1619}
1720
1821const Input = React . forwardRef < HTMLInputElement , InputProps > ( ( props , ref ) => {
19- const { onChange, onKeyDown, onBlur, ...restProps } = props ;
22+ const { onChange, onKeyDown, onBlur, style , syncWidth , value , ...restProps } = props ;
2023 const { prefixCls, mode, onSearch, onSearchSubmit, onInputBlur, autoFocus } =
2124 useSelectInputContext ( ) ;
2225
@@ -25,27 +28,34 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
2528 // Used to handle input method composition status
2629 const compositionStatusRef = React . useRef < boolean > ( false ) ;
2730
31+ // ============================== Refs ==============================
32+ const inputRef = React . useRef < HTMLInputElement > ( null ) ;
33+
34+ React . useImperativeHandle ( ref , ( ) => inputRef . current ) ;
35+
36+ // ============================== Data ==============================
2837 // Handle input changes
2938 const handleChange : React . ChangeEventHandler < HTMLInputElement > = ( event ) => {
30- const { value } = event . target ;
39+ const { value : nextVal } = event . target ;
3140
3241 // Call onSearch callback
3342 if ( onSearch ) {
34- onSearch ( value , true , compositionStatusRef . current ) ;
43+ onSearch ( nextVal , true , compositionStatusRef . current ) ;
3544 }
3645
3746 // Call original onChange callback
3847 onChange ?.( event ) ;
3948 } ;
4049
50+ // ============================ Keyboard ============================
4151 // Handle keyboard events
4252 const handleKeyDown : React . KeyboardEventHandler < HTMLInputElement > = ( event ) => {
4353 const { key } = event ;
44- const { value } = event . currentTarget ;
54+ const { value : nextVal } = event . currentTarget ;
4555
4656 // Handle Enter key submission - referencing Selector implementation
4757 if ( key === 'Enter' && mode === 'tags' && ! compositionStatusRef . current && onSearchSubmit ) {
48- onSearchSubmit ( value ) ;
58+ onSearchSubmit ( nextVal ) ;
4959 }
5060
5161 // Call original onKeyDown callback
@@ -71,38 +81,41 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
7181 compositionStatusRef . current = false ;
7282
7383 // Trigger search when input method composition ends
74- const { value } = event . currentTarget ;
75- onSearch ?.( value , true , false ) ;
84+ const { value : nextVal } = event . currentTarget ;
85+ onSearch ?.( nextVal , true , false ) ;
7686 } ;
7787
78- // ============================= Mouse ==============================
79- // const onMouseDown: React.MouseEventHandler<HTMLElement> = (event) => {
80- // // const inputMouseDown = getInputMouseDown();
81- // // // when mode is combobox and it is disabled, don't prevent default behavior
82- // // // https://github.com/ant-design/ant-design/issues/37320
83- // // // https://github.com/ant-design/ant-design/issues/48281
84- // // if (
85- // // event.target !== inputRef.current &&
86- // // !inputMouseDown &&
87- // // !(mode === 'combobox' && disabled)
88- // // ) {
89- // // event.preventDefault();
90- // // }
91- // // if ((mode !== 'combobox' && (!showSearch || !inputMouseDown)) || !open) {
92- // // if (open && autoClearSearchValue !== false) {
93- // // onSearch('', true, false);
94- // // }
95- // // onToggleOpen();
96- // // }
97- // };
88+ // ============================= Width ==============================
89+ const [ widthCssVar , setWidthCssVar ] = React . useState < number | undefined > ( undefined ) ;
90+
91+ // When syncWidth is enabled, adjust input width based on content
92+ useLayoutEffect ( ( ) => {
93+ const input = inputRef . current ;
94+
95+ if ( syncWidth && input ) {
96+ input . style . width = '0px' ;
97+ const scrollWidth = input . scrollWidth ;
98+ setWidthCssVar ( scrollWidth ) ;
99+
100+ // Reset input style
101+ input . style . width = '' ;
102+ }
103+ } , [ syncWidth , value ] ) ;
98104
99105 // ============================= Render =============================
100106 return (
101107 < input
102108 { ...restProps }
103- ref = { ref }
109+ ref = { inputRef }
110+ style = {
111+ {
112+ ...style ,
113+ '--select-input-width' : widthCssVar ,
114+ } as React . CSSProperties
115+ }
104116 autoFocus = { autoFocus }
105117 className = { inputCls }
118+ value = { value || '' }
106119 onChange = { handleChange }
107120 onKeyDown = { handleKeyDown }
108121 onBlur = { handleBlur }
0 commit comments