@@ -56,11 +56,12 @@ export default function useSingle(props: SelectInputProps) {
5656
5757 const inputRef = useRef < InputRef > ( null ) ;
5858 const blurTimeoutRef = useRef ( null ) ;
59- const customElementRef = useRef < HTMLDivElement > ( null ) ;
59+ const customElementRef = useRef < HTMLSpanElement > ( null ) ;
6060
6161 const [ isTyping , setIsTyping ] = useState < boolean > ( false ) ;
6262 const [ labelWidth , setLabelWidth ] = useState < number > ( 0 ) ;
6363 const [ customElementWidth , setCustomElementWidth ] = useState < number > ( 0 ) ;
64+ const [ suffixSpace , setSuffixSpace ] = useState < number > ( 0 ) ;
6465
6566 const singleValueDisplay = useMemo (
6667 ( ) => props . valueDisplay ?? getOptionLabel ( value , props . keys ) ,
@@ -99,6 +100,45 @@ export default function useSingle(props: SelectInputProps) {
99100 }
100101 } , [ showCustomElement , singleValueDisplay ] ) ;
101102
103+ useEffect ( ( ) => {
104+ const inputEl = inputRef . current ?. inputElement ;
105+ if ( ! inputEl || ! props . autoWidth ) return ;
106+ if ( showCustomElement && customElementWidth > 0 ) {
107+ inputEl . style . minWidth = `${ customElementWidth } px` ;
108+ } else {
109+ inputEl . style . minWidth = '' ;
110+ }
111+ } , [ props . autoWidth , showCustomElement , customElementWidth ] ) ;
112+
113+ useEffect ( ( ) => {
114+ // 自定义 valueDisplay 时,labelNode 使用绝对定位
115+ // 避免内容延伸盖到右侧的 suffixIcon 区域,需要测量 input 右侧到 wrapper 右侧的距离作为 right 留白
116+ if ( ! showCustomElement ) {
117+ setSuffixSpace ( 0 ) ;
118+ return ;
119+ }
120+ const wrapperEl = inputRef . current ?. currentElement ;
121+ const inputEl = inputRef . current ?. inputElement ;
122+ if ( ! wrapperEl || ! inputEl ) return undefined ;
123+
124+ const measure = ( ) => {
125+ const wrapperRect = wrapperEl . getBoundingClientRect ( ) ;
126+ const inputRect = inputEl . getBoundingClientRect ( ) ;
127+ // wrapper 右内边距 + suffix 区域 + suffixIcon 区域
128+ const space = Math . max ( wrapperRect . right - inputRect . right , 0 ) ;
129+ setSuffixSpace ( space ) ;
130+ } ;
131+
132+ measure ( ) ;
133+
134+ wrapperEl . addEventListener ( 'mouseenter' , measure ) ;
135+ wrapperEl . addEventListener ( 'mouseleave' , measure ) ;
136+ return ( ) => {
137+ wrapperEl . removeEventListener ( 'mouseenter' , measure ) ;
138+ wrapperEl . removeEventListener ( 'mouseleave' , measure ) ;
139+ } ;
140+ } , [ showCustomElement , singleValueDisplay , props . clearable , props . suffixIcon , props . suffix ] ) ;
141+
102142 const renderSelectSingle = (
103143 popupVisible : boolean ,
104144 onInnerBlur ?: ( context : { e : React . FocusEvent < HTMLInputElement > } ) => void ,
@@ -130,7 +170,7 @@ export default function useSingle(props: SelectInputProps) {
130170 // !popupVisible && setInputValue(getInputValue(value, keys), { ...context, trigger: 'input' });
131171 } ;
132172
133- const displayedValue = ( ) => {
173+ const displayedValue = ( ) : string => {
134174 if ( popupVisible && inputValue ) {
135175 return inputValue ;
136176 }
@@ -143,7 +183,7 @@ export default function useSingle(props: SelectInputProps) {
143183 return inputValue ;
144184 } ;
145185
146- const displayedPlaceholder = ( ) => {
186+ const displayedPlaceholder = ( ) : string => {
147187 if ( popupVisible && singleValueDisplay && ! showCustomElement ) {
148188 return singleValueDisplay ;
149189 }
@@ -153,20 +193,22 @@ export default function useSingle(props: SelectInputProps) {
153193
154194 const labelNode = showCustomElement ? (
155195 < div
156- ref = { customElementRef }
157196 style = { {
158197 position : 'absolute' ,
159198 left : `${ labelWidth + 8 } px` ,
199+ right : `${ suffixSpace } px` ,
160200 top : '50%' ,
161201 transform : 'translateY(-50%)' ,
162202 pointerEvents : 'none' ,
163203 textAlign : 'initial' ,
164- zIndex : 3 ,
204+ overflow : 'hidden' ,
165205 // 输入状态,降低透明度,仿造 placeholder 效果
166206 opacity : popupVisible && props . allowInput ? 0.5 : undefined ,
167207 } }
168208 >
169- { singleValueDisplay }
209+ < span ref = { customElementRef } style = { { display : 'inline-block' , whiteSpace : 'nowrap' } } >
210+ { singleValueDisplay }
211+ </ span >
170212 </ div >
171213 ) : null ;
172214
0 commit comments