Introducing Stimulus-use composable behaviors for your controllers
Tags: stimulus, turbolinks, rails
Published: 2020-05-19 16:51:38

TL;DR : it is not React hooks for Stimulus, just a simple way to add new behaviors and lifecycle methods to your controllers.

From the early days of Stimulus, I enjoyed the simplicity and elegance of this modest framework. Nice conventions, simple and flexible API and not the least **very robust**.

## Motivations

In the past I explored several ways to create standard controllers either wrappers of libraries [stimulus-flatpickr](https://github.com/adrienpoly/stimulus-flatpickr) or [stimulus-conductor](https://github.com/adrienpoly/stimulus-conductor). While the first got a bit of traction mostly due to the popularity of Flatpickr, very few standard Stimulus controllers really stand out from the crowd. 

I spent some time recently doing quite a bit of React and got to discover the hooks and among them the [react-use library](https://github.com/streamich/react-use).

While in no way I ambition to bring full-blown hooks to Stimulus, I think there is a sweet spot for having composable modules that can enhance with new behaviors your controllers.  

## Stimulus-use

So with this in mind, I imagined [Stimulus-use](https://github.com/stimulus-use/stimulus-use). For now, it is a modest set of new behaviors (your can think of lifecycle events too) that you can add to your controller. For this initial release, it adds only a few behaviors but the objective was to get it out, show it, get it tested and get feedbacks on the overall API. 

## Extend or Compose

All new behavior are available either as a `Controller` that you can extend.

```js
import { IntersectionController } from 'stimulus-use'

export default class extends IntersectionController {
  appear(entry) {
    // triggered when the element appears within the viewport
  }
}
```

Or as `useFunction` you can use when you want to enhance your controller with a new behavior or compose several new ones into a single Controller.

```js
import { Controller } from 'stimulus'
import { useIntersection, useResize } from 'stimulus-use'

export default class extends Controller {
  connect() {
    useIntersection(this)
    useResize(this)
  }

  appear(entry) {
    // triggered when the element appears within the viewport
  }

  resized({ height, width }) {
    // trigered when the element is resized
  }
}
```

## Future & vision

While I don't think all behaviors available in React-use would make sens in Stimulus, quite a few are interesting and can be ported in a Stimulus way to this project. Things like idle, visible, windowResize, clipboard, lazyImage, localStorage, animations, clipboard etc.

While things tends to move slowly within Stimulus core (and I don't think it is a real issue as long as the list of issues remains close to nil) and as more and more people are getting into Stimulus we see definitely a need for more examples and standard patterns. 
Some great projects such as :
- [BetterStimulus](www.betterstimulus.com)
- [StimulusReflex](https://docs.stimulusreflex.com)
- [all of the free screencast on GoRails](https://gorails.com/series/stimulus-js)
- [StimulusAwesome](https://github.com/skatkov/awesome-stimulusjs)

are really helping

I hope this project can bring together more contributors so that we can all create in a more agile way some enhancement to Stimulus that would be :
- Standard, (stop reinventing the wheel)
- Battle tested
- Polyfilled
- Documented
- easy to use and compose with existing code

All contributions/contributors are welcome just ping me here or on the issues/PR [Stimulus-use](https://github.com/stimulus-use/stimulus-use)


{% github stimulus-use/stimulus-use %}