An open API service indexing awesome lists of open source software.

https://github.com/graphieros/target-highlight

A lightweight, zero‑dependency JavaScript library to spotlight DOM elements. Ideal to create tutorials!
https://github.com/graphieros/target-highlight

dom highlight overlay spotlight tour

Last synced: 2 months ago
JSON representation

A lightweight, zero‑dependency JavaScript library to spotlight DOM elements. Ideal to create tutorials!

Awesome Lists containing this project

README

          

# target-highlight

[![npm](https://img.shields.io/npm/v/target-highlight)](https://github.com/graphieros/target-highlight)
[![GitHub issues](https://img.shields.io/github/issues/graphieros/target-highlight)](https://github.com/graphieros/target-highlight/issues)
[![License](https://img.shields.io/badge/license-MIT-green)](https://github.com/graphieros/target-highlight?tab=MIT-1-ov-file#readme)
[![npm](https://img.shields.io/npm/dt/target-highlight)](https://github.com/graphieros/target-highlight)

A lightweight, zero‑dependency JavaScript library to spotlight DOM elements with a customizable overlay, border, padding, and optional tooltip. Single or multiple elements can be highlighted, using usual selectors.

[DEMO](https://target-highlight.graphieros.com)

**target-highlight** can be used for example to setup a tutorial by highlighting elements.

## Features

- **Overlay** the page, carving out “holes” around target elements
- **Customizable** overlay color, border color, width, radius, padding
- **Tooltip** support (single or per‑element) with automatic positioning
- **Configurable** via options or global defaults

---

## Installation

```bash
npm install target-highlight
# or
yarn add target-highlight
```

## Usage

```ts
import {
targetHighlight,
targetHide,
defaultConfig,
HighlightOptions,
} from "target-highlight";

// Define options
const options = {
overlayColor: "#00000080", // all color formats will work
borderColor: "red", // all color formats will work
singleTooltip: true,
padding: "2px", // same as css
borderRadius: 2,
overlayZIndex: 2,
hidePointerEvents: false,
scrollToTarget: {
// Use the same options as the native scrollIntoView api
behavior: "smooth",
block: "center",
inline: "center",
},
nextCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-previous
previousCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-previous
stopCallback: () => {}, // use your callback when clicking on a button with an id of target-highlight-button-stop
tooltip: "My content", // can also be a callback returning html content
forceTooltipPosition: null, // 'top' | 'right' | 'bottom' | 'left' | null, default: null
useResizeObserver: true, // If true, will trigger a re-render when the highlighted element resizes
blockedKeys: [], // Add keyboard keys that will be inactive when the application is running
};

// Target an element using any selector

targetHighlight("#myDiv", {
...options,
tooltip: "This is my div",
});

// Or target many elements
targetHighlight(".myClass", options);

// Remove all highlights
targetHide();
```

## Customize the tooltip

Target the following css class to customize the tooltip:

```css
.target-highlight-tooltip {
}
```

The tooltip can also be passed a callback returning html content:

```js
targetHighlight("#myDiv", {
...config,
tooltip: () => {
return `


My custom tooltip

`;
},
});
```

When highlighting multiple elements, you may need to show individual tooltips on each element.
Use the data-target-highlight-tooltip attribute on the highlighted elements to setup the individual tooltip contents. You can also use the data-target-highlight-tooltip-position to force the tooltip position ('top' | 'right' | 'bottom' | 'left'). In this case, you won't need the tooltip option normally passed to targetHighlight. Bear in mind using data attributes, the tooltip content can only be a string.

```html


Some content


Some other content

```

## Defining steps

You can create a scenario to move from step to step.
Add data-step="step" on the elements part of the scenario, where step is a number.

```js
// Define step variables
const step = {
current: 0,
max: 5,
};

// Define callbacks in options
const options = {
nextCallback: () => moveStep("next"),
previousCallback: () => moveStep("previous"),
stopCallback: targetHide,
};

// Define blocked keys
const blockedKeys = [" ", "Tab"];

// Define a function to call the library and apply event listeners
// In this example, chevron icons are added as plain svg
// Buttons with id #target-highlight-button-previous and #target-highlight-button-next will be recognized by the library, and events attached to them.
function applySteps() {
targetHighlight(`[data-step="${step.current}"]`, {
...options,
blockedKeys,
tooltip: () => {
return `

This is step ${step.value}
${chevronLeftIcon}${chevronRightIcon}`;
},
});

setTimeout(() => {
applyStepListeners(options);
}, 10);
}

// Define a function to move through the steps
function moveStep(direction) {
if (direction === "next") {
step.current += 1;
if (step.current > step.max) {
step.current = 0;
}
} else {
step.current -= 1;
if (step.current < 0) {
step.current = step.max;
}
}
applySteps();
}
```

## Ignore elements

Use the data-target-highlight ignore data attribute on elements never to be highlighted:

```html

I will be selected

I will not be selected

```

## Blocked keys

Combine `hidePointerEvents: false` with blocked keys, to prevent events outside of the tour.
List of all the available blockable keys:

```ts
type KeyboardNavigationKey =
| " "
| "Tab"
| "Enter"
| "ArrowUp"
| "ArrowDown"
| "ArrowLeft"
| "ArrowRight"
| "Home"
| "End"
| "PageUp"
| "PageDown"
| "Escape";
```

Set blocked keys in the options object:

```js
blockedKeys: [
" ",
"Tab",
"Enter",
"ArrowUp",
"ArrowDown",
"ArrowLeft",
"ArrowRight",
"Home",
"End",
"PageUp",
"PageDown",
"Escape",
];
```

Blocked events will be restored when `targetHide` is called.

## Tooltip transitions

This library does not inject CSS. To enable tooltip transitions, add for example the following to your app’s global styles:

```css
.target-highlight-tooltip {
opacity: 1;
transition: opacity 0.3s;
will-change: opacity;
}

.target-highlight-tooltip.fade-in {
opacity: 0;
animation: fadeIn 0.3s forwards;
}

.target-highlight-tooltip.fade-out {
opacity: 1;
animation: fadeOut 0.3s forwards;
pointer-events: none;
}

@keyframes fadeIn {
to {
opacity: 1;
}
}

@keyframes fadeOut {
to {
opacity: 0;
}
}
```