React Bootstrap: triggering a Popover seems to break Dropdown components - javascript

I have a parent component that renders both a react-bootstrap Popover and a DropdownButton, like so.
const OverlayTrigger = ReactBootstrap.OverlayTrigger;
const Popover = ReactBootstrap.Popover;
const DropdownButton = ReactBootstrap.DropdownButton;
const Dropdown = ReactBootstrap.Dropdown;
class App extends React.Component {
render() {
return (
<React.Fragment>
<div className="d-flex w-50 justify-content-around">
<OverlayTrigger
trigger="hover"
placement="right"
overlay={
<Popover id="popover-basic">
<Popover.Title as="h3">Popover</Popover.Title>
<Popover.Content>My Popover</Popover.Content>
</Popover>
}
>
<Button>Hover Over Me First</Button>
</OverlayTrigger>
<DropdownButton title="Then, Click Me Second">
<Dropdown.Item href="#/action-1">This</Dropdown.Item>
<Dropdown.Item href="#/action-2">Overlay</Dropdown.Item>
<Dropdown.Item href="#/action-2">Won't</Dropdown.Item>
<Dropdown.Item href="#/action-2">Apper</Dropdown.Item>
<Dropdown.Item href="#/action-3">After</Dropdown.Item>
<Dropdown.Item href="#/action-3">Clicking</Dropdown.Item>
<Dropdown.Item href="#/action-3">Popover</Dropdown.Item>
</DropdownButton>
</div>
</React.Fragment>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Issue:
Once the popover is triggered via an event, the Dropdown no longer works at all, even after the popover is dismissed. I have used both the Dropdown and DropdownButton components, and the issue persists. I have even tried changing the popover's triggering event to hover, and no luck there either.
Specs:
React-Bootstrap 1.4.0
React and ReactDOM 17.0.1
Twitter Bootstrap 4.5.0
Here is a pen demonstrating the problem if you want to fiddle with it https://codepen.io/UntidyJoseph/pen/abZaZqe
Any ideas on what I'm doing wrong?
EDIT:
I should also mention that both of these components come straight from the React-Bootstrap documentation, and seem to have every reason to work together.

An update of "react-overlays" to version >= 4.1.1 fixes this problem. I simply added this specific version into my package.json file to avoid sticking to the old 2.x through dependency resolution.

Related

URL not changing consistently in React router

I'm getting odd behavior using #reach/router. My aim is to have a page with tabs. When I click on a tab the url changes and the page changes (though it doesn't reload the whole page). I've been using chakra ui since it makes the theme making easier for me.
The behavior I get is odd. Sometimes the URL changes as I switch between tabs. It works great. Then sometimes the URL doesn't change, even though I've switched tabs.
My project is located here
import React from "react";
import { Router, Link } from "#reach/router";
import {
Tab,
Tabs,
TabList,
TabPanel,
TabPanels,
useColorModeValue
} from "#chakra-ui/react";
import Somatic from "../pages/somatic";
import Ef from "../pages/executive_functions_coaching";
import Intro from "../pages/home";
function ConceptTabs(props) {
const [tabIndex, setTabIndex] = React.useState(0);
return (
<>
<Tabs
size="lg"
isFitted
variant="soft-rounded"
colorScheme="yellow"
onChange={(index) => {
setTabIndex(index);
}}
>
<TabList>
<Tab>
<Link to="/">
Tab1
</Link>
</Tab>
<Tab>
<Link to="/executive_functions_coaching/">
Tab2
</Link>
</Tab>
<Tab>
<Link to="/somatics/">
Tab3
</Link>
</Tab>
</TabList>
<TabPanels p="2rem">
<TabPanel>
<Router>
<Intro path='/' />
</Router>
</TabPanel>
<TabPanel>
<Router>
<Ef path='/executive_functions_coaching/' />
</Router>
</TabPanel>
<TabPanel>
<Router>
<Somatic path='/somatics/' />
</ Router>
</TabPanel>
</TabPanels>
</Tabs>
</>
);
}
export default ConceptTabs;
I've tried to use <NavLink> but had similar issues.
I'm quite new to routing, but I've gotten this to work without the tabs. I'm wondering if there's a way to get the router to work with tabs?
It seems odd that you are mixing reach-router and react-router-dom, it's successor, but the root of your issue with the tabs is because each Tab component is rendering a Link but the entire tab isn't responsible for navigation.
Only the text part in the middle of each tab/button is the actual link, so the navigation only works if you precisely click on the text part of each tab that is the link.
To resolve you can render each Tab component as a Link component.
The as prop and custom component
<TabList>
<Tab as={Link} to="/">
tab1
</Tab>
<Tab as={Link} to="/executive_functions_coaching/">
tab
</Tab>
<Tab as={Link} to="/somatics/">
tab3
</Tab>
</TabList>
See as following 2 screenshots.
As you can see, 'a' tag is in a 'button' tag.
Real size of "a" is very small.
If you might click tab1, it is occured by button.
So, Please, Drew Reese's answer is fit you.
Thanks.
What you could do is to add onClick={()=>history.push('/route')} on your tabs.
Here is how to initialize history:
improt { useHistory } from 'react-router-dom';
// inside your component:
history = useHistory();

Browser does not render images in React App

Images not rendered when I use Brave browser but when I use other browsers i.e. Chrome, the images in my app are rendered.
as you can see in my code I created an object that handles all the images so that I can dynamically import those images in my components.
const Assets = {
logo: require('./logo.svg').default,
spots: require('./spots.svg').default,
};
export default Assets;
here is the component that imports some of those images:
import Assets from '../Assets/Index.js'
export default function ButtonAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="fixed">
<Toolbar variant='regular'>
<Button className='button-image__logo' variant="text">
<img src={Assets.logo} alt="logo" />
</Button>
<Button className='button-image__spot' >
<img src={Assets.spots} alt="car-spot" />
</Button>
<Button variant="text" color="primary" size='large'>Login</Button>
</Toolbar>
</AppBar>
</div>
);
}
other stack overflow solutions say that I should reinstall webpack, this I have done but the problem still persists.
I have also tried clearing Brave's Cache, it does not change anything.
Is it a problem with Brave Browser or React itself and what can I do to fix this?
NB: I used yarn create react-app

Can I target imported classes with Styled Components to change CSS?

I'm using react-bootstrap for modal window component in my code, and I wanted to customize it by using styled components (StyledModalWindow) but for some reason it's not working.
Here's the code:
<StyledModalWindow>
<Modal show={isOpen} onHide={hideModal}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header>
<Modal.Title>Deleting a user</Modal.Title>
</Modal.Header>
<Modal.Body>Are you sure about this?</Modal.Body>
<Modal.Footer>
<button onClick={hideModal}>Yes</button>
<button>No</button>
</Modal.Footer>
</Modal>
</StyledModalWindow>
When I inspect elements in my browser the class names for these components are modal-content, modal-header, modal-body etc. so here's what I tried to use in my Styled Component:
import styled from 'styled-components';
export const StyledModalWindow = styled.div`
&.modal-header{
background-color: red;
}
`
If anyone can help I'd be graeful!
Modal component of react-bootstrap cannot be styled in this way.
Pay attention to the fact, that your Modal component is mounted into body and not into div with id="root" used in React. This means that StyledModalWindow styles are not wrapping ".modal-header" class.
Instead, I would propose adding style={{backgroundColor: 'red'}} directly to the Modal component.

How can I display photos when I click dropdown items with React

I'm new to the world of React. I'm doing a simple react project with Ant Design. I have a dropdown menu in my project and I have items of this menu. I want to display photos on the screen dynamically when I click on the items.For example, When I click option 1, I want a photo to appear on the screen. When I click option 2, I want a different photo to appear on the screen etc... Alert pops up when i click on it now. But how can i display the photo. Please give me opinion. How can I do?
This is my code.
import React from "react";
import { Menu, Dropdown, Button, message } from "antd";
import "./SingleDropdown.css"
function SingleDropdown() {
function handleMenuClick(e) {
message.info("Image showed");
console.log("click", e);
}
const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">
Option 1
</Menu.Item>
<Menu.Item key="2">
Option 2
</Menu.Item>
<Menu.Item key="3">
Option 3
</Menu.Item>
</Menu>
);
return (
<div className="singledropdown">
<Dropdown overlay={menu}>
<Button className="button-color">
Dropdown
</Button>
</Dropdown>
</div>
);
}
export default SingleDropdown;
Your antd is able to do that.
Refer the link here
Futuremore, you may try to take a look at the API below, I think that helps :D
On the other hand, you may try onClick function in React, since I worked with react-bootstrap it worked, and I think antd is able to handle that too.
What I am trying to do is something like this:
const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="1" onClick={this.showPic1}>
Option 1
</Menu.Item>
<Menu.Item key="2" onClick={this.showPic2}>
Option 2
</Menu.Item>
<Menu.Item key="3" onClick={this.showPic3}>
Option 3
</Menu.Item>
</Menu>
);
*Show you some example how it works
onClick is a React function, this is the link You may brief around and see how that works :D

Z-Index on Popper menu?

I have a working example reproducing this issue on codesandbox.io.
What I'm trying to do is do the 'sit below' menu as demonstrated on the Material-UI documentation.
return (
<div className={classes.root}>
<div>
<Button
buttonRef={node => {
this.anchorEl = node;
}}
aria-owns={open ? "menu-list-grow" : null}
aria-haspopup="true"
onClick={this.handleToggle}
>
Toggle Menu Grow
</Button>
<Popper open={open} anchorEl={this.anchorEl} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
id="menu-list-grow"
style={{
transformOrigin:
placement === "bottom" ? "center top" : "center bottom"
}}
>
<Paper>
<ClickAwayListener onClickAway={this.handleClose}>
<MenuList>
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
<Button color="default" variant="contained">
{" "}
I'm a button that sits under the menu
</Button>
</div>
);
The issue I have here is that the Button further down the DOM, from the menu is always on top.
I've tried manually adding zIndex to various parts of the menu - but to no avail.
I suspect that the issue is something to do with the transition.
Can someone explain what's going on here, and how would I solve it?
I removed the disablePortal prop on the Popper component :
<Popper open={open} anchorEl={this.anchorEl} transition disablePortal>
Which now becomes
<Popper open={open} anchorEl={this.anchorEl} transition>
See the Material-UI documentation for the Popper component disablePortal prop to see why:
Disable the portal behavior. The children stay within it's parent DOM hierarchy.
By default, the Popper component uses the React Portal API : https://reactjs.org/docs/portals.html
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component
Using the React Portal API, the Material-UI Popper component renders by default outside the DOM hierarchy of the parent tree, this explains why it resolves the overlaying issue.
The modified working code is on codesandbox.io
If anyone still looking to change z-index or if you want to keep disablePortal try the methods below.
Method 1
Give an id to Popper
<Popper id='popper-1' .... />
Now in your CSS file
#popper-1 {
z-index: 5; // or anything higher
}
Method 2
Set z-index in Popper itself using style prop
z-index working code (with disablePortal enabled) here
for me following solution worked: adding zIndex to popper.
<Popper style={{zIndex: 10000}} open={open} anchorEl={this.anchorEl} transition disablePortal>
for me removing disablePortal didn't work
As Suggested by #Ricovitch, remove disablePortal attribute from Popper element or set it's value to false
<Popper open={open} anchorEl={this.anchorEl} transition disablePortal={false}>
As shown in the material-ui popper scroll playground example when disablePortal is false, the popup element is attached to body element, which is the default behavior. For example, your HTML structure will look like:
<body>
... existing elements ...
<parent>
<button onClick={openMenu}/>
</parent>
... more elements ...
... attached popup menu for Popper ...
</body>
However, when you set disablePortal to true, it will have following html structure:
<body>
... existing elements ...
<parent>
<button onClick={openMenu}/>
... attached popup menu for Popper ...
</parent>
... more elements ...
</body>
I hope this makes things clearer!
mobile stepper: 1000
speed dial: 1050
app bar: 1100
drawer: 1200
modal: 1300
snackbar: 1400
tooltip: 1500
<Popper style={{ zIndex: 1900 }} open={open1} anchorEl={anchorRef1.current} role={undefined} transition disablePortal>any thing in the popper </Popper>

Categories