I gave this question some thought and experimented a bunch.
Then I also looked at the source maps of Hey.com. It seems that they are using Stimulus to show/and the empty state of the inbox. So it’s always there, and shows when you have no new messages.
After some experimentation, I created a Stimulus controller that uses a JavaScript MutationObserver to watch changes in the tree. If there are changes I count the targets. If there are no targets I show the empty state.
index.html.erb
:
<div id="vehicles" data-controller="empty-state">
<div data-empty-state-target="emptyState">
<%= render "empty_state" %>
</div>
<%= render @vehicles %>
</div>
_vehicle.html.erb
: (simplified)
<div class="p-4" data-empty-state-target="item" id="<%= dom_id(vehicle) %>">
...
</div>
empty_state_controller.js
:
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ["emptyState", "item"];
connect() {
this.observer = new MutationObserver(this.update.bind(this));
this.observer.observe(this.element, {
childList: true,
attributes: false,
subtree: true
});
this.update();
}
disconnect() {
this.observer.disconnect();
}
update() {
this.emptyStateTarget.classList.toggle("hidden", this.itemTargets.length !== 0);
}
}
I hope this helps someone with this question.