Senren UI
Components / Settings Section

Settings Section

Stable

grouped settings inside a settings page

Workspace visibility

Control whether teammates can discover this workspace.

Visible workspaces appear in team search and invite suggestions.

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/.../settings_section_example.html.erb
<div class="w-full max-w-xl">
  <%= render Senren::SettingsSectionComponent.new(
    title: "Workspace visibility",
    description: "Control whether teammates can discover this workspace."
  ) do |section| %>
    <% section.with_actions do %>
      <%= render Senren::SwitchComponent.new(name: "visibility", checked: true, label: "Public") %>
    <% end %>
    <div class="grid gap-3 text-sm text-[hsl(var(--senren-muted-foreground))]">
      <p>Visible workspaces appear in team search and invite suggestions.</p>
      <%= render Senren::NativeSelectComponent.new(name: "workspace_visibility", options: [["team", "Team only"], ["public", "Public profile"]], selected: "team") %>
    </div>
  <% end %>
</div>

Install this component #

Copy the official component into your app

Use this when you want the Senren-maintained implementation copied into app/components/senren.

Terminal
bin/rails senren:add settings_section

Create a custom component with the same conventions

Use this when you need an app-specific static component that follows Senren's ViewComponent structure.

Terminal
bin/rails generate senren:component settings_section --no-client

Dependencies are resolved by senren:add: card, separator, typography.

At a glance #

Category Saas
Class name Senren::SettingsSectionComponent
Stimulus
Variants default
Depends on card, separator, typography
Pairs with form, switch, button

Source #

app/components/senren/settings_section_component.html.erb
<%= tag.section(**root_attrs("rounded-(--senren-radius) border border-[hsl(var(--senren-border))] bg-[hsl(var(--senren-card))] p-5 shadow-sm")) do %>
  <% if title.present? || description.present? || actions? %>
    <div class="flex items-start justify-between gap-4 border-b border-[hsl(var(--senren-border))] pb-4">
      <div class="min-w-0">
        <% if title.present? %>
          <h2 class="font-display text-base font-semibold text-[hsl(var(--senren-foreground))]"><%= title %></h2>
        <% end %>
        <% if description.present? %>
          <p class="mt-1 text-sm leading-6 text-[hsl(var(--senren-muted-foreground))]"><%= description %></p>
        <% end %>
      </div>
      <% if actions? %>
        <div class="shrink-0"><%= actions %></div>
      <% end %>
    </div>
    <div class="pt-4"><%= content %></div>
  <% else %>
    <%= content %>
  <% end %>
<% end %>
app/components/senren/settings_section_component.rb
# frozen_string_literal: true

module Senren
  class SettingsSectionComponent < BaseComponent
    renders_one :actions

    VARIANTS = { default: '' }.freeze
    SIZES = { md: '' }.freeze

    def initialize(title: nil, description: nil, class_name: nil, **html)
      super(variant: :default, size: :md, class_name: class_name, **html)
      @title = title
      @description = description
    end

    attr_reader :title, :description
  end
end

AI agent rules #

Use for

  • +grouped settings inside a settings page

Avoid

  • -unrelated content blocks

Accessibility #

  • Each section has a heading and consistent label/value layout.