@gluonjs/core


@gluonjs/core / src / defineGluonElement

Function: defineGluonElement()

defineGluonElement<TagName, Properties, Events, Slots, FormAssociated, Public>(definition, options?): FunctionalElementClass<Properties, Events, FormAssociated, Public>

Defines and registers one autonomous Custom Element backed by GluonElement. Setup runs once per connection inside the element's owned reactive scope.

Type Parameters

TagName

TagName extends `${string}-${string}`

Properties

Properties extends Readonly<Record<string, PropertyDefinition<any>>> = Record<never, never>

Events

Events extends Readonly<Record<string, EventDeclaration<any>>> = Record<never, never>

Slots

Slots extends Readonly<Record<string, SlotDeclaration>> = Record<never, never>

FormAssociated

FormAssociated extends boolean = false

Public

Public extends object = Record<string, never>

Parameters

definition

FunctionalElementDefinition<TagName, Properties, Events, Slots, FormAssociated, Public>

options?

DefineGluonElementOptions = {}

Returns

FunctionalElementClass<Properties, Events, FormAssociated, Public>

Example

Define one registered autonomous Custom Element with inferred properties, events, slots, form APIs, retained local state, connection-owned cleanup, and a render function:

ts
import { defineGluonElement, elementEvent, elementProperty, html } from '@gluonjs/core';

type Product = { id: string; price: number };
const QuantityControl = defineGluonElement({
  tagName: 'shop-quantity',
  formAssociated: true,
  properties: {
    product: elementProperty<Product>({ type: Object, required: true }),
    value: { type: Number, reflect: true, default: 1 },
  },
  events: { change: elementEvent<{ value: number }>({ cancelable: true }) },
  slots: { default: { required: true }, help: { fallback: true } },
  setup(context) {
    const value = context.state('value', context.props.value);
    const total = context.computed(() => value.value * context.props.product.price);
    context.onUpdated(() => context.form.setValue(String(value.value)));
    context.onCleanup(() => console.log('quantity setup released'));
    return {
      expose: { focus: () => context.host.shadowRoot?.querySelector('button')?.focus() },
      render: () => html`<slot></slot><button>${value.value}</button><output>${total.value}</output><slot name="help"></slot>`,
    };
  },
});

const quantity = new QuantityControl();
quantity.product = { id: 'lamp', price: 12 };
quantity.value = 2;
quantity.focus();