Пользовательский интерфейс материала — закрывающий модальный режим оставляет состояние фокусировки на кнопке, которая его открыла

#reactjs #material-ui #focus

Вопрос:

Допустим, у меня есть кнопка, которая открывает Dialog компонент. Кнопка имеет настраиваемую тематику/стиль для указания различных состояний, одним из которых является :focus состояние:

 const useStyles = makeStyles({
  root: {
    "amp;:focus": {
      backgroundColor: "#3A7DA9"
    }
  }
});

export default function App() {
  const [open, setOpen] = useState(false);
  const classes = useStyles();

  return (
    <div className="App">
      <Button 
        id="button-that-opens-modal"
        className={classes.root} 
        onClick={() => setOpen(true)} 
      >
        Open the modal
      </Button>
      <Dialog open={open}>
        <h3>This is the modal</h3>
        <Button onClick={() => setOpen(false)}>
          Close
        </Button>
      </Dialog>
    </div>
  );
}
 

Что я заметил, так это то, что каждый раз, когда у меня есть этот шаблон (где кнопка открывает модальный диалог), когда модальный закрывается, #button-that-opens-modal остается :focus состояние, которое выглядит плохо с точки зрения стиля. Вот краткий gif:

введите описание изображения здесь

Codesandbox, демонстрирующий проблему

Это известная проблема? Я не понимаю, почему :focus это должно автоматически применяться к кнопке при закрытии модала. Как я могу это остановить?

Я попробовал это:

Я могу добавить ссылку на кнопку и обязательно вручную расфокусировать кнопку в разных местах. Добавление его в onExited метод диалогового окна работает, но на секунду мигает состояние фокусировки:

 export default function App() {
  const [open, setOpen] = useState(false);
  const buttonRef = useRef();
  const classes = useStyles();

  return (
    <div className="App">
      <Button
        ref={buttonRef}
        className={classes.root}
        onClick={() => setOpen(true)}
      >
        Open the modal
      </Button>
      <Dialog
        open={open}
        TransitionProps={{
          onExited: () => {
            buttonRef.current?.blur(); // helps but creates a flash
          }
        }}
      >
        <h3>This is the modal</h3>
        <Button onClick={() => {setOpen(false)}}>
          Close
        </Button>
      </Dialog>
    </div>
  );
}
 

песочница, демонстрирующая это очень несовершенное решение

И даже если я нашел точно правильный обработчик событий, чтобы размыть кнопку, чтобы стиль выглядел правильно, это не то, что я хочу делать для каждого Dialog в приложении, в котором много Button Dialog пар. Есть ли опора для пользовательского интерфейса, которую я могу использовать, чтобы отключить этот «автофокус» на кнопке, вместо того, чтобы создавать ссылку и вручную .blur для каждого Dialog ?

Комментарии:

1. Это делается для обеспечения доступности. Вы можете отключить его, добавив реквизит disableRestoreFocus в свой диалог

2. Спасибо! Если вы хотите, опубликуйте это в качестве ответа, и я отмечу его как таковой

Ответ №1:

Это делается для обеспечения доступности. Вы можете отключить его, добавив реквизит disableRestoreFocus в свой диалог 🙂