erb

erb
<div data-controller="char-counter" data-char-counter-max-value="280">
  <%= form.text_area :body, rows: 6, data: { char_counter_target: 'input' }, class: 'w-full rounded border p-2' %>
  <div class="mt-1 text-sm text-gray-500">
    <span data-char-counter-target="output"></span> characters remaining
  </div>
</div>

Character counter for textareas with Stimulus

rails hotwire stimulus
by Henry Kim 2 tabs
erb
<nav class="mt-6 flex gap-2">
  <% if @page > 1 %>
    <%= link_to 'Prev', projects_path(page: @page - 1), data: { turbo_frame: '_top' }, class: 'rounded bg-gray-100 px-3 py-1' %>
  <% end %>

  <%= link_to 'Next', projects_path(page: @page + 1), data: { turbo_frame: '_top' }, class: 'rounded bg-gray-100 px-3 py-1' %>

Pagination links that escape a Turbo Frame with _top

rails hotwire turbo
by Henry Kim 2 tabs
erb
<div id="<%= dom_id(post) %>">
  <%= render 'posts/card', post: post %>
</div>

Use dom_id everywhere to keep Turbo replacements deterministic

rails hotwire turbo
by Henry Kim 2 tabs
javascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["sentinel"]
  static values = {
    url: String

Infinite scroll with Turbo Frames and Intersection Observer

hotwire turbo stimulus
by Jordan Lee 3 tabs
erb
<%= turbo_frame_tag 'wizard_step' do %>
  <%= render "onboarding/steps/#{@step}", onboarding: @onboarding %>
<% end %>

Multi-step wizard navigation with Turbo Frames

rails hotwire turbo
by Henry Kim 2 tabs
erb
<%= turbo_stream.prepend 'items' do %>
  <%= render @item %>
<% end %>

<turbo-stream action="reset_form" target="new_item_form"></turbo-stream>

Custom Turbo Stream action: reset a form after success

rails hotwire turbo
by Henry Kim 3 tabs
javascript
// app/javascript/controllers/dropdown_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["menu"]

Stimulus for sprinkles of JavaScript interactivity

ruby rails stimulus
by Sarah Mitchell 3 tabs
erb
<div data-controller="clipboard" data-clipboard-text-value="<%= invite_url(@invite) %>">
  <button type="button" data-action="clipboard#copy" class="rounded bg-gray-100 px-3 py-1">
    Copy invite link
  </button>
</div>

Copy-to-clipboard button with Stimulus

rails hotwire stimulus
by Henry Kim 2 tabs
erb
<%= turbo_stream_from [current_member, :notifications] %>

<div id="notification_badge">
  <%= render 'notifications/badge', count: current_member.notifications.unread.count %>
</div>

Notifications dropdown that live-updates with Turbo Streams

rails hotwire turbo
by Henry Kim 2 tabs
ruby
class ApplicationController < ActionController::Base
  helper_method :turbo_native_app?

  private

  def turbo_native_app?

Turbo Native bridge for mobile hybrid apps

hotwire turbo-native mobile
by Jordan Lee 3 tabs
erb
<div class="settings-layout">
  <nav class="settings-sidebar">
    <h2>Settings</h2>
    <ul>
      <% settings_sections.each do |section| %>
        <li class="<%= "active" if current_page?(section.path) %>">

Turbo Frames: scoped navigation inside a sidebar

rails turbo hotwire
by codesnips 3 tabs
javascript
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = { keymap: Object }

  connect() {

Stimulus: keyboard shortcuts that work with Turbo navigation

rails stimulus hotwire
by codesnips 3 tabs