Custom Component
Rules
- The component must inherit the
componentelement. - The component must meet the convention of the component.
Simple custom component
Content can be pass by variable (content) or by block (block).
content(content of component by variable or by block)options(options of component)html_options(html options of component)
Component.new(content = nil, options = {}, html_options = {}, &block).render
Component render: The component must use the render method to generate html code.
Structure
Useful methods to add default options and html options for a component:component_html_classescomponent_optionscomponent_html_options
module UiBibz::Ui::Ux
class MyComponent < UiBibz::Ui::Core::Component
# Pre Render html
def pre_render
# Put your main code here, the pre_render method is called in the render method
# The pre_render method exists to allow you to use the cache
end
private
# Default component classes [String, Array] - This method is not required
def component_html_classes
end
# Default component options [Hash] - This method is not required
def component_options
end
# Default component html options [Hash] - This method is not required
def component_html_options
end
end
end
Html classes structure
Several methods are called during the creation of html options classes:statestatuseffectconnectcomponent_html_classes
module UiBibz::Ui::Ux
class MyComponent < UiBibz::Ui::Core::Component
# Pre Render html
def pre_render
end
private
# To define state html class [:active, :disabled]
def state
end
# To define status html class [primary, secondary, success, danger, warning, info, light, dark]
def status
end
# To define effect html class
def effect
end
# To define connect html class
def connect
end
# To add classes to html classes
def component_html_classes
end
end
end
Example 1
Create a ui folder in your application in app and put your components inside.
Creation of component
# app/ui/my_component.rb
module UiBibz::Ui::Ux
class MyComponent < UiBibz::Ui::Core::Component
def pre_render
content_tag :div, html_options do
link_to content, options[:url]
end
end
end
end
Call custom Component
UiBibz::Ui::Ux::MyComponent.new('My link', { url: '/' }, { class: 'my-link'}).render
# or
UiBibz::Ui::Ux::MyComponent.new({ url: '/' }, { class: 'my-link'}) do
"My link"
end.render
<div class='my-link'><a href='/'>My link</a></div>
Example 2
Creation of component
# app/ui/my_component.rb
module UiBibz::Ui::Ux
class MyComponent2 < UiBibz::Ui::Core::Component
def pre_render
content_tag :div, html_options do
link_to content, options[:url]
end
end
private
# Add default classes
def component_html_classes
['my-class', status]
end
# Disabled component by default
def component_options
{ state: :disabled } unless options[:state].nil
end
# Add html options data
def component_html_data
add_html_data('target', options[:target]) unless options[:target].nil?
end
# Add status class if status option is not nil
def plugged
"my-component-#{ options[:plugged] }" unless options[:plugged].nil?
end
# Method is called during the component html class creation
def status
"my-component-#{ options[:status] || :secondary }"
end
end
end
Create a helper
# app/helpers/component_helper.rb
def my_custom_component_2_helper content = nil, options = nil, html_options = nil, &block
UiBibz::Ui::Ux::MyComponent2.new(content, options, html_options, block).render
end
Call custom helper
my_custom_component_2_helper('My link', { url: '/', plugged: true, target: '#target' }, { class: 'my-link'})
# or
my_custom_component_2_helper({ url: '/', plugged: true, target: '#target' }, { class: 'my-link'}) do
'My link'
end
<div class='my-class my-component-plugged my-component-secondary my-link' data-target='#target'><a href='/'>My link</a></div>
Complex custom component
module UiBibz::Ui::Ux
class MyComplexComponent < UiBibz::Ui::Core::Component
# initialize component
def initialize content = {}, options = {}, html_options = {}, &block
super
@items = []
end
# Render html
def pre_render
content_tag :div, @items.map(&:render).join.html_safe, html_options
end
# add links
def link content = nil, options = nil, html_options = nil, &block
@items << UiBibz::Ui::Core::Navigations::Link.new(content, options, html_options, &block)
end
private
def component_html_classes
"my-complex-component"
end
end
end
Create a helper
# app/helpers/component_helper.rb
def my_complex_component content = nil, options = nil, html_options = nil, &block
UiBibz::Ui::Ux::MyComplexComponent.new(content, options, html_options).tap(&block).render
end
Call custom helper
my_complex_component class: 'my-class' do |cc|
cc.link "Link1", url: "#link1", class: "me-2"
cc.link url: "#link2" do
Link 2
end
end
<div class='my-class my-complex-component'>
<a href='#link1' class="me-2">Link 1</a>
<a href='#link2'>Link 2</a>
</div>
Tree architecture in your app
app
|_ ui
|_ component_name.rb
# or
app
|_ui
|_ component_name_folders
|_ component_name.rb
|_ components
|_ sub_component_1.rb
|_ sub_component_2.rb