Elena Authoring — Critical Rules
Full reference: https://getelena.github.io/elena/llms-full.txt Page index: https://getelena.github.io/elena/llms.txt
Component types
Three types — the type determines whether render() is present:
- Primitive: owns its DOM, MUST have
render()returning anhtmltagged template. Elena callsreplaceChildren()on every render. - Composite: wraps composed children, must NOT have
render(). Never touches light DOM children. - Declarative: hybrid using
<template shadowrootmode="open">in the HTML markup. Norender().
Props
- Props must be declared in BOTH
static propsAND as class field defaults. Neither alone is sufficient. - The type is inferred from the default value:
false→ Boolean,0→ Number,[]→ Array,{}→ Object,"..."→ String. "text"is a reserved built-in prop. Never include it instatic props— Elena throws:"text" is reserved.- Use
{ name: "icon", reflect: false }instatic propsto suppress attribute reflection for a specific prop. - Annotate every prop with JSDoc
@propertyand@typeon the class field.
Events
static eventstells Elena which events to manage from the inner element.- Bubbling events (like
click,change,input) pass through to the host naturally with all their original properties intact. - Non-bubbling events (like
focusandblur) are forwarded to the host as plainEventinstances. - Never override
handleEvent()on a component that usesstatic events— Elena uses it internally for delegation. - Dispatch custom events with
new CustomEvent("my-event", { bubbles: true, composed: true, detail: { value } }).
Templates
render()must return anhtmltagged template literal. Importhtmlandnothingfrom@elenajs/core.- Use
nothing(not""orfalse) in conditional expressions to avoid template shape changes. - Nested
htmlfragments pass through without double-escaping. Plain string values are auto-escaped (XSS-safe). this.textcaptures the element'stextContenton connect. Use it inrender()for text content.unsafeHTML(str)bypasses escaping — only use for trusted, sanitized content.htmldoes NOT block JavaScript URIs. Always validate URLs before interpolating intohrefor other URL attributes:const safeUrl = /^https?:\/\//.test(url) ? url : "#";
Lifecycle
willUpdate()— runs before every render. Must NOT callsuper. Use for derived state.firstUpdated()— runs once after the first render.this.elementis available here.updated()— runs after every render, including the first. Runs afterfirstUpdated().this.elementis available inrender(), lifecycle methods, and custom methods. It is resolved after the first render completes.requestUpdate()— manually schedule a re-render when Elena cannot detect a change (e.g. mutating an array in place).updateComplete— Promise that resolves after the current render microtask finishes. Use to await DOM updates:await element.updateComplete.- All lifecycle methods except
willUpdate()should callsuper.
Mixins
- Apply mixins after
Elena():class Foo extends Draggable(Elena(HTMLElement)) {}. - Mixins that override lifecycle methods must call
super(exceptwillUpdate()). - Props introduced by a mixin must be listed in
static propson the final concrete class.
Registration
- Always call
ClassName.define()after the class body, not inside it. define()is a no-op in non-browser environments (SSR-safe).
Framework compatibility
- Never render a framework component inside a Primitive Component. Elena calls
replaceChildren()on render, destroying the framework tree. - For dynamic text content in frameworks, use the
textproperty:<elena-button text={label} />. Children won't update after hydration. - Avoid letting the framework and Elena both mutate the same attribute — the framework's reconciler will win on next render.
- Angular: Text children are inserted after
connectedCallbackfires, so Elena has already replaced the host's inner DOM by then. Always usetextas a property binding, never as a child node:<elena-button [text]="label"></elena-button>. - React 17: Does not pass
ArrayorObjecttype props or event handlers to custom elements correctly. Use React 18+ or pass all props as string attributes.
Source: getelena/elena — distributed by TomeVault.