Tab Color disorder and single click ripple effect disappears after I add active tabs - material-ui

Here's my header copmponent where I try to apply active tabs effect, the text completely disappers.
Header.js
import {
AppBar,
Toolbar,
useScrollTrigger,
Typography,
Tabs,
Tab,
Button,
} from "#mui/material";
import DeveloperModeIcon from "#mui/icons-material/DeveloperMode";
import { Box } from "#mui/system";
import { styled } from "#mui/material/styles";
import { Link } from "react-router-dom";
const Header = () => {
const [value, setValue] = useState(window.location.pathname);
function ElevationScroll(props) {
const { children } = props;
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 0,
});
return React.cloneElement(children, {
elevation: trigger ? 4 : 0,
});
}
const TabComponent = styled(Tab)(({ theme }) => ({
fontWeight: 600,
fontSize: "1rem",
textTransform: "none",
// color: theme.palette.common.white,
}));
const onTabChangeHandler = (event, newValue) => {
setValue(newValue);
};
return (
<React.Fragment>
<ElevationScroll>
<AppBar position="fixed">
<Toolbar>
<DeveloperModeIcon sx={{ fontSize: "3rem" }} />
<Typography variant="h4">Lopxhan Development</Typography>
<Tabs
sx={{ marginLeft: "auto" }}
value={value}
onChange={onTabChangeHandler}
aria-label="secondary tabs example"
>
<TabComponent label="Home" component={Link} to="/" value="/" />
<TabComponent
label="Services"
component={Link}
to="/services"
value="/services"
disableRipple
/>
<TabComponent
label="Projects"
component={Link}
to="/projects"
value="/projects"
/>
<TabComponent
label="About Us"
component={Link}
to="/aboutus"
value="/aboutus"
/>
<TabComponent
label="Conatct Us"
component={Link}
to="/contactus"
value="/contactus"
/>
</Tabs>
<Button
variant="contained"
color="secondary"
sx={{
borderRadius: "50px",
fontWeight: 600,
}}
>
Get a Quote
</Button>
</Toolbar>
</AppBar>
</ElevationScroll>
<Box
sx={[
(theme) => ({
marginBottom: {
...theme.mixins.toolbar,
},
}),
]}
/>
</React.Fragment>
);
};
export default Header;
Theme.js
const arcBlue = "#0B72B9";
const arcOrange = "#e67700";
const arcGrey = "#868686";
export const appTheme = createTheme({
palette: {
common: {
blue: arcBlue,
orange: arcOrange,
white: "#fff",
},
primary: {
main: arcBlue,
},
secondary: {
main: arcOrange,
},
},
});
App.js
import { Routes, Route } from "react-router-dom";
import { ThemeProvider } from "#mui/material/styles";
import Header from "./components/UI/Header";
import { appTheme } from "./components/UI/Theme";
import HomePage from "./components/pages/HomePage";
import ServicesPage from "./components/pages/ServicesPage";
import ProjectsPage from "./components/pages/ProjectsPage";
import GetAQuotePage from "./components/pages/GetAQuotePage";
import AboutUsPage from "./components/pages/AboutUsPage";
import ContactUsPage from "./components/pages/ContactUsPage";
function App() {
return (
<ThemeProvider theme={appTheme}>
<Header />
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/services" element={<ServicesPage />} />
<Route path="/projects" element={<ProjectsPage />} />
<Route path="/aboutus" element={<AboutUsPage />} />
<Route path="/contactus" element={<ContactUsPage />} />
<Route path="/getaquote" element={<GetAQuotePage />} />
</Routes>
</ThemeProvider>
);
}
export default App;
I tried applying textColor and indicatorColor to Tabs, and its kinda somehow shows the tab text but ripple effect changes to double click. Also ripple effect on tab changes to double click as soon as I add active tab effect.

Related

How can I add linear-gradient to my Material-UI (v5.11.5) background

I have an Appbar that has a fixed colour background that has been applied using the createTheme module for material-ui. I have been asked to apply a linear gradient for a transitioning color effect to the Appbar. I have tried using palette: {
background: {
paper: '-webkit-linear-gradient(to left, #30e8bf, #ff8235)',
}, in my createTheme then using sx={{ bgcolor: 'background.paper' }} in my Appbar.
Any suggestion to changes I need to make ?
import * as React from 'react'
import AppBar from '#mui/material/AppBar'
import Box from '#mui/material/Box'
import Toolbar from '#mui/material/Toolbar'
import Stack from '#mui/material/Stack'
import Button from '#mui/material/Button'
import Tabs from '#mui/material/Tabs'
import Tab from '#mui/material/Tab'
import Typography from '#mui/material/Typography'
import IconButton from '#mui/material/IconButton'
import MenuIcon from '#mui/icons-material/Menu'
import AccountCircle from '#mui/icons-material/AccountCircle'
import Switch from '#mui/material/Switch'
import FormControlLabel from '#mui/material/FormControlLabel'
import FormGroup from '#mui/material/FormGroup'
import MenuItem from '#mui/material/MenuItem'
import Menu from '#mui/material/Menu'
import CssBaseline from '#mui/material/CssBaseline'
import { ThemeProvider, createTheme } from '#mui/material/styles'
import Chip from '#mui/material/Chip'
import Check from '#mui/icons-material/Check'
const finalTheme = createTheme({
components: {
// Name of the component
MuiButton: {
styleOverrides: {
// Name of the slot
root: {
// Some CSS
fontSize: '3rem',
backgroundColor: '#fff',
},
},
},
},
typography: {
// In Chinese and Japanese the characters are usually larger,
// so a smaller fontsize may be appropriate.
fontSize: 15,
},
palette: {
background: {
paper: '-webkit-linear-gradient(to left, #30e8bf, #ff8235)',
},
},
})
export default function NavBar() {
const [auth, setAuth] = React.useState(true)
const [anchorEl, setAnchorEl] = React.useState(null)
const [value, setValue] = React.useState('apple')
const handleChange = (event) => {
setAuth(event.target.checked)
}
const handleMenu = (event) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
return (
<React.StrictMode>
<Box sx={{ flexGrow: 1 }}>
<ThemeProvider theme={finalTheme}>
<AppBar position="static" sx={{ bgcolor: 'background.paper' }}>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }} />
<Tab value="0" label="Sessions" />
<Tab value="1" label="Gallery" />
<Tab value="2" label="About Us" />
{auth && (
<div>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleMenu}
color="inherit"
>
<AccountCircle />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
</Menu>
</div>
)}
</Toolbar>
</AppBar>
</ThemeProvider>
</Box>
</React.StrictMode>
)
}

REACT 17 wrap mui tab in form how to control form submission with react hook form

I'm stuck can a charitable soul advise me : I have a form that wraps 3 tabs
which contain text fields
interface TabPanelProps {
// eslint-disable-next-line react/require-default-props
children?: ReactNode;
index: number;
value: number;
}
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
aria-labelledby={`simple-tab-${index}`}
hidden={value !== index}
id={`simple-tabpanel-${index}`}
role="tabpanel"
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<div>{children}</div>
</Box>
)}
</div>
);
}
function getTab(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
export default function tt({ closeModal, testData }: any) {
const [value, setvalue] = useState(0);
const methods = useForm<MyInterface>();
const {
register,
handleSubmit,
formState: { errors, isDirty },
} = methods;
const onSubmit = (formValue: MyInterface) => {
console.log("isSubmitted");
console.log(formValue);
};
const handleChangeTab = (event: SyntheticEvent, newValue: number) => {
setvalue(newValue);
};
return (
<FormProvider {...methods} >
< form className="myForm"
onSubmit={methods.handleSubmit(onSubmit)} >
<Box sx={{ width: '100%' }}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs aria-label="basic tabs example" onChange={handleChangeTab} value={value}>
<Tab label="1" {...getTab(0)} />
<Tab label="2" {...getTab(1)} />
<Tab label="3" {...getTab(2)} />
</Tabs>
</Box>
<TabPanel index={0} value={value}>
<Component1 />
</TabPanel>
<TabPanel index={1} value={value}>
<Component2 testData={testData} />
</TabPanel>
<TabPanel index={2} value={value}>
<Component3 />
</TabPanel>
</Box>
<DialogActions>
<Button onClick={methods.handleSubmit(onSubmit)}>Enregistrer</Button>
<Button onClick={closeModal}>Annuler</Button>
</DialogActions>
</form>
</FormProvider>
);
}
2 and 3 have for example juste textField which are required in Component 1 but not in Component 2 and 3 :
import { useFormContext } from "react-hook-form";
import { TextField } from '#mui/material';
export default function Component1() {
const { register, formState } = useFormContext();
return (
<>
<TextField
error={Boolean(formState.errors?.name)}
fullWidth
helperText={Boolean(formState.errors?.name) === false ? "give the name" : formState.errors.name?.message}
{...register('name', { required: "name is required." })}
label="name"
variant="standard"
/>
</>
);
}
code in the Component2:
import { Controller, useFormContext } from 'react-hook-form';
import { Checkbox, Chip, FormControl, InputLabel, ListItemText, MenuItem, Select, SelectChangeEvent, TextField } from '#mui/material';
export default function Component3(props: any) {
const { register, control } = useFormContext();
return (
<>
<FormControl sx={{ m: 1, minWidth: '100%' }} variant="standard">
<InputLabel id="test">En prod</InputLabel>
<Controller
control={control}
defaultValue=""
name="test"
render={({ field }) => (
<Select labelId="test" {...field}>
<MenuItem value="yes">yes</MenuItem>
<MenuItem value="no">no</MenuItem>
</Select>
)}
/>
</FormControl>
my problem is:
when I change tab without clicking in a field of the form, that is sent even if the required fields are not filled.
On the contrary when I click in any field and the required fields are not filled in isDirty remains true.
Which is normal.
But if I fill in the required fields and I change tab isDirty always stays true and I can't send the form.
Thank you for your help!!

Why the theme doesnt change to darkmode - using Material ui ThemeProvider? What am I doing wrong?

on my app.tsx file
<ThemeProvider theme={darkTheme}>
<CssBaseline />
<Paper>
<Layout>
<Component {...pageProps} />
</Layout>
{/* <AnimatedWrapper children></AnimatedWrapper> */}
</Paper>
</ThemeProvider>
then I made a useDarkMode.ts function
export const useDarkMode = () => {
const [darkState, setDarkState] = useState<boolean>(false);
const palletType = darkState ? 'dark' : 'light';
const darkTheme = createMuiTheme({
palette: {
type: palletType,
},
});
return { darkState, setDarkState, darkTheme };
};
and I am using Switcher from material ui on the NavBar component
export const NavBar = (): JSX.Element => {
const { darkState, setDarkState } = useDarkMode();
const classes = useStyles();
...
<Typography className={classes.logoText}>
<Switch checked={darkState} onChange={() => setDarkState(!darkState)} />
</Typography>

How can I override the user-select: none in RadioButton and CheckBox control labels?

Currently for pre 1.0.0 releases Material-UI does not allow text selection on RadioButton and Checkbox control labels.
How can I override this behavior? Apparently passing labelStyle={{ userSelect: 'all' }} to the component doesn't help.
What I'm trying to achieve is being able to highlight the text in the option label as per this screenshot:
You need to override the CSS class that prevents selection of the labels.
The labels are made with components of type FormControlLabel. At the bottom of the doc page for that component, you can see that the CSS label class is available to override.
So, you need to override the label class on each FormControlLabel like this:
// Define the overriding style
const styles = () => ({
selectableLabel: {
userSelect: 'all',
},
});
// Override the label CSS that prevents selection
<FormControlLabel classes={{ label: classes.selectableLabel }} value="male" control={<Radio />} label="Male" />
Here's full code for a group of selectable radio buttons (derived from the Radio buttons example in the docs:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Radio, { RadioGroup } from 'material-ui/Radio';
import { FormLabel, FormControl, FormControlLabel } from 'material-ui/Form';
const styles = theme => ({
root: {
display: 'flex',
},
formControl: {
margin: theme.spacing.unit * 3,
},
group: {
margin: `${theme.spacing.unit}px 0`,
},
selectableLabel: {
userSelect: 'all',
},
});
class RadioButtonsGroup extends React.Component {
state = {
value: '',
};
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<FormControl component="fieldset" required className={classes.formControl}>
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup
aria-label="gender"
name="gender1"
className={classes.group}
value={this.state.value}
onChange={this.handleChange}
>
<FormControlLabel classes={{ label: classes.selectableLabel }} value="male" control={<Radio />} label="Male" />
<FormControlLabel classes={{ label: classes.selectableLabel }} value="female" control={<Radio />} label="Female" />
<FormControlLabel classes={{ label: classes.selectableLabel }} value="other" control={<Radio />} label="Other" />
<FormControlLabel classes={{ label: classes.selectableLabel }} value="disabled" disabled control={<Radio />} label="Disabled" />
</RadioGroup>
</FormControl>
</div>
);
}
}
RadioButtonsGroup.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(RadioButtonsGroup);
And here's the full code for the Checkbox buttons (derived from the Checkboxes example in the doc):
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import { FormControl, FormGroup, FormControlLabel } from 'material-ui/Form';
import Checkbox from 'material-ui/Checkbox';
const styles = {
selectableLabel: {
userSelect: 'all',
},
};
class CheckboxesGroup extends React.Component {
state = {
gilad: true,
jason: false,
antoine: true,
};
handleChange = name => (event, checked) => {
this.setState({ [name]: checked });
};
render() {
const { classes } = this.props;
return (
<FormControl component="fieldset">
<FormGroup>
<FormControlLabel
classes={{ label: classes.selectableLabel }}
control={
<Checkbox
checked={this.state.gilad}
onChange={this.handleChange('gilad')}
value="gilad"
/>
}
label="Gilad Gray"
/>
<FormControlLabel
classes={{ label: classes.selectableLabel }}
control={
<Checkbox
checked={this.state.jason}
onChange={this.handleChange('jason')}
value="jason"
/>
}
label="Jason Killian"
/>
</FormGroup>
</FormControl>
);
}
}
CheckboxesGroup.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(CheckboxesGroup);

RadioButtonGroup within nested List

I'm using Material-UI and I'd like to use the List/ListItem Component to group my Radio Buttons.
Similar to this one:
<RadioButtonGroup ...>
<List>
<ListItem
...
nestedItems={[
<RadioButton ... />,
<RadioButton ... />
]}
/>
<ListItem
...
nestedItems={[
<RadioButton ... />,
<RadioButton ... />
]}
/>
</List>
</RadioButtonGroup>
Is there a way to archive this?
Thanks.
My temporary workaround is to use checkboxes which look and behave like radio buttons.
import List from 'material-ui/lib/lists/list';
import ListItem from 'material-ui/lib/lists/list-item';
import Checkbox from 'material-ui/lib/checkbox';
import RadioChecked from 'material-ui/lib/svg-icons/toggle/radio-button-checked';
import RadioUnchecked from 'material-ui/lib/svg-icons/toggle/radio-button-unchecked';
...
onChangeRadio = (event) => this.setState({ radioValue: event.target.value });
...
<List>
<ListItem
primaryText='First Group'
primaryTogglesNestedList={true}
nestedItems={[
<ListItem
primaryText='Radio 1'
leftCheckbox={
<Checkbox
value='1'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '1'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
<ListItem
primaryText='Radio 2'
leftCheckbox={
<Checkbox
value='2'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '2'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>}
/>
]}
/>
<ListItem
primaryText='Second Group'
primaryTogglesNestedList={true}
nestedItems={[
<ListItem
primaryText='Radio 3'
leftCheckbox={
<Checkbox
value='3'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '3'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
<ListItem
primaryText='Radio 4'
leftCheckbox={
<Checkbox
value='4'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '4'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
]}
/>
</List>
I hope there is a better solution than this.
Maybe this will help
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemSecondaryAction from '#material-ui/core/ListItemSecondaryAction';
import ListItemText from '#material-ui/core/ListItemText';
import Checkbox from '#material-ui/core/Checkbox';
import IconButton from '#material-ui/core/IconButton';
import CommentIcon from '#material-ui/icons/Comment';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormHelperText from '#material-ui/core/FormHelperText';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
overflow: 'auto',
maxHeight: 500,
backgroundColor: theme.palette.background.paper,
},
});
class RadioList extends React.Component {
state = {
checked: 0,
};
handleToggle = value => () => {
this.setState({ checked: value });
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<List>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(value => (
<ListItem
key={value}
role={undefined}
dense
button
onClick={this.handleToggle(value)}
className={classes.listItem}
>
<FormControlLabel control={<Radio />}
checked={this.state.checked === value}
tabIndex={-1}
disableRipple
/>
<ListItemText primary={`Line item ${value + 1}`} />
</ListItem>
))}
</List>
</div>
);
}
}
RadioList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(RadioList);