Conditional styles for Turbo Native in TailwindCSS
Joe Masilotti, in his Rails World 2023 talk, shows how to create custom styles for Turbo Native Rails applications in a way that does not break cache:
# app/assets/stylesheets/native.css
.turbo-native-hidden {
display: hidden important!
}
# app/views/layouts/application.html.erb
<head>
<%= stylesheet_include_tag "application" %>
<%= stylesheet_include_tag "native" if turbo_native_app? %>
</head>
This works great for simple scenarios when I must show or hide certain elements. With Tailwind, however, I would like to benefit from the full richness of all its utility classes.
How
In config/tailwind.config.js, add the following function to the plugins section:
plugins: [
# ...
({ addVariant }) => {
addVariant('turbo-native', "html[data-turbo-native-app] &"),
addVariant('non-turbo-native', "html:not([data-turbo-native-app]) &")
},
]
Next, add a conditional data attribute to your layout html tag:
<!DOCTYPE html>
<html <%= 'data-turbo-native-app' if turbo_native_app? %> >
<head>
In case the helper is not available in your views, add the following line to your application controller:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
helper_method :turbo_native_app?
end
And that's it! Now, you can use these variants to display your app on iOS/Android native app differently, from simple cases like:
<div class="flex turbo-native:flex-col">
</div>
To more complex scenarios:
<div class="flex non-turbo-native:group-data-[hide]:hidden turbo-native:flex">
<%= render 'overdue_tasks_count', overdue_tasks_count: @overdue_tasks_count %>
</div>
Enjoy! I hope this helps (me remember).