CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tether

A client-side library to make absolutely positioned elements attach to elements in the page efficiently.

Pending
Overview
Eval results
Files

event-system.mddocs/

Event System

Event handling system for responding to positioning changes and tether lifecycle events. Tether extends the Evented base class to provide comprehensive event management capabilities including registration, removal, and triggering of custom events.

Capabilities

Event Registration

Register event handlers for tether events.

/**
 * Adds an event listener to the tether instance
 * @param event - Event name to listen for
 * @param handler - Function to call when event is triggered
 * @param ctx - Context (this value) for the handler function
 * @param once - Whether to execute the handler only once
 * @returns The tether instance for method chaining
 */
on(event: string, handler: Function, ctx?: any, once?: boolean): Tether;

/**
 * Adds a one-time event listener that will be removed after first execution
 * @param event - Event name to listen for
 * @param handler - Function to call when event is triggered
 * @param ctx - Context (this value) for the handler function
 * @returns The tether instance for method chaining
 */
once(event: string, handler: Function, ctx?: any): Tether;

Usage Examples:

import Tether from "tether";

const tether = new Tether({
  element: '.tooltip',
  target: '.button',
  attachment: 'top center',
  targetAttachment: 'bottom center'
});

// Listen for positioning updates
tether.on('update', function(data) {
  console.log('Attachment changed:', data.attachment, data.targetAttachment);
});

// Listen for repositioning events
tether.on('repositioned', function() {
  console.log('Element has been repositioned');
});

// One-time listener
tether.once('repositioned', function() {
  console.log('First reposition complete');
});

// Custom context
tether.on('update', function(data) {
  this.handleUpdate(data);
}, myObject);

Event Removal

Remove event listeners from the tether instance.

/**
 * Removes event listeners
 * @param event - Event name to remove listeners for (optional)
 * @param handler - Specific handler to remove (optional)
 * @returns The tether instance for method chaining
 */
off(event?: string, handler?: Function): Tether;

Usage Examples:

// Remove all listeners for 'update' event
tether.off('update');

// Remove specific handler
const myHandler = function(data) { /* ... */ };
tether.on('update', myHandler);
tether.off('update', myHandler);

// Remove all event listeners
tether.off();

Event Triggering

Manually trigger events on the tether instance.

/**
 * Triggers an event on the tether instance
 * @param event - Event name to trigger
 * @param args - Arguments to pass to event handlers
 * @returns The tether instance for method chaining
 */
trigger(event: string, ...args: any[]): Tether;

Usage Example:

// Manually trigger a custom event
tether.trigger('custom-event', { customData: 'value' });

Built-in Events

'update' Event

Fired when attachment points change due to constraints or positioning adjustments.

interface UpdateEventData {
  /** New element attachment configuration */
  attachment: AttachmentConfig;
  /** New target attachment configuration */
  targetAttachment: AttachmentConfig;
}

Usage Example:

tether.on('update', function(data) {
  // Handle attachment point changes
  console.log('Element attachment:', data.attachment);
  console.log('Target attachment:', data.targetAttachment);
  
  // Update UI or perform custom logic
  if (data.attachment.top === 'bottom') {
    element.classList.add('flipped');
  }
});

'repositioned' Event

Fired after the element has been repositioned in the DOM.

Usage Example:

tether.on('repositioned', function() {
  // Element position has been updated
  console.log('Element repositioned');
  
  // Trigger animations or other side effects
  element.classList.add('positioned');
  
  // Notify other components
  this.notifyPositionChange();
});

Event Patterns

Chaining Event Handlers

Events support method chaining for fluent API usage.

tether
  .on('update', handleUpdate)
  .on('repositioned', handleReposition)
  .once('repositioned', handleFirstReposition)
  .enable();

Error Handling in Events

Handle errors gracefully in event handlers.

tether.on('update', function(data) {
  try {
    // Your event handling logic
    this.processUpdate(data);
  } catch (error) {
    console.error('Error handling update event:', error);
  }
});

Context Management

Use context parameter to maintain proper this binding.

class MyComponent {
  constructor() {
    this.tether = new Tether({
      element: '.my-element',
      target: '.my-target',
      attachment: 'top center',
      targetAttachment: 'bottom center'
    });
    
    // Bind events with component context
    this.tether.on('update', this.handleUpdate, this);
    this.tether.on('repositioned', this.handleReposition, this);
  }
  
  handleUpdate(data) {
    // 'this' refers to MyComponent instance
    this.updateState(data);
  }
  
  handleReposition() {
    // 'this' refers to MyComponent instance
    this.onPositionChange();
  }
}

Types

interface AttachmentConfig {
  top: string | false;
  left: string | false;
}

type EventHandler = (...args: any[]) => void;

interface EventBinding {
  handler: EventHandler;
  ctx: any;
  once: boolean;
}

interface EventedInstance {
  bindings?: {
    [eventName: string]: EventBinding[];
  };
}

// Built-in Tether events
type TetherEventName = 'update' | 'repositioned' | string;

Install with Tessl CLI

npx tessl i tessl/npm-tether

docs

constraints.md

core-positioning.md

event-system.md

index.md

optimization.md

tile.json