Skip to content

Editor setup

Relements ships two opt-in aids for authoring: editor IntelliSense (autocomplete and hovers for the <re-*> tags, the data-* attributes, and the --re-* tokens), and TypeScript types for the custom elements. Both are optional — nothing about the library requires them.

The package ships editor metadata in two formats, so the completions work beyond VS Code:

  • VS Code custom-data (html.custom-data.json + css.custom-data.json) — read by VS Code and by any editor that runs the same HTML/CSS language servers over LSP (Neovim, Helix, Zed, Sublime Text, Emacs).
  • web-types (web-types.json) — read by JetBrains IDEs (WebStorm, IntelliJ, …), auto-discovered from node_modules with no configuration.

Either way you get, in HTML and framework templates:

  • the four <re-tabs> / <re-menu> / <re-popover> / <re-toast> tags, with a hover description and a docs link;
  • the styling attributes — data-variant, data-tone, data-size, data-placement, … (their allowed values, e.g. data-tone=info · success · warning · danger · neutral, are offered in VS Code and LSP editors);
  • the declarative data-re-* behavior hooks (data-re-dialog-trigger, data-re-dismiss, …);

and in CSS, every --re-* token inside var(…), with its default (and dark) value on hover:

.my-card {
padding: var(--re-space-4); /* hover shows: `1rem` */
color: var(--re-color-text);
}

Point your workspace at the two custom-data files in .vscode/settings.json:

{
"html.customData": ["./node_modules/@relements/core/html.custom-data.json"],
"css.customData": ["./node_modules/@relements/core/css.custom-data.json"]
}

Nothing to configure — JetBrains reads the package’s web-types field automatically after npm install. The <re-*> tags, data-* attributes, and --re-* tokens complete out of the box.

Other editors (Neovim, Helix, Zed, Sublime, Emacs)

Section titled “Other editors (Neovim, Helix, Zed, Sublime, Emacs)”

These run the same language servers (vscode-langservers-extracted), which load the HTML custom-data from the server’s dataPaths init option. For example, with Neovim’s built-in LSP:

vim.lsp.config("html", {
init_options = {
provideFormatter = true,
dataPaths = { vim.fn.getcwd() .. "/node_modules/@relements/core/html.custom-data.json" },
},
})

The files are editor-agnostic JSON at @relements/core/html.custom-data.json and @relements/core/css.custom-data.json — see your LSP client’s docs for how it forwards custom data (CSS custom-data is delivered via an LSP notification that some clients wire up for you).

Each <re-*> element ships a typed class (ReTabsElement, ReMenuElement, RePopoverElement, ReToastElement) from its subpath. Two small declarations wire those types into the DOM and into your framework’s templates. Drop them in a relements.d.ts that your tsconfig.json includes.

Augment HTMLElementTagNameMap so document.querySelector / createElement return the right element type everywhere:

relements.d.ts
import type { ReTabsElement } from "@relements/core/elements/re-tabs";
import type { ReMenuElement } from "@relements/core/elements/re-menu";
import type { RePopoverElement } from "@relements/core/elements/re-popover";
import type { ReToastElement } from "@relements/core/elements/re-toast";
declare global {
interface HTMLElementTagNameMap {
"re-tabs": ReTabsElement;
"re-menu": ReMenuElement;
"re-popover": RePopoverElement;
"re-toast": ReToastElement;
}
}
export {};
const tabs = document.querySelector("re-tabs"); // ReTabsElement | null
tabs?.value; // string | null — typed

So the <re-*> tags type-check inside your framework’s templates, add the matching augmentation. Each uses the element class from @relements/core/elements/*.

// relements.d.ts — React 19 (jsx: "react-jsx")
import type { DetailedHTMLProps, HTMLAttributes } from "react";
import type { ReTabsElement } from "@relements/core/elements/re-tabs";
declare module "react/jsx-runtime" {
namespace JSX {
interface IntrinsicElements {
"re-tabs": DetailedHTMLProps<HTMLAttributes<ReTabsElement>, ReTabsElement>;
// …repeat for re-menu / re-popover / re-toast
}
}
}

For jsx: "react" or "preserve", augment "react" instead of "react/jsx-runtime".

The runtime registration is unchanged — import "@relements/core/elements/re-tabs" once to define the tag. See the custom elements overview for that, and the framework guides for the per-framework enhance* wiring.