Eunomia v1.0.0-beta.2
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Events

A component needs a way to tell the rest of the page what just happened: a value changed, a panel closed, an option got picked. Eunomia does this the same way across every component, so once one event makes sense, every other component's events do too.

The naming convention

Almost every event a component dispatches is named eun, followed by what happened, in one word: eunchange, eunclose, eunselect, euncommit, eunconfirm. Seeing a eun-prefixed event name in an inspector or a console log immediately tells you it came from a Eunomia component, not from the browser itself or from another library sharing the page.

document.querySelector("eun-select").addEventListener("eunchange", (event) => {
  console.log(event.target.value);
});

One exception steps outside that convention on purpose, reusing a native browser event name instead of inventing a eun-prefixed one: Button and Fab dispatch the platform's own command event on their target as part of the Invoker Commands API, and Modal and Drawer listen for it. Reusing the existing name means a listener written for the native version keeps working unchanged against the Eunomia one, rather than asking every consumer to learn a second name for the same idea.

Reading what happened

An event rarely needs to say more than what already happened, so most of the useful information lives in one of two places instead of a generic grab-bag object.

For anything describing the component's own current state, read it straight off event.target, the same element already sitting in your markup:

No size picked yet
select.addEventListener("eunchange", (event) => {
  console.log(event.target.value);
});

For anything specific to that one occurrence and not part of the component's ongoing state, such as which option was picked from a menu or which slide is now active in a carousel, it's exposed as a plain, read-only property directly on the event object itself:

dropdownButton.addEventListener("eunselect", (event) => {
  console.log(event.key);
});

carousel.addEventListener("eunslidechange", (event) => {
  console.log(event.index, event.count);
});

Either way, nothing is ever buried inside a generic event.detail object: every event exposes a small, specific, named shape instead, and every one of those shapes is fully typed if the project uses TypeScript, letting an editor autocomplete event.target.value or event.key rather than requiring a lookup on this page every time. See Types for how that typing is wired up.

Bubbling

Every Eunomia event bubbles, so a single listener on a shared ancestor, such as a <form> or a whole page section, catches every matching event from any component inside it, without wiring a listener onto each one by hand:

document.querySelector("form").addEventListener("eunchange", (event) => {
  console.log(event.target.name, event.target.value);
});

Whether a given event also crosses a shadow DOM boundary (composed) depends on that specific event: one meant to stay inside the component that raised it stops there, while one meant to be caught from anywhere on the page, even through another component's shadow root, is composed so it can. Neither detail changes how you listen for it: it only matters if a listener sits on document itself, above every shadow root, rather than somewhere inside the same component tree.

Every event

Every custom event the library dispatches, what raises it, and what it means. Each component's own API tab still has the last word on the exact typed shape, for example Select: API or Modal: API, but this is the one place that lists them all side by side.

Event Dispatched by Means
eunchange Any form field (Input, Select, Textarea, Checkbox, Radio, Slider, Counter, Input file, Date picker, Time picker, Input phone), plus Toggle, Toggle group, Collapse, Sidebar, and Toolbar The component's own current value or state changed
euncommit Any editable form field (Input, Textarea, Counter, and similar) The current value is finalized (e.g. on blur), separate from every keystroke's own eunchange
eunclose Alert, Toast, Chip The close action was activated, or (Toast) its exit transition finished
eunselect Dropdown button An option was chosen from the menu
eunconfirm Modal The confirm action was triggered. Cancelable
euncancel Modal, Drawer The cancel action was triggered, including an implicit backdrop click or Escape
eundirtyclose Drawer A close attempt was gated behind unsaved changes, right before the discard-confirmation modal opens. Cancelable
eunnavigate Link, Button and Fab (with href set), Toolbar About to follow a link; lets an SPA router intercept it. Cancelable
eunloadmore Infinite list, Table Scrolled near the end of the known items; fetch the next page
eunpagechange Pagination A page control was activated, requesting a page change
eunpagesizechange Pagination A new page size was chosen
eunstepchange Stepper A reachable step was activated, requesting navigation to it
tabchange Tabs The active tab changed
eunslidechange Carousel The active slide settled on a new index
eunimagechange Image carousel The active image changed
eunfilereject Input file One or more offered files were rejected (type, size, or count)
eunslotclick Calendar An empty hour-grid slot was clicked, a create-event intent
euneventclick Calendar An event chip was clicked
euneventcreate Scheduler, Scheduler event editor A new event was saved
euneventupdate Scheduler, Scheduler event editor, Calendar An existing event was saved, or moved by dragging it to a new time or day
euneventdelete Scheduler, Scheduler event editor An event was deleted
eunguestinvite Scheduler event editor A guest email was added to an event's guest list
eunperiodchange Scheduler The visible date range changed
euntableaction Table, Table action bar An action button, or a dropdown action's option, was activated
euntablerowclick Table item A row was clicked outside its checkbox or action cell
euntableselectionchange Table The set of selected rows changed
command Button, Fab (as invokers), received by Modal, Drawer An invoker requested a command on its target; see Invoker Commands API

Two names above don't carry the eun prefix: command is the deliberate platform-native reuse covered under The naming convention above, while tabchange is a naming exception with no further significance, listen for it exactly as written.

See also