What is the best way to utilize the sx prop in Material UI for applying styles specifically when the component is active or selected?

In the code snippet below, I have set up the useState hook so that when a ListItem is clicked on, the selected state becomes true. My goal is to apply specific styling when an item is selected using the sx prop instead of creating a styled component for such simple styling requirements. What I want to achieve is to change the color of the ListItemText to blue and the background color of the ListItem to a lighter shade of blue when it is selected.

import { useState } from 'react'
import { Box, Drawer, CssBaseline, AppBar, Toolbar, Avatar, List } from '@mui/material';
import Typography from '@mui/material/Typography';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import HomeOutlinedIcon from "@mui/icons-material/HomeOutlined"
import PeopleOutlinedIcon from "@mui/icons-material/PeopleOutlined"
import PersonOutlinedIcon from "@mui/icons-material/PersonOutlined"
import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
import HelpOutlinedIcon from "@mui/icons-material/HelpOutlined"
import PieChartOutlineOutlinedIcon from "@mui/icons-material/PieChartOutlineOutlined"
import TimelineOutlinedIcon from "@mui/icons-material/TimelineOutlined"
import FolderSharedOutlinedIcon from '@mui/icons-material/FolderSharedOutlined';
import { Link as RouterLink } from 'react-router-dom'
import { useTheme } from '@mui/material'
import { ColorModeContext, tokens } from "./../theme"
import { useContext } from 'react';
import Logo from "./../assets/code2.jpg"

const SideBar = () => {
    const theme = useTheme();
    const colorMode = useContext(ColorModeContext);
    const colors = tokens(theme.palette.mode);
    const [selected, setSelected] = useState("Dashboard")

    const handleListItemClick = (text) => {
        setSelected(text)
    }

    const Item = ({ icon, text, to, selected }) => {
        console.log(selected === text);
        return (
            <ListItem key={text}
                selected={selected === text}
                disablePadding
                onClick={() => handleListItemClick(text)}
                sx={{
                    "&$selected": {
                        "& .MuiListItem.Mui-selected": {
                            backgroundColor: "blue",
                        }
                    },
                    "&$selected:hover": {
                        backgroundColor: "white",
                        '& .MuiListItem-root': {
                            color: "white"
                        }
                    }
                }}>
                <ListItemButton component={RouterLink} to={to}>
                    <ListItemIcon>
                        {icon}
                    </ListItemIcon>
                    <ListItemText selected={selected === text} primary={text}
                        sx={{
                            "&$selected": {
                                "& .MuiListItemText.Mui-selected": {
                                    color: "blue",
                                }
                            }}}                    />
                </ListItemButton>
            </ListItem>)
    }

    return (
        <Drawer sx={{
            width: 240,
            flexShrink: 0,
            '& .MuiDrawer-paper': {
                p: 2,
                width: 240,
                boxSizing: 'border-box',
                backgroundColor: `${colors.primary[500]}`,
            }
        }} variant="permanent" anchor="left">
            <Box textAlign="center" m="0 0 15px 0">
                <Typography variant="h3" color={colors.grey[100]} fontWeight="bold" sx={{ m: "10px 0 0 0" }}> ADMINIS</Typography>
            </Box>
            <Box mb="10px">
                <Box display="flex" justifyContent="center" alignItems="center">
                    <Avatar alt="logo" src={Logo} sx={{ width: 100, height: 100, cursor: "pointer"}} />
                </Box>
            </Box>
            <Box textAlign="center">
                <Typography variant="h2" color={colors.grey[100]} fontWeight="bold" sx={{ m: "10px 0 0 0" }}> Huvon Goodridge</Typography>
                <Typography variant="h5" color={colors.greenAccent[500]}>VP Fancy Admin</Typography>
            </Box>
            <List>
                <Item selected={selected} icon={<HomeOutlinedIcon />} text={"Dashboard"} to={'dashboard'} />
            </List>
            <Typography variant="h6" color={colors.grey[300]} sx={{ m: "15px 0px 0px 5px" }}>
                Data
            </Typography>
            <List>
                <Item selected={selected} icon={<PeopleOutlinedIcon />} text={"Team"} to={'team'} />
                <Item selected={selected} icon={<FolderSharedOutlinedIcon />} text={"Projects"} to={"projects"} />
            </List>
            <Typography variant="h6" color={colors.grey[300]} sx={{ m: "15px 0px 0px 5px" }}>
                Pages
            </Typography>
            <List>
                <Item selected={selected} icon={<PersonOutlinedIcon />} text={"Profile"} to={'profile'} />
                <Item selected={selected} icon={<CalendarTodayOutlinedIcon />} text={"Calendar"} to={'calendar'} />
                <Item selected={selected} icon={<HelpOutlinedIcon />} text={"FAQ"} to={'faq'} />
            </List>
            <Typography variant="h6" color={colors.grey[300]} sx={{ m: "15px 0px 0px 5px" }}>
                Charts
            </Typography>
            <List>
                <Item selected={selected} icon={<PieChartOutlineOutlinedIcon />} text={"Pie Chart"} to={'piechart'} />
                <Item selected={selected} icon={<TimelineOutlinedIcon />} text={"Timeline"} to={'timeline'} />
            </List>
        </Drawer>)
}

export default SideBar;

I've made numerous attempts to target the classes of the components I need to style, but none have been successful. I expected the changes in background color and text color when using the provided CSS properties, but unfortunately, it did not work as intended. Despite consulting the material UI website documentation, I was unable to find a solution to this issue.

Answer №1

When utilizing the sx prop to customize the selected component, consider incorporating styles into the &.Mui-selected and &.Mui-selected:hover property names.

For instance, you can refer to this simplified demonstration: stackblitz

<ListItemButton
  sx={{
    "&.Mui-selected": { backgroundColor: "hotpink", color: "#fff" },
    "&.Mui-selected:hover": {
      backgroundColor: "hotpink",
    },
  }}
></ListItemButton>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Returning Props in Dynamic Components with Vue 3

Exploring the capabilities of Vue3's Dynamic Component <component>, I am currently working with this setup: Component 1: <template> <div> <h1> Name Input: </h2> <Input :model="props.name" /> ...

"Exploring the best locations for storing CSS, JS, and image files in Spring

Having trouble figuring out where to place my public files. I attempted the solution mentioned in this thread on Stack Overflow but it didn't work for me. I've tried putting my public folder in various locations within the WEB-INF directory, but ...

Guide to generating a downloadable link using React and Express

In my React app, I have a button which is essentially a div. The Button Component returns this structure with all other elements as props: <button className={"button "+styleButton} onClick={handleClick}> {source && <img src= ...

Trouble with CSS3 Perspective rendering issue

Here's a simple example showcasing the use of CSS3 Perspective property to create a 3D side flip effect. However, this basic demonstration does not seem to achieve the desired outcome. <html> <head> <style> .div1{height:300px; ...

Changing the background color using jQuery switch case statement

I am attempting to utilize jquery to dynamically change the background image of a webpage based on different cases in a JavaScript switch statement. I have completed three steps: 1) Included this script tag in my HTML document: <script src="http://co ...

Getting values from an array using Reactjs

I'm working on a project that involves handling a list of images. I need to retrieve the name of the image located at the beginning of the matrix. https://i.stack.imgur.com/5G6Bk.png Looking at the image, you can see that the name is stored under Fi ...

Discovering all mongoDB documents utilizing geolocation can be achieved by implementing specific queries that target

Utilizing the react geosuggest package, I am saving event locations in MongoDB. The data retrieved from Google Places gets stored in this format each time: "_id": "vvagbSbEginyrQGK8", "name": "test3", "googleLocation": { "label": "Testaccio, Roma, Ita ...

javascript loop that runs on every second element only

After completing an ajax query, the following JavaScript code is executed. All of my images are named "pic". <script type="text/javascript> function done() { var e = document.getElementsByName("pic"); alert(e.length); for (var i = 0; ...

Tips for updating the CSS properties of the "html" element

html { width:100%; } Looking to dynamically update the CSS of the html tag upon button click using JavaScript. The goal is to modify the existing HTML CSS code as shown below, but achieving this dynamically with a script. Is it possible? html { w ...

Remove a comment from the page without needing to refresh the entire

Is there a way to enhance this code so that when a comment is deleted, the page does not refresh? It can be frustrating when deleting a comment causes the page to scroll back to the top. AJAX function deleteComment(pid){ $.ajax({ type: "PO ...

How can we show a div element when hovering over another element using css-in-js?

Is there a way to use material ui withStyles component in order to show information only on hover for a specific div? ...

Execute Function after Gridview Sorting

While working on a gridview within an update panel, I encountered a scenario where the gridview successfully resorts itself upon clicking on the column header. However, post-sorting, I wish to execute a JavaScript function named MyScript. Any suggestions ...

Issue with incremental static generation in version 13 not functioning as expected

Is ISR working for anyone in the NextJS 13 Beta version? I have set revalidate to 15 as follows. export const revalidate = 15; However, even after running `npm run build`, the page still remains a statically generated site (SSG). The symbol is showing u ...

Is it feasible to insert the result of a JavaScript code into a PHP script?

Alternatively, you can view both codes side by side on the panelbackup(dot)com/codes page Alright, I have a code placed on page 1.html that adds four random numbers at the end of any given URL: <head><script>window.onload = function() { ...

Validate input strings in Node.js using Joi to detect and return an error if there are leading or trailing spaces

Looking to set up JOI validation in Node.js that flags errors if a string begins or ends with an empty space. For example: name = "test123" //valid name = "test(space)" or "(space)test" // invalid ...

Adding content to a paragraph using Jquery

I have 4 sets of data associated with a click-bind event. My goal is to retrieve the value from a hidden field in each set and display it in a paragraph elsewhere on the page when the corresponding checkbox is clicked. Currently, I'm focused on gettin ...

Incorporating traditional Javascript classes for modeling in React development

Can traditional JavaScript classes be utilized in models within the MVC framework while using React, as opposed to relying on Redux or contexts & reducers which may impact reusability? If this approach is feasible, how can we efficiently 'subscribe&ap ...

The app bar menu items are failing to open the appropriate submenus in a correct

I am in the process of developing a frontend application using React16 along with the Material UI library. My current task involves creating a navigation bar at the top that contains multiple menu items. For this, I referred to the "simple menu" example o ...

Error: The module '@emotion/react' cannot be found while attempting to integrate Gatsby with Material-UI and Styled-Components

While attempting to integrate Gatsby with MUI and Styled-Components, I encountered an error message stating: ModuleNotFoundError: Module not found: Error: Can't resolve '@emotion/react'. This issue seems unusual considering the documentation ...

The Nuxt authentication middleware fails to function properly upon clicking the back button in the browser

When it comes to implementing the protected route in Nuxt, I have found that using middleware is the best approach. In my implementation, I utilized the cookie-universal-nuxt module. Everything was running smoothly until I encountered a bug. When a user&a ...