Enhance

The enhance() function lets you add Lightview's reactivity to existing HTML elements. Perfect for progressive enhancement - start with plain HTML and add interactivity where needed.

Why Enhance?

Sometimes you have existing HTML - maybe from a CMS, a server-rendered template, or just plain HTML. Rather than rebuilding everything with Lightview elements, enhance() lets you incrementally add reactivity to what's already there.

Basic Usage

const { signal, enhance } = Lightview;

// Select an existing element and make it reactive
const counter = signal(0);
enhance('#my-element', {
    innerText: () => `Count: ${counter.value}`
});

// Now when counter changes, the element updates automatically!

Syntax

enhance(selectorOrNode, options)

// selectorOrNode: CSS selector string or DOM element
// options: { innerText?, innerHTML?, ...attributes }

// Returns: Lightview element wrapper (or null if not found)

Live Example: Basic Enhancement

const { signal, enhance } = Lightview;

const name = signal('');

// Enhance the input field
enhance('#name-input', {
    oninput: (e) => name.value = e.target.value,
    value: () => name.value
});

// Enhance the greeting title
enhance('#greeting-title', {
    innerText: () => name.value ? `Hello, ${name.value}!` : 'Welcome!'
});

// Enhance the greeting message
enhance('#greeting-message', {
    innerText: () => name.value 
        ? `Nice to meet you, ${name.value}!` 
        : 'Enter your name below',
    style: () => name.value 
        ? 'color: #28a745; font-weight: 500;'
        : 'color: #6c757d;'
});

// Enhance the reset button
enhance('#reset-btn', {
    onclick: () => name.value = '',
    disabled: () => !name.value,
    style: () => `padding: 0.5rem 1rem; background: ${name.value ? '#dc3545' : '#6c757d'}; color: white; border: none; border-radius: 4px; cursor: ${name.value ? 'pointer' : 'not-allowed'}; opacity: ${name.value ? 1 : 0.5};`
});

Options

innerText

Replace the text content of an element. Can be static or reactive:

// Static text
enhance('#greeting', { innerText: 'Hello World' });

// Reactive text - updates when signal changes
const name = signal('Alice');
enhance('#greeting', { innerText: () => `Hello ${name.value}` });

innerHTML

Replace the HTML content. Use with caution - only with trusted content:

const html = signal('Bold text');
enhance('#content', { innerHTML: () => html.value });

Attributes

Any other properties in options are treated as attributes. These can also be reactive:

const isDisabled = signal(false);
const theme = signal('light');

enhance('#my-button', {
    disabled: () => isDisabled.value,
    class: () => `btn btn-${theme.value}`,
    'data-active': () => !isDisabled.value
});

Live Example: Reactive Attributes

const { signal, enhance, tags } = Lightview;
const { div } = tags;

const disabled = signal(false);

enhance('#toggle-btn', {
    onclick: () => disabled.value = !disabled.value,
    innerText: () => disabled.value ? 'Enable' : 'Disable'
});

enhance('#target-btn', {
    disabled: () => disabled.value,
    style: () => `opacity: ${disabled.value ? 0.5 : 1}; cursor: ${disabled.value ? 'not-allowed' : 'pointer'};`
});

Progressive Enhancement Pattern

Start with semantic HTML that works without JavaScript, then enhance with Lightview:


<div id="user-info">
    <h2>Guest</h2>
    <p>Please log in</p>
</div>

<script>
    // Enhancement kicks in when JS loads
    const { signal, enhance } = Lightview;
    const user = signal(null);

    // Fetch user data
    fetch('/api/user').then(r => r.json()).then(data => {
        user.value = data;
    });

    // Enhance the existing markup
    enhance('#user-info h2', {
        innerText: () => user.value?.name ?? 'Guest'
    });

    enhance('#user-info p', {
        innerText: () => user.value
            ? `Welcome back, ${user.value.name}!`
            : 'Please log in'
    });

Return Value

enhance() returns a Lightview element wrapper with a domEl property pointing to the actual DOM node. This lets you further manipulate it:

const el = enhance('#my-div', { class: 'enhanced' });

// Access the wrapped element
if (el) {
    console.log(el.domEl);  // The actual DOM node
    el.attributes.id = 'new-id';  // Update attributes reactively
}

Tips & Patterns

Enhance Multiple Elements

// Enhance a list of elements
document.querySelectorAll('.counter').forEach(el => {
    const count = signal(0);
    enhance(el, {
        innerText: () => count.value,
        onclick: () => count.value++
    });
});

Reusing Elements

If you call enhance() on an already-enhanced element, it merges the new options:

// First enhancement
enhance('#btn', { innerText: 'Click me' });

// Second enhancement - adds to the first
enhance('#btn', { onclick: "alert('clicked')" });

// Result: <button onclick="alert('clicked')">Click me

When to Use

  • Use enhance(): When you have existing HTML (server-rendered, CMS, etc.)
  • Use element/tags: When building new UI from scratch in JavaScript
  • Mix both: Enhance static structure, build dynamic parts with tags