Senren UI
Components / Page Header

Page Header

Stable

titled page header with actions

Workspace

Projects

Manage active product work, owners, and delivery status.

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/.../page_header_example.html.erb
<div class="w-full max-w-2xl">
  <%= render Senren::PageHeaderComponent.new(
    title: "Projects",
    description: "Manage active product work, owners, and delivery status."
  ) do |header| %>
    <% header.with_eyebrow { "Workspace" } %>
    <% header.with_actions do %>
      <%= render(Senren::ButtonComponent.new(variant: :secondary)) { "Export" } %>
      <%= render(Senren::ButtonComponent.new(variant: :primary)) { "New project" } %>
    <% end %>
  <% 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 page_header

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 page_header --no-client

Dependencies are resolved by senren:add: typography, button.

At a glance #

Category Saas
Class name Senren::PageHeaderComponent
Stimulus
Variants default
Depends on typography, button
Pairs with breadcrumb, app_shell

Source #

app/components/senren/page_header_component.html.erb
<%= tag.header(**root_attrs("flex flex-col gap-4 border-b border-[hsl(var(--senren-border))] pb-6 sm:flex-row sm:items-end sm:justify-between")) do %>
  <% if content? && title.blank? && description.blank? %>
    <%= content %>
  <% else %>
    <div class="min-w-0">
      <% if eyebrow? %>
        <div class="mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-[hsl(var(--senren-muted-foreground))]"><%= eyebrow %></div>
      <% end %>
      <% if title.present? %>
        <h1 class="font-display text-3xl font-semibold tracking-tight text-[hsl(var(--senren-foreground))]"><%= title %></h1>
      <% end %>
      <% if description.present? %>
        <p class="mt-2 max-w-2xl text-sm leading-6 text-[hsl(var(--senren-muted-foreground))]"><%= description %></p>
      <% end %>
    </div>
    <% if actions? %>
      <div class="flex shrink-0 flex-wrap items-center gap-2"><%= actions %></div>
    <% end %>
  <% end %>
<% end %>
app/components/senren/page_header_component.rb
# frozen_string_literal: true

module Senren
  class PageHeaderComponent < BaseComponent
    renders_one :actions
    renders_one :eyebrow

    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

  • +titled page header with actions

Avoid

  • -stacking multiple page_headers per page

Accessibility #

  • Use h1 for page title.