Foundational classes and utilities for building interactive widgets in Jupyter environments
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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.
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();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);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);
});NativeView provides several performance advantages:
addEventListener instead of jQuery-style delegationElement.matches() with fallbacksNativeView includes fallbacks for older browsers:
Element.matches()webkitMatchesSelectormozMatchesSelectormsMatchesSelectoroMatchesSelectorquerySelectorAll fallbackWhen 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.