Senren UI
Components / Codeblock

Codeblock

Stable

displaying code samples

Terminal bash
bin/rails generate senren:install
bin/rails senren:add button card command

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/.../codeblock_example.html.erb
<div class="w-full max-w-lg text-left">
  <%= render Senren::CodeblockComponent.new(
    filename: "Terminal",
    language: "bash",
    source: "bin/rails generate senren:install\nbin/rails senren:add button card command"
  ) %>
</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 codeblock

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

At a glance #

Category Rich
Class name Senren::CodeblockComponent
Stimulus
Variants default
Depends on
Pairs with clipboard

Source #

app/components/senren/codeblock_component.html.erb
<%= tag.figure(**root_attrs("overflow-hidden rounded-(--senren-radius) border")) do %>
  <% if filename.present? || language_label.present? || caption.present? %>
    <figcaption class="flex items-center justify-between gap-3 border-b border-[hsl(var(--senren-border))] px-4 py-2 text-xs text-[hsl(var(--senren-muted-foreground))]">
      <span class="min-w-0 truncate font-medium text-[hsl(var(--senren-foreground))]"><%= filename.presence || caption %></span>
      <% if language_label.present? %>
        <span class="shrink-0 rounded bg-[hsl(var(--senren-muted))] px-1.5 py-0.5 font-mono uppercase tracking-wide"><%= language_label %></span>
      <% end %>
    </figcaption>
  <% end %>
  <pre class="overflow-x-auto p-4 text-left text-sm leading-6 text-[hsl(var(--senren-foreground))] <%= wrap? ? 'whitespace-pre-wrap break-words' : '' %>"><code class="font-mono"><%= code_text %></code></pre>
<% end %>
app/components/senren/codeblock_component.rb
module Senren
  class CodeblockComponent < BaseComponent
    VARIANTS = {
      default: 'border-[hsl(var(--senren-border))] bg-[hsl(var(--senren-muted)/0.35)]',
      elevated: 'border-[hsl(var(--senren-border))] bg-[hsl(var(--senren-card))] shadow-sm'
    }.freeze
    SIZES = { md: '' }.freeze

    def initialize(source: nil, language: nil, filename: nil, caption: nil, wrap: false, variant: :default,
                   class_name: nil, **html)
      super(variant: variant, size: :md, class_name: class_name, **html)
      @source = source
      @language = language
      @filename = filename
      @caption = caption
      @wrap = wrap
    end

    attr_reader :source, :language, :filename, :caption

    def wrap? = !!@wrap

    def code_text
      source.presence || content.to_s
    end

    def language_label
      language.to_s.presence
    end
  end
end

AI agent rules #

Use for

  • +displaying code samples

Avoid

  • -running code - this is read-only display

Accessibility #

  • Use pre/code; preserve whitespace.