element

DOM manipulation with reactive support for imperative DOM interactions.

API

function element<T extends Element = Element>(
  selector: string
): ReactiveElement<T>

interface ReactiveElement<T extends Element = Element> {
  node: T | null;
  text(value: string | Signal<string> | (() => string)): ReactiveElement<T>;
  attr(attributes: HellaProps): ReactiveElement<T>;
  on(type: string, handler: EventListener): ReactiveElement<T>;
}

text

Sets the text content of the selected element. Automatically detects form elements (input, textarea, select) and sets their value property instead of textContent.

// Regular elements - sets textContent
element('.title').text('Hello World');

// Form elements - sets value property
element('#username').text('john@example.com');
element('#message').text('Type your message here...');

// Reactive text with signal
const message = signal('Dynamic content');
element('.title').text(message);

// Works with all element types reactively
element('#search-input').text(() => `Search: ${query()}`);

attr

Sets attributes on the selected element using an object. Supports static values, signals, and functions.

// Static attributes
element('.button').attr({ 
  disabled: true,
  class: 'btn btn-primary'
});

// Multiple attributes at once
element('.node').attr({
  'data-value': 'static',
  class: ['btn', 'btn-primary', 'large'],
  id: 'unique-id'
});

// Reactive attributes
const isActive = signal(false);
element('.button').attr({ 
  class: () => isActive() ? 'active' : 'inactive' 
});

// Mixed static and reactive
const status = signal('online');
element('.user').attr({
  'data-static': 'fixed-value',
  'data-status': status,
  class: () => `user ${status()}`
});

on

Attaches an event handler using HellaJS’s efficient event delegation system.

element('.button').on('click', () => {
  console.log('Button clicked!');
});

element('.input').on('input', (e) => {
  console.log('Input value:', e.target.value);
});

node

Provides access to the raw DOM element. Returns null if no element was found.

const wrapper = element('.my-element');
if (wrapper.node) {
  wrapper.node.focus();
}

Basic Usage

Use element to enhance existing DOM elements with reactive behavior.

import { signal } from '@hellajs/core';
import { element } from '@hellajs/dom';

const count = signal(0);

// Single element enhancement
element('.counter').text(count);
element('.increment').on('click', () => count(count() + 1));

// For multiple elements, use the elements() function instead

Key Concepts

Method Chaining

All methods return the ReactiveElement, enabling fluent method chaining:

element('.node')
  .text('Hello')
  .attr({ class: 'active', 'data-value': someSignal })
  .on('click', handleClick);

Reactive Integration

The element function integrates with HellaJS’s reactive system:

const user = signal({ name: 'John', status: 'online' });

element('.user-name').text(() => user().name);
element('.user-status').attr({ 
  class: () => `status ${user().status}`,
  'data-user': () => user().name
});

// When user() changes, both elements update automatically
user({ name: 'Jane', status: 'offline' });

Error Handling

The element function gracefully handles missing elements:

// If .nonexistent doesn't exist, methods are no-ops
element('.nonexistent')
  .text('test')
  .attr({ class: 'x' })
  .on('click', fn); // No errors thrown

// Check if element exists
const wrapper = element('.maybe-exists');
if (wrapper.node) {
  // Element exists, safe to use
  wrapper.text('Found!');
}