Ways to restructure a CSS class into a Material-UI class

Hello everyone 🌟

I've been working on a project using material-UI, and I encountered an issue with the popover functionality. It seems that MUI popovers have a z-index of 1500 which blocks all events like mouseEnter/mouseLeave. I need my users to be able to navigate and interact with buttons and collapse elements within this div, so I decided to try implementing a pure CSS solution instead. After spending hours trying to tweak the behavior of the MUI popover, I ended up grabbing some old CSS from another project. Now, I'm struggling to convert it into a format that MUI accepts.

The CSS code I'm trying to integrate looks like this:

.popover__wrapper {
  position: relative;
}

.popover__content {
  opacity: 0;
  visibility: hidden;
  position: absolute;
  left: -100px;
  transform: translate(0, 10px);
  background-color: #bfbfbf;
  padding: 1.5rem;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
  width: auto;
  text-align: center;
}
.popover__content:before {
  position: absolute;
  z-index: -1;
  content: "";
  right: calc(50% - 10px);
  top: -8px;
  border-style: solid;
  border-width: 0 10px 10px 10px;
  border-color: transparent transparent #bfbfbf transparent;
  transition-duration: 0.3s;
  transition-property: transform;
}
.popover__wrapper:hover .popover__content {
  z-index: 10;
  opacity: 1;
  visibility: visible;
  transform: translate(0, -20px);
  transition: all 0.5s cubic-bezier(0.75, -0.02, 0.2, 0.97);
}

My attempt to adapt this into MUI-compatible CSS is as follows:

popover__content: {
    opacity: 0,
    visibility: "hidden",
    position: "absolute",
    left: "-150px",
    transform: "translate(0, 10px)",
    width: "100%",
    "&:before": {
      position: "absolute",
      zIndex: "-1",
      right: "calc(50% - 10px)",
      transitionDuration: "0.3s",
      transitionProperty: "transform",
    },
    "&:hover": {
      zIndex: "10",
      opacity: "1",
      visibility: "visible",
      transform: "translate(0, -20px)",
      transition: " all 0.5s cubic-bezier(0.75, -0.02, 0.2, 0.97)",
    },
  },

I've consulted the MUI theming documentation, but I'm still stuck on this issue. Any help or guidance would be greatly appreciated! Have a fantastic day, everyone!

Answer â„–1

To solve the issue with the popover, I utilized a combination of CSS and hooks to achieve the desired behaviors on the DOM:

import React, { useState } from "react"
import { useSelector } from "react-redux"
import {
  Grid, List, ListItem, Paper, Typography,
  Divider, makeStyles, ListItemIcon,
  ListItemText, Box,
} from "@material-ui/core"
import DescriptionIcon from "@material-ui/icons/Description"

const useStyles = makeStyles((theme) => ({
  container: {
    padding: theme.spacing(1),
    borderRadius: theme.spacing(1.5),
    background: "#FFFFFF",
    boxShadow: "2px 2px 4px rgba(0, 0, 0, 0.0449219)",
  },
  title: {
    color: "#4873c5",
  },
  paragraph: {
    color: "#818181",
  },
  popover: {
    zIndex: 2,
    position: "absolute",
    top: theme.spacing(-1),
    left: theme.spacing(-24),
  },
  arrowRight: {
    width: 0,
    height: 0,
    borderTop: "10px solid transparent",
    borderBottom: "10px solid transparent",
    borderLeft: "10px solid black",
    position: "absolute",
    right: theme.spacing(-1),
    top: theme.spacing(2),
  },
}))

const stages = [{ name: "Drafting", docs: 15 }, { name: "To Execute", docs: 5 }, { name: "Signature", docs: 10 }]
const tags = [{ name: "HR", docs: 10 }, { name: "Sales", docs: 4 }, { name: "Fundraising", docs: 1 }]

export default function ActiveDocuments() {
  const classes = useStyles()
  const documents = useSelector(state => state.documents)
  const [popoverDetails, setPopoverDetails] = useState(null)

  const onMouseLeaveDetails = (e) => {
    if (e.relatedTarget.id === "activeDocumentsContainer")
      return
    setPopoverDetails(null)
  }

  // in case moving precisely on the diagonal of arrow
  const hoverProtection = () => {
    if (popoverDetails)
      setPopoverDetails(null)
  }

  return (
    <>
      <Paper style={{ padding: 16 }} onMouseEnter={hoverProtection} id="activeDocumentsContainer">
        <Box display="flex">
          <Typography style={{ fontWeight: "bold", flexGrow: 1 }}>Active Documents</Typography>
          <Typography>{documents.length}</Typography>
        </Box>
        <List id="testlist">
          {stages.map((stage, idx) => (
            <ListItem disableGutters key={idx}>
              <div onMouseOver={() => setPopoverDetails(stage.name)}
                onMouseLeave={onMouseLeaveDetails}>
                <Typography className={classes.title}>
                  {stage.name}
                </Typography>
                {popoverDetails === stage.name && (
                  <Paper className={classes.popover} onMouseLeave={() => setPopoverDetails(null)}>
                    <div className={classes.arrowRight} />
                    <List>
                      {tags.map((tag, idx) => (
                        <ListItem key={idx}>
                          <Typography className={classes.title}>{tag.name}</Typography>
                        </ListItem>
                      ))}
                    </List>
                    <Box>
                      <Typography style={{ fontWeight: "bold" }}>Latest Documents</Typography>
                      <List>
                        {documents.map((document, idx) => (
                          <ListItem key={idx}>
                            <ListItemIcon style={{ color: "#4873c5" }}>
                              <DescriptionIcon />
                            </ListItemIcon>
                            <ListItemText className={classes.title}>{document.filename}</ListItemText>
                          </ListItem>
                        ))}
                      </List>
                    </Box>
                  </Paper>
                )}
              </div>
            </ListItem>
          ))}
        </List>
      </Paper>
      <List>
        <ListItem>
          <Grid container>
            <Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
              <Typography className={classes.title}>Template</Typography>
            </Grid>
            <Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
              <Typography className={classes.paragraph} variant="body2">5 new this week</Typography>
            </Grid>
          </Grid>
        </ListItem>
        <Divider varient="fullWidth" style={{ backgroundColor: "#dcdee1" }} />
        <ListItem>
          <Grid container>
            <Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
              <Typography className={classes.title}>Signed</Typography>
            </Grid>
            <Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
              <Typography className={classes.paragraph} variant="body2">8 new this week</Typography>
            </Grid>
          </Grid>
        </ListItem>
      </List>
    </>
  )
}

I plan to raise an issue on the MUI GitHub repository to address this frustrating behavior in the popover component.

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

The Tailwind preset is generating CSS code, but the webpage is not displaying the intended styles

Can anyone explain why the preset is generating CSS in the output file, but the styles are not displaying in the browser? When I manually write CSS in newstyle.css, it gets outputted to output.css and renders correctly in the browser. I attempted adding t ...

Challenge with Express Helmet: CSS fails to load properly on iOS Safari browser

After successfully adding Helmet to my Node/Express/EJS project and configuring my CSP to allow inline scripts, styles, and certain external sources on my Windows laptop in Opera, Chrome & Edge, I encountered a problem when connecting via iOS Safari on mob ...

Button failing to align properly in the center position

I was able to successfully create a responsive input box, but for some reason, the button is not aligned in the center. Below is the CSS code: .webdesigntuts-workshop button { background: linear-gradient(#333, #222); border: 1px solid #444; border- ...

Styling elements with CSS to achieve proper positioning

I am in search of a way to align rows utilizing the style property. The following HTML code is being transformed using XSL: <span style="white-space: pre; font-size: 8pt; font-family: Lucida console, Courier ">&lt;40 : item1</span>&l ...

Incorporating CSS animations into Vue.js while an API call is being made

When a specific icon is clicked, an API call is triggered: <i class="fas fa-sync" @click.prevent="updateCart(item.id, item.amount)"></i> I am looking to add an animation to rotate the icon until the API call is complete or ...

MUI's Checkbox with Radio Button feature functionality

In my project, I am looking to implement a Checkbox with radio button behavior inside an Accordion component. The challenge here is that only one item should be selected at a time. If one item is checked, it should automatically uncheck the previously sele ...

Ways to remove the initial row of inline-block divs

My webpage is filled with inline-block divs that are contained within a larger div like so: <div class="container"> <div class="text">Text 1</div> <div class="text">Text 2 ... rest of the nu ...

What could be causing my website's screen resolution to not fit properly on mobile devices?

Initially, the resolution perfectly matched the width of mobile devices. However, after changing the background image, for some reason, the width no longer fits the device length precisely. I've tried resetting to a point where the resolution was fine ...

Can anyone explain why I am having trouble loading JavaScript files into a different HTML file?

Currently, I am developing an electron application. In my index.html file, I have successfully loaded JavaScript files in the head tag and can access the JS functions without any problems. Now, I have created a separate browser window with another HTML fi ...

5 MUI Autocomplete options narrowed down to display count

Is there a way to retrieve the number of filtered options from the MUI 5 Autocomplete component, without altering the default behavior of the filterOptions prop? ...

Creating customized JQuery UI tabs to perfectly accommodate the available horizontal space

Can JQuery UI Tabs be modified to fill the horizontal space and stack to the left? In order to achieve this, could we consider using a markup like the one below: <table width="100%"> <tr> <td> ...content... </td> ...

URL for CSS Background-Image

While working on CSS styling for the body, I ran into a problem and was curious to understand the distinction. Initially, I tried this body { background-image: url('img/bg.png'); } However, it did not produce the desired result. http://www ...

Accessing a New Router with ReactJS

Within my navigation bar, I have implemented an AppRouter using the material-ui library. <NavigationBar> <AppRouter/> </NavigationBar> The structure of my AppRouter is as follows: <Switch> <PublicRoute path="/" compon ...

What could be the reason for my onChange event not functioning properly?

The issue I'm experiencing involves my onchange event not properly copying the text from the current span to the hidden field. Any ideas on why this might be happening? Check out my code at this link. ...

Craft a search bar inspired by Google's iconic design using CSS styling

I need to recreate a custom input styled like the Google Material Theme design. This is the desired outcome: https://i.stack.imgur.com/QU5dp.png While I am aware that frameworks/libraries can achieve this, it is part of my assignment to create it from s ...

Different ways to personalize Material UI select

I'm currently working on enhancing the design of a material-ui dropdown menu, aiming to achieve a specific look. You can preview what I have so far by visiting this link: https://codesandbox.io/s/busy-black-2fgdn?file=/src/App.js. My goal is to enabl ...

How come certain invisible screen elements suddenly become visible when the document is printed?

When creating a play-off tournament bracket, I face the challenge of adjusting for varying numbers of participants in each round. Typically, there are 2^n participants in each tour: 16, 8, 4, 2 which can be easily accommodated in a flex column layout. Howe ...

How can I disable the background color in Chrome autocomplete? Is there a way to make the background

There's a form on my website where the autocomplete feature shows a blue background color. The form itself has a semi-transparent white background. I managed to change the autofill color to white using this CSS property: -webkit-box-shadow: 0 ...

It is important for the CSS :active state to transition to an "inactive" state after a certain period of

For mobile, I utilized the :hover and :active pseudo-classes to create a transition effect when tapping on a tab that enlarges the elements for more information. However, I am seeking a way for the activated element to return to its original state after a ...

Exploring the Possibilities of Personalizing Data Tables

I have a unique requirement that I need help with: 1. On the mobile site, only 5 records should load by default with paginated data for subsequent pages. and 2. In desktop view, the default should be 10 records loaded with paginated data for subsequent ...