0

I have a disabled list item that contains a button that I want enabled.

The Mui-disabled class on the parent disabled everything all the way down.

Is there a way to override this?

enter image description here

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
Chris
  • 679
  • 1
  • 11
  • 26

2 Answers2

1

The ListItemButton which is disabled has the pointer-events set to none so you can't click anything inside. To resolve that override your inner button again:

V5

import Button, { buttonClasses } from "@mui/material/Button";
<List
  sx={{
    [`&& .${buttonClasses.disabled}`]: {
      opacity: 1,
      // anything that's not a button inside ListItem
      [`& > :not(.${buttonClasses.root})`]: {
        opacity: (theme) => theme.palette.action.disabledOpacity
      },
      // inner button
      [`& > .${buttonClasses.root}`]: {
        pointerEvents: "auto"
      }
    }
  }}
>

Codesandbox Demo

V4

const useStyles = makeStyles(theme => ({
  list: {
    '&& .Mui-disabled': {
      opacity: 1,
      '& > :not(.MuiButton-root)': {
         opacity: theme.palette.action.disabledOpacity
      },
      '& > .MuiButton-root': {
         pointerEvents: "auto"
      },
    },
  }
}));
<List className={classes.list}

Codesandbox Demo

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
  • what is sx? That is not a valid property for me. – Chris Oct 01 '21 at 15:54
  • 1
    @Chris I assume you're using v4? I've updated the answer for you. – NearHuscarl Oct 01 '21 at 15:55
  • Thank you, exactly.. I am on v4. I actually came up with the same css solution based on your initial comment, thank you. That said, the style is still that of a disabled button. I imagine I can continue overriding styles to achieve the appearance of an enabled button, but I'm wondering if that is the best way. Is there a way to just remove the Mui-disabled class? – Chris Oct 01 '21 at 15:59
  • @Chris You need to reset the opacity in parent because it's applied to all descendent elements, then set the disable opacity to all children except the inner buttons. I've updated my answer and the demo for you. – NearHuscarl Oct 02 '21 at 12:35
  • I don't think I explained my goal too well... I want the button in a disabled list item to be both functionally and visually enabled, while the list item itself remains both functionally and visually disabled. In your code example the button in the disabled list item is functionally enabled, but it's still appears to be disabled. – Chris Oct 04 '21 at 13:30
  • @Chris I swear to god the demo worked last week. I've fixed it again for you. – NearHuscarl Oct 04 '21 at 13:32
  • Dang you're quick. Did you just change the code sandbox code? The code in the comment looks the same to me – Chris Oct 04 '21 at 13:35
  • @Chris Yes I updated both the answer and the live demo. It's just some css specificity issue (add a another ampersand to double the class name to bump the style up) – NearHuscarl Oct 04 '21 at 13:37
  • Ok, there is something different about how it's working for me , maybe b/c its v4. Even when i put opacity 1 directly on the button in dev tools, the parent's opacity is still causing it to appear disabled. – Chris Oct 04 '21 at 13:41
  • @Chris I'm not sure what's wrong, but I added the v4 Codesandbox for you to reference. – NearHuscarl Oct 04 '21 at 14:14
  • I think it's not working for me b/c my element structure is not quite the same. My button is actually inside a ListItemText . Your example couldn't be any more clear :) – Chris Oct 04 '21 at 14:25
  • https://codesandbox.io/s/69408141-how-to-enable-a-button-in-a-disabled-list-item-forked-v08tf?file=/demo.js – Chris Oct 04 '21 at 14:37
  • 1
    @Chris yeah unfortunately after half an hour of playing around, I found there [is no easy way](https://stackoverflow.com/a/5770892/9449426) to reset the `opacity` or `filter` in the children once set in the parent, so you have to reset the parent opacity, and tiptoe around and set the opacity in the children selectively. See [this](https://codesandbox.io/s/69408141-how-to-enable-a-button-in-a-disabled-list-item-03mpj?file=/demo.js) demo. – NearHuscarl Oct 04 '21 at 16:02
  • Thank you so much, I was able to add a small tweak and get it to do what I wanted! – Chris Oct 04 '21 at 16:14
0

My problem was in opacity. When I apply the "disabled" prop to the ListItem, it will apply opacity: 0.38, to the li element. So I just put

sx={{ opacity: disabled ? 0.38 : 1 }}

to each element inside except the required one. It looks like a bypass, but it works.