Rails frontend specialist with deep expertise in Hotwire (Turbo & Stimulus). Building fast, interactive UIs with minimal JavaScript. 7+ years crafting responsive, accessible...
class ApplicationController < ActionController::Base
helper_method :turbo_native_app?
private
def turbo_native_app?
class ButtonComponent < ViewComponent::Base
VARIANTS = {
primary: "bg-blue-600 hover:bg-blue-700 text-white",
secondary: "bg-gray-200 hover:bg-gray-300 text-gray-900",
danger: "bg-red-600 hover:bg-red-700 text-white"
}.freeze
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["field", "status"]
static values = {
key: String,
class Comment < ApplicationRecord
belongs_to :post
belongs_to :author, class_name: 'User'
# Automatically broadcast changes to all subscribers of this post
after_create_commit -> { broadcast_append_to post, target: "comments" }
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["field"]
validateField(event) {
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["sentinel"]
static values = {
url: String
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["modal", "message", "confirm", "cancel"]
static values = {
message: String
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["parent", "child"]
static values = {
options: Object,
<article class="post">
<h1><%= @post.title %></h1>
<%= simple_format @post.body %>
<!-- Lazy load comments when scrolled into view -->
<%= turbo_frame_tag "post_#{@post.id}_comments",
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.build(comment_params)
@comment.author = current_user
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input", "counter"]
static values = {
max: { type: Number, default: 280 }
<div class="post">
<h1><%= @post.title %></h1>
<%= turbo_frame_tag "post_#{@post.id}" do %>
<div class="post-content">
<%= simple_format @post.body %>