🌶️

MUIのAutocompleteで最初入力欄にフォーカスしないようにする

2023/07/04に公開

環境

"react": "^18.2.0","@mui/material": "^5.11.16",

実施内容

MUIのAutocompleteはすごく便利かつ簡単に実装できるので、使っているのですが、クリックした際に自動的に入力欄にフォーカスしてしまうので、スマホだとクリックするたびにキーボードが出現して、煩わしいことがあります。
そこで入力欄のフォーカスを2回クリックしたときから実施するコンポーネントを作成したので、載せておきます。

完成品

import React, { useState, useRef } from 'react';
import FormControl from '@mui/material/FormControl';
import ClickAwayListener from '@mui/base/ClickAwayListener';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';

const selectItems = ['Apple', 'Orange', 'Banana'];

export default const AutocompleteWithoutFocus = () => {
  // AutocompleteのopenのためのuseState
  const [open, setOpen] = useState(false);
  // Autocompleteの中のTextFieldのカウンター(1回目のクリックではテキスト入力にフォーカスしないようにするため)
  let refCounter = useRef(0);
  // Autocompleteのref、最後にフォーカスを外す用に使う
  const ref = useRef(null);
  // Autocompleteの値取得用のuseState
  const [value, setValue] = useState('Apple')

  // 値が変わったときにテキストボックスフォーカスを外す
  const handleChange = (event, newValue) => {
    // 値のセット
    setValue(newValue)
    // カウンターを0にする
    refCounter.current=0;
    // Autocomplete内のテキストボックスフォーカスを外す
    ref.current.firstElementChild.firstElementChild.nextElementSibling.firstElementChild.blur();
    // Autocompleteを閉じる
    setOpen(false);

  };

  console.log(refCounter.current, value);
  return (
    <ClickAwayListener  //Autocomplete外をクリックしたときにテキストボックスフォーカスを外す
                        onClickAway={() => {  refCounter.current=0;
                                              ref.current.firstElementChild.firstElementChild.nextElementSibling.firstElementChild.blur();
                                              setOpen(false); 
                                            }} 
                        // マウス押下時に発動する
                        mouseEvent={'onMouseDown'}
                      >
      <FormControl>
        <Autocomplete
          disableClearable
          ref={ref}
          open={open}
          onOpen={() => {
            setOpen(true);
          }}
          value={value}
          onChange={handleChange}
          id="without-focus-autocomplete"
          options={selectItems}
          sx={{ width:'200px'}}
          // Autocomplete内のテキストボックス要素
          renderInput={(params) => <TextField  {...params} 
                                                label={'果物'} 
                                                InputProps={{  ...params.InputProps,
                                                               // クリック時にカウンターを増やす(onFocusの前に発動)
                                                               onClick:()=>{refCounter.current = refCounter.current+1;},
                                                               // 初めの1回はフォーカスをはずす 
                                                               onFocus:(event) => {if(refCounter.current<=1){event.currentTarget.blur();};}, 
                                                            }}
                                            />}
        />
      </FormControl>
    </ClickAwayListener>
  )
}

onFocusの前にonClickが発動するみたいなので、そこでカウンターを増やして、1回目はフォーカスを外すようにしました。

Discussion