apps/docs/src/content/guides/styling-hints.mdx
import { HintsSample } from "../../components/HintsSample.tsx";
Everything about a hint can be customized: the beacon's color, size and animation through CSS variables, and the popover through the same theming that tours use. If you haven't read the Hints guide yet, start there.
With overlay: true an open hint reads exactly like a tour step: the element
is spotlighted and stays interactive, the popover frames the element (the
beacon steps aside while it is up), and the other beacons wait under the
overlay. Clicking the dimmed page closes the hint.
<HintsSample idPrefix="overlay" config={{ overlay: true, overlayOpacity: 0.5 }} hints={[ { element: "#overlay-export", id: "export", popover: { title: "Focus mode", description: "The Export button is spotlighted and still clickable; the rest of the page is dimmed.", }, }, { element: "#overlay-summary", id: "summary", beacon: { side: "left", align: "center" }, popover: { title: "One at a time", description: "The other beacons wait under the dim. Close this hint to get back to them.", side: "bottom", }, }, ]} client:load />
const productHints = hints({
overlay: true,
overlayOpacity: 0.5,
hints: [...],
});
Beacons read two CSS variables. Set them globally on .driver-hint, or give
individual beacons a className and scope the variables to it:
<HintsSample idPrefix="styled" hints={[ { element: "#styled-export", id: "export", beacon: { className: "docs-hint-rose" }, popover: { title: "A rose beacon", description: "This beacon carries a custom class that overrides the color variable.", }, }, { element: "#styled-summary", id: "summary", beacon: { side: "left", align: "center", className: "docs-hint-large" }, popover: { title: "A larger beacon", description: "The same class trick, overriding both the size and the color.", side: "bottom", }, }, ]} client:load />
/* All beacons */
.driver-hint {
--driver-hint-color: #e11d48;
--driver-hint-size: 28px;
}
/* Only beacons carrying a class */
.my-special-hint {
--driver-hint-color: #059669;
}
const productHints = hints({
hints: [
{
element: "#export-btn",
beacon: { className: "my-special-hint" },
popover: { title: "A rose beacon", description: "..." },
},
],
});
Set animate: false on a hint (or on the instance-level beacon defaults)
for a still dot without the pulse. Users who prefer reduced motion get the
still dot automatically.
<HintsSample idPrefix="static" hints={[ { element: "#static-export", id: "export", beacon: { animate: false }, popover: { title: "No pulse", description: "This beacon sits still until it is clicked.", }, }, ]} client:load />
const productHints = hints({
// Applies to every hint; a hint's own beacon config wins.
beacon: { animate: false },
hints: [...],
});
The dismiss button says Got it by default. Change it for all hints with the
instance-level buttonText, per hint through the popover, or hide it entirely
with showButton: false for hints you dismiss programmatically.
<HintsSample idPrefix="button" hints={[ { element: "#button-export", id: "export", popover: { title: "Custom button", description: "The dismiss button below has its own label.", buttonText: "Thanks, understood", }, }, { element: "#button-share", id: "share", popover: { title: "No button at all", description: "Click anywhere outside to close me; I can only be dismissed from code.", showButton: false, }, }, ]} client:load />
const productHints = hints({
buttonText: "Thanks, understood",
hints: [
{
element: "#share-btn",
popover: {
title: "No button at all",
description: "...",
showButton: false,
},
},
],
});
Hint popovers are regular Driver.js popovers, so popoverClass and the
popover styling techniques apply unchanged, shown here with
the same theme used across these docs:
<HintsSample idPrefix="themed" config={{ popoverClass: "driverjs-theme" }} hints={[ { element: "#themed-export", id: "export", popover: { title: "A themed popover", description: "Styled through popoverClass, exactly like a tour popover.", }, }, ]} client:load />
const productHints = hints({
popoverClass: "driverjs-theme",
hints: [...],
});