Created
April 25, 2024 11:56
-
-
Save RStankov/1117fcde73c70e5d4695119d77398ce0 to your computer and use it in GitHub Desktop.
ViewComponent Tips
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationComponent < ViewComponent::Base | |
private | |
def fetch_with_fallback(hash, key, fallback) | |
hash.fetch(key) do | |
ErrorReporting.capture_exception(%(key not found: "#{key}")) | |
fallback | |
end | |
end | |
def t_label(key) | |
return '' if key.blank? | |
return key if key.is_a?(String) | |
t(key, default: :"label_#{key}") | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ApplicationHelper | |
def component(name, *args, **kwargs, &) | |
render("#{name}_component".classify.constantize.new(*args, **kwargs), &) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%= form_tag @action, method: :get, class: 'c-filter-form' do %> | |
<% inputs.each do |(label, input)| %> | |
<label class="flex items-center gap-x-2 c-hint"> | |
<%= t_label(label) %> | |
<%= input %> | |
</label> | |
<% end %> | |
<%= submit_tag t(:button_filter), name: nil, class: 'c-button' %> | |
<% end %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FilterFormComponent < ApplicationComponent | |
attr_reader :action, :inputs | |
def initialize(action: nil, params: {}) | |
@params = params | |
@action = action | |
@inputs = [] | |
end | |
def before_render | |
# needed to trigger the builder methods | |
content | |
end | |
def search(name, label: nil) | |
@inputs << [label, render(SearchInputComponent.new(name, @params[name]))] | |
end | |
def select(name, options:, label: nil, placeholder: nil, classes: nil) | |
input = select_tag( | |
name, | |
options_for_select(options, @params[name]), | |
class: "c-input #{classes}", | |
) | |
@inputs << [label, input] | |
end | |
def text(name, label: nil, placeholder: nil, classes: nil) | |
input = text_field_tag( | |
name, | |
@params[name], | |
class: "c-input #{classes}", | |
placeholder: t_label(placeholder), | |
) | |
@inputs << [label, input] | |
end | |
def date_range(name) | |
gteq = date_field_tag("#{name}[gteq]", @params.dig(name, :gteq), class: 'c-input') | |
lteq = date_field_tag("#{name}[lteq]", @params.dig(name, :lteq), class: 'c-input') | |
@inputs << [:start_date, gteq] | |
@inputs << [:end_date, lteq] | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<table class="c-table"> | |
<thead class="header"> | |
<tr valign="top"> | |
<% columns.each do |column| %> | |
<%= column.render_header %> | |
<% end %> | |
</tr> | |
</thead> | |
<tbody> | |
<% records.each do |record| %> | |
<tr valign="top"> | |
<% columns.each do |column| %> | |
<%= column.render_cell(record) %> | |
<% end %> | |
</tr> | |
<% end %> | |
</tbody> | |
<% if records.respond_to?(:current_page) && records.total_pages > 1 %> | |
<tfoot> | |
<tr> | |
<td colspan="<%= columns.size %>"> | |
<%= paginate records %> | |
</td> | |
</tr> | |
</tfoot> | |
<% end %> | |
</table> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TableComponent < ApplicationComponent | |
attr_reader :records, :columns | |
FORMAT_MONEY = -> { Format.money(_1) } | |
FORMAT_DATE = -> { Format.date(_1) } | |
def initialize(records) | |
@records = records | |
@columns = [] | |
end | |
def before_render | |
content | |
end | |
def column(name, classes = nil, format = nil, &) | |
@columns << TableColumn.new(name, classes, format, helpers, &) | |
end | |
def number(name, &) | |
column(name, 'number', &) | |
end | |
def money(name, &) | |
column(name, 'number', FORMAT_MONEY, &) | |
end | |
def date(name, options = {}, &) | |
column(name, 'time', FORMAT_DATE, &) | |
end | |
def record(name, attribute_name = name) | |
column(name) do |record| | |
link_record = record.public_send(attribute_name) | |
if link_record.present? | |
helpers.link_to t_display(link_record), Routes.record_path(link_record) | |
end | |
end | |
end | |
class TableColumn | |
def initialize(name, classes, format, helpers, &block) | |
@name = name | |
@classes = classes | |
@format = format | |
@helpers = helpers | |
@block = block | |
end | |
def render_header | |
@helpers.tag.th(@helpers.t_label(@name), role: 'col', class: classes) | |
end | |
def render_cell(record) | |
content = if @block | |
@helpers.capture { @block.call(record).presence || '' }.strip | |
else | |
record.public_send(@name) | |
end | |
content = format.call(content) if content.present? && format.present? | |
@helpers.tag.td(content, class: classes) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment