React+Material UI:Popper显示时侧边栏子组件左移避位咨询
To make your sidebar's child component shift left and avoid overlapping with the Popper when it's open, we'll add a conditional margin to the main content area with smooth transitions. Here's how to implement it step by step:
Step 1: Add Transition and Shift Styles
First, update the styles object in your TaskListMain component to include a transition for the content and a class that adds the right margin (to push content left):
const styles = theme => ({ // ... keep all existing styles content: { flexGrow: 1, padding: theme.spacing.unit * 3, // Add smooth transition for margin changes transition: theme.transitions.create(['margin-right'], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen, }), }, // Class to apply when Popper is open contentShift: { marginRight: theme.spacing.unit * 20, // Adjust this value (each unit = 8px) to match your Popper's width }, });
Step 2: Apply Conditional Class to Main Content
Modify the <main> element in your render method to use the contentShift class whenever either popup or notifier is true:
<main className={classNames(classes.content, { [classes.contentShift]: popup || notifier, })}> <div className={classes.toolbar} /> {this.props.children} </main>
How It Works
- When either the "Other Tasks" or "Notifications" Popper is open, the
contentShiftclass adds a right margin to the main content area. This pushes the content left, creating space for the Popper and preventing overlap. - The transition property ensures the shift happens smoothly, matching the existing Material-UI transition style used for the drawer.
Advanced: Dynamic Width Adjustment (Optional)
If your Popper has a dynamic width, you can adjust the margin based on the actual width of the Popper instead of using a fixed value:
- Add a
popperWidthstate variable:
state = { open: false, popup:false, anchorEl: null, notifier:false, popperWidth: 0 };
- Add refs to your Popper's Paper components:
<Popper open={popup} anchorEl={anchorEl}> <Paper ref={el => this.otherTaskPopper = el}> {otherTask} </Paper> </Popper> <Popper open={notifier} anchorEl={anchorEl}> <Paper ref={el => this.notifierPopper = el}> {notify} </Paper> </Popper>
- Update your handlers to calculate the Popper width when it opens:
handleToggle = event => { const { currentTarget } = event; this.setState(state => ({ anchorEl: currentTarget, popup: !state.popup, }), () => { if (this.state.popup && this.otherTaskPopper) { this.setState({ popperWidth: this.otherTaskPopper.offsetWidth }); } else if (!this.state.popup && !this.state.notifier) { this.setState({ popperWidth: 0 }); } }); }; handleIcon = event => { const { currentTarget } = event; this.setState(state => ({ anchorEl: currentTarget, notifier: !state.notifier, }), () => { if (this.state.notifier && this.notifierPopper) { this.setState({ popperWidth: this.notifierPopper.offsetWidth }); } else if (!this.state.notifier && !this.state.popup) { this.setState({ popperWidth: 0 }); } }); };
- Use inline style for dynamic margin:
<main className={classes.content} style={{ marginRight: (popup || notifier) ? `${this.state.popperWidth}px` : 0 }}> <div className={classes.toolbar} /> {this.props.children} </main>
This ensures the content shifts exactly enough to avoid the Popper, no matter its width.
内容的提问来源于stack exchange,提问作者Roshni Vidyadharan

