Senren UI
Components / Theme Toggle

Theme Toggle

Stable Stimulus: senren--theme-toggle

light/dark/system theme switching

Usage example #

Copy this ERB into a Rails view after installing the component. The snippet below is the same code used by the live preview above.

app/views/.../theme_toggle_example.html.erb
<div class="flex justify-center">
  <%= render Senren::ThemeToggleComponent.new %>
</div>

Install this component #

Copy the official component into your app

This component requires Stimulus. Keep --client so the controller is copied with the ViewComponent.

Terminal
bin/rails senren:add theme_toggle --client

Create a custom component with the same conventions

Use this when you need an app-specific component that follows Senren's ViewComponent and Stimulus structure. --client is required for this behavior.

Terminal
bin/rails generate senren:component theme_toggle --client

Dependencies are resolved by senren:add: button.

At a glance #

Category Navigation
Class name Senren::ThemeToggleComponent
Stimulus senren--theme-toggle
Variants default
Depends on button
Pairs with top_nav

Source #

app/components/senren/theme_toggle_component.html.erb
<button type="button" <%= tag.attributes(**root_attrs("inline-flex h-10 cursor-pointer items-center justify-center gap-2 rounded-(--senren-radius) border border-[hsl(var(--senren-border))] bg-[hsl(var(--senren-background))] px-3 text-sm font-medium text-[hsl(var(--senren-foreground))] transition-colors hover:bg-[hsl(var(--senren-accent))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--senren-ring))]", data: { controller: "senren--theme-toggle", action: "click->senren--theme-toggle#toggle" }, aria: { label: label, pressed: "false" })) %>>
  <span aria-hidden="true" data-senren--theme-toggle-target="icon">O</span>
  <span data-senren--theme-toggle-target="label"><%= label %></span>
</button>
app/components/senren/theme_toggle_component.rb
# frozen_string_literal: true

module Senren
  class ThemeToggleComponent < BaseComponent
    VARIANTS = { default: '' }.freeze
    SIZES = { md: '' }.freeze

    def initialize(label: 'Toggle theme', class_name: nil, **html)
      super(variant: :default, size: :md, class_name: class_name, **html)
      @label = label
    end

    attr_reader :label
  end
end

AI agent rules #

Use for

  • +light/dark/system theme switching

Avoid

  • -non-theme settings

Accessibility #

  • Announce current theme via aria-pressed or aria-label.