There is playground example on Popper component page of material-ui. To add arrow they use arrowRef. Please explain me where do they get it from?
For anyone else that needs it, the OP is asking about Material-UI Poppers.
Dmitriy,
Think of React Refs as a variable that always references the element (if rendered) OUTSIDE of the DOM. React best practices are typically to stay out of the DOM if at all possible. There are of course exceptions to this, but it's the rule of thumb.
In this particular instance, it appears that they are creating an element elsewhere and referencing it using the ref so that it can be utilized by the Popper. I found an example of this here. It's a little hard to read through, but the jist is that he creates a span and styles it how he wants to be applied.
You can find the source code of the Material UI Popper "Scroll Playgroud" example here: https://github.com/mui-org/material-ui/blob/4f2a07e140c954b478a6670c009c23a59ec3e2d4/docs/src/pages/components/popper/ScrollPlayground.js
As you can see, there is some extra styling that you will need to add to your app to display the arrow correctly, because it's not included in the Material UI library itself.
For others looking for a concrete, reusable component that is simple to use like Tooltip
but has a more interactive nature like Popper
or Popover
you can lift and shift the RichTooltip
component from the following sandbox I created - it's typescript too. Hope this helps the next person and hides the complexity of arrows for you.
For anyone else that needs it, the OP is asking about Material-UI Poppers.
Dmitriy,
Think of React Refs as a variable that always references the element (if rendered) OUTSIDE of the DOM. React best practices are typically to stay out of the DOM if at all possible. There are of course exceptions to this, but it's the rule of thumb.
In this particular instance, it appears that they are creating an element elsewhere and referencing it using the ref so that it can be utilized by the Popper. I found an example of this here. It's a little hard to read through, but the jist is that he creates a span and styles it how he wants to be applied.
MUI v5
- Add the modifiers for arrow. Make sure a proper ref is provided.
const [arrowRef, setArrowRef] = useState(null);
<Popper
modifiers={[
{
name: 'arrow',
enabled: true,
options: {
element: arrowRef,
}
}
]}
>
<Box component="span" className="arrow" ref={setArrowRef} />
</Popper>
- Add arrow specific styles.
const styles = {
arrow: {
position: 'absolute',
fontSize: 7,
width: '3em',
height: '3em',
'&::before': {
content: '""',
margin: 'auto',
display: 'block',
width: 0,
height: 0,
borderStyle: 'solid',
},
}
};
<Box component="span" className="arrow" ref={setArrowRef} sx={styles.arrow}/>
- Add styles for making CSS triangles used by arrow. Make a styled Popper, as Popper doesn't support
sx
prop.
const StyledPopper = styled(Popper)(({ theme }) => ({ // You can replace with `PopperUnstyled` for lower bundle size.
zIndex: 1,
maxWidth: '375px',
width: '100%',
'&[data-popper-placement*="bottom"] .arrow': {
top: 0,
left: 0,
marginTop: '-0.9em',
width: '3em',
height: '1em',
'&::before': {
borderWidth: '0 1em 1em 1em',
borderColor: `transparent transparent ${theme.palette.background.paper} transparent`,
},
},
'&[data-popper-placement*="top"] .arrow': {
bottom: 0,
left: 0,
marginBottom: '-0.9em',
width: '3em',
height: '1em',
'&::before': {
borderWidth: '1em 1em 0 1em',
borderColor: `${theme.palette.background.paper} transparent transparent transparent`,
},
},
'&[data-popper-placement*="right"] .arrow': {
left: 0,
marginLeft: '-0.9em',
height: '3em',
width: '1em',
'&::before': {
borderWidth: '1em 1em 1em 0',
borderColor: `transparent ${theme.palette.background.paper} transparent transparent`,
},
},
'&[data-popper-placement*="left"] .arrow': {
right: 0,
marginRight: '-0.9em',
height: '3em',
width: '1em',
'&::before': {
borderWidth: '1em 0 1em 1em',
borderColor: `transparent transparent transparent ${theme.palette.background.paper}`,
},
},
}));
Replace the Popper
with the above StyledPopper
<StyledPopper
modifiers={[
{
name: 'arrow',
enabled: true,
options: {
element: arrowRef,
}
]}
>
<Box component="span" className="arrow" ref={setArrowRef} />
// rest of the code
</StyledPopper>
© 2022 - 2024 — McMap. All rights reserved.