Is ther anyway to set the Material UI Tabs unselected as default? - material-ui

I'm using the material UI Tabs in my project cause I thought it fits my web logic.
However, I need to set it as unselected as default. What I did is set the default state value as 'undefinded'. It acturly works as the 1st item of the Tabs won't be selected as default, but I also getting the following error from the console:
Material-UI: The value provided to the Tabs component is invalid.
None of the Tabs' children match with undefined.
You can provide one of the following values: 0, 1, 2.
Anyone knows how to accomplish my target and avoid the error message?
export default function SimpleTabs() {
const classes = useStyles();
const [value, setValue] = React.useState(); //I set the default value to undefinded to make the Tabs unselected as default but also getting the error message.
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={handleChange} aria-label="simple tabs example">
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0}>
Item One
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Three
</TabPanel>
</div>
);
}

From the docs > Props > value:
The value of the currently selected Tab. If you don't want any selected Tab, you can set this prop to false.
To accomplish this, set the initial value to false:
const [value, setValue] = React.useState(false);

Related

Material UI - How Do I Pass In Styles Through the Select Component To Change The Popover Menu Look?

I am currently using the following to generate a select dropdown on my page:
<Select>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>
When I click on the dropdown on the page, an element with MuiPaper-root class appears on the page. This shows me the list of options in menu item format. I would like to style the MuiPaper-root element.
Is there a way to do this by passing in an attribute to the <Select> component?
Yes, you can change the paper by MenuProps
https://material-ui.com/api/select/#props
const useStyles = makeStyles((theme) => ({
paper: {
"& ul": {
backgroundColor: "red",
},
}
}));
export default function CustomizedSelects() {
const classes = useStyles();
return (
<Select MenuProps={{ classes: { paper: classes.paper} }}>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>);
}

Material ui Checkbox is not working in React-hook form

I want to make a Form with validation for that I used react-hook-form with Material UI. And for validation, yup and hook/resolver are also used. when I click the Checkbox I want to show another textField but the checkbox is not working. watch is used for that which comes from react-hook-form(useForm). what is my mistake? plz, help.
Here is my code: - codesanbox
You've to use the Controller or useController for the MUI checkbox, for instance:
<Controller
name="hasPhone"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Checkbox
defaultValue={data.hasPhone}
defaultChecked={data.hasPhone}
color="primary"
onChange={(e) => field.onChange(e.target.checked)}
checked={field.value}
/>
}
label="Do you have a phone"
/>
)}
/>
👉🏻 https://codesandbox.io/s/practical-morning-v6yp1
for those who are struggling with MUI5, NextJs 12 and RHF 7 in typescript, here is how I make it working
Please note that the RHF Controller is inside the FormControlLabel and not the opposite. Also the defaultValue matters
import { FormControlLabel } from "#mui/material";
import Checkbox, { CheckboxProps } from "#mui/material/Checkbox";
import { Control, Controller } from "react-hook-form";
type ICheckBoxFieldProps = CheckboxProps & {
name: string;
control: Control;
label: string;
};
const CheckBoxField: React.FC<ICheckBoxFieldProps> = ({
name,
control,
label,
defaultChecked,
...rest
}: ICheckBoxFieldProps): JSX.Element => {
return (
<FormControlLabel
label={label}
control={
<Controller
name={name}
control={control}
defaultValue={!!defaultChecked}
render={({ field }) => (
<Checkbox
checked={field.value}
onChange={field.onChange}
{...rest}
/>
)}
/>
}
/>
);
};
export default CheckBoxField;
and how to call it inside a form or a FormProvider
<CheckBoxField
name="istrue"
control={control}
defaultChecked={true}
label="isTrue"
color="success"
/>

Incorrect popover menu position when anchor element is externalized into another component

I'm new to both React and Material-UI. While examples work fine and perfectly make sense, they all use inline elements for both triggering button and the menu itself. I want to have some conditionals. For this, I'd rather have a separate component/function that renders this or that. However as soon as I move triggering button into a function, I get
Material-UI: the `anchorEl` prop provided to the component is invalid.
The anchor element should be part of the document layout.
Make sure the element is present in the document or that it's not display none.
I looked through similar questions here, but none of them looked relevant… or I didn't get them:(
Here is the code for modified example where I want to externalize button rendering into a function (to later add conditional and what not)
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const Qqq = () => {
return (
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Broken Menu
</Button>
)
}
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<p> hello</p>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Qqq />
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
Here is the fiddle
https://codesandbox.io/s/material-demo-7bnki?fontsize=14&hidenavigation=1&theme=dark . I did try to use SO code snippet, but I was getting some error about https://stacksnippets.net/js :(
What am I missing to make things work?
placing Qqq code inside SimpleManu is causing Qqq to remount on every SimpleMenu render.
Because Qqq remounted, the anchorEl reference is no longer valid.
To fix that, move Qqq outside SimpleMenu.
const Qqq = (props) => {
return (
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={props.handleClick}
>
Broken Menu
</Button>
)
}
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<p> hello</p>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Qqq handleClick={handleClick}/>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
Code Sandbox
To see that Qqq really re mounts on every SimpleMenu render, go to the Code Sandbox and move Qqq to be inside SimpleMenu like before.
useEffect will print to console on every mount, and you can see what happens.

Over-ride styling for Material-UI Tag

I was unable to over ride the styling for Material UI's Tabs in React. I used the component wanted to override it's indicator color, text color but failed.
I already tried adding a new className to override the values but failed. event I switch the indicator color and text color to none, it only switch back to the default setting.
<Tabs value={TabValue} className={classes.tabs}
indicatorColor="primary"
textColor="primary"
onChange={this.handleChange}
>
I expect the .tabs will change the value of my indicator and text color but nothing happens
Hope someone can enlighten me on this!
According to Tabs docs:
indicatorColor can be one of: 'primary', 'secondary'. default is 'secondary'
textColor can be one of: 'primary', 'secondary', 'inherit'. default is 'inherit
In the following example, I change (not override) the default textColor and indicatorColor:
<AppBar position="static">
<Tabs value={value} onChange={handleChange}
indicatorColor="primary" //default is secondary
textColor="secondary" //default is inherit
>
<Tab label="Item One" />
<Tab label="Item Two" />
<Tab label="Item Three" />
</Tabs>
</AppBar>
If you want to override the primary and secondary colors, use MuiTheme:
import { createMuiTheme } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
import {green, blue} from '#material-ui/core/colors';
const theme = createMuiTheme({
palette: { // i override the default palette
primary: green,
secondary: blue
}
});
And than wrap your component with ThemeProvider:
<ThemeProvider theme={theme}>
<AppBar position="static">
<Tabs value={value} onChange={handleChange} indicatorColor="secondary">
<Tab label="Item One" />
<Tab label="Item Two" />
<Tab label="Item Three" />
</Tabs>
</AppBar>
</ThemeProvider>
You can refer to this CodeSandbox working example: https://codesandbox.io/s/material-demo-49mym?fontsize=14

material-ui tab conpment Too slow to switch

I have a problem in switching component. It's too slow to switch animation, there are more delays than 1000ms.
My Component structure looks like this:
<div>
<Tabs
value={value}
onChange={this.handleChange}
>
<Tab label="Item One" />
<Tab label="Item Two" />
</Tabs>
{value === 0 && <TabContainer>Item One</TabContainer>}
</div>
The component is a complex component, where there are many data needs to be displayed.
I want the < Tab > component to complete the switching animation immediately, instead of waiting to happen with the < TabContainer > component.