Typography
Stablepage titles
Display heading
Section heading
Subsection
Card title
Body copy renders with comfortable rhythm and a measured line length.
Muted supporting text.
Smaller secondary text.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/.../typography_example.html.erb
<div class="space-y-3 text-left w-full">
<%= render(Senren::TypographyComponent.new(variant: :h1)) { "Display heading" } %>
<%= render(Senren::TypographyComponent.new(variant: :h2)) { "Section heading" } %>
<%= render(Senren::TypographyComponent.new(variant: :h3)) { "Subsection" } %>
<%= render(Senren::TypographyComponent.new(variant: :h4)) { "Card title" } %>
<%= render(Senren::TypographyComponent.new(variant: :p)) { "Body copy renders with comfortable rhythm and a measured line length." } %>
<%= render(Senren::TypographyComponent.new(variant: :muted)) { "Muted supporting text." } %>
<%= render(Senren::TypographyComponent.new(variant: :small)) { "Smaller secondary text." } %>
</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 typography
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 typography --no-client
At a glance #
Category
Layout
Class name
Senren::TypographyComponent
Stimulus
—
Variants
h1, h2, h3, h4, p, lead, large, small, muted
Depends on
—
Pairs with
card, page_header
Source #
app/components/senren/typography_component.html.erb
<%= content_tag(html_tag, content, **root_attrs("")) %>
app/components/senren/typography_component.rb
module Senren
class TypographyComponent < BaseComponent
VARIANTS = {
h1: 'scroll-m-20 text-4xl font-bold tracking-tight',
h2: 'scroll-m-20 text-3xl font-semibold tracking-tight',
h3: 'scroll-m-20 text-2xl font-semibold tracking-tight',
h4: 'scroll-m-20 text-xl font-semibold tracking-tight',
p: 'leading-7',
lead: 'text-xl text-[hsl(var(--senren-muted-foreground))]',
large: 'text-lg font-semibold',
small: 'text-sm font-medium leading-none',
muted: 'text-sm text-[hsl(var(--senren-muted-foreground))]'
}.freeze
SIZES = { md: '' }.freeze
TAG_FOR = {
h1: :h1, h2: :h2, h3: :h3, h4: :h4,
p: :p, lead: :p, large: :p, small: :small, muted: :p
}.freeze
def html_tag = TAG_FOR[variant]
end
end
AI agent rules #
Use for
- +page titles
- +body copy
- +captions
Avoid
- -styling without semantic tag matching
Accessibility #
- Heading levels must be sequential; do not skip levels.