Make server-rendered apps feel like modern SPAs
...at a fraction of the complexity
def create
@todo = Todo.new(todo_params)
if @todo.save
redirect_to todos_path
else
redirect_to todos_path,
alert: @todo.errors.full_messages.to_sentence
end
end
def toggle
@todo.update!(completed: !@todo.completed)
redirect_to todos_path
end
def destroy
@todo.destroy!
redirect_to todos_path
end
<%# app/views/todos/index.html.erb %>
<% turbo_refreshes_with method: :morph, scroll: :preserve %>
<% turbo_refreshes_with method: :morph, scroll: :preserve %>
document.startViewTransition(() => {
// Mutate the DOM however you want
element.textContent = "New content";
someList.appendChild(newItem);
otherElement.remove();
});
Default: nice crossfade. No CSS, no JS animation logic.
view-transition-name
Hello
Browser tracks this element across DOM mutations
Animates movement automatically!
view-transition-class
...
...
::view-transition-group(.card) {
animation-duration: 0.3s;
}
✅ Chrome, Edge, Firefox, Safari
<%# app/views/layouts/application.html.erb %>
startViewTransition()
<%# app/views/todos/_todo.html.erb %>
<%= tag.div id: dom_id(todo),
style: "view-transition-name: #{dom_id(todo)};
view-transition-class: todo" do %>
<%# ... %>
<% end %>
Write HTML to describe what the state should look like,
let the technology handle the transition.
We still wait for the server response
before seeing the visual change
Apply checked style as soon as the todo is clicked
<%= todo.name %>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = {
attribute: String
}
toggle(event) {
const currentValue =
this.element.getAttribute(this.attributeValue)
const isTrue = currentValue === "true"
this.element.setAttribute(
this.attributeValue, (!isTrue).toString()
)
}
}
<%= tag.div id: dom_id(todo),
data: {
controller: "toggle-attribute",
toggle_attribute_attribute_value: "aria-checked",
} do %>
<%= button_to toggle_todo_path(todo),
data: {
action: "click->toggle-attribute#toggle"
} do %>
<%# ... %>
<% end %>
<% end %>
= Modern SPA feel, fraction of the complexity
Browsers are catching up:
View Transitions, Dialogs, Popovers,
Container Queries, Web Components...
Presentation & all links available here :