CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-slidev--types

Comprehensive TypeScript type definitions and interfaces for the Slidev presentation framework ecosystem

Pending
Overview
Eval results
Files

clicks-interactions.mddocs/

Click and Interaction System

Types for managing slide interactions, animations, and click-based progression through presentation content.

Capabilities

Click Value Types

Types for defining click values and ranges for slide interactions.

/**
 * Raw single value types for 'at' attribute
 */
type RawSingleAtValue = null | undefined | boolean | string | number;

/**
 * Raw range value types for 'at' attribute
 */
type RawRangeAtValue = null | undefined | false | [string | number, string | number];

/**
 * Combined raw 'at' value type
 */
type RawAtValue = RawSingleAtValue | RawRangeAtValue;

/**
 * Normalized single click value types
 */
type NormalizedSingleClickValue =
  | number    // since absolute click
  | string    // since relative click
  | null;     // disabled

/**
 * Normalized range click value types
 */
type NormalizedRangeClickValue =
  | [number, number]                    // [absolute start, absolute end]
  | [number, string]                    // [absolute start, absolute end based on start]
  | [string, number]                    // [relative start, absolute end]
  | [string, string]                    // [relative start, relative end]
  | [string | number, string | number]  // make TypeScript happy
  | null;                               // disabled

/**
 * Combined normalized value type
 */
type NormalizedAtValue =
  | NormalizedSingleClickValue  // since
  | NormalizedRangeClickValue;  // range

/**
 * Click element type
 */
type ClicksElement = Element | string;

Clicks Information Interface

Information structure for click states and calculations.

/**
 * Click information interface providing state and calculations
 */
interface ClicksInfo {
  /** The absolute start click num */
  start: number;
  /** The absolute end click num */
  end: number;
  /** The required total click num */
  max: number;
  /** The delta for relative clicks */
  delta: number;
  /** currentClicks - start */
  currentOffset: ComputedRef<number>;
  /** currentOffset === 0 */
  isCurrent: ComputedRef<boolean>;
  /** Computed ref of whether the click is active */
  isActive: ComputedRef<boolean>;
}

Clicks Context Interface

Main interface for managing clicks within a slide.

/**
 * Clicks context interface for managing slide interactions
 */
interface ClicksContext {
  /** Current click position */
  current: number;
  /** Starting click position for the slide */
  readonly clicksStart: number;
  /** Map of elements to their relative sizes */
  readonly relativeSizeMap: Map<ClicksElement, number>;
  /** Map of elements to their maximum click values */
  readonly maxMap: Map<ClicksElement, number>;
  /** Calculate click info for since-style values */
  calculateSince: (at: RawSingleAtValue, size?: number) => ClicksInfo | null;
  /** Calculate click info for range-style values */
  calculateRange: (at: RawRangeAtValue) => ClicksInfo | null;
  /** Calculate click info for any at value */
  calculate: (at: RawAtValue) => ClicksInfo | null;
  /** Register an element with click information */
  register: (el: ClicksElement, info: Pick<ClicksInfo, 'delta' | 'max'> | null) => void;
  /** Unregister an element */
  unregister: (el: ClicksElement) => void;
  /** Whether the context is mounted */
  readonly isMounted: boolean;
  /** Setup the clicks context */
  setup: () => void;
  /** Current offset from start */
  readonly currentOffset: number;
  /** Total clicks for the slide */
  readonly total: number;
}

Usage Examples

Basic Click Usage:

import type { ClicksContext, ClicksInfo } from "@slidev/types";

// Using clicks context in a component
function useSlideClicks(clicksContext: ClicksContext) {
  // Register an element for clicks
  const element = document.querySelector('.animated-element');
  
  clicksContext.register(element, {
    delta: 1,  // This element needs 1 click
    max: 3     // Maximum 3 clicks total for this element
  });
  
  // Calculate click info for specific values
  const sinceInfo = clicksContext.calculateSince(2);  // Show since click 2
  const rangeInfo = clicksContext.calculateRange([1, 3]);  // Show from click 1 to 3
  
  return {
    isVisible: sinceInfo?.isActive,
    currentClick: clicksContext.current
  };
}

Click Info Calculations:

// Example of working with click information
function handleClickInfo(clicksInfo: ClicksInfo | null) {
  if (!clicksInfo) return;
  
  console.log(`Click range: ${clicksInfo.start} to ${clicksInfo.end}`);
  console.log(`Total clicks needed: ${clicksInfo.max}`);
  console.log(`Current offset: ${clicksInfo.currentOffset.value}`);
  
  // React to click state changes
  watch(clicksInfo.isActive, (active) => {
    if (active) {
      console.log('Element is now active');
    } else {
      console.log('Element is now inactive');
    }
  });
  
  watch(clicksInfo.isCurrent, (current) => {
    if (current) {
      console.log('Element is at current click position');
    }
  });
}

Dynamic Click Registration:

function dynamicClickRegistration(clicksContext: ClicksContext) {
  const elements = document.querySelectorAll('.click-element');
  
  elements.forEach((element, index) => {
    // Register each element with different click requirements
    clicksContext.register(element, {
      delta: 1,
      max: index + 1
    });
  });
  
  // Later, unregister elements if needed
  const cleanup = () => {
    elements.forEach(element => {
      clicksContext.unregister(element);
    });
  };
  
  return cleanup;
}

Advanced Click Calculations:

function advancedClickUsage(clicksContext: ClicksContext) {
  // Calculate different types of click ranges
  const examples = [
    clicksContext.calculate(1),           // Show since click 1
    clicksContext.calculate([2, 4]),      // Show from click 2 to 4
    clicksContext.calculate(["+1", 3]),   // Relative start, absolute end
    clicksContext.calculate(["1", "+2"]), // Relative start and end
    clicksContext.calculate(null),        // Disabled
    clicksContext.calculate(false)        // Disabled range
  ];
  
  examples.forEach((info, index) => {
    if (info) {
      console.log(`Example ${index}:`, {
        start: info.start,
        end: info.end,
        max: info.max,
        delta: info.delta
      });
    } else {
      console.log(`Example ${index}: Disabled`);
    }
  });
}

Reactive Click State:

import { computed, watch } from 'vue';

function reactiveClickState(clicksContext: ClicksContext) {
  // Create reactive computations based on click state
  const progress = computed(() => {
    if (clicksContext.total === 0) return 0;
    return (clicksContext.current - clicksContext.clicksStart) / clicksContext.total;
  });
  
  const isComplete = computed(() => {
    return clicksContext.current >= clicksContext.clicksStart + clicksContext.total;
  });
  
  const remainingClicks = computed(() => {
    return Math.max(0, clicksContext.clicksStart + clicksContext.total - clicksContext.current);
  });
  
  // Watch for click changes
  watch(() => clicksContext.current, (newClick, oldClick) => {
    console.log(`Click changed from ${oldClick} to ${newClick}`);
    console.log(`Progress: ${Math.round(progress.value * 100)}%`);
    
    if (isComplete.value) {
      console.log('All clicks completed for this slide');
    } else {
      console.log(`${remainingClicks.value} clicks remaining`);
    }
  });
  
  return {
    progress,
    isComplete,
    remainingClicks
  };
}

Install with Tessl CLI

npx tessl i tessl/npm-slidev--types

docs

cli-build.md

clicks-interactions.md

code-execution.md

config-frontmatter.md

context-menu.md

index.md

markdown-transform.md

options-system.md

setup-plugins.md

slide-data.md

table-of-contents.md

tile.json