New Stimulus Package: Stimulus Reactive!

Hi All

Took a deep dive into Stimulus source code and just released this package!

What this allows one to do is simply declare the controller logic and reduce a lot of boilerplate!

In the following shopping cart example:

When a cart item gets added or removed, or an existing item’s quantity or price is updated

  • The cart total will show the correct value
  • The checkout button will be enabled or disabled based on the total.
class CartItemController extends Controller {
  static targets = ["total"];
  static values = {
    price: Number,
    quantity: { type: Number, default: 1 },
  };

  static afterLoad(identifier, application) {
    useStimulusReactive(identifier, application);
  }

  connect() {
    // item total will be updated when price or quantity changes
    this.effect(() => {
      this.totalTarget.textContent = (
        this.priceValue * this.quantityValue
      ).toString();
    });
  }
}
class CartController extends Controller {
  static targets = ["checkout", "cartTotal"];
  static outlets = ["cart-item"];

  static afterLoad(identifier, application) {
    useStimulusReactive(identifier, application);
  }

  connect() {
    // total will be updated when items get added or removed
    // or when an individual item's price or quantity changes!
    const total = this.computed(() =>
      this.cartItemOutlets.reduce(
        (total, item) => total + item.priceValue * item.quantityValue,
        0
      )
    );

    // checkout button will be enabled only when balance is due
    this.effect(() => (this.checkoutTarget.disabled = total.value <= 0));

    // text content is kept in sync with cart total
    this.effect(
      () => (this.cartTotalTarget.textContent = total.value.toString())
    );
  }
}

As you can see there is inter-controller communication and state management and everything just works without needing to wire up any custom events!

How this works is by hooking onto the controller value and outlet changes and making the state reactive using @vue/reactivity

Thanks

Ajai

Cool idea, thanks! For my case, for more complex reactive components i found Svelte as a alternative, see video and how to integrate in rails.

From the view of developer ergonomics Svelte is TOP, you just will love it.

From the view of progressive web enhancement Rails 7 and, also, your here posted «Stimulus Reactive» are THE unique selling point because you are really hardcoding html and setting js on the top. This is the way the web is invented and like it should be. And all this resulting in a app that has a user-experience like a SPA - great!

Thanks @christian1

Will definitely take a look at Svelte.

Though not a rails developer, I found Turbo and Stimulus to be such a welcome change from how we are used to doing things.

That said, am a huge fan of Remix JS and have used it successfully in personal projects.

My evil plan is to get Hotwire integrated with a Java stack (Springboot/Javalin) at work :slight_smile:

Ajai

1 Like

Idea of a new HTML Markup language