Skip to main content
userTourKit
@tour-kit/coreUtilities

Helper Functions

Helper utilities: step index calculations, progress percentages, and common tour operation functions in userTourKit

domidex01Published

getElement

Resolves a target selector to an HTMLElement.

import { getElement } from '@tour-kit/core';

const element = getElement('#my-button');
// Returns: HTMLElement | null

// Also works with functions
const dynamicElement = getElement(() => document.querySelector('.dynamic'));

waitForElement

Waits for an element to appear in the DOM.

import { waitForElement } from '@tour-kit/core';

// Wait up to 5 seconds for element to appear
const element = await waitForElement('#lazy-loaded', {
  timeout: 5000,
  interval: 100,
});

scrollToElement

Scrolls an element into view with options.

import { scrollToElement } from '@tour-kit/core';

await scrollToElement(element, {
  behavior: 'smooth',
  block: 'center',
  offset: { top: -20 },
});

calculatePlacement

Calculates optimal tooltip placement based on viewport.

import { calculatePlacement } from '@tour-kit/core';

const placement = calculatePlacement(targetRect, tooltipRect, {
  preferred: 'bottom',
  fallback: ['top', 'right', 'left'],
  padding: 8,
});
// Returns: 'bottom' | 'top' | 'right' | 'left' | ...

mergeConfig

Deep merges tour configurations.

import { mergeConfig } from '@tour-kit/core';

const baseConfig = {
  keyboard: true,
  spotlight: { padding: 8 },
};

const tourConfig = mergeConfig(baseConfig, {
  id: 'my-tour',
  steps: [...],
  spotlight: { borderRadius: 4 },
});

// Result:
// {
//   id: 'my-tour',
//   steps: [...],
//   keyboard: true,
//   spotlight: { padding: 8, borderRadius: 4 },
// }

isElementVisible

Checks if an element is visible in the viewport.

import { isElementVisible } from '@tour-kit/core';

const visible = isElementVisible(element);
// Returns: boolean

RTL Helpers

mirrorSide

Mirror a Side for RTL layout. left ↔ right; top / bottom are unchanged.

import { mirrorSide } from '@tour-kit/core';

mirrorSide('left', true);  // 'right'
mirrorSide('top',  true);  // 'top'

mirrorAlignment

Mirror an Alignment for RTL layout. start ↔ end; center is unchanged.

import { mirrorAlignment } from '@tour-kit/core';

mirrorAlignment('start', true); // 'end'

For full placement mirroring use mirrorPlacementForRTL.

Branch Helpers

These are exported for tours that drive branch logic from custom UI. Most consumers don't need them — <TourCard> and the built-in navigation reach for branching automatically.

MAX_BRANCH_DEPTH

import { MAX_BRANCH_DEPTH } from '@tour-kit/core';
// 50 — recursion guard for nested branch resolvers

Type Guards

import {
  isBranchResolver,
  isBranchSkip,
  isBranchToTour,
  isBranchWait,
  isSpecialTarget,
  isLoopDetected,
} from '@tour-kit/core';

declare function isBranchResolver(
  branch: Branch
): branch is (context: BranchContext) => BranchTarget | Promise<BranchTarget>;

declare function isBranchToTour(target: BranchTarget): target is BranchToTour;
declare function isBranchSkip(target: BranchTarget): target is BranchSkip;
declare function isBranchWait(target: BranchTarget): target is BranchWait;

declare function isSpecialTarget(
  target: BranchTarget
): target is 'next' | 'prev' | 'complete' | 'skip' | 'restart';

declare function isLoopDetected(
  stepId: string,
  visitCount: Map<string, number>,
  maxVisits?: number
): boolean;

resolveBranch

Resolve a Branch (static or function) into a concrete BranchTarget. Throws if depth exceeds MAX_BRANCH_DEPTH.

import { resolveBranch } from '@tour-kit/core';

const target = await resolveBranch(branch, context);

resolveTargetToIndex

Convert a BranchTarget to a step index inside the current tour.

import { resolveTargetToIndex } from '@tour-kit/core';

const stepIndex = resolveTargetToIndex(
  target,
  currentIndex,
  stepIdMap,        // Map<string, number>
  totalSteps,
);
// → number | null (null when the target cannot be resolved within this tour)

Initial State

initialTourState

The default TourState shape used when bootstrapping a tour reducer.

import { initialTourState } from '@tour-kit/core';
import type { TourState } from '@tour-kit/core';

const state: TourState = { ...initialTourState };