Skip to content

Component Context

The Component Context is the object passed to your factory function in defineComponent. It provides all the tools needed to build reactive components.

The component’s root element (the element with data-lume).

defineComponent(({ root }) => {
  root.classList.add("initialized");
  return {};
});

Type: HTMLElement


Finds a single element with data-lume-part="name" inside the root.

const button = part("button"); // HTMLElement

Throws if the element is not found.


Finds all elements with data-lume-part="name" inside the root.

const items = parts("item"); // HTMLElement[]

Returns an empty array if no elements match.


Returns a factory function that clones a <template data-lume-part="name"> element.

const createItem = template("item");
const fragment = createItem(); // DocumentFragment
root.appendChild(fragment);

Returns: () => DocumentFragment


Creates a reactive signal with an initial value.

const count = signal(0);

count();              // Read: 0
count.set(5);         // Write: 5
count.update(v => v + 1); // Transform: 6

Returns: SignalGetter<T> — a callable object with .set() and .update() methods.


Runs a function immediately and re-runs it whenever any signal it reads changes.

effect(() => {
  element.textContent = String(count());
});

The function may return a cleanup function:

effect(() => {
  const timer = setInterval(() => tick(), interval());
  return () => clearInterval(timer);
});

Adds an event listener that is automatically removed on unmount.

on(button, "click", () => count.update((v) => v + 1));
on(window, "resize", handleResize, { passive: true });
ParameterTypeDescription
targetEventTargetAny event target (element, window, etc.)
eventstringEvent name
handlerEventListenerEvent handler function
optionsAddEventListenerOptionsOptional listener options

Registers a function to be called when the component unmounts.

const observer = new IntersectionObserver(callback);
observer.observe(root);

cleanup(() => observer.disconnect());

Emits a local event within the app.

emit("item-selected", { id: 42 });

Listens to local app events. Automatically cleaned up on unmount.

listen("theme-changed", (detail) => {
  applyTheme(detail);
});

Object for global (cross-app) events.

global.emit("user-action", { type: "click" });
global.listen("app-ready", () => {
  initialize();
});

import { defineComponent } from "@beardcoder/lume";

export const accordion = defineComponent(
  ({ root, part, parts, signal, effect, on, cleanup, emit }) => {
    const items = parts("item");
    const activeIndex = signal(-1);

    for (const [i, item] of items.entries()) {
      const trigger = item.querySelector("[data-role='trigger']")!;
      on(trigger, "click", () => {
        activeIndex.update((v) => (v === i ? -1 : i));
      });
    }

    effect(() => {
      const idx = activeIndex();
      for (const [i, item] of items.entries()) {
        item.classList.toggle("active", i === idx);
      }
      emit("accordion-changed", { index: idx });
    });

    return {
      open: (index: number) => activeIndex.set(index),
      close: () => activeIndex.set(-1),
    };
  }
);