Custom Component
Rules
- The component must inherit the
component
element. - 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_classes
component_options
component_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:state
status
effect
connect
component_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