Frameworks
Relements is framework-agnostic with no wrappers. There is no
@relements/react or @relements/vue — the published package is just
@relements/core, and the same surface works everywhere:
.re-*classes on native elements — the zero-JS styling baseline.data-*attributes — declarative hooks that behaviors read.re-*CustomEvents — bubbling DOM events you listen to withaddEventListener.enhance*(root) → { destroy() }behaviors — optional JS that wires a subtree and tears itself down.<re-*>light-DOM custom elements — self-registering, self-managing tags.
Because all five are plain web-platform primitives — classes, attributes, DOM
events, functions, and custom elements — every framework already speaks them.
The only thing that differs per framework is where you call enhance*() on
mount and destroy() on unmount, plus a line or two of config so the
framework lets <re-*> tags and their events through.
The integration shape
Section titled “The integration shape”Every framework page boils down to the same five steps:
-
Install + import the CSS once at the app entry —
import "@relements/core/index.css";. From here, native elements with.re-*classes anddata-*attributes work with zero JavaScript.<button className="re-button" type="button">Save</button> -
Behaviors — run
enhance*(el)in the framework’s “on mount” primitive against a ref to your subtree, and call the returnedcontroller.destroy()in “on unmount”. That is the whole lifecycle; behaviors are idempotent and remove every listener they added.const controller = enhanceTabs(el); // on mount// …controller.destroy(); // on unmount -
Events — a
re-*CustomEventis a normal bubbling DOM event. Listen with the framework’s event syntax and readevent.detail(e.g.enhanceTabsemitsre-changewith{ tabId, panelId }). -
Custom elements —
<re-*>are light-DOM custom elements, so they need no Shadow-DOM workarounds. Register each one with its bare side-effect import (import "@relements/core/elements/re-tabs";—package.jsonlistselements/*.jsundersideEffectsso thecustomElements.definesurvives tree-shaking), then tell the framework to pass the unknown tag through:Framework Config to allow <re-*>tagsListening to re-changeReact 19 none — renders unknown tags as-is ref+addEventListenerinuseEffectVue isCustomElement: (t) => t.startsWith("re-")@re-change="onChange"Svelte 5 none — unknown tags pass through onre-change={onChange}(case-sensitive)Angular CUSTOM_ELEMENTS_SCHEMAon the component(re-change)="onChange($event)"(cast$event) -
Forms / native inputs —
.re-input,.re-select,.re-textarea,.re-checkbox, … are just classes on native form controls, so they bind with the framework’s ordinary model/state (value/onChange,v-model,bind:value,[(ngModel)]) with no special handling.
That is it. The DOM, class names, --re-* tokens, and event contract are
identical across stacks; only the glue in steps 2 and 4 changes.
Pick your framework
Section titled “Pick your framework”Each page mirrors a runnable example app and walks through the five steps above:
Open any example live, no install — in StackBlitz or CodeSandbox (each framework page has its own one-click buttons).
Not using a framework? The same markup is the baseline everywhere — see
plain HTML usage, where <re-*> elements work
as-is and you listen with addEventListener("re-change", …).
The example corpus
Section titled “The example corpus”Every framework page is backed by an app under
docs/examples/frameworks/<fw>/ that consumes only the published
@relements/core API. All five render the same one flow:
- a
<button class="re-button">— the CSS class surface; - a tabs region enhanced by
enhanceTabs()— the behavior surface, with itsre-changeevent anddestroy()teardown (the apps mount/unmount the region to prove cleanup); - a
<re-tabs>custom element whosere-changeevent updates an<output>— the custom-element + event surface.
The DOM, class names, --re-* tokens, and re-change contract are identical
across all five; only the framework glue differs. Browse the source on
GitHub.
Related
Section titled “Related”- Behaviors & custom elements — the
full
enhance*contract, the<re-*>elements, and which to reach for. - HTML-first policy — why JS is an optional layer over markup that already works.
- Tabs ·
<re-tabs>— the component used throughout the examples.