bootstrap_ui_helper 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,141 @@
1
+ module BootstrapFormOptionsHelper
2
+
3
+ class ActionView::Helpers::FormBuilder
4
+ include FormatHelper
5
+ include BootstrapFormHelper
6
+
7
+
8
+ def select(method, choices = nil, options = {}, html_options = {}, &block)
9
+ label_class, field_wrapper = horizontal_layout? ? ['col-sm-3 control-label', true] : []
10
+
11
+ required = 'required' if html_options.delete(:required)
12
+ label_sr_only = 'sr-only' if html_options[:label].is_a?(FalseClass)
13
+ html_options[:class] = squeeze_n_strip("form-control #{html_options[:class]}")
14
+ label_class = squeeze_n_strip("#{label_class} #{required} #{label_sr_only}")
15
+ help_text = (html_options[:help] ? "<span class='help-block text-left'>#{html_options[:help]}</span>" : '').html_safe
16
+
17
+ select_proc = proc do
18
+ @template.select(@object_name,
19
+ method,
20
+ choices,
21
+ objectify_options(options),
22
+ @default_options.merge(html_options),
23
+ &block) + help_text
24
+ end
25
+
26
+ label_proc = proc { label(method, html_options[:label], class: label_class) }
27
+
28
+ render_field(field_wrapper, label_proc, select_proc)
29
+ end
30
+
31
+ def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
32
+ check_boxes_proc = proc do
33
+ @template.collection_check_boxes(@object_name, method, collection, value_method, text_method,
34
+ objectify_options(options), @default_options.merge(html_options),
35
+ &block)
36
+ end
37
+
38
+ render_collection(options[:label], &check_boxes_proc)
39
+ end
40
+
41
+ def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
42
+ radion_buttons_prc = proc do
43
+ @template.collection_radio_buttons(@object_name, method, collection, value_method, text_method,
44
+ objectify_options(options), @default_options.merge(html_options),
45
+ &block)
46
+ end
47
+
48
+ render_collection(options[:label], &radion_buttons_prc)
49
+ end
50
+
51
+ private
52
+
53
+ def render_label(label)
54
+ label_class = 'col-sm-3 control-label' if horizontal_layout?
55
+
56
+ label.present? ? "<label class='#{label_class}'>#{label}</label> " : ''
57
+ end
58
+
59
+ def render_input(&input_block)
60
+ horizontal_layout? ? (content_tag :div, class: 'col-sm-9', &input_block) : yield
61
+ end
62
+
63
+ def render_collection(label, &input_block)
64
+ content_tag :div, class: 'form-group' do
65
+ (render_label(label) + render_input(&input_block)).html_safe
66
+ end
67
+ end
68
+
69
+ def horizontal_layout?
70
+ BootstrapFormHelper.layout == :horizontal
71
+ end
72
+ end
73
+
74
+ class ActionView::Helpers::Tags::CollectionCheckBoxes
75
+ attr_accessor :output_buffer
76
+
77
+ def render(&block)
78
+ rendered_collection = render_collection do |item, value, text, default_html_options|
79
+ default_html_options[:multiple] = true
80
+ builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
81
+
82
+ if block_given?
83
+ @template_object.capture(builder, &block)
84
+ else
85
+ render_check_box(builder, @options.fetch(:inline, false))
86
+ end
87
+ end
88
+
89
+ if @options.fetch(:include_hidden, true)
90
+ rendered_collection + hidden_field
91
+ else
92
+ rendered_collection
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def render_check_box(builder, inline=false)
99
+ label_class, input_wrapper = 'checkbox-inline', true if inline
100
+
101
+ input_proc = proc do
102
+ content_tag :label, class: label_class do
103
+ builder.check_box + ' ' + builder.text
104
+ end
105
+ end
106
+
107
+ input_wrapper ? input_proc.call : (content_tag :div, class: 'checkbox', &input_proc)
108
+ end
109
+ end
110
+
111
+ class ActionView::Helpers::Tags::CollectionRadioButtons
112
+ attr_accessor :output_buffer
113
+
114
+ def render(&block)
115
+ render_collection do |item, value, text, default_html_options|
116
+ builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)
117
+
118
+ if block_given?
119
+ @template_object.capture(builder, &block)
120
+ else
121
+ render_radio_button(builder, @options.fetch(:inline, false))
122
+ end
123
+ end
124
+ end
125
+
126
+ private
127
+
128
+ def render_radio_button(builder, inline=false)
129
+ label_class, input_wrapper = 'radio-inline', true if inline
130
+
131
+ input_proc = proc do
132
+ content_tag :label, class: label_class do
133
+ builder.radio_button + ' ' + builder.text
134
+ end
135
+ end
136
+
137
+ input_wrapper ? input_proc.call : (content_tag :div, class: 'radio', &input_proc)
138
+ end
139
+ end
140
+
141
+ end
@@ -0,0 +1,23 @@
1
+ module BreadcrumbHelper
2
+ include FormatHelper
3
+
4
+ def breadcrumb(links=[], options={})
5
+ return if links.blank?
6
+
7
+ prepend_class(options, 'breadcrumb')
8
+
9
+ content_tag :ol, options do
10
+ links.map.with_index do |link, index|
11
+ render_li(link, (index == links.length - 1))
12
+ end.join('').html_safe
13
+ end
14
+ end
15
+
16
+ def render_li(link, last_li)
17
+ active = {class: 'active'} if last_li
18
+
19
+ content_tag :li, active do
20
+ last_li ? link[:text] : (link_to link.delete(:text), link.delete(:link), link)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,91 @@
1
+ module ButtonHelper
2
+ include ActionView::Helpers
3
+ include FormatHelper
4
+
5
+ def button(content_or_options=nil, options={}, &block)
6
+ content_or_options.is_a?(Hash) ? options = content_or_options : content = content_or_options
7
+
8
+ layout = 'btn-block' if options.delete(:layout).try(:to_sym) == :block
9
+ size = get_btn_size(options.delete(:size))
10
+ type = get_btn_type(options.delete(:type))
11
+ prepend_class(options, 'btn', type, size, layout)
12
+
13
+ content_tag :button, options do
14
+ content.presence || capture(&block)
15
+ end
16
+ end
17
+
18
+ def button_group(options={}, &block)
19
+ size = get_btn_group_size(options.delete(:size))
20
+ layout = if options.delete(:layout).try(:to_sym) == :vertical
21
+ 'btn-group-vertical'
22
+ else
23
+ 'btn-group'
24
+ end
25
+
26
+ prepend_class(options, layout, size)
27
+ options[:role] = squeeze_n_strip("group #{options[:role]}")
28
+ options[:data] = (options[:data] || {}).merge({bui: 'btn_group', size: size})
29
+
30
+ content_tag :div, options, &block
31
+ end
32
+
33
+ def button_toolbar(options={}, &block)
34
+ prepend_class(options, 'btn-toolbar')
35
+ prepend_role(options, 'toolbar')
36
+
37
+ content_tag :div, options, &block
38
+ end
39
+
40
+ def navbar_button(content_or_options=nil, options={}, &block)
41
+ content_or_options.is_a?(Hash) ? options = content_or_options : content = content_or_options
42
+
43
+ prepend_class(options, 'navbar-btn')
44
+ button content, options, &block
45
+ end
46
+
47
+ private
48
+
49
+ def get_btn_size(size)
50
+ case size.try(:to_sym)
51
+ when :xsmall
52
+ 'btn-xs'
53
+ when :small
54
+ 'btn-sm'
55
+ when :large
56
+ 'btn-lg'
57
+ else
58
+ end
59
+ end
60
+
61
+ def get_btn_type(type)
62
+ case type.try(:to_sym)
63
+ when :primary
64
+ 'btn-primary'
65
+ when :info
66
+ 'btn-info'
67
+ when :success
68
+ 'btn-success'
69
+ when :warning
70
+ 'btn-warning'
71
+ when :danger
72
+ 'btn-danger'
73
+ when :link
74
+ 'btn-link'
75
+ else
76
+ 'btn-default'
77
+ end
78
+ end
79
+
80
+ def get_btn_group_size(size)
81
+ case size.try(:to_sym)
82
+ when :xsmall
83
+ 'btn-group-xs'
84
+ when :small
85
+ 'btn-group-sm'
86
+ when :large
87
+ 'btn-group-lg'
88
+ else
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,17 @@
1
+ module ButtonToHelper
2
+ include FormatHelper
3
+
4
+ def button_to(name = nil, options = nil, html_options = nil, &block)
5
+ html_options, options = options, name if block_given?
6
+ options ||= {}
7
+ html_options ||= {}
8
+
9
+ layout = 'btn-block' if html_options.delete(:layout).try(:to_sym) == :block
10
+ size = get_btn_size(html_options.delete(:size))
11
+ style = get_btn_type(html_options.delete(:style))
12
+
13
+ prepend_class(html_options, 'btn', style, layout, size)
14
+
15
+ super(name, options, html_options, &block)
16
+ end
17
+ end
@@ -0,0 +1,137 @@
1
+ module DropdownHelper
2
+
3
+ # TODO: support split button dropdowns
4
+ class DropdownListItem
5
+ include FormatHelper
6
+ include ActionView::Helpers
7
+
8
+ attr_accessor :options
9
+
10
+ def initialize(options={})
11
+ @options = options
12
+ end
13
+
14
+ def construct
15
+ content_tag :li, parse_type(options), options
16
+ end
17
+
18
+ def parse_type(options={})
19
+ case options[:type].try(:to_sym)
20
+ when :link
21
+ return link_to(options[:text], options[:link], role: :menuitem,
22
+ tabindex: -1)
23
+ when :header
24
+ prepend_class(options, 'dropdown-header')
25
+ return options[:text]
26
+ when :divider
27
+ prepend_class(options, 'divider')
28
+ options[:role] = 'separator'
29
+ else
30
+ end
31
+ end
32
+ end
33
+
34
+ class DropdownCreator
35
+ include FormatHelper
36
+ include ActionView::Helpers
37
+
38
+ attr_accessor :content
39
+ attr_accessor :list
40
+ attr_accessor :options
41
+ attr_accessor :output_buffer
42
+
43
+ def initialize(content, list, options)
44
+ @content = content
45
+ @list = list
46
+ @options = options
47
+ end
48
+
49
+ def build
50
+ navbar, btn_id, klass, align, direction, size, type = process_dropdown_options(options)
51
+
52
+ btn_options = button_options(content, size, type, btn_id, navbar)
53
+ list_options = list_options(btn_id, align)
54
+
55
+ tag = navbar ? :li : :div
56
+ prepend_class(options, 'btn-group',
57
+ (direction == :up ? 'dropup' : 'dropdown'), klass)
58
+
59
+ content_tag tag, options do
60
+ (dropdown_button(btn_options) +
61
+ dropdown_list(list, list_options)).html_safe
62
+ end
63
+ end
64
+
65
+ private
66
+ def process_dropdown_options(options)
67
+ navbar = options.delete(:category).try(:to_sym) == :navbar
68
+ btn_id = options.delete(:id) || "dropdown-#{rand(0...999)}"
69
+ klass = options.delete(:class)
70
+ active = 'active' if options.delete(:active)
71
+ align = options.delete(:align).try(:to_sym)
72
+ direction = options.delete(:direction).try(:to_sym)
73
+ size = get_btn_size(options.delete(:size))
74
+ type = get_btn_type(options.delete(:type))
75
+
76
+ [navbar, btn_id, "#{klass} #{active}", align, direction, size,
77
+ "btn #{type}"]
78
+ end
79
+
80
+ def button_options(content, size, type, id, navbar)
81
+ klass = navbar ? 'dropdown-toggle' : "dropdown-toggle #{size} #{type}"
82
+
83
+ {
84
+ content: content,
85
+ class: klass,
86
+ id: id,
87
+ data: {toggle: 'dropdown'},
88
+ aria: {haspopup: true, expended: false},
89
+ navbar: navbar
90
+ }
91
+ end
92
+
93
+ def list_options(btn_id, align)
94
+ {
95
+ class: align == :right ? 'dropdown-menu-right' : 'dropdown-menu-left',
96
+ role: 'menu',
97
+ aria: {labelledby: btn_id}
98
+ }
99
+ end
100
+
101
+ def dropdown_button(options={})
102
+ content = options.delete(:content)
103
+ navbar = options.delete(:navbar)
104
+
105
+ if navbar
106
+ link_to '#', options do
107
+ (content + " <span class='caret'></span>").html_safe
108
+ end
109
+ else
110
+ button_tag options do
111
+ (content + " <span class='caret'></span>").html_safe
112
+ end
113
+ end
114
+ end
115
+
116
+ def dropdown_list(list_items, options={})
117
+ prepend_class(options, 'dropdown-menu')
118
+
119
+ content_tag :ul, options do
120
+ list_items.map do |item|
121
+ DropdownListItem.new(item).construct
122
+ end.join('').html_safe
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ def dropdown(content=nil, list=[], options={})
129
+ return if content.blank? || list.empty?
130
+
131
+ DropdownCreator.new(content, list, options).build
132
+ end
133
+
134
+ def navbar_dropdown(content=nil, list=[], options={})
135
+ dropdown(content, list, options.merge({category: :navbar}))
136
+ end
137
+ end
@@ -0,0 +1,12 @@
1
+ module FormatHelper
2
+
3
+ def squeeze_n_strip(string='')
4
+ string.squeeze(' ').strip
5
+ end
6
+
7
+ %w(class role).each do |attr|
8
+ define_method "prepend_#{attr}" do |options={}, *attrs|
9
+ options[attr.to_sym] = squeeze_n_strip("#{attrs.join(' ')} #{options[attr.to_sym]}")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,112 @@
1
+ module IconHelper
2
+
3
+ class IconCreator
4
+ include ValidIcons
5
+ include FormatHelper
6
+ include ActionView::Helpers
7
+
8
+ attr_accessor :type
9
+ attr_accessor :options
10
+
11
+ def initialize(type, options)
12
+ @type = type
13
+ @options = options
14
+ end
15
+
16
+ def build
17
+ icon_options = {
18
+ type: type,
19
+ size: options.delete(:size).presence || :normal,
20
+ fw: options.delete(:fixed_with).presence,
21
+ li: options.delete(:list_icon).presence,
22
+ inverse: options.delete(:inverse).presence,
23
+ border: options.delete(:border).presence,
24
+ pull: options.delete(:pull).presence,
25
+ animate: options.delete(:animate).presence,
26
+ orientation: options.delete(:orientation).presence
27
+
28
+ # TODO add fa-stack support
29
+ # stack = options.delete(:stack).presence
30
+ }
31
+
32
+ prepend_class(options, 'fa', build_fa_class(icon_options))
33
+
34
+ content_tag :i, nil, options
35
+ end
36
+
37
+ private
38
+ def build_fa_class(options)
39
+ type = "fa-#{options[:type]}"
40
+ raise 'Invalid Icon Type!' if ValidIcons::VALID_ICONS.exclude?(type)
41
+
42
+ size = get_icon_size(options.delete(:size))
43
+ fw = options[:fw].presence ? 'fa-fw' : nil
44
+ li = options[:li].presence ? 'fa-li' : nil
45
+ inverse = options[:inverse].presence ? 'fa-inverse' : nil
46
+ border = options[:border].presence ? 'fa-border' : nil
47
+ pull = get_icon_position(options[:pull])
48
+ animate = get_icon_animation(options[:animate])
49
+ orientation = get_icon_orientation(options[:orientation])
50
+
51
+ "#{type} #{size} #{fw} #{li} #{inverse} #{border} #{pull} #{animate} #{orientation}"
52
+ end
53
+
54
+ def get_icon_size(size)
55
+ case size.try(:to_sym)
56
+ when :lg
57
+ 'fa-lg'
58
+ when :'2x'
59
+ 'fa-2x'
60
+ when :'3x'
61
+ 'fa-3x'
62
+ when :'4x'
63
+ 'fa-4x'
64
+ when :'5x'
65
+ 'fa-5x'
66
+ else
67
+ end
68
+ end
69
+
70
+ def get_icon_position(position)
71
+ case position.try(:to_sym)
72
+ when :right
73
+ 'fa-pull-right'
74
+ when :left
75
+ 'fa-pull-left'
76
+ else
77
+ end
78
+ end
79
+
80
+ def get_icon_animation(animation)
81
+ case animation.try(:to_sym)
82
+ when :spin
83
+ 'fa-spin'
84
+ when :pulse
85
+ 'fa-pulse'
86
+ else
87
+ end
88
+ end
89
+
90
+ def get_icon_orientation(orientation)
91
+ case orientation.try(:to_sym)
92
+ when :'90'
93
+ 'fa-rotate-90'
94
+ when :'180'
95
+ 'fa-rotate-180'
96
+ when :'270'
97
+ 'fa-rotate-270'
98
+ when :horizontal
99
+ 'fa-flip-horizontal'
100
+ when :vertical
101
+ 'fa-flip-vertical'
102
+ else
103
+ end
104
+ end
105
+ end
106
+
107
+ def icon(type=nil, options={})
108
+ raise 'Please provide an icon type!' if type.blank?
109
+
110
+ IconCreator.new(type, options).build
111
+ end
112
+ end