Reusable UI components are HTML tags that can be used in different parts of a web project. These components are usually small and designed for specific functionalities. Instead of coding everything from scratch, you can write the code once and then import these UI components wherever needed. For instance, you can create a card component to display information or a navigation bar that appears at the top of all web pages. These UI elements can be imported and added to any desired web page. Other examples of reusable UI components include input fields, buttons, modals, and progress bars. There are several advantages to using reusable UI components. They save time and effort by allowing you to reuse code instead of starting from scratch. They improve code quality and maintainability, bringing consistency to your project. Additionally, reusable components make your project more modular, making it easier to track down and isolate errors and bugs. In this tutorial, we will guide you on how to identify reusable components in your project and how to develop these UI widgets in Rails. Let’s get started.
Identifying and extracting reusable components
It is good practice to analyze the structure of your application and identify parts that can be broken down into smaller, reusable components. Look for common functional patterns that appear in multiple places in your application. Pay attention to the relationship between models, controllers, and views to identify areas where they share logic or functionality. Also, inspect your application for instances of code repetition, as this may indicate the need for a reusable component. Review your view templates and files to identify common HTML elements, forms, and other components that can be modularized.
Creating reusable components
In this step, we will learn how to create reusable components in Rails using ViewComponent. ViewComponent is a Ruby on Rails library that helps create reusable and encapsulated UI components for your application. By breaking down an application into smaller chunks, this framework makes it easy to perform unit tests and track down sources of error, facilitating faster debugging.
We will create a simple website using reusable components. Specifically, we will create two reusable UI components: the navigation bar and the product card.
Getting started
Add the following code to your Gemfile and run the bundle install command to install the ViewComponent library into your project.
“`html
$ bundle install
Fetching gem metadata from https://rubygems.org/
Resolving dependencies…
Using rake 13.0.6
Using concurrent-ruby 1.2.2
Fetching view_component 3.6.0
Using rails 7.0.8
Installing view_component 3.6.0
Bundle complete! 15 Gemfile dependencies, 76 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
“`
Creating components
Components in ViewComponent are subclasses of ViewComponent::Base. When you create a ViewComponent, an app/components directory is generated to store all the component files. It is best practice to name components based on what they do or render, rather than what they accept. For example, a CardComponent is preferred over a ReportComponent. Components can contain HTML, CSS, and JavaScript code. You can also add logic to guide the behavior of these components in a separate Ruby class.
To create a ViewComponent, run the following code, replacing “Navigation” with the desired name of your component:
“`html
bin/rails generate component Navigation nav
“`
This will generate a navigation_component file to store your component’s logic, and a navigation_component.html.erb file for your HTML and CSS code.
The navigation_component.rb file should look like this:
“`html
# frozen_string_literal: true
class NavigationComponent < ViewComponent::Base def initialize(nav:) @nav = nav end end ``` The navigation_component.html.erb file should look like this: ```html
“`
You can add navigation elements to the template, as shown below. We’re using TailwindCSS for styling, but you can also use custom stylesheets.
“`html
“`
To render the component, add the following code snippet to the respective view. In this case, we will render the element in the `application.html.erb` layout file since we want it displayed across all web pages. Use the `<%= render NavigationComponent.new(nav: @nav) %>` code to render the nav component in the browser.
“`html
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "tailwind" , "inter-font", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<%= render NavBarComponent.new() %>
<%= yield %>
“`
Let’s create a new CardComponent to display items retrieved from the database. To generate the component, run the following command:
“`html
bin/rails generate component ItemCardComponent title description
“`
Replace “title” and “description” with the desired variables for your product.
The item_card_component.rb file should look like this:
“`html
# frozen_string_literal: true
class ItemCardComponent < ViewComponent::Base def initialize(title:, description:) @title = title @description = description end end ``` The item_card_component.html.erb file should look like this: ```html
<%= @title %>
<%= @description %>
“`
You can also create a BannerComponent to communicate information to users. Run the following command to generate the component:
“`html
bin/rails generate component banner title message
“`
Replace “title” and “message” with the desired variables for your banner.
The banner_component.rb file should look like this:
“`html
# frozen_string_literal: true
class BannerComponent < ViewComponent::Base def initialize(title:, message:) @title = title @message = message end end ``` The banner_component.html.erb file should look like this: ```html
<%= @title %>
<%= @message %>
“`
To render the ItemCardComponent and BannerComponent in the index.html.erb file, use the render() method as shown below:
“`html
Dashboard
<%= render(ItemCardComponent.new(title: product.title, description: product.description)) %>
<% end %>
<%= render(BannerComponent.new(title: "Status", message: "Completed")) %>
“`
You can download the full code used in this tutorial from this GitHub repository.
Best practices for building reusable UI components
When creating reusable UI components, it is important to follow certain principles. These practices will help you create components that are easier to understand, configure, and manage.
1. Ensure each component has a specific responsibility: Each component should have a clear purpose, making it easier to understand its usage and how it fits into a project.
2. Use props to pass values to UI: Reusable components should be flexible and dynamic. They should accept different types of data, such as collections, strings, and objects, to
Source link