I am currently using material ui and I would like to change the color of my icon class when the active class is triggered by react-router-dom's NavLink
my code is as follows:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import Typography from "#material-ui/core/Typography";
import PeopleIcon from "#material-ui/icons/People";
import AssignmentOutlinedIcon from "#material-ui/icons/AssignmentOutlined";
import TransferWithinAStationOutlinedIcon from "#material-ui/icons/TransferWithinAStationOutlined";
import ScheduleIcon from "#material-ui/icons/Schedule";
import { NavLink } from "react-router-dom";
import { BrowserRouter as Router } from "react-router-dom";
const drawerWidth = 220;
const useStyles = makeStyles((theme) => ({
paper: {
width: drawerWidth,
borderBottomLeftRadius: 10,
borderTopLeftRadius: 10,
height: "calc(100% - 10px)",
border: "solid 1px #CCCCCC",
paddingTop: 5
},
icon: {
width: 20,
height: 20,
color: "#999999"
},
listItem: {
textDecoration: "none",
color: "inherit",
padding: 5,
cursor: "pointer",
"&:hover": {
backgroundColor: "#EEEEEE"
}
},
active: {
backgroundColor: "#999999",
color: "white",
"&:hover": {
backgroundColor: "#999999"
}
}
}));
const App = () => {
const classes = useStyles();
const routes = [
{
path: "/admin/users",
name: "Users",
icon: <PeopleIcon className={classes.icon} />
},
{
path: "/admin/assignments",
name: "Assignments",
icon: <AssignmentOutlinedIcon className={classes.icon} />
},
{
path: "/admin/transfers",
name: "Transfers",
icon: <TransferWithinAStationOutlinedIcon className={classes.icon} />
},
{
path: "/admin/liveClock",
name: "Live Clock",
icon: <ScheduleIcon className={classes.icon} />
}
];
return (
<>
<Paper variant="outlined" square className={classes.paper}>
{routes.map((r, i) => {
return (
<Router>
<NavLink
activeClassName={classes.active}
to={r.path}
key={i}
style={{
display: "flex",
alignItems: "center",
paddingLeft: 10
}}
className={classes.listItem}
>
{r.icon}
<Typography
variant="body1"
style={{ marginLeft: 10, fontSize: "15px" }}
>
{r.name}
</Typography>
</NavLink>
</Router>
);
})}
</Paper>
</>
);
};
export default App;
I would like the icon color to be white when the active class is triggered but I cannot seem to target the icon class within the active class.
Please Note: I understand my react router logic is set up incorrectly this is just to allow the active class to be triggered within my code sandbox. Thanks!
attached is a code sandbox for debuggging:
https://codesandbox.io/s/vigilant-curran-iwdtq?file=/src/App.js:0-2628
Try to reference your icon style within your active style:
active: { ...
'& $icon':{ color: '#EEEEEE'}
See it live: https://codesandbox.io/s/so-answer-cute1?file=/src/App.js
I put the activeClassname behavior on hover to show it working, as you did before.
Related
Hey guys and gals i am trying to pass data from a text field in one component to another component. But the component that calls the text field is called in my Home.tsx file while i need the data from my Search.tsx file ( which also has where the text field is created ) to be sent to my searchResults.tsx file. Hope that makes sense
Here is my Home.tsx
import { ChakraProvider, Flex, Heading, IconButton, Input, Spacer, useColorMode, useDisclosure, VStack } from "#chakra-ui/react";
import Search from "../components/Search";
const Home = () => {
return(
<div>
<Flex>
<Search></Search>
</Flex>
</div>
)
}
export default Home
Here is my Search.tsx
import { TextField, IconButton} from "#material-ui/core"
import {Router, SearchOutlined } from '#material-ui/icons';
import { makeStyles } from "#material-ui/core/styles";
import "../App.css";
import { useState } from "react";
import { ChakraProvider,Box, color, position } from "#chakra-ui/react";
import { ReactComponent as Logo } from '../images/logo.svg';
const useStyles = makeStyles({
input: {
color: "blue"
}
})
const Search = () => {
const [searchTerm, setSearchTerm] = useState("");
const [displaySearchTerm, setDisplaySearchTerm] = useState("");
const useStyles = makeStyles((theme) => ({
input: {
color: "#fcba03",
},
}));
const classes = useStyles();
return(
<div>
<div className='searchCont' style={{alignItems: "center", justifyContent: 'center'}} >
<Logo style={{ height: 150, width: 300, position: "absolute", verticalAlign: "middle", marginTop: 200, left: '40%', backgroundColor: '#1a202c', borderRadius: 10 }} />
<TextField
inputProps={{color: classes.input}}
style={{width: 600, display: "flex", position: "absolute", verticalAlign: "middle", backgroundColor: "white", borderRadius: 5, alignItems: "center", justifyContent: 'center', marginTop: 400, marginBottom: 50, left: '32%', marginRight: 200}}
margin="normal"
className="textField"
fullWidth
id="standard-bare"
variant="outlined"
label="Search for Domains..."
onChange={(e) => setSearchTerm(e.target.value)}
InputProps={{
endAdornment: (
<IconButton onClick={() =>{searchTerm}}>
<SearchOutlined />
</IconButton>
),
}}
/>
</div>
</div>
)
}
export default Search
Here is my searchResults.tsx
import { Flex } from "#chakra-ui/react";
import React from "react";
import {searchTerm} from "../components/Search";
const SearchResults = () => {
return(
<div>
<Flex>
<Search data={searchTerm} /> //error here
</Flex>
</div>
)
}
export default SearchResults;
use Redux as your state management system for this, this will help you read and write states across application without worrying.
You can also try react Context if its a one off issue and you dont wana invest into the redux system and its boiler plate code, but if you face this issue more frequently as your project grows complex use redux.
just having issues with trying to implememnt a custom Step Label Icon within the nodes of the Stepper Component provided by Material UI. I am trying to implement an icon within each circle, as seen here from Material UI's demo
however, am coming across an error
Please see my code below. Thanks!
import React from 'react';
import { Typography } from '#material-ui/core';
import { withStyles, styles } from '#material-ui/core/styles';
const styles = theme => ({
checklistHeader: {
fontWeight: 'bold',
marginTop: '80px',
color: 'white'
},
connectorIcon: {
color: theme.palette.text.secondary
},
active: {
backgroundColor: 'green'
}
});
const steps = ['Select campaign settings', 'Select campaign settings', 'Select campaign settings'];
const ColorlibStepIconRoot = styled('div')(({ theme, ownerState }) => ({
backgroundColor: theme.palette.mode === 'dark' ? theme.palette.grey[700] : '#ccc',
zIndex: 1,
color: '#fff',
width: 50,
height: 50,
display: 'flex',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
...(ownerState.active && {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
}),
...(ownerState.completed && {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
}),
}));
const ColorlibStepIcon = ({
icon, active, completed, className
}) => {
const icons = {
1: <Icon style={{ color: 'red' }}>create_outline</Icon>,
2: <Icon style={{ color: 'red' }}>star</Icon>,
3: <Icon style={{ color: 'red' }}>people</Icon>,
};
return (
<ColorlibStepIconRoot ownerState={{ completed, active }} className={className}>
{icons[String(icon)]}
</ColorlibStepIconRoot>
);
};
const Stepper = ({ classes }) => {
return (
<React.Fragment>
<Typography variant="h6" align="center" gutterBottom className={classes.checklistHeader}>Please complete the following criterion</Typography>
<Stepper alternativeLabel activeStep={2} style={{ background: 'none' }}>
{steps.map(label => (
<Step key={label}>
<StepLabel StepIconComponent={ColorlibStepIcon}>{label}</StepLabel>
</Step>
))}
</Stepper>
</React.Fragment>
);
};
Stepper.defaultProps = {
};
Stepper.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles, { withTheme: true })(Stepper);
It seems like the styled component is undefined. Is there any way that I can bypass this
The styled() function is only available in v5. You either need to upgrade to MUI v5 using this installation guide or use the older API in v4, (The equivalent is withStyles):
V5
import { styled } from '#mui/material/styles';
const StyledComponent = styled(Component)({
// your styles
});
V4
import { withStyles, styles } from '#material-ui/core/styles';
const StyledComponent = withStyles({
// your styles
})(Component);
You can see the v4 docs here and the v5 docs here.
I'm trying to update from admin-on-rest to react-admin, the components on the dashboard go under the AppBar and being hidden by the appbar. How can I add margin or padding from the AppBar?
You should add a margin top to your layout.. Check the example from the react-admin documentation dedicated to custom layouts](https://marmelab.com/react-admin/Theming.html#layout-from-scratch):
// in src/MyLayout.js
import * as React from 'react';
import { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useSelector, useDispatch } from 'react-redux';
import { makeStyles } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
import {
AppBar,
Menu,
Notification,
Sidebar,
setSidebarVisibility,
ComponentPropType,
} from 'react-admin';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexDirection: 'column',
zIndex: 1,
minHeight: '100vh',
backgroundColor: theme.palette.background.default,
position: 'relative',
},
appFrame: {
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
},
contentWithSidebar: {
display: 'flex',
flexGrow: 1,
},
content: {
display: 'flex',
flexDirection: 'column',
flexGrow: 2,
padding: theme.spacing(3),
marginTop: '4em',
paddingLeft: 5,
},
}));
const MyLayout = ({
children,
dashboard,
logout,
title,
}) => {
const classes = useStyles();
const dispatch = useDispatch();
const open = useSelector(state => state.admin.ui.sidebarOpen);
useEffect(() => {
dispatch(setSidebarVisibility(true));
}, [setSidebarVisibility]);
return (
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar title={title} open={open} logout={logout} />
<main className={classes.contentWithSidebar}>
<Sidebar>
<Menu logout={logout} hasDashboard={!!dashboard} />
</Sidebar>
<div className={classes.content}>
{children}
</div>
</main>
<Notification />
</div>
</div>
);
};
MyLayout.propTypes = {
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
dashboard: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string,
]),
logout: ComponentPropType,
title: PropTypes.string.isRequired,
};
export default MyLayout;
I want to change Material UI Slider component color
I have tried to change CSS style and it's not working, then I tried the solution given in this issue and applied this code but it's not working
getMuiTheme:
const muiTheme = getMuiTheme({
slider: {
trackColor: "yellow",
selectionColor: "green"
}
});
and in Component:
<MuiThemeProvider muiTheme={muiTheme}>
<Slider
min={18}
max={90}
ValueLabelComponent={ValueLabelComponent}
defaultValue={40}
/>
</MuiThemeProvider>
It depends what version of Material-UI you are using.
Your code matches Material-UI v0.x:
import React from 'react';
import Slider from 'material-ui/Slider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import { MuiThemeProvider } from 'material-ui';
const muiTheme = getMuiTheme({
slider: {
trackColor: "yellow",
selectionColor: "red"
}
});
export default function V0Slider() {
return (
<MuiThemeProvider muiTheme={muiTheme}>
<Slider
min={18}
max={90}
ValueLabelComponent={0}
defaultValue={40}
/>
</MuiThemeProvider>
);
}
If you are using Material-UI v4, that would be the way to go:
import React from "react";
import Slider from '#material-ui/core/Slider';
import { createMuiTheme } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
const muiTheme = createMuiTheme({
overrides:{
MuiSlider: {
thumb:{
color: "yellow",
},
track: {
color: 'red'
},
rail: {
color: 'black'
}
}
}
});
export default function V4Slider() {
return (
<ThemeProvider theme={muiTheme}>
<Slider min={18} max={90} defaultValue={40} />
</ThemeProvider>
);
}
If you are using another version of material-ui, let me know which one and i'll try to help.
I did the override with the 'withStyles' of material-ui v4.
This is for the Slider styles :
const CustomSlider = withStyles({
root: {
color: "#6f8eff",
height: 3,
padding: "13px 0",
},
track: {
height: 4,
borderRadius: 2,
},
thumb: {
height: 20,
width: 20,
backgroundColor: "#fff",
border: "1px solid currentColor",
marginTop: -9,
marginLeft: -11,
boxShadow: "#ebebeb 0 2px 2px",
"&:focus, &:hover, &$active": {
boxShadow: "#ccc 0 2px 3px 1px",
},
color: "#fff",
},
})(Slider);
And just after that render your slider :
<CustomSlider
value={value}
onChange={handleChange}
step={20} />
And Color should update, i also update the thumbs here for custom thumbs.
Hope it's helps : )
When I set a className to change the background of Snackbar it does not overwrite it. Instead, when the page renders it momentarily displays the background color that I want and then is immediately overwritten.
I looked at some other Stackoverflow answers and I still can't get it working.
// imports....
import Snackbar from '#material-ui/core/Snackbar';
import createClientsStyle from "../../../PageComponents/Landing/CreateClients/style";
function CreateClients(props) {
//....code
const { classes } = props;
return (
//............code
<div>
<Snackbar
className={classes.snackbarStyle} //<--- here
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={true}
autoHideDuration={6000}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id"><div>Hi there! Some message.</div></span>}
/>
</div>
);
}
CreateClients.propTypes = {
classes: PropTypes.object.isRequired
}
const styles = (theme)=>(createClientsStyle(theme));
export default withStyles(styles)(CreateClients)
Stylesheet
const createClientsStyle = function(theme){
return {
root: {
flexGrow: 1,
position:"relative",
top:"175px"
},
logoContainer:{
position:"relative",
margin:"0 auto",
top:"120px"
},
container: {
marginTop:"0px",
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
clientItem:{
fontSize:"2em",
display:"inline-block",
textAlign:"center",
width:"100%",
color:"grey",
'&:hover': {
background: "#8a0eff3b",
transition: "0.4s"
},
},
clientItemSelected: {
background: "#8a0eff3b",
fontSize:"2em",
display:"inline-block",
textAlign:"center",
color:"grey",
'&:hover': {
background: "#8a0eff3b",
transition: "0.4s"
},
},
textField:{
width:"25em",
},
listItem:{
fontSize:'35px',//Insert your required size
},
clientButton:{
backgroundColor:"purple"
},
tinyTextClickMe:{
position:"relative",
fontSize:"0.5em",
right:"10%"
},
snackbarStyle:{
backgroundColor:"orange"
}
}
}
export default createClientsStyle
The Snackbar component handles open/close state, transitions, and positioning, but Snackbar delegates control of the look of the Snackbar (e.g. background color, typography, padding) to the SnackbarContent component.
If you look at the Customized snackbars demo, you'll see that it changes the background color by specifying a className on the SnackbarContent element rather than on the Snackbar element. You can also achieve the same effect by specifying the className within the ContentProps.
The example below demonstrates both approaches for specifying the class name for the content.
import React from "react";
import ReactDOM from "react-dom";
import Snackbar from "#material-ui/core/Snackbar";
import SnackbarContent from "#material-ui/core/SnackbarContent";
import { withStyles } from "#material-ui/core/styles";
const styles = {
snackbarStyleViaContentProps: {
backgroundColor: "orange"
},
snackbarStyleViaNestedContent: {
backgroundColor: "lightgreen",
color: "black"
}
};
function App({ classes }) {
return (
<div>
<Snackbar
anchorOrigin={{
vertical: "top",
horizontal: "right"
}}
open={true}
ContentProps={{
"aria-describedby": "message-id",
className: classes.snackbarStyleViaContentProps
}}
message={
<span id="message-id">
<div>Hi there! Some message.</div>
</span>
}
/>
<Snackbar
anchorOrigin={{
vertical: "bottom",
horizontal: "right"
}}
open={true}
>
<SnackbarContent
aria-describedby="message-id2"
className={classes.snackbarStyleViaNestedContent}
message={
<span id="message-id2">
<div>Hi there! Message 2.</div>
</span>
}
/>
</Snackbar>
</div>
);
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);