TourKit
@tour-kit/hintsHeadless

Headless Hints

Headless hint components: build custom beacon animations, tooltip designs, and hotspot UIs with render props

Headless Hints

Build completely custom hint UIs while leveraging User Tour Kit's logic for positioning, state management, and accessibility.

Why Use Headless Components?

  • Full design control - No pre-built styles to override
  • Custom rendering - Use render props for complete flexibility
  • Same logic - Position calculation, floating UI, dismissal state
  • Accessibility - ARIA attributes and keyboard support included

Available Components


Quick Example

import {
  HintHeadless,
  HintHotspotHeadless,
  HintTooltipHeadless,
} from '@tour-kit/hints/headless';

function CustomHint() {
  return (
    <HintHeadless
      id="feature-hint"
      target="#new-feature"
      content="Check out this new feature!"
      render={({
        isOpen,
        targetRect,
        hotspotRef,
        position,
        tooltipPlacement,
        content,
        dismiss,
        targetElement,
      }) => (
        <>
          <HintHotspotHeadless
            ref={hotspotRef}
            targetRect={targetRect}
            position={position}
            isOpen={isOpen}
            render={({ position: pos }) => (
              <button
                className="custom-pulse-dot"
                style={{
                  position: 'fixed',
                  top: pos.top,
                  left: pos.left,
                }}
              >
                <span className="dot" />
              </button>
            )}
          />

          {isOpen && targetElement && (
            <HintTooltipHeadless
              target={targetElement}
              placement={tooltipPlacement}
              onClose={dismiss}
              render={({ floatingStyles, refs, getFloatingProps }) => (
                <div
                  ref={refs.setFloating}
                  style={floatingStyles}
                  className="custom-tooltip"
                  {...getFloatingProps()}
                >
                  <p>{content}</p>
                  <button onClick={dismiss}>Got it</button>
                </div>
              )}
            />
          )}
        </>
      )}
    />
  );
}

Render Props Pattern

All headless components support render props for full customization:

// Render prop pattern
<HintHeadless
  render={(props) => <CustomUI {...props} />}
/>

// Props include:
// - isOpen, isDismissed
// - show, hide, dismiss
// - targetElement, targetRect
// - position, tooltipPlacement
// - content

Composing Components

You can use the headless components individually or compose them:

Full Composition

<HintHeadless
  id="my-hint"
  target="#element"
  render={(props) => (
    <>
      <HintHotspotHeadless {...} />
      {props.isOpen && <HintTooltipHeadless {...} />}
    </>
  )}
/>

Hotspot Only

<HintHotspotHeadless
  targetRect={rect}
  position="top-right"
  isOpen={isOpen}
  onClick={toggle}
/>

Tooltip Only

<HintTooltipHeadless
  target={element}
  placement="bottom"
  onClose={close}
>
  <MyTooltipContent />
</HintTooltipHeadless>

Comparison: Styled vs Headless

FeatureStyled (Hint)Headless (HintHeadless)
StylingTailwind classesNone (you provide)
VariantsPre-built (primary, success, etc.)Custom
FlexibilityComponent propsRender props
Bundle sizeIncludes stylesMinimal
Use caseQuick implementationCustom design systems

On this page