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;
Related
Having trouble moving pages in React Navigator, it worked fine when we had homeStack and would just run through an object but now that we're trying to introduce a stationary button in the header that moves to another page it is running into problem. We still move just fine when we go from first to second page, but I think we're missing something.
OnPress is working when we press the folder icon as we console logged it, but it simply takes us back to our starting screen rather than to the screen we want to get to. I've tried to share the code needed but let me know if other pages are needed.
Below is our Header component, you can see where we're trying to onPress and then navigate.
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {MaterialIcons} from '#expo/vector-icons';
import History from '../History'
import { NavigationContainer, StackActions } from "#react-navigation/native";
import { createNativeStackNavigator } from 'react-navigation-stack';
export default function Header({ navigation }){
const historyFolder = () => {
navigation.navigate('History')
}
return(
<View style={styles.header}>
<View>
<Text style={styles.headerText}></Text>
</View>
<MaterialIcons name='folder' size={28} onPress={historyFolder} style={styles.icon}></MaterialIcons>
</View>
)
}
const styles = StyleSheet.create({
header: {
width: '100%',
height: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
fontWeight: 'bold',
fontSize: 20,
color: '#333',
letterSpacing:1,
},
icon:{
position: 'absolute',
right: 16,
}
})
This is the History page that we're aiming to get to.
import { StyleSheet, Text, View, FlatList, SafeAreaView, Image } from 'react-native'
import Card from './shared/Card';
import React from 'react';
import { NavigationContainer, StackActions } from "#react-navigation/native";
import { createNativeStackNavigator } from 'react-navigation-stack';
export default function History({navigation}) {
const present = [{
id: 1,
name: 'PresentOne',
slug: 'PresentOne Slug',
image: require('../assets/present.jpeg')
},
{
id:2,
name: 'PresentTwo',
slug: 'PresentTwo Slug',
image: require('../assets/present2.jpeg')
},
{
id:3,
name: 'PresentThree',
slug: 'PresentThree Slug',
image: require('../assets/present3.jpeg')
},
{
id:4,
name: 'PresentFour',
slug: 'PresentFour Slug',
image: require('../assets/present4.jpeg')
},
{
id:5,
name: 'PresentFive',
slug: 'PresentFive Slug',
image: require('../assets/present5.jpeg')
},
];
const onePresent = ( { item } ) => (
<Card>
<View style={styles.item}>
<View style={styles.avatarContainer}>
<Image source = {item.image} style={styles.avatarContainer}/>
</View>
<Text style={styles.name}> {item.name}</Text>
<Text style={styles.slug}>{item.slug}</Text>
</View>
</Card>
)
const headerComponent = () => {
return <Text style={styles.listHeadline}>Presents</Text>
}
const itemSeperator = () => {
return <View style = {styles.seperator}/>
}
return (
<View>
<FlatList
ListHeaderComponentStyle={styles.listHeader}
ListHeaderComponent={headerComponent}
data = { present }
renderItem = { onePresent }
ItemSeperatorComponent = { itemSeperator }
ListEmptyComponent = { <Text>Empty</Text>}
/>
</View>
);
}
const styles = StyleSheet.create({
slug:{
transform: [{translateX: -100}],
// alignContent: 'center',
flexDirection: 'column',
alignItems: 'center',
},
name:{
transform: [{translateY: -30},{translateX: 10}],
fontSize: 20,
},
listHeadline:{
color:'#333',
fontSize: 21,
fontWeight: 'bold',
},
item: {
flex:1,
flexDirection:'row',
alignItems:'center',
paddingVertical:13,
},
avatarContainer:{
backgroundColor:'#D9D9D9',
borderRadius:100,
height:89,
width:89,
justifyContent:'center',
alignItems: 'center',
margin:10,
},
listHeader:{
height:55,
alignItems:'center',
justifyContent: 'center'
},
seperator: {
height: 1,
width: '100%',
backgroundColor: '#CCC',
}
})
And this is the homeStack we're running the page from.
import React from 'react';
import {StyleSheet, View, Text} from 'react-native';
import { createStackNavigator } from 'react-navigation-stack'
import { createAppContainer } from 'react-navigation'
import PositiveCollectForm from '../Components/PositiveCollectForm';
import NegativeCollectForm from '../Components/NegativeCollectForm';
import Swipe from '../Components/Swipe';
import History from '../Components/History';
import Header from '../Components/shared/Header';
const screens = {
PositiveCollectForm: {
screen: PositiveCollectForm,
navigationOptions: ({ navigation }) => {
return {
// headerTitle: () => <Header navigation={navigation} />
}
}
},
Swipe: {
screen: Swipe,
navigationOptions: {
title: '',
headerTitle: () => <Header navigation={navigation} />
},
},
History: {
screen: History,
navigationOptions: {
title: '',
headerStyle: {backgroundColor: '#555'}
}
},
}
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
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.
This question already has an answer here:
How do you get Material-UI Drawer to highlight the page it is currently at?
(1 answer)
Closed 1 year ago.
I'm using react-router and material UI. I integrated the routes with my material UI persist drawer list items with some custom styling like when I click on a list item it highlights it. But I'm facing an issue when I refresh the page my selected list item gets reset, even though I'm still on the same page. Can anyone tell me how do I persist the selected list item even if a page gets refreshed?
Inshort: Issue- when I refresh the page my drawer list item selected color get reset to top item even though I'm on the same page.
Here is the gif to demonstrate my issue
Here is my sandbox code link
Below is the code for the same
Note: I would suggest you go through my code sandbox it'll be better for you to lookup in code. Thank you
App.js
import { Switch, Route } from "react-router-dom";
import Login from "./pages/Login";
import Dashboard from "./pages/Dashboard";
import "./styles.css";
export default function App() {
return (
<div className="App">
<Switch>
<Route path="/dashboard" component={Dashboard} />
<Route path="/" exact component={Login} />
</Switch>
</div>
);
}
Dashboard.jxs for nested routes in dashboard
import { Switch, Redirect, Route, useRouteMatch } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import NavBar from "../components/NavBar";
const Dashboard = () => {
const { path } = useRouteMatch();
return (
<>
<NavBar>
<Switch>
<Route path={`${path}/about`} component={About} />
<Route path={`${path}/home`} component={Home} />
<Redirect to={`${path}/home`} />
</Switch>
</NavBar>
</>
);
};
export default Dashboard;
NavBar.js
import React from "react";
import clsx from "clsx";
import { makeStyles, useTheme } from "#material-ui/core";
import CssBaseline from "#material-ui/core/CssBaseline";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
import { useRouteMatch } from "react-router-dom";
import SideDrawer from "./SideDrawer";
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: "flex"
},
appBar: {
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginRight: theme.spacing(2)
},
hide: {
display: "none"
},
drawer: {
width: drawerWidth,
flexShrink: 0
},
drawerPaper: {
width: drawerWidth
},
drawerHeader: {
display: "flex",
alignItems: "center",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: "flex-end"
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
marginLeft: -drawerWidth
},
contentShift: {
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
}),
marginLeft: 0
}
}));
export default function NavBar({ children }) {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(true);
const { url } = useRouteMatch();
const handleDrawerOpen = () => {
if (!open) {
setOpen(true);
} else {
setOpen(false);
}
};
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Persistent drawer
</Typography>
</Toolbar>
</AppBar>
{/* child compoent to render side drawer and state is passing to open & close */}
<SideDrawer open={open} />
<main
className={clsx(classes.content, {
[classes.contentShift]: open
})}
>
<div className={classes.drawerHeader} />
{children}
</main>
</div>
);
}
SideDrawer.js its a child component inside NavBar.js
import {
useTheme,
Divider,
Drawer,
IconButton,
List,
ListItem,
ListItemIcon,
makeStyles
} from "#material-ui/core";
import React from "react";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import DrawerList from "./DrawerList";
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
drawer: {
width: drawerWidth,
flexShrink: 0
},
drawerPaper: {
width: drawerWidth
},
drawerHeader: {
display: "flex",
alignItems: "center",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: "flex-end"
}
}));
const SideDrawer = (props) => {
const theme = useTheme();
const classes = useStyles();
const { open } = props;
return (
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper
}}
>
<div className={classes.drawerHeader}>
<h1>Header</h1>
</div>
<Divider />
<List>
{/* my component to render list of icons in side drawer */}
<DrawerList />
</List>
</Drawer>
);
};
export default SideDrawer;
DrawerList.js child component of SideDrawer.js Issue is arising here
import React, { useState } from "react";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import { DashboardOutlined, AddCircleOutline } from "#material-ui/icons";
import ListItemText from "#material-ui/core/ListItemText";
import { makeStyles, Typography } from "#material-ui/core";
import Box from "#material-ui/core/Box";
import { Link, useRouteMatch } from "react-router-dom";
const useStyles = makeStyles((theme) => ({
root: {
marginTop: theme.spacing(1)
},
iconStyle: {
margin: theme.spacing(0, 0),
color: "#676767"
},
iconTitle: {
margin: theme.spacing(0, 0, 0, 1),
color: "#676767"
},
listItem: {
"&.Mui-selected": {
// it is used to change external svg color during click
"& path": {
fill: "#fff"
},
margin: theme.spacing(1.5, 1)
}
}
}));
const DrawerList = ({ children }) => {
console.log(children);
const [selectedIndex, setSelectedIndex] = useState(0);
const classes = useStyles();
const { url } = useRouteMatch();
const itemList = [
{
text: "Home",
icon: <DashboardOutlined />,
keys: "home",
to: `${url}/home`
},
{
text: "Appointment",
icon: <AddCircleOutline />,
keys: "about",
to: `${url}/about`
}
];
const ListData = () =>
itemList.map((item, index) => {
const { text, icon, to, keys } = item;
return (
<ListItem
className={classes.listItem}
button
key={keys}
to={to}
component={Link}
selected={index === selectedIndex}
onClick={(e) => handleListItemClick(e, index)}
style={
selectedIndex === index
? {
background: "#3f51b5",
width: 200,
marginLeft: 8,
paddingLeft: 10,
borderRadius: 4,
boxShadow: "2px 3px 6px rgba(0, 0, 0, 0.3)"
}
: {}
}
>
<ListItemIcon
className={classes.iconStyle}
style={selectedIndex === index ? { color: "#fff" } : {}}
>
{icon}
<ListItemText>
<Typography
component="div"
className={classes.iconTitle}
style={selectedIndex === index ? { color: "#fff" } : {}}
>
<Box fontWeight={700} fontSize={13.8}>
{text}
</Box>
</Typography>
</ListItemText>
</ListItemIcon>
</ListItem>
);
});
const handleListItemClick = (e, index) => {
setSelectedIndex(index);
};
return (
<div className={classes.root}>
<ListData />
</div>
);
};
export default DrawerList;
You need to track the url to show the selected items instead of a useState that gets reseted:
const { url } = useRouteMatch()
const {pathname} = useLocation();
const itemList = [
{
text: "Home",
icon: <DashboardOutlined />,
keys: "home",
to: `${url}/home`
},
{
text: "About",
icon: <AddCircleOutline />,
keys: "about",
to: `${url}/about`
}
];
...
selected={pathname === to}
To persist data between page refresh, you can use localStorage API.
You need to initialize your state with the value from localStorage. And whenever you update your react state, you also need to update the value in localStorage, so that after page is refreshed, your component state gets initialized with this stored value.
For eg:
const storedOpen = JSON.parse(localStorage.getItem('drawerOpen'));
const [open, setOpen] = React.useState(storedOpen);
const handleDrawerOpen = () => {
if (!open) {
setOpen(true);
localStorage.setItem('drawerOpen', true);
} else {
setOpen(false);
localStorage.setItem('drawerOpen', false);
}
};
Error is:
Invariant Violation: View config getter callback for component 'H' must be a function (received undefined)
I'm using react-native to make application and error happens when I clicked login button in MainLogin.js file. (It has to move to mainpage when clicking login button in login page)
I searched a lot but cannot know what is component 'H'.
attatched index.js (src/screens/index.js) and MainLogin.js (src/screens/MainLogin.js)
<index.js>
import React from 'react';
import {
Text
} from 'react-native';
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";
import LoginScreen from './MainLogin';
import HomeScreen from './MainPage';
import DiaryScreen from './Diarymemo';
import StatScreen from './MoodStatistics';
import CommuScreen from './Community';
import StoreScreen from './Store';
const HomeStack = createStackNavigator(
{
HomeScreen
},
{ defaultNavigationOptions : ({navigation}) => ({
title: 'Home'}),
}
);
const DiaryStack = createStackNavigator(
{
DiaryScreen
},
{ defaultNavigationOptions : ({navigation}) => ({
title: 'Diary'}),
}
);
const StatStack = createStackNavigator(
{
StatScreen
},
{ defaultNavigationOptions : ({navigation}) => ({
title: 'Stat'}),
}
);
const CommunityStack = createStackNavigator(
{
CommuScreen
},
{ defaultNavigationOptions : ({navigation}) => ({
title: 'Network'}),
}
);
const StoreStack = createStackNavigator(
{
StoreScreen
},
{ defaultNavigationOptions : ({navigation}) => ({
title: 'Store'}),
}
);
const TabNavigator = createBottomTabNavigator(
InitialRouteName = 'Home',
{
Diary: DiaryStack,
Stat: StatStack,
Home: HomeStack,
Network: CommunityStack,
Store: StoreStack,
},
{
defaultNavigationOptions: ({navigation}) => ({
tabBarIcon: ({focused, horizontal, tintColor}) => {
const {routeName} = navigation.state;
let icon = "▲";
if(routeName === 'Diary'){
icon = "📓";
} else if(routeName === 'Stat'){
icon = "📊"
} else if(routeName === 'Home'){
icon = "🍎"
} else if(routeName === 'Network'){
icon = "👫"
} else if(routeName === 'Store'){
icon = "🛍"
}
// can use react-native-vector-icons
// <Icon name={iconName} size={iconSize} color={iconColor} />
return <Text style={{color: focused && "#46c3ad" || "#888"}}>{icon}</Text>
}
}),
lazy: false,
tabBarOptions: {
activeTintColor: "#46c3ad",
inactiveTintColor: "#888",
},
}
);
const AppStack = createStackNavigator(
{
LoginScreen: LoginScreen,
TabNavigator: {
screen: TabNavigator,
navigationOptions: ({navigation}) => ({
headerShown: false,
}),
},
}
);
export default createAppContainer(AppStack);
<MainLogin.js>
import React, {Component} from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet
} from 'react-native';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
export default class LoginScreen extends Component{
static navigationOptions = {
headerShown: false,
};
_doLogin(){
// do something
this.props.navigation.replace('TabNavigator')
}
render(){
return (
<View style={styles.container}>
<View style={styles.titleArea}>
<Text style={styles.title}>MoodiBuddy</Text>
</View>
<View style={styles.formArea}>
<TextInput
style={styles.textForm}
placeholder={"ID"}/>
<TextInput
style={styles.textForm}
placeholder={"Password"}/>
</View>
<View style={styles.buttonArea}>
<TouchableOpacity
style={styles.button}
onPress={this._doLogin.bind(this)}>
<Text style={styles.buttonTitle}>Login</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
paddingLeft: wp('10%'),
paddingRight: wp('10%'),
justifyContent: 'center',
},
titleArea: {
width: '100%',
padding: wp('10%'),
alignItems: 'center',
},
title: {
fontSize: wp('10%'),
},
formArea: {
width: '100%',
paddingBottom: wp('10%'),
},
textForm: {
borderWidth: 0.5,
borderColor: '#888',
width: '100%',
height: hp('5%'),
paddingLeft: 5,
paddingRight: 5,
marginBottom: 5,
},
buttonArea: {
width: '100%',
height: hp('5%'),
},
button: {
backgroundColor: "#46c3ad",
width: "100%",
height: "100%",
justifyContent: 'center',
alignItems: 'center',
},
buttonTitle: {
color: 'white',
},
})
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.