# Lite::Component [![Gem Version](https://badge.fury.io/rb/lite-component.svg)](http://badge.fury.io/rb/lite-component) [![Build Status](https://travis-ci.org/drexed/lite-component.svg?branch=master)](https://travis-ci.org/drexed/lite-component) Lite::Component is a library for building component base objects. This technique simplifies and organizes often used or logically complex page objects. ## Installation Add this line to your application's Gemfile: ```ruby gem 'lite-component' ``` And then execute: $ bundle Or install it yourself as: $ gem install lite-component ## Table of Contents * [Setup](#setup) * [Generator](#generator) * [Assets](#assets) * [Routes](#routes) * [Usage](#usage) * [Rendering](#rendering) * [Context](#context) * [Helpers](#helpers) * [Locals](#locals) * [Iterations](#iterations) * [Views](#views) ## Setup ### Generator Use `rails g component NAME` will generate the following files: ```erb app/assets/javascripts/components/[name].js app/assets/stylesheets/components/[name].scss app/components/[name]_component.rb app/views/components/_[name].html.erb ``` The generator also takes `--skip-css`, `--skip-js` and `--skip-erb` options. It will also properly namespace nested components. If a `ApplicationComponent` file in the `app/components` directory is available, the generator will create file that inherit from `ApplicationComponent` if not it will fallback to `Lite::Component::Base`. ### Assets Component's `*.scss` and `*.js` will be automatically load via the tree lookup in basic Rails setups. ### Routes If you want to access route helpers in `*_component.rb` just include them like: ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base include Rails.application.routes.url_helpers def link_to_account link_to('Return to account', account_path, class: 'text-underline') end end ``` ## Usage ### Rendering To render a component in any view template or partial, you can use the the provided helper. Its has the same setup as `render` and takes all [Action View Partials](https://api.rubyonrails.org/classes/ActionView/PartialRenderer.html) options. ```erb <%= component("alert") %> <%= component(AlertComponent, locals: { message: "Something went right!", type: "success" }) %> ``` Render namespaced components by following standard naming conventions: ```erb <%= component("admin/alert") %> <%= component(Admin::AlertComponent) %> ``` Render collection of components just as you would render collections of partials. ```erb <%= component("comment_card", collection: @comments, spacer_template: "components/spacer") %> ``` If you can skip rendering by evaluating complex logic in the `render?` method: ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def render? object.some_complex_check? end end ``` ### Context All components include `ActionView::Context` which will give you access to request context such as helpers, controllers, etc. It can be accessed using `context` or `c` methods. ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def protected_page? context.controller_name == 'admin' end end ``` ### Helpers All components include `ActionView::Helpers` which will give you access to default Rails helpers without the need to invoke the context. Use the helper methods to access helper methods from your `app/helpers` directory. It can be accessed using `helpers` or `h` methods. ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def close_icon h.icon_tag(:close) end def link_to_close link_to(close_icon, '#', data: { alert: :dismiss }) end end ``` ### Locals All components include access to partial locals via the `locals` or `l` methods. *Note: Objects will be automatically added to locals when rendering collections.* ```erb <%= component("alert", locals: { object: @user }) %> ``` ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def type_tag <<~HTML.squish.html_safe #{locals.object.first_name}! HTML end end ``` ### Iterations All components will hav access to an iteration object which can be accessed using the `iteration` or `i` methods. It provides access to each iterations `first?`, `last?`, `size`, and `index` methods. ```erb <%= component("alert", collection: @users) %> ``` ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def limit_hit? i.index == 5 end end ``` ### Views *For the following examples, components will have the following setup:* ```ruby # app/components/alert_component.rb class AlertComponent < Lite::Component::Base def link_to_back link_to('Go back', :back, class: 'text-underline') end end ``` ```erb <%= component("alert", collection: @users, locals: { message: "Something went right!", type: "success" }) %> ``` Component view partials behave just as a normal view partial would. All locals can be accessed by their key. ```erb <%# app/views/components/_alert.html.erb %>