ViewComponent Documentation

repository·main·Indexed 25 days ago

https://github.com/viewcomponent/view_component

A Ruby on Rails framework for creating reusable, encapsulated, and testable UI components by shifting view logic from templates into dedicated Ruby classes. Includes guides on component generation, preview settings, testing with ViewComponent::TestHelpers, and best practices for organizing general-purpose versus application-specific components.

Tokens
21.8K
Snippets
91
Records
148
Agent score
86%

What's inside ViewComponent

  1. Overview of ViewComponent

    main
    ViewComponent is a framework for building reusable, testable, and encapsulated view components in Ruby on Rails. It allows developers to move logic out of templates and into dedicated Ruby classes, improving maintainability and testability of the UI layer.
  2. Understand the ViewComponent lifecycle

    main

    ViewComponent operates through three distinct phases: application boot, component instantiation, and render time.

    1. At application boot: When a class inherits from ViewComponent::Base, the ViewComponent::Compiler.compile process transforms the component's template(s) into instance methods on the component class.
    2. At component instantiation: The component's initialize method runs. ViewComponent performs no additional actions during this phase.
    3. At render: When passed to render, Rails calls render_in, providing an ActionView::Context. This context provides access to the current controller, request, and helpers.

    The render sequence is:

    • before_render is called (allowing logic execution after initialization but before rendering).
    • render? is called; if it returns false, rendering stops and an empty string is returned.
    • The template is rendered, wrapped within an around_render call.
  3. Extend ViewComponent with extensions and tools

    main

    Enhance your ViewComponent development workflow using these extensions and tools:

    ViewComponent extensions

    Tools

  4. Test ViewComponents against rendered content

    main

    When writing tests for ViewComponents, prioritize asserting against the actual rendered output rather than testing internal instance methods. This ensures you are testing what the end user actually sees.

    Use render_inline to perform these assertions.

    # good
    render_inline(MyComponent.new)
    assert_text("Hello, World!")
    
    # bad
    assert_equal(MyComponent.new.message, "Hello, World!")
  5. Profile ViewComponent rendering with rack-mini-profiler

    main

    To see detailed breakdowns of ViewComponent rendering alongside views and partials in the rack-mini-profiler UI, add a subscription to the render.view_component event in your development environment configuration.

    # config/environments/development.rb
    # Profile rendering of ViewComponents
    Rack::MiniProfilerRails.subscribe("render.view_component") do |_name, start, finish, _id, payload|
      Rack::MiniProfilerRails.render_notification_handler(
        Rack::MiniProfilerRails.shorten_identifier(payload[:identifier]),
        finish,
        start
      )
    end
  6. Implement a ViewComponent

    main

    A ViewComponent is a Ruby class that inherits from ViewComponent::Base. You can define an erb_template directly in the class or use a separate template file. Use initialize to accept arguments. Content passed to the component via a block is accessible through the content accessor.

    class ExampleComponent < ViewComponent::Base
      erb_template <<-ERB
        <span title="<%= @title %>"><%= content %></span>
      ERB
    
      def initialize(title:)
        @title = title
      end
    end
  7. Define inline templates

    main

    You can define a template directly inside your component class using the erb_template or slim_template macros. This is useful for small, simple components.

    Note for Slim users: When using slim_template, you must escape interpolations (e.g., \#{name}) if you want them to be evaluated in the template context rather than the component class context.

    class InlineErbComponent < ViewComponent::Base
      erb_template <<~ERB
        <h1>Hello, <%= @name %>!</h1>
      ERB
    
      def initialize(name)
        @name = name
      end
    end
  8. Create a Rails application to demonstrate a ViewComponent bug

    main

    When reporting a bug, provide a minimal Rails application that reproduces the issue. Follow these steps:

    1. Create a minimal Rails app: rails new --minimal view_component-bug-replica.
    2. Add ViewComponent: bundle add view_component (or specify a specific version in the Gemfile and run bundle install).
    3. Generate a controller: rails generate controller Home index.
    4. Set the root route: Add root to: 'home#index' to your routes.
    5. Add the minimum amount of code necessary to reproduce the bug, ideally using the original code that caused the issue.
    6. Publish the repository and include the link in your bug report.
    rails new --minimal view_component-bug-replica
    bundle add view_component
    rails generate controller Home index
  9. Use component-local translations with sidecar YAML files

    main

    You can define translations specific to a component by creating a sidecar YAML file in the same directory as your component.

    To define a default translation, create a file named [component_name].yml. To define translations for specific locales, create files named [component_name].[locale].yml (e.g., example_component.en.yml or example_component.fr.yml).

    These files can be automatically generated using the component generator with the --locale flag.

    # app/components/example_component.yml
    en:
      hello: "Hello world!"
    
    # app/components/example_component.en.yml
    en:
      hello: "Hello world!"
    
    # app/components/example_component.fr.yml
    fr:
      hello: "Bonjour le monde !"
  10. Submit a pull request

    main

    Follow these steps to contribute code:

    1. Fork and clone the repository.
    2. Ensure all tests pass using appraisal-run gemfiles/*.gemfile -- bundle exec rake.
    3. Create a new branch: git checkout -b my-branch-name.
    4. Implement changes and add corresponding tests.
    5. Important: Add an entry to the top of docs/CHANGELOG.md for your changes.
    6. Push your branch and submit a pull request.