Categories
React Bootstrap

React Bootstrap — Customizing Overlays

Spread the love

React Bootstrap is one version of Bootstrap made for React.

It’s a set of React components that have Bootstrap styles.

In this article, we’ll look at how to add overlays with React Bootstrap.

Disabled Elements

If we want to trigger overlays on a disabled element, we’ve to trigger the overlay from a wrapper element that isn’t disabled.

This is because disabled elements aren’t interactive.

For example, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Button from "react-bootstrap/Button";
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
import Tooltip from "react-bootstrap/Tooltip";

export default function App() {
  return (
    <>
      <OverlayTrigger
        trigger="click"
        placement="right"
        overlay={<Tooltip id="tooltip-disabled">Tooltip!</Tooltip>}
      >
        <span className="d-inline-block">
          <Button disabled style={{ pointerEvents: "none" }}>
            Disabled button
          </Button>
        </span>
      </OverlayTrigger>
    </>
  );
}

We add the trigger and placement props so that we see the tooltip when we click on the disabled button.

This is possible because we have a span around the button, which lets us trigger the tooltip when the span is clicked.

Changing Containers

We can change the container to control the DOM element that the overlay is appended to.

For example, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Button from "react-bootstrap/Button";
import Overlay from "react-bootstrap/Overlay";
import Popover from "react-bootstrap/Popover";

export default function App() {
  const [show, setShow] = React.useState(false);
  const [target, setTarget] = React.useState(null);
  const ref = React.useRef(null);

  const handleClick = event => {
    setShow(!show);
    setTarget(event.target);
  };

  return (
    <div ref={ref}>
      <Button onClick={handleClick}>click me</Button>

      <Overlay
        show={show}
        target={target}
        placement="bottom"
        container={ref.current}
        containerPadding={20}
      >
        <Popover>
          <Popover.Title as="h1">Title</Popover.Title>
          <Popover.Content>
            Lorem ipsum dolor sit amet, consectetur adipiscing <b>elit</b>.
          </Popover.Content>
        </Popover>
      </Overlay>
    </div>
  );
}

to attach the popover to the div instead of the button.

we set the container to the ref of the div’s ref.

The rest of the code is the same as other popovers.

Updating Position Dynamically

The position of the popover can be updated dynamically.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Button from "react-bootstrap/Button";
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
import Popover from "react-bootstrap/Popover";

const UpdatingPopover = React.forwardRef(
  ({ popper, children, show: _, ...props }, ref) => {
    React.useEffect(() => {
      popper.scheduleUpdate();
    }, [children, popper]);

    return (
      <Popover ref={ref} content {...props}>
        {children}
      </Popover>
    );
  }
);

const longContent = `
  Lorem ipsum dolor sit amet,
  consectetur adipiscing elit.
  Cras ac urna bibendum, pretium magna id,
  imperdiet erat.
`;
const shortContent = "Lorem ipsum";

export default function App() {
  const [content, setContent] = React.useState(shortContent);

  React.useEffect(() => {
    const timerId = setInterval(() => {
      setContent(content === shortContent ? longContent : shortContent);
    }, 3000);

    return () => clearInterval(timerId);
  });

  return (
    <>
      <style type="text/css">
        {`
        .btn-primary {
          position: absolute;
          top: 50vh;
          left: 0vw;
        }
      `}
      </style>
      <OverlayTrigger
        trigger="click"
        overlay={<UpdatingPopover>{content}</UpdatingPopover>}
      >
        <Button>click me!</Button>
      </OverlayTrigger>
    </>
  );
}

to create a tooltip that changes text periodically.

We have th UpdatingPopover component that has the useEffect hook to watch for changes.

We call scheduleUpdate to update the popover.

We watch for changes for the children and popper props to make sure that we call scheduleUpdate when those changes.

We pass the ref and other props to the popover over so the position and other things can be applied.

children is the content of our tooltip.

In App , we have the OverlayTrigger with the text that changes periodically.

It’s triggered when we click on the button.

The content of the tooltip is set by setContent function in the useEffect callback.

Then function we return in there is for clearing the timer when we unmount the component.

Conclusion

We can make popovers dynamic.

Also, we can trigger overlays in disabled elements by adding a wrapper around them.

We can specify the container to attach the overlay to.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *