Highlight specific part of a component in React

Darshana Prachi
3 min readJul 11, 2021

--

There are a lot of libraries available on the internet like Intro.js, Joyride to create guided tours or onboarding on your website. However, after using all these libraries and wasting a LOT of time on this, I realised that none one them provide full autonomy over the UI, which was my use case. I was given a task to make the onboarding tour flow for new users. In this, a part of the screen is highlighted and a message is shown that pops out. I was stuck for quite some time on trying to figure out how to do this.

So I decided to write a custom hook called useHighlight, that will highlight a specific part of the component.

What will the hook do?

demo

The hook useHighlight will accept a reference (ID) to an element and then will highlight that portion of your page.

Let’s look at the code now.

First, we are going to add a button, on clicking which our element will be highlighted. Next, we are going to assume that the most interesting part of our website is on the left side, hence, highlight the left part of the screen and have an overlay on the right part, so that the interesting part of our website really pops out. So we are going to divide our screen in two parts, left and right.

<button onClick={onHighlightElement}>
Highlight
</button>
<div className="App">
<div className="card" id="leftSide">
<h3>Introduce users to your product</h3>
</div>
<div className="right">Not important content</div>
</div>
.App {
text-align: center;display: flex;
flex-direction: row;
}
.right {
background: #2f80ed;width: 70%;
}
.card {
background: #fff;height: 100vh;width: 30%;
}

Now time to start writing the hook

Our hook is going to expose 2 functions, called removeHighlightEl, highlightElement and 1 boolean variable for knowing if highlight state is on. To use the hook in App.js:

const {isHighlight, highlightElement, removeHighlightEl} = useHighLight();

Inside our hook, useHighlight

import { useState } from "react";
import "./styles.css";
export const useHighLight = () => {
const [isHighlight, setIsHighlight] = useState(false);
const setOverlayOnElement = (elem, id) => {
const rect = elem.getBoundingClientRect();
const x = rect.left;
const y = rect.top;
const w = rect.width;
const h = rect.height;
const overlay = document.createElement("div");
overlay.setAttribute("id", id);
overlay.style.width = `${w}px`;
overlay.style.height = `${h}px`;
overlay.style.top = `${y}px`;
overlay.style.left = `${x}px`;
overlay.style.position = "absolute";
elem.classList.add("overlayActive");
document.body.appendChild(overlay);
}
const highlightElement = (targetID) => {
const elem = document.getElementById(targetID);
if (elem) {
setOverlayOnElement(elem, "overlayID");
setIsHighlight(true);
}
};
const removeHighlightElement = (targetID) => {
const elem = document.getElementById(targetID);
const myobj = document.getElementById("overlayID");
elem.classList.remove("overlayActive");
myobj.remove();
setIsHighlight(false);
};
return {
highlightElement,
removeHighlightElement,
isHighlight
};
};

First, highlightElement function is getting called, it is accepting the ID of the element (‘leftSide’). Function setOverlayOnElement next, is finding the dimensions of the element being passed. Next, it is manually creating a HTML element called overlay, whose dimensions matches that of our element and is positioned on top of our ‘leftSide’ element by giving position ‘absolute’.

elem.classList.add("overlayActive");

The above line is adding a class overlayActive to our ‘leftSide’ id div.

Don’t forget to add overlayActive css in App.css file

.overlayActive {
z-index: 1;
}

removeHighlightElement element gets called when we click on the remove highlight button on the screen. It is just removing the class and the manual overlay element we created in the setOverlayOnElement function.

Now, for the final step, we are going to the add the background overlay div in our App.js file.

{isHighlight && <div className={"overlay"} />}

isHighlight is a boolean variable which gets true when you click on highlight element and is exposed by the hook.

Css for the background overlay, to be added in the App.css file:

.overlay {
background: rgba(0, 0, 0, 0.5);
position: fixed;
width: 100%;
height: 100%;
top: 0;
right: 0;
z-index: 1;
}

After adding this, our App.js content will look something like this.

import "./styles.css";
import { useHighLight } from "./useHighlight";
export default function App() {
const {
isHighlight,
highlightElement,
removeHighlightElement
} = useHighLight();
const onHighlightElement = () => {
highlightElement("leftSide");
};
const onRemoveHighlightElement = () => {
removeHighlightElement("leftSide");
};
return (
<>
{isHighlight && <div className={"overlay"} />}
<button onClick={onHighlightElement}>Highlight</button>
<div className="App">
<div className="card" id="leftSide">
<h3>Introduce users to your product</h3>
{isHighlight && (
<button onClick={onRemoveHighlightElement}>Remove Highlight</button>
)}
</div>
<div className="right">Not important content</div>
</div>
</>
);
}

Yay! Now, the interesting part of our app is highlighted. I have also made a Codesandbox with this code.

--

--