I have an appbar with an image link, a warning to show the user which environment they are on, and some text which shows details on the current logged in user.
I am testing accessibility with a screen reader, but tab focus on the user details is skipped in favor of a link in my sidebar.
How can I get tab focus on the user details correctly?
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<div>
<Box style={{ display: "flex", alignItems: "center" }}>
<a aria-label="Logo Link to home page" className={classes.prodLink} href="/home">
<SVGLOGO className="logo_stack" />
<SVGLOGOHORI className="logo" />
</a>
<Typography aria-label="environment warning" className={classes.envFlag} hidden={hidden}>
You are on the {process.env.REACT_APP_ENVIRONMENT} environment. Click{" "}
<a
aria-label="Link to production environment"
className={classes.prodLink}
href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
rel="noreferrer"
>
here
</a>{" "}
to go to production.
</Typography>
</Box>
// The user details are here. Focus on this information is being skipped
<Box
id="user-info-box"
aria-label="Logged in user details"
>
<i icon }}></i>
<Box style={{ marginLeft: "10px" }}>
<Typography className={classes.userInfo} aria-label="User name and role">
{loggedUser} {userRole}
</Typography>
<Typography className={classes.userInfo} aria-label="User's experience">
{userExperience}
</Typography>
</Box>
</Box>
</div>
</Toolbar>
</AppBar>
Use tabindex to make the user details focusable. See this answer for more details: Influence tab order of Material UI controls
Maybe this link could also be helpful: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex?retiredLocale=de
What do you mean by user details? Something to fill out like a form or is it just plain text?
You do not interact with plain text (like <p>) using tab key, you can scroll with arrow keys in order to read the information. The tab key is used to interact with links and buttons.
Related
I have a centered Toolbar in Material UI that has 3 components. Each component is a button. I want to add a margin around each button. I tried adding the {mt} option to the component button as below, but nothing changed. I've been experimenting with makeStyles, but haven't figured it out.
<Box display="flex">
<Box m="auto">
<Toolbar>
<SeasonComponent>
<WeekComponent>
<GameComponent>
</Toolbar>
</Box>
</Box>
Season component:
return (
<div>
<Button
variant="outlined"
color="primary"
onClick={handleClickOpen}
mt={2}
>
Button text
</Button>
</div>
Here is a picture of the buttons:
You can wrap buttons in a horizontal <Stack>:
<Toolbar>
<Stack spacing={2} direction="row">
<SeasonComponent>
<WeekComponent>
<GameComponent>
</Stack>
</Toolbar>
Here's a simple example: https://codesandbox.io/s/basicbuttons-material-demo-forked-0gpgz?file=/demo.js:234-269
Rather than upgrade my repo to version 5 right now, I just added an invisible button between the buttons. Not a perfect solution, but it solved the problem in the short term.
// SpacerButton.js
import React from 'react';
import Button from '#material-ui/core/Button';
const style = {
minWidth: 1
}
export default function SpacerButton(props) {
return (
<Button variant="text" style={style}>
</Button>
);
}
Suppose I have a Material-UI FAB that's code looks like this:
<Fab size="medium" color="primary" aria-label="add">
<AddIcon />
</Fab>
I have a controlled way to toggle between this other state:
<Fab
variant="extended"
size="medium"
color="primary"
aria-label="add"
>
<NavigationIcon/>
Extended
</Fab>
My question is how do I achieve some kind of animation between these two states? I'm thinking of a way when the FAB expands, instead of suddenly displaying the text. I can't figure it out, any help is appreciated.
You could use MUI Transitions for example a Zoom animation. So your code becomes:
<Zoom
in={checked} //<-- checked is a bool that you should set to true when this Fab is active
>
<Fab size="medium" color="primary" aria-label="add">
<AddIcon />
</Fab>
</Zoom>
And the same thing for the other Fab.
I am having a problem with stacking some cards on the mobile version of an application I'm developing that is using a react conversation component. On the desktop version and in inspect mode, the cards stack perfectly with a 15px space between them but when I fire it up on iPhone, I get the result you can see in the 3rd picture. I cannot find where this bug comes from and any help or similar issues stories are very welcome.
<Box
display="flex"
flexDirection="column"
style={{
overflowY: 'auto',
WebkitOverflowScrolling: 'touch',
}}
onScroll={handleScroll}
{...conversationProps}
>
{messages.map((item, index) => (
<Box
ref={ref}
display="flex"
flexDirection="row"
justifyContent={
item.user.username === username ? 'flex-end' : 'flex-start'
}
marginBottom={Spaces.component}
>
<ApplicationMessage
key={index}
isFromMe={item.user.username === username ? true : false}
profilePicture={item.user.profile_picture}
username={item.user.username}
timestamp={item.timestamp}
message={item.data.message}
timestampLanguage={timestampLanguage}
containerProps={{ flexShrink: 0 }}
/>
</Box>
))}
</Box>
On desktop:
On responsive console (chrome):
On Safari:
Thank you,
Max
To fix it, I just removed flex property to the scrollable (overflow) div.
It renders something like that in my code :
<Box
overflowY="auto"
onScroll={handleScroll}
{...conversationProps}
>
{messages.map((item, index) => (
<Box
ref={ref}
display="flex"
flexDirection="row"
justifyContent={
item.user.username === username ? 'flex-end' : 'flex-start'
}
marginBottom={Spaces.component}
>
<ApplicationMessage
key={index}
isFromMe={item.user.username === username ? true : false}
profilePicture={item.user.profile_picture}
username={item.user.username}
timestamp={item.timestamp}
message={item.data.message}
timestampLanguage={timestampLanguage}
containerProps={{ flexShrink: 0 }}
/>
</Box>
))}
</Box>
I have added the material ui error message display to my text field, if I click on the button without any text typed on the text field, an error message will be shown, this message will push down the button, I want to stop that, I am unable to find the way to do that
This is my form code.
<Grid container justify='center' alignContent='center' >
<Grid item xs={12} >
<TextField
id="outlined-full-width"
label="Input"
style={{ width:'100%',marginTop:30 }}
placeholder="Add A Todo Item "
margin="normal"
InputLabelProps={{
shrink: true,
}}
error={this.state.errorState }
helperText={
this.state.errorState && "Item name can't be blank"
}
size="large"
variant="outlined"
value={newItem}
onChange={handleInput}
/>
</Grid>
</Grid>
<CardActions>
<Grid container justify='center' alignContent='center' >
<Grid item xs={12} md={6} >
<Button
type="submit"
variant="contained"
color='inherit'
fontsize='inherit'
style={styles.add}
startIcon={<AddIcon/>}
>
Add Item
</Button>
</Grid>
</Grid>
</CardActions>
</form>
In your main theme, add these rules so that the helperText / error text stays within the margin of your field. This will prevent the text from pushing down the content underneath.
const theme = createTheme({
// ...
MuiFormHelperText: {
root: {
// Use existing space / prevents shifting content below field
marginTop: 0,
height: 0,
},
}
})
I'm using Meteor + ReactJS and I'm pulling Material-UI via node modules.
<RadioButtonGroup name="shipSpeed" defaultSelected="not_light">
<RadioButton value="light" label="Simple" style={styles.radioButton} />
<RadioButton value="not_light" label="Selected by default" style={styles.radioButton} />
<RadioButton value="ludicrous" label="Disabled" disabled={true} style={styles.radioButton} />
</RadioButtonGroup>
Here is what it renders.
But it won't change values like it's supposed to do on click. It just stays static.
Check the below example. You have to pass valueSelected and onChange props to RadioButtonGroup to get the values of RadioButton. In onChange function set the selected value in state and pass that state to valueSelected that’s all. As simple as that.
<RadioButtonGroup
valueSelected={this.state.cranRadio}
onChange={this.handleCRAN}
style={{ display: "flex", flexWrap: "wrap", justifyContent: "space-between" }}
name="coin"
defaultSelected="not_light"
>
<RadioButton
value="Yes"
label="Yes"
inputStyle={styles.inputStyle}
style={{ width: "auto" }}
labelStyle={{ marginLeft: "-10px" }}
/>
<RadioButton
value="No"
label="No"
style={{ width: "auto" }}
inputStyle={styles.inputStyle}
labelStyle={{ marginLeft: "-10px" }}
/>
</RadioButtonGroup>;
I maybe having similar issue with Checkbox.
If i provide a handler, then the checkbox is not showing 'tick' when checked. Without handler, the check shows with ripple effect.
import mui from 'material-ui';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
...
<mui.Checkbox
label="Employed"
name="Employed"
labelPosition="left"
style={fstyles.checkbox}
onCheck={props.cb}
/>
If I dont provide the onCheck, then the check shows.. should the handler return some value? currently it sets my top level component's state . I tried returning true, but did not help.