Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Influence tab order of Material UI controls

I have an app built up with React and Material UI. Within one view it is possible to have several text fields and several buttons. Now, when I have the focus on one text field and then press Tab I cannot reliably anticipate which one of the controls will be the next one to get the focus. I want to first tab through all the text fields and then secondly tab through all the buttons.

enter image description here

<DialogContent>
    <DialogContentText>
        The username and password that were used are incorrect. Please provide the correct credentials in order to login to the API.
        <Stepper activeStep={this.state.credentialsStep} orientation='vertical'>
            {
                this.steps.map((label, index) => (
                    <Step key={label}>
                        <StepLabel>{label}</StepLabel>
                        <StepContent>
                            <Typography>{this.stepContent[index]}</Typography>
                            {this.stepAction[index]}
                            <Grid container direction='row' className='m-t-26'>
                                <Button color='primary'
                                        onClick={() => {
                                    this.state.credentialsStep === 0 ? this.onClickCancel() : this.onClickBack();
                                }}>
                                    {this.state.credentialsStep === 0 ? 'Cancel' : 'Back'}
                                </Button>
                                <Button variant='contained'
                                        color='primary'
                                        onClick={() => {
                                    this.state.credentialsStep === this.steps.length - 1 ? this.onClickLogin() : this.onClickNext();
                                }}>
                                    {this.state.credentialsStep === this.steps.length - 1 ? 'Login' : 'Next'}
                                </Button>
                            </Grid>
                        </StepContent>
                    </Step>
                ))
            }
        </Stepper>
    </DialogContentText>
</DialogContent>

Is there a way to set the tab order of controls?

like image 822
Socrates Avatar asked Mar 04 '19 22:03

Socrates


1 Answers

You can control this with the tabIndex property, but you may be better off to figure out how to have the elements appear in the source in the order you would want the focus to go.

I have found this resource handy: https://bitsofco.de/how-and-when-to-use-the-tabindex-attribute/

When to use a positive tabindex value

There is almost no reason to ever use a positive value to tabindex, and it is actually considered an anti-pattern. If you’re finding the need to use this value to change the order in which elements become focusable, it is likely that what you actually need to do is change the source order of the HTML elements.

One of the problems with explicitly controlling tabindex order is that any elements with a positive value are going to come before any other focusable elements that you haven't explicitly put a tabindex on. This means that you could end up with very confusing focus order if you miss any elements that you would want in the mix.

If you want to have the button on the right come before the button on the left in the focus order, there are various CSS options that would allow the button on the right to come first in the source order.

If, however, you decide that explicitly specifying the tabindex is your best option, here is an example showing how to do this for TextField and Button:

import React from "react";
import ReactDOM from "react-dom";

import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";

function App() {
  return (
    <div className="App">
      <TextField label="1" inputProps={{ tabIndex: "1" }} />
      <br />
      <TextField label="3" inputProps={{ tabIndex: "3" }} />
      <br />
      <TextField label="2" inputProps={{ tabIndex: "2" }} />
      <br />
      <Button tabIndex="5">Button 5</Button>
      <Button tabIndex="4">Button 4</Button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit tabindex

like image 160
Ryan Cogswell Avatar answered Oct 21 '22 19:10

Ryan Cogswell