Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Backdrop that overlays single component such as Paper rather than entire screen

The standard Backdrop implementation overlays the entire screen with a loading indicator.

I have a table within a Paper component that I'm doing server-side pagination/loading and I want to display an overlay just over the Paper or even just the TableBody while loading.

Does anyone know how this could be achieved?

Thanks!

like image 340
user2576960 Avatar asked Dec 23 '22 18:12

user2576960


1 Answers

Below are the default styles for Backdrop:

export const styles = {
  /* Styles applied to the root element. */
  root: {
    // Improve scrollable dialog support.
    zIndex: -1,
    position: 'fixed',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    right: 0,
    bottom: 0,
    top: 0,
    left: 0,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    WebkitTapHighlightColor: 'transparent',
  },
  /* Styles applied to the root element if `invisible={true}`. */
  invisible: {
    backgroundColor: 'transparent',
  },
};

You can see that the approach it uses for covering the whole screen is to use right, bottom, top, and left of zero along with a position of fixed. By changing the position to absolute, it will instead cover its closest positioned ancestor. This means that you will want to change the containing Paper to have a position of relative (unless it already had a position of absolute). You also need to adjust the z-index of the backdrop, since it defaults to -1 which will put it behind other things in the current stacking context (such as the Paper it is contained within).

Below is a working example:

import React from "react";
import CssBaseline from "@material-ui/core/CssBaseline";
import Paper from "@material-ui/core/Paper";
import { withStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Backdrop from "@material-ui/core/Backdrop";
import Button from "@material-ui/core/Button";

const StyledPaper = withStyles({
  root: {
    height: 200,
    position: "relative"
  }
})(Paper);
const LimitedBackdrop = withStyles({
  root: {
    position: "absolute",
    zIndex: 1
  }
})(Backdrop);
export default function App() {
  const [showBackdrop, setShowBackdrop] = React.useState(false);
  return (
    <div>
      <CssBaseline />
      <Grid container spacing={2}>
        <Grid item xs={6}>
          <StyledPaper>
            <LimitedBackdrop open={showBackdrop}>
              <Button onClick={e => setShowBackdrop(!showBackdrop)}>
                Hide Backdrop
              </Button>
            </LimitedBackdrop>
            <div>
              Paper 1<br />
              {!showBackdrop && (
                <Button onClick={e => setShowBackdrop(!showBackdrop)}>
                  Show Backdrop
                </Button>
              )}
            </div>
          </StyledPaper>
        </Grid>
        <Grid item xs={6}>
          <StyledPaper>Paper 2</StyledPaper>
        </Grid>
      </Grid>
    </div>
  );
}

Edit Backdrop within parent

like image 68
Ryan Cogswell Avatar answered May 05 '23 08:05

Ryan Cogswell