CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jupyter-widgets--base

Foundational classes and utilities for building interactive widgets in Jupyter environments

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

nativeview.mddocs/

NativeView

NativeView is a foundational class that extends Backbone.View with native DOM event delegation, providing enhanced performance and modern DOM handling capabilities. It serves as the base class for WidgetView and other view components.

Capabilities

NativeView Class

Enhanced Backbone.View with native DOM event delegation and element manipulation utilities.

/**
 * Native DOM view implementation extending Backbone.View
 * Provides enhanced event delegation using native DOM methods
 */
class NativeView<T extends Backbone.Model> extends Backbone.View<T> {
  /**
   * Delegate event listeners using native DOM methods
   * @param eventName - DOM event name (e.g., 'click', 'change')
   * @param listener - Event handler function
   * @returns This view instance for chaining
   */
  delegate(eventName: string, listener: Function): this;
  
  /**
   * Delegate event listeners with CSS selector
   * @param eventName - DOM event name
   * @param selector - CSS selector for event delegation
   * @param listener - Event handler function  
   * @returns This view instance for chaining
   */
  delegate(eventName: string, selector: string, listener: Function): this;

  /**
   * Remove delegated event listener
   * @param eventName - DOM event name to remove
   * @param selector - Optional CSS selector
   * @param listener - Optional specific listener to remove
   * @returns This view instance for chaining
   */
  undelegate(eventName: string, selector?: string, listener?: Function): this;
  
  /**
   * Remove delegated event listener by selector
   * @param selector - CSS selector
   * @param listener - Optional specific listener to remove
   * @returns This view instance for chaining
   */
  undelegate(selector: string, listener?: Function): this;

  /**
   * Remove all delegated event listeners from the element
   * @returns This view instance for chaining
   */
  undelegateEvents(): this;

  /**
   * Remove the view's element from the DOM and clean up events
   */
  _removeElement(): void;

  /**
   * Set the DOM element for this view
   * @param element - HTML element to attach to this view
   */
  _setElement(element: HTMLElement): void;

  /**
   * Set attributes on the view's element
   * @param attrs - Hash of attributes to set
   */
  _setAttributes(attrs: Backbone.ObjectHash): void;
}

Usage Examples:

import { NativeView } from "@jupyter-widgets/base";

// Create a custom view extending NativeView
class MyCustomView extends NativeView<MyModel> {
  initialize() {
    // Delegate click events to buttons within this view
    this.delegate('click', 'button', this.handleButtonClick);
    
    // Delegate change events with selector
    this.delegate('change', 'input[type="text"]', this.handleTextChange);
    
    // Delegate without selector (binds to this.el)
    this.delegate('keydown', this.handleKeyDown);
  }

  handleButtonClick(event: Event) {
    const button = event.delegateTarget as HTMLButtonElement;
    console.log('Button clicked:', button.textContent);
  }

  handleTextChange(event: Event) {
    const input = event.delegateTarget as HTMLInputElement; 
    this.model.set('text_value', input.value);
  }

  handleKeyDown(event: KeyboardEvent) {
    if (event.key === 'Escape') {
      this.remove();
    }
  }

  remove() {
    // Clean up all delegated events
    this.undelegateEvents();
    
    // Remove specific event
    this.undelegate('click', 'button');
    
    return super.remove();
  }
}

// Manual event management
const view = new MyCustomView();

// Add event delegation
view.delegate('mouseover', '.tooltip-trigger', (e) => {
  showTooltip(e.delegateTarget);
});

// Remove specific delegated event
view.undelegate('mouseover', '.tooltip-trigger');

// Remove all events for cleanup
view.undelegateEvents();

Advanced Event Delegation

CSS Selector Support

NativeView supports full CSS selector syntax for event delegation:

// Class selectors
view.delegate('click', '.button-primary', handlePrimaryClick);

// Attribute selectors  
view.delegate('change', 'input[data-validate]', handleValidation);

// Descendant selectors
view.delegate('click', '.panel .close-button', handlePanelClose);

// Pseudo-selectors
view.delegate('focus', 'input:not([readonly])', handleFocus);

Event Object Enhancement

When using delegated events with selectors, the event object is enhanced:

view.delegate('click', '.item', function(event) {
  // event.delegateTarget is the element matching the selector
  const item = event.delegateTarget as HTMLElement;
  
  // event.target is the actual clicked element (may be a child)
  const clickedElement = event.target as HTMLElement;
  
  console.log('Clicked on', clickedElement, 'within', item);
});

Performance Benefits

NativeView provides several performance advantages:

  • Native Event Delegation: Uses addEventListener instead of jQuery-style delegation
  • Efficient Selector Matching: Leverages native Element.matches() with fallbacks
  • Memory Management: Proper cleanup of event listeners to prevent memory leaks
  • Cross-browser Compatibility: Handles vendor prefixes and IE9+ compatibility

Browser Compatibility

NativeView includes fallbacks for older browsers:

  • Modern browsers: Uses Element.matches()
  • Webkit: Uses webkitMatchesSelector
  • Mozilla: Uses mozMatchesSelector
  • Microsoft: Uses msMatchesSelector
  • Opera: Uses oMatchesSelector
  • IE9+: Uses querySelectorAll fallback

Migration from Backbone.View

When extending NativeView instead of Backbone.View:

// Old Backbone.View approach
class OldView extends Backbone.View {
  events: {
    'click button': 'handleClick',
    'change input': 'handleChange'
  }
  
  handleClick(e) { /* ... */ }
  handleChange(e) { /* ... */ }
}

// New NativeView approach
class NewView extends NativeView {
  initialize() {
    this.delegate('click', 'button', this.handleClick);
    this.delegate('change', 'input', this.handleChange);
  }
  
  handleClick(e) { /* ... */ }
  handleChange(e) { /* ... */ }
}

The NativeView approach provides more explicit control over event delegation and better performance with native DOM methods.

docs

communication.md

error-handling.md

index.md

layout-style.md

nativeview.md

registry.md

utilities.md

widget-classes.md

widget-manager.md

tile.json