ViewComponent helper

ViewComponent helper
Icons/chart bar
Used 71 times
Created by
S Scott Barrow

Usage
component :some_awesome_component do |awesome|
  awesome.slot :slot_one do |slot_one|
    ...
  end
  component :alert, type: 'success' do |alert|
    component :button, classes: 'justify-end ml-2 items-start' do
      <span>Submit</span>
    end
    component(:button, classes: 'primary') { "Submit" } #inline block requires parens
  end
end

With optional Cache params
component :some_awesome_component, cache: @record do |awesome|
  awesome.slot :slot_one do |slot_one|
    ...
  end
  component :alert, type: 'success' do |alert|
    component :button, classes: 'justify-end ml-2 items-start'
  end
end

Run this command in your Rails app directory in the terminal:

rails app:template LOCATION="https://railsbytes.com/script/xjNsDY"
Template Source

Review the code before running this template on your machine.

say "This template creates a helper file and method, choose how to name below..."
helper_name = ask("Helper name e.g. component:") || "component"

create_file 'app/helpers/view_component_helper.rb' do <<-HEREDOC
module ViewComponentHelper
  def #{helper_name}(name, context: nil, **args, &block)
    cache_keys = Array(args.delete(:cache))

    cache_if cache_keys.present?, cache_keys do
      return render_component_in(context, name, **args, &block) if context

      return render component_class_for(name).new(args), &block
    end
  end

  def render_component_in(context, name, **args, &block)
    component_class_for(name).new(args).render_in(context, &block)
  end
  
  private

  def component_class_for(path)
    name, namespace = path.to_s.split('/').reverse

    file_name = name + "_component"
    component_name = file_name.classify
    namespace ||= namespace(file_name)
    return (namespace.capitalize + "::" + component_name).constantize unless namespace == 'components'

    component_name.constantize
  end

  def namespace(file_name)
    file_path = component_path(file_name)
    File.dirname(file_path).split('/').last
  end

  def component_path(file_name)
    Dir.glob(File.join(Rails.root, 'app', 'components', '**', file_name + ".rb")).first
  end
end 
  HEREDOC
end

Comments

Sign up or Login to leave a comment.