Custom Elements

Attractions components can also be used as Web Components directly using the Custom Elements API. This use case is most convenient when a quick prototype is needed without including any frameworks or bundlers, where you just need to include a script tag and then use the components right away. An example usage is as follows:

<!DOCTYPE html>
<html lang="en">
  <script src=""></script>

    <a-button filled="true" danger="true">
      <a-dot style="margin-left: 10px;" attention="attention" />

    <!-- camelCase props do not work (HTML is case-insensitive) -->
    <a-switch slotLeft="true">

    <!-- Cannot use the self-closing syntax! -->
    <a-calendar id="calendar"></a-calendar>

  <div id="container">
    <!-- more elements will be injected here -->

    // Or using the normal constructor
    const { Button } = attractions;
    new Button({
      target: document.getElementById('container'),
      props: {
        filled: true,

    const calendar = document.getElementById('calendar');
    // Setting props that aren't string
      year: 2020,
      month: 11,

    // Listening to events
    calendar.$on('day-select', (e) => {
      alert(`You selected ${e.detail}`);

    // Utils are also exposed
    const { range } = attractions.utils;
    for (const val of range(2, 9, 3)) {

As shown in the example above, events must be listened to using $on and not addEventListener. Additionally, props that are passed in the HTML are only limited to props with lowercase string names. For any other props, use $$set.