View Component dumpyard (examples)
here I'm placing old code for ViewComponents I no longer use for whatever reason. Some where good ideas no longer needed, some were experiments that failed, so don't treat them as examples on how to do stuff, but rather flavor of what's possible
Example for TextFieldComponent form EntsTw project (2024)
app/components/text_field_component.rb
# frozen_string_literal: true
class TextFieldComponent < ApplicationComponent
def initialize(name:, form: nil, value: nil, **options)
raise ArgumentError, "class will be ignored" if options[:class].present?
@form = form
@name = name
@value = value
@error = options.delete(:error)
@hint = options.delete(:hint)
@label = options.delete(:label)
@options = options
end
def input_options
@options['class'] = input_class
@options['aria-describedby'] = hint_html_id if @hint.present?
if error.present?
@options['aria-invalid'] = "true"
@options['aria-describedby'] = error_html_id
end
@options
end
def input_class
if error.present?
"col-start-1 row-start-1 block w-full rounded-md bg-white py-1.5 pr-10 pl-3 text-base text-red-900 outline-1 -outline-offset-1 outline-red-300 placeholder:text-red-300 focus:outline-2 focus:-outline-offset-2 focus:outline-red-600 sm:pr-9 sm:text-sm/6"
else
"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
end
end
def error
return @error if @error.present?
return @form.object.errors[@name].first if @form && @form.object.errors[@name].present?
nil
end
def error_html_id
"#{@name.to_s.parameterize}-error"
end
def hint_html_id
"#{@name.to_s.parameterize}-hint"
end
def input_html
return @form.text_field(@name, **input_options) if @form.present?
text_field_tag @name, @value, **input_options
end
def label_html(class_css)
return @form.label @name, @label, class: class_css if @form.present?
label_tag @name, @label, class: class_css
end
end
<!-- app/components/text_field_component.html.erb -->
<div>
<% if error.present? %>
<%= label_html("block text-sm/6 font-medium text-red-500") %>
<div class="mt-2 grid grid-cols-1">
<%= input_html %>
<svg class="pointer-events-none col-start-1 row-start-1 mr-3 size-5 self-center justify-self-end text-red-500 sm:size-4" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" />
</svg>
</div>
<p class="mt-2 text-sm text-red-600" id="<%= error_html_id %>"><%= error %></p>
<% else %>
<%= label_html("block text-sm/6 font-medium text-gray-900 dark:text-gray-300") %>
<div class="mt-2">
<%= input_html %>
</div>
<% end %>
<% if @hint.present? %>
<p class="mt-2 text-sm text-gray-500" id="<%= hint_html_id %>"><%= @hint %></p>
<% end %>
</div>