Types
Several properties across the library only ever accept one of a fixed,
short list of words: a severity is always info, success, warning,
critical, or neutral, never anything else. Rather than leaving that
list implicit, something you'd have to copy by hand into your own code
and hope you spelled the same way, the library exports it as a real
TypeScript type. Import it once, and your own functions, props, and
variables are checked against the exact same vocabulary the components
themselves use.
Importing one
Every type is available from the package's main entry point, alongside the components themselves:
import type { EunomiaSeverity } from "@eunomia/elements";
function bannerFor(status: EunomiaSeverity) {
// status is narrowed to "info" | "success" | "warning" | "critical" | "neutral"
}
import type (rather than a plain import) tells the bundler this line
exists only for the type checker, so it's fully removed from the
JavaScript that actually ships. It's the recommended way to bring in
any Eunomia type, since none of them exist at runtime as a value you
could accidentally reference.
The shared vocabulary
These five cover most of what
| Type | Values |
|---|---|
EunomiaSeverity |
info, success, warning, critical, neutral |
EunomiaActionVariant |
primary, secondary, critical, success, warning |
EunomiaAppearance |
default, fill, outline, flat, raised, ghost |
EunomiaTone |
primary, secondary, light, medium, dark |
EunomiaSize |
xs, s, m, l, xl |
What each of those words means and looks like once applied to a real
component is covered on
A component that only makes sense with a subset of a type still uses that
narrower subset, not the full union: eun-card's appearance,
for instance, only ever accepts default, fill, or
raised, three of EunomiaAppearance's six values. Check the
component's own API tab for its exact type rather than assuming the full
union above always applies unchanged.
A component's own type
A handful of components go one step further and export a type of their
own instead of reusing one of the five above directly, because their
own subset needs a name distinct from the general one. Chip is the
clearest example: it exports EunomiaChipColor, EunomiaChipSeverity,
EunomiaChipAppearance, and EunomiaChipSize rather than pointing at
EunomiaTone/EunomiaSeverity/EunomiaAppearance/EunomiaSize directly,
since a future change to Chip's own subset shouldn't silently reshape
every other component sharing the general type. Import the
component-specific name in that case:
import type { EunomiaChipSeverity } from "@eunomia/elements";
Either way, the component's own API tab always names the exact type
backing a given property, for example
Typing an element itself
Importing a component's class, such as EunomiaButton, brings its full
set of properties along with it, already typed. What TypeScript can't
know on its own, since it's a plain DOM API rather than something a
package can extend, is the custom element tag itself: teaching it that
shape is a short, one-time addition, covered in
Typing an event listener
Every event class the library dispatches, ChangeEvent, CloseEvent,
SelectEvent, and the rest, augments the browser's own
addEventListener overloads by itself, the moment the component using
it is imported, the same import already needed to render the component
at all:
import "@eunomia/elements/select.js";
select.addEventListener("eunchange", (event) => {
event.target.value; // already typed, no cast needed
});
See
See also
Variants : what each value in the shared vocabulary above actually looks likeEvents : the naming convention behind every typed event listenerGet started: TypeScript : teaching TypeScript a custom element's tag name