0.2.0

Steps are the core of any tour. Each step defines which element to spotlight, what content to show in the tooltip, and optional lifecycle hooks that fire during navigation.

Config

PropertyTypeDescription
targetstring | HTMLElement | BordaStepTargetQueryElement to spotlight. CSS selector, HTMLElement, or structured query. Required.
titlestringTooltip heading text. Required.
descriptionstringTooltip body text. Required.
imagestring | BordaStepImageImage shown above the tooltip heading. A string sets the source; an object carries its own alt.
placementComponentPlacementTooltip placement relative to the target.
prepareElement() => Promise<void> | voidAsync hook called before entering this step. Navigation waits for it to resolve.
onBeforeHighlighted() => voidFires before the target is highlighted, after prepareElement.
onHighlighted() => voidFires after the target is highlighted and the step index is updated.
onDeselected() => voidFires when navigating away from this step.
onNext() => voidStep-level next handler; fires alongside the tour-level onNext.
onPrev() => voidStep-level prev handler; fires alongside the tour-level onPrev.

Basic example

await borda.mount({
  steps: [
    {
      target: '#sidebar',
      title: 'Navigation',
      description: 'Use the sidebar to browse different sections.',
      placement: ComponentPlacement.MIDDLE_END,
    },
    {
      target: '#search',
      title: 'Search',
      description: 'Find anything quickly with the search bar.',
      placement: ComponentPlacement.BOTTOM_CENTER,
    },
    {
      target: '#settings',
      title: 'Settings',
      description: 'Customize your experience here.',
      placement: ComponentPlacement.MIDDLE_START,
    },
    {
      target: '#help',
      title: 'Need help?',
      description: 'Open the docs link from anywhere in the app.',
      placement: ComponentPlacement.TOP_END,
    },
  ],
});

Target resolution

The target field accepts three formats:

// CSS selector string
{ target: '#my-element' }

// Direct HTMLElement reference
{ target: document.getElementById('my-element') }

// Structured query (data attributes)
{ target: { id: 'my-element', class: 'active', data: { name: 'tour-target', value: 'step-1' } } }

Images

Add an image above the tooltip heading:

// Simple string (empty alt)
{ target: '#el', title: 'Title', description: 'Text', image: '/tour/step-1.png' }

// Object with alt text
{ target: '#el', title: 'Title', description: 'Text', image: { src: '/tour/step-1.png', alt: 'Dashboard overview' } }

Per-step component overrides

Each step can override global component settings. Pass false to disable a component for that step only:

await borda.mount({
  steps: [
    {
      target: '#intro',
      title: 'Welcome',
      description: 'Getting started.',
      placement: ComponentPlacement.BOTTOM_CENTER,
      tourButtons: { skip: false },
      tourProgress: false,
    },
    {
      target: '#details',
      title: 'Details',
      description: 'More info here.',
      placement: ComponentPlacement.MIDDLE_END,
      closeButton: false,
    },
  ],
});

Lifecycle hooks

Use prepareElement for async setup before a step is shown — expand a panel, scroll to an element, or fetch data:

{
  target: '#hidden-panel',
  title: 'Advanced settings',
  description: 'These options are for power users.',
  placement: ComponentPlacement.MIDDLE_END,
  prepareElement: async () => {
    await expandSettingsPanel();
    await waitForElement('#hidden-panel');
  },
}

Interface

interface BordaStep {
  target: BordaStepTarget;
  title: string;
  description: string;
  image?: BordaStepImageSource;
  placement: ComponentPlacement;
  onBeforeHighlighted?: () => void;
  onHighlighted?: () => void;
  onDeselected?: () => void;
  onNext?: () => void;
  onPrev?: () => void;
  prepareElement?: () => Promise<void> | void;
}