1- import Select , { InputActionMeta } from 'react-select'
1+ import { useRef , useEffect } from 'react'
2+ import Select , { InputActionMeta , SelectInstance } from 'react-select'
23
34interface Option {
45 value : string
@@ -24,37 +25,92 @@ interface MultiSelectDropdownProps {
2425 placeholder ?: string
2526}
2627
28+ function isTouchCapable ( ) {
29+ try {
30+ document . createEvent ( 'TouchEvent' ) ;
31+ return true ;
32+ } catch ( e ) {
33+ console . log ( 'notsp======' )
34+ return false ;
35+ }
36+ }
37+
2738export const MultiSelectDropdown = ( {
2839 options,
2940 values,
3041 limit,
3142 onChange,
3243 placeholder,
3344} : MultiSelectDropdownProps ) => {
45+ const selectRef = useRef < SelectInstance < Option > | null > ( null )
46+
3447 const handleChange = ( selectedValue : any ) => {
3548 if ( ! selectedValue ) return [ ]
3649 if ( limit && selectedValue ?. length > limit ) return values
3750 const selectedValuesMapped = selectedValue . map ( ( value : { value : any } ) => value . value )
3851 return onChange ( selectedValuesMapped )
3952 }
4053
41- // Avoid input reset on select
42- // @see https://github.com/JedWatson/react-select/blob/06e34882638d1526b9f5a1238bb567a3e9460ce5/docs/examples/OnSelectResetsInput .tsx
54+ // Avoid input reset on select item
55+ // @see https://github.com/JedWatson/react-select/blob/master/storybook/stories/OnSelectKeepsInput.stories .tsx
4356 const handleInputChange = (
4457 inputValue : string ,
4558 { action, prevInputValue} : InputActionMeta
4659 ) => ( action === 'input-change' ) ? inputValue : prevInputValue
4760
61+ // I specifically avoided using the `blurInputOnSelect` prop because it causes
62+ // an undesirable lag. When `blurInputOnSelect` is enabled, the input briefly gains
63+ // focus and then blurs, which creates a flickering effect and feels unpolished.
64+ // This custom solution ensures that the input never gains focus during events like
65+ // "add" or "remove", while still allowing the user to focus it by clicking.
66+ useEffect ( ( ) => {
67+ if ( selectRef . current ) {
68+
69+ if ( ! selectRef . current . inputRef ) {
70+ return
71+ }
72+
73+ // Override the focus method to prevent auto-focus
74+ const originalFocus = selectRef . current . inputRef . focus
75+ selectRef . current . inputRef . focus = ( ) => null
76+
77+ // Override the onControlMouseDown method to temporarily restore the original focus
78+ // behavior during user interactions (e.g., clicking on the search input)
79+ const originalOnControlMouseDown = selectRef . current . onControlMouseDown
80+ selectRef . current . onControlMouseDown = ( ...args ) => {
81+ if ( ! selectRef . current || ! selectRef . current . inputRef ) {
82+ return
83+ }
84+
85+ selectRef . current . inputRef . focus = originalFocus
86+ originalOnControlMouseDown ( ...args )
87+ selectRef . current . inputRef . focus = ( ) => null
88+ }
89+
90+ // Cleanup on unmount
91+ return ( ) => {
92+ if ( selectRef . current ) {
93+ selectRef . current . onControlMouseDown = originalOnControlMouseDown
94+
95+ if ( selectRef . current . inputRef ) {
96+ selectRef . current . inputRef . focus = originalFocus
97+ }
98+ }
99+ }
100+ }
101+ } , [ ] )
102+
48103 return (
49104 < div className = "relative custom-select-box" >
50105 < Select
106+ ref = { selectRef }
51107 value = { values }
52108 options = { options as any }
53109 onChange = { handleChange }
54110 onInputChange = { handleInputChange }
55111 placeholder = { placeholder }
56112 isMulti = { true }
57- autoFocus = { true }
113+ autoFocus = { ! isTouchCapable ( ) }
58114 menuIsOpen = { true }
59115 isClearable = { false }
60116 isSearchable = { true }
0 commit comments