Page Header
Stabletitled 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.