Hints
A hint is a passive guide, usually of one step, that starts on its own when its target scrolls into view: a pulsing beacon on the target, and the step's content in a popover when the user clicks it.
ts
// lib/guides.tsexport const exportStep = createGuideStep({ id: "reports.export", side: "left" });
export const exportHint = defineGuide({ id: "export-hint", mode: "passive", trigger: "visible", // or { on: "visible", delay: 1000, threshold: 1 } steps: [exportStep],});
export const guides = createGuideManager({ guides: [onboarding, exportHint] });tsx
// app/providers.tsx: mount the hint frame next to the tour frame.<GuideRoot manager={guides} router={router}> {children} <GuideSpotlight /> <TourFrame /> <Hint /></GuideRoot>tsx
// app/reports/export-button.tsxconst ExportContent = ({ ctx }: WithGuideContext) => ( <> <HintTitle ctx={ctx}>Export to CSV</HintTitle> <HintDescription ctx={ctx}>Download the filtered rows, ready for a spreadsheet.</HintDescription> </>);
export function ExportButton() { const { ref } = useGuideAnchor(exportStep, { content: ExportContent }); return <Button ref={ref}>Export</Button>;}The anchor and its content work exactly as in a tour; only the frame changes. Hint selects the passive runs and, for each one:
- draws the beacon on the target's corner, from
frame.rects: abuttonwitharia-expanded, pulsing in CSS (animate-ping, off with reduced motion); - opens the popover on click: the frame's
floatingProps, placed next to the target like the tour frame, with the content, a counter when the hint has several steps, and Next or Got it (end("completed")); - closes the popover on a press outside, and dismisses the hint with its close button or Escape while the focus is in it (
end("dismissed"), hidden when not dismissible).
It never takes the focus on its own: the popover only receives it after a click on the beacon, and after Next, when it stays open on the next step. A tour closes it: the hint comes back with its beacon only. A visible hint that was completed or dismissed never comes back by itself; bump its version to show it again. Labels are props with English defaults:
tsx
<Hint labels={{ open: "Voir l'astuce", close: "Fermer", next: "Suivant", done: "Compris" }} />