twitter-bootstrap-for-rails 1.3.3
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +694 -0
- data/Rakefile +1 -0
- data/app/helpers/bootstrap_panel_helper.rb +62 -0
- data/app/helpers/breadcrumbs_helper.rb +10 -0
- data/app/helpers/dropdown_helper.rb +144 -0
- data/app/helpers/flash_block_helper.rb +48 -0
- data/app/helpers/form_group_helper.rb +21 -0
- data/app/helpers/glyphicon_helper.rb +38 -0
- data/app/helpers/modal_dialog_helper.rb +81 -0
- data/app/helpers/navbar_helper.rb +234 -0
- data/app/helpers/paginator_helper.rb +63 -0
- data/app/helpers/resource_table_helper.rb +165 -0
- data/app/helpers/title_helper.rb +24 -0
- data/app/views/twitter-bootstrap/_breadcrumbs.erb +13 -0
- data/lib/bs_form_builder.rb +95 -0
- data/lib/form_builder.rb +125 -0
- data/lib/helpers.rb +14 -0
- data/lib/twitter/bootstrap/for/rails.rb +50 -0
- data/lib/twitter/bootstrap/for/rails/breadcrumbs.rb +65 -0
- data/lib/twitter/bootstrap/for/rails/version.rb +10 -0
- data/twitter-bootstrap-for-rails.gemspec +23 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.svg +229 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/javascripts/bootstrap.js +2002 -0
- data/vendor/assets/javascripts/bootstrap.min.js +9 -0
- data/vendor/assets/javascripts/bs-confirmation-dialog.js.erb +24 -0
- data/vendor/assets/stylesheets/bootstrap.css.erb +7098 -0
- data/vendor/assets/stylesheets/bootstrap.min.css.erb +9 -0
- metadata +105 -0
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'helpers'
|
2
|
+
|
3
|
+
module BootstrapPanelHelper
|
4
|
+
def panel(options={}, &block)
|
5
|
+
unless block_given?
|
6
|
+
raise 'Missing block'
|
7
|
+
end
|
8
|
+
|
9
|
+
panel_options = options.dup
|
10
|
+
panel_options[:class] = parse_html_classes_to_arr panel_options[:class]
|
11
|
+
panel_options[:class] << 'panel'
|
12
|
+
|
13
|
+
header = panel_options.delete :header
|
14
|
+
title = panel_options.delete :title
|
15
|
+
footer = panel_options.delete :footer
|
16
|
+
context = panel_options.delete :context
|
17
|
+
|
18
|
+
unless %w(primary info success warning danger).include? context.to_s
|
19
|
+
context = :default
|
20
|
+
end
|
21
|
+
|
22
|
+
panel_options[:class] << "panel-#{context}"
|
23
|
+
|
24
|
+
content = []
|
25
|
+
content << panel_header(header || title)
|
26
|
+
content << panel_body(&block)
|
27
|
+
content << panel_footer(footer)
|
28
|
+
|
29
|
+
content_tag :div, content.join("\n").html_safe, panel_options
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def panel_body(&block)
|
34
|
+
content = capture &block
|
35
|
+
|
36
|
+
content_tag :div, content, class: 'panel-body'
|
37
|
+
end
|
38
|
+
|
39
|
+
def panel_header(header)
|
40
|
+
return unless header
|
41
|
+
|
42
|
+
if header.is_a? Hash
|
43
|
+
level = header[:level]
|
44
|
+
|
45
|
+
unless (1..6).include? level
|
46
|
+
level = 1
|
47
|
+
end
|
48
|
+
|
49
|
+
content = content_tag "h#{level}", header[:content], class: 'panel-title'
|
50
|
+
else
|
51
|
+
content = header
|
52
|
+
end
|
53
|
+
|
54
|
+
content_tag :div, content, class: 'panel-heading'
|
55
|
+
end
|
56
|
+
|
57
|
+
def panel_footer(content)
|
58
|
+
if content
|
59
|
+
content_tag :div, content, class: 'panel-footer'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'helpers'
|
2
|
+
|
3
|
+
module BreadcrumbsHelper
|
4
|
+
def render_breadcrumbs(options={})
|
5
|
+
br_options = options.dup
|
6
|
+
br_options[:class] = parse_html_classes_to_arr br_options[:class]
|
7
|
+
br_options[:class] << 'breadcrumb'
|
8
|
+
render :partial => 'twitter-bootstrap/breadcrumbs', :layout => false, locals: {options: br_options}
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module DropdownHelper
|
2
|
+
require 'helpers'
|
3
|
+
|
4
|
+
def dropdown(text, options={}, &block)
|
5
|
+
container_options = options.dup
|
6
|
+
button_options = container_options.delete(:button) || {}
|
7
|
+
menu_options = container_options.delete(:menu) || {}
|
8
|
+
|
9
|
+
drop_direction = container_options.delete :drop_direction
|
10
|
+
container_classes = parse_html_classes_to_arr container_options[:class]
|
11
|
+
container_classes << 'btn-group'
|
12
|
+
|
13
|
+
if drop_direction == :up
|
14
|
+
container_classes << 'dropup'
|
15
|
+
end
|
16
|
+
|
17
|
+
container_options[:class] = container_classes
|
18
|
+
|
19
|
+
content_tag :div, render_dropdown(text, button_options, menu_options, &block), container_options
|
20
|
+
end
|
21
|
+
|
22
|
+
class Dropdown
|
23
|
+
include ActionView::Helpers::TagHelper
|
24
|
+
|
25
|
+
def item(text, link_or_options=nil, options={})
|
26
|
+
if link_or_options.is_a? Hash
|
27
|
+
link_or_options, options = nil, link_or_options
|
28
|
+
end
|
29
|
+
|
30
|
+
link_or_options ||= '#'
|
31
|
+
|
32
|
+
content = content_tag :a, text, href: link_or_options
|
33
|
+
content_tag :li, content, options
|
34
|
+
end
|
35
|
+
|
36
|
+
def divider(options={})
|
37
|
+
classes = parse_html_classes_to_arr options[:class]
|
38
|
+
classes << 'divider'
|
39
|
+
divider_options = options.dup
|
40
|
+
divider_options[:class] = classes
|
41
|
+
content_tag :li, '', divider_options
|
42
|
+
end
|
43
|
+
|
44
|
+
def header(text, options={})
|
45
|
+
header_options = options.dup
|
46
|
+
classes = parse_html_classes_to_arr header_options[:class]
|
47
|
+
classes << 'dropdown-header'
|
48
|
+
header_options[:class] = classes
|
49
|
+
|
50
|
+
content_tag :li, text, header_options
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def render_dropdown(button_text, button_options, menu_options, &block)
|
56
|
+
content = []
|
57
|
+
content << render_button(button_text, button_options)
|
58
|
+
content << render_menu(menu_options, &block)
|
59
|
+
content.join("\n").html_safe
|
60
|
+
end
|
61
|
+
|
62
|
+
def btn_regex
|
63
|
+
/btn-(?>default|primary|warning|success|info|danger|link)/
|
64
|
+
end
|
65
|
+
|
66
|
+
def render_button(button_text, options={})
|
67
|
+
split = options[:split]
|
68
|
+
|
69
|
+
button_classes = parse_html_classes_to_arr options[:class]
|
70
|
+
|
71
|
+
unless button_classes.join =~ btn_regex
|
72
|
+
button_classes << 'btn-default'
|
73
|
+
options[:class] = button_classes
|
74
|
+
end
|
75
|
+
|
76
|
+
if split
|
77
|
+
render_split_button button_text, options
|
78
|
+
else
|
79
|
+
render_single_button button_text, options
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_split_options(button_options)
|
84
|
+
split_options =
|
85
|
+
case button_options[:split]
|
86
|
+
when Hash then button_options[:split]
|
87
|
+
else {}
|
88
|
+
end
|
89
|
+
|
90
|
+
classes = parse_html_classes_to_arr split_options[:class]
|
91
|
+
|
92
|
+
unless classes.join =~ btn_regex
|
93
|
+
classes << btn_regex.match(parse_html_classes_to_arr(button_options[:class]).join)
|
94
|
+
end
|
95
|
+
|
96
|
+
classes << 'btn'
|
97
|
+
classes << 'dropdown-toggle'
|
98
|
+
split_options[:class] = classes
|
99
|
+
split_options[:type] = 'button'
|
100
|
+
split_options[:data] = { toggle: 'dropdown' }
|
101
|
+
|
102
|
+
split_options
|
103
|
+
end
|
104
|
+
|
105
|
+
def render_single_button(button_text, options)
|
106
|
+
content = []
|
107
|
+
content << button_text
|
108
|
+
content << caret
|
109
|
+
|
110
|
+
button_classes = parse_html_classes_to_arr options[:class]
|
111
|
+
button_classes << 'btn dropdown-toggle'
|
112
|
+
options[:class] = button_classes
|
113
|
+
options[:type] = 'button'
|
114
|
+
options[:data] = { toggle: 'dropdown' }
|
115
|
+
|
116
|
+
content_tag :button, content.join("\n").html_safe, options
|
117
|
+
end
|
118
|
+
|
119
|
+
def render_split_button(button_text, options)
|
120
|
+
content = []
|
121
|
+
split_options = get_split_options(options)
|
122
|
+
options.delete :split
|
123
|
+
|
124
|
+
classes = parse_html_classes_to_arr options[:class]
|
125
|
+
classes << 'btn'
|
126
|
+
options[:class] = classes
|
127
|
+
options[:type] = 'button'
|
128
|
+
|
129
|
+
content << content_tag(:button, button_text, options)
|
130
|
+
content << content_tag(:button, caret, split_options)
|
131
|
+
content.join("\n").html_safe
|
132
|
+
end
|
133
|
+
|
134
|
+
def caret
|
135
|
+
content_tag :span, '', class: 'caret'
|
136
|
+
end
|
137
|
+
|
138
|
+
def render_menu(options, &block)
|
139
|
+
content = capture Dropdown.new, &block
|
140
|
+
options[:class] = 'dropdown-menu'
|
141
|
+
options[:role] = 'menu'
|
142
|
+
content_tag :ul, content, options
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'helpers'
|
2
|
+
|
3
|
+
module FlashBlockHelper
|
4
|
+
def flash_block(options={})
|
5
|
+
content = []
|
6
|
+
|
7
|
+
flash.each do |type, message|
|
8
|
+
content << bs_alert(type, message)
|
9
|
+
end
|
10
|
+
|
11
|
+
content_tag :div, content.join("\n").html_safe, options
|
12
|
+
end
|
13
|
+
|
14
|
+
def bs_alert(type, message, options={})
|
15
|
+
alert_options = options.dup
|
16
|
+
alert_options[:class] = parse_html_classes_to_arr alert_options[:class]
|
17
|
+
alert_options[:class] << 'alert'
|
18
|
+
alert_options[:class] << 'alert-dismissable'
|
19
|
+
alert_options[:class] << alert_class(type)
|
20
|
+
|
21
|
+
content = []
|
22
|
+
content << content_tag(:button, '×'.html_safe, class: 'close', type: 'button', data: {dismiss: :alert}, aria: {hidden: 'true'})
|
23
|
+
content << message
|
24
|
+
|
25
|
+
content_tag :div, content.join("\n").html_safe, alert_options
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
#Render rules
|
30
|
+
#- `:success` render as `.alert-success`;
|
31
|
+
#- `:info` render as `.alert-info`;
|
32
|
+
#- `:warning` render as `.alert-warning`;
|
33
|
+
#- `:danger` render as `.alert-danger`;
|
34
|
+
#- `:notice` render as `.alert-success`;
|
35
|
+
#- `:alert` render as `.alert-danger`;
|
36
|
+
#- another keys render as `alert-info`.
|
37
|
+
def alert_class(type)
|
38
|
+
act_type =
|
39
|
+
case type
|
40
|
+
when :success, :notice then :success
|
41
|
+
when :danger, :alert then :danger
|
42
|
+
when :warning, :info then type
|
43
|
+
else :info
|
44
|
+
end
|
45
|
+
|
46
|
+
"alert-#{act_type}"
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FormGroupHelper
|
2
|
+
# Return a bootstrap form group markup
|
3
|
+
def form_group(options = {}, &block)
|
4
|
+
form_group_options = options.dup
|
5
|
+
classes = split_html_class options[:class]
|
6
|
+
classes << :'form-group'
|
7
|
+
form_group_options[:class] = classes
|
8
|
+
content = capture &block
|
9
|
+
content_tag :div, content, form_group_options
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def split_html_class(classes)
|
14
|
+
case classes
|
15
|
+
when NilClass then []
|
16
|
+
when String then classes.split
|
17
|
+
when Array then classes
|
18
|
+
when Symbol then [classes]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module GlyphiconHelper
|
2
|
+
require 'helpers'
|
3
|
+
|
4
|
+
# Return the Twitter Bootstrap glyphicon html markup
|
5
|
+
# Parameter name is the name of icon
|
6
|
+
# Parameter options is the hash of additional options generating span
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# invoke
|
10
|
+
# glyph :search
|
11
|
+
#
|
12
|
+
# returns
|
13
|
+
# <span class="glyphicon glyphicon-search"></span>
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# invoke
|
17
|
+
# glyph :search, class: 'pull-right'
|
18
|
+
#
|
19
|
+
# returns
|
20
|
+
# <span class="pull-right glyphicon glyphicon-search"></span>
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# invoke
|
24
|
+
# glyph :search, class: 'pull-right', data: { action: 'search' }
|
25
|
+
#
|
26
|
+
# returns
|
27
|
+
# <span class="pull-right glyphicon glyphicon-search" data-action="search"></span>
|
28
|
+
def glyph(name, options={})
|
29
|
+
glyph_options = options.dup
|
30
|
+
glyph_classes = parse_html_classes_to_arr glyph_options[:class]
|
31
|
+
glyph_classes << 'glyphicon'
|
32
|
+
glyph_classes << "glyphicon-#{name.to_s.gsub('_', '-')}"
|
33
|
+
glyph_options[:class] = glyph_classes
|
34
|
+
|
35
|
+
|
36
|
+
content_tag :span, '', glyph_options
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helpers'
|
2
|
+
|
3
|
+
module ModalDialogHelper
|
4
|
+
def modal_dialog(options={})
|
5
|
+
modal_dialog_options = options.dup
|
6
|
+
modal_dialog_options[:class] = parse_html_classes_to_arr modal_dialog_options[:class]
|
7
|
+
modal_dialog_options[:class] << 'modal'
|
8
|
+
modal_dialog_options[:class] << 'fade'
|
9
|
+
|
10
|
+
modal_header = modal_dialog_options.delete :header
|
11
|
+
modal_body = modal_dialog_options.delete :body
|
12
|
+
modal_footer = modal_dialog_options.delete :footer
|
13
|
+
|
14
|
+
modal_dialog_builder = ModalDialog.new self, modal_header, modal_body, modal_footer
|
15
|
+
|
16
|
+
content = modal_dialog_builder.render
|
17
|
+
|
18
|
+
content_tag :div, content, modal_dialog_options
|
19
|
+
end
|
20
|
+
|
21
|
+
def dismiss_button(text, options={})
|
22
|
+
#<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
23
|
+
button_options = options.dup
|
24
|
+
button_options[:class] = parse_html_classes_to_arr button_options[:class]
|
25
|
+
button_options[:class] << 'btn'
|
26
|
+
button_options[:data] ||= {}
|
27
|
+
button_options[:data][:dismiss] = 'modal'
|
28
|
+
|
29
|
+
unless button_options[:class].join =~ /btn-(?>default|primary|warning|success|info|danger|link)/
|
30
|
+
button_options[:class] << 'btn-default'
|
31
|
+
end
|
32
|
+
|
33
|
+
content_tag :button, text, button_options
|
34
|
+
end
|
35
|
+
|
36
|
+
class ModalDialog
|
37
|
+
attr_accessor :parent, :header, :body, :footer
|
38
|
+
delegate :content_tag, to: :parent
|
39
|
+
|
40
|
+
def initialize(parent, header, body, footer)
|
41
|
+
@parent = parent
|
42
|
+
@header = header
|
43
|
+
@body = body
|
44
|
+
@footer = footer
|
45
|
+
end
|
46
|
+
|
47
|
+
def render
|
48
|
+
content_tag :div, modal_content_block, class: 'modal-dialog'
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def modal_content_block
|
53
|
+
content = []
|
54
|
+
content << modal_header_block
|
55
|
+
content << modal_body_block
|
56
|
+
content << modal_footer_block
|
57
|
+
|
58
|
+
content_tag :div, content.join("\n").html_safe, class: 'modal-content'
|
59
|
+
end
|
60
|
+
|
61
|
+
def modal_header_block
|
62
|
+
if @header
|
63
|
+
content_tag :div, close_button + @header, class: 'modal-header'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def close_button
|
68
|
+
content_tag :button, '×'.html_safe, type: 'button', class: 'close', data: {dismiss: 'modal'}, aria: {hidden: 'true'}
|
69
|
+
end
|
70
|
+
|
71
|
+
def modal_body_block
|
72
|
+
content_tag :div, @body, class: 'modal-body'
|
73
|
+
end
|
74
|
+
|
75
|
+
def modal_footer_block
|
76
|
+
if @footer
|
77
|
+
content_tag :div, @footer, class: 'modal-footer'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
module NavbarHelper
|
2
|
+
require 'helpers'
|
3
|
+
|
4
|
+
def navbar(options={}, &block)
|
5
|
+
navbar_options = options.dup
|
6
|
+
navbar_options[:class] = parse_html_classes_to_arr navbar_options[:class]
|
7
|
+
navbar_options[:class] << 'navbar'
|
8
|
+
navbar_options[:class] << 'navbar-default'
|
9
|
+
navbar_options[:role] = :navigation
|
10
|
+
|
11
|
+
fixed = navbar_options.delete(:fixed).to_s
|
12
|
+
|
13
|
+
if fixed == 'top' || fixed == 'bottom'
|
14
|
+
navbar_options[:class] << "navbar-fixed-#{fixed}"
|
15
|
+
end
|
16
|
+
|
17
|
+
static = navbar_options.delete(:static).to_s
|
18
|
+
|
19
|
+
if static == 'top'
|
20
|
+
navbar_options[:class] << 'navbar-static-top'
|
21
|
+
end
|
22
|
+
|
23
|
+
inverse = navbar_options.delete :inverse
|
24
|
+
|
25
|
+
if inverse == true
|
26
|
+
navbar_options[:class] << 'navbar-inverse'
|
27
|
+
end
|
28
|
+
|
29
|
+
brand = navbar_options.delete :brand
|
30
|
+
|
31
|
+
navbar_id = SecureRandom.hex
|
32
|
+
|
33
|
+
content = []
|
34
|
+
content << render_navbar_header(brand, navbar_id)
|
35
|
+
content << render_navbar_body(navbar_id, &block)
|
36
|
+
|
37
|
+
content_tag :nav, content.join("\n").html_safe, navbar_options
|
38
|
+
end
|
39
|
+
|
40
|
+
def uri_state(uri)
|
41
|
+
root_url = request.host_with_port + '/'
|
42
|
+
request_uri = request.path[1..-1]
|
43
|
+
|
44
|
+
uri.gsub(root_url)
|
45
|
+
|
46
|
+
if uri.start_with? '/'
|
47
|
+
uri = uri[1..-1]
|
48
|
+
end
|
49
|
+
|
50
|
+
if uri == request_uri
|
51
|
+
return :active
|
52
|
+
end
|
53
|
+
|
54
|
+
uri_parts = uri.split '/'
|
55
|
+
request_uri_parts = request_uri.split '/'
|
56
|
+
|
57
|
+
uri_parts.each_with_index do |uri_part, index|
|
58
|
+
if uri_part != request_uri_parts[index]
|
59
|
+
return :inactive
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
:chosen
|
64
|
+
end
|
65
|
+
|
66
|
+
class Navbar
|
67
|
+
attr_accessor :parent
|
68
|
+
|
69
|
+
def initialize(parent)
|
70
|
+
self.parent = parent
|
71
|
+
end
|
72
|
+
|
73
|
+
delegate :capture, :content_tag, :to => :parent
|
74
|
+
|
75
|
+
def group(options={}, &block)
|
76
|
+
navbar_group_builder = NavbarGroup.new self.parent
|
77
|
+
content = capture navbar_group_builder, &block
|
78
|
+
|
79
|
+
menu_group_options = options.dup
|
80
|
+
menu_group_options[:class] = parse_html_classes_to_arr menu_group_options[:class]
|
81
|
+
menu_group_options[:class] << 'nav'
|
82
|
+
menu_group_options[:class] << 'navbar-nav'
|
83
|
+
pull = menu_group_options.delete(:pull).to_s
|
84
|
+
|
85
|
+
if pull == 'left' || pull == 'right'
|
86
|
+
menu_group_options[:class] << "navbar-#{pull}"
|
87
|
+
end
|
88
|
+
|
89
|
+
content_tag :ul, content, menu_group_options
|
90
|
+
end
|
91
|
+
|
92
|
+
def button(text, options={})
|
93
|
+
button_options = options.dup
|
94
|
+
button_options[:class] = parse_html_classes_to_arr button_options[:class]
|
95
|
+
button_options[:class] << 'btn'
|
96
|
+
button_options[:class] << 'navbar-btn'
|
97
|
+
|
98
|
+
unless button_options[:class].join =~ /btn-(?>default|primary|warning|success|info|danger|link)/
|
99
|
+
button_options[:class] << 'btn-default'
|
100
|
+
end
|
101
|
+
|
102
|
+
content_tag :button, text, button_options
|
103
|
+
end
|
104
|
+
|
105
|
+
def text(text, options={})
|
106
|
+
text_options = options.dup
|
107
|
+
text_options[:class] = parse_html_classes_to_arr text_options[:class]
|
108
|
+
text_options[:class] << 'navbar-text'
|
109
|
+
|
110
|
+
pull = text_options.delete(:pull).to_s
|
111
|
+
|
112
|
+
if pull == 'left' || pull == 'right'
|
113
|
+
text_options[:class] << "navbar-#{pull}"
|
114
|
+
end
|
115
|
+
|
116
|
+
content_tag :p, text, text_options
|
117
|
+
end
|
118
|
+
|
119
|
+
def link(text, uri, options={})
|
120
|
+
link_options = options.dup
|
121
|
+
link_options[:class] = parse_html_classes_to_arr link_options[:class]
|
122
|
+
link_options[:class] << 'navbar-link'
|
123
|
+
link_options[:href] = uri
|
124
|
+
|
125
|
+
content_tag :a, text, link_options
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class NavbarGroup
|
130
|
+
attr_accessor :parent
|
131
|
+
|
132
|
+
def initialize(parent)
|
133
|
+
self.parent = parent
|
134
|
+
end
|
135
|
+
|
136
|
+
delegate :capture, :content_tag, :request, :link_to, :uri_state, :to => :parent
|
137
|
+
|
138
|
+
def item(text, uri, options={})
|
139
|
+
menu_item_options = options.dup
|
140
|
+
menu_item_options[:class] = parse_html_classes_to_arr menu_item_options[:class]
|
141
|
+
|
142
|
+
state = uri_state uri
|
143
|
+
|
144
|
+
if state == :active || state == :chosen
|
145
|
+
menu_item_options[:class] << 'active'
|
146
|
+
end
|
147
|
+
|
148
|
+
content = link_to text, uri
|
149
|
+
content_tag :li, content, menu_item_options
|
150
|
+
end
|
151
|
+
|
152
|
+
def dropdown(text, options={}, &block)
|
153
|
+
dropdown_builder = Dropdown.new self.parent
|
154
|
+
content = []
|
155
|
+
content << link_to("#{text} #{caret}".html_safe, '#', class: 'dropdown-toggle', data: {toggle: 'dropdown'})
|
156
|
+
items = capture dropdown_builder, &block
|
157
|
+
content << content_tag(:ul, items, class: 'dropdown-menu')
|
158
|
+
|
159
|
+
dropdown_options = options.dup
|
160
|
+
dropdown_options[:class] = parse_html_classes_to_arr dropdown_options[:class]
|
161
|
+
dropdown_options[:class] << 'dropdown'
|
162
|
+
|
163
|
+
if dropdown_builder.chosen
|
164
|
+
dropdown_options[:class] << 'active'
|
165
|
+
end
|
166
|
+
|
167
|
+
content_tag :li, content.join("\n").html_safe, dropdown_options
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def caret
|
172
|
+
content_tag :span, '', class: 'caret'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class Dropdown
|
177
|
+
attr_accessor :parent, :chosen
|
178
|
+
|
179
|
+
def initialize(parent)
|
180
|
+
self.parent = parent
|
181
|
+
@chosen = false
|
182
|
+
end
|
183
|
+
|
184
|
+
delegate :capture, :content_tag, :request, :link_to, :uri_state, :to => :parent
|
185
|
+
|
186
|
+
def item(text, uri, options={})
|
187
|
+
menu_item_options = options.dup
|
188
|
+
menu_item_options[:class] = parse_html_classes_to_arr menu_item_options[:class]
|
189
|
+
|
190
|
+
state = uri_state uri
|
191
|
+
|
192
|
+
if state == :active || state == :chosen
|
193
|
+
menu_item_options[:class] << 'active'
|
194
|
+
@chosen = true
|
195
|
+
end
|
196
|
+
|
197
|
+
content = link_to text, uri
|
198
|
+
content_tag :li, content, menu_item_options
|
199
|
+
end
|
200
|
+
|
201
|
+
def divider
|
202
|
+
content_tag :li, '', class: 'divider'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
207
|
+
def render_navbar_header(brand, navbar_id)
|
208
|
+
content = []
|
209
|
+
content << navbar_collapse_button(navbar_id)
|
210
|
+
|
211
|
+
unless brand.blank?
|
212
|
+
content << link_to(brand, root_path, class: 'navbar-brand')
|
213
|
+
end
|
214
|
+
|
215
|
+
content_tag :div, content.join("\n").html_safe, class: 'navbar-header'
|
216
|
+
end
|
217
|
+
|
218
|
+
def navbar_collapse_button(navbar_id)
|
219
|
+
content = []
|
220
|
+
|
221
|
+
3.times do
|
222
|
+
content << content_tag(:span, '', class: 'icon-bar')
|
223
|
+
end
|
224
|
+
|
225
|
+
content_tag :button, content.join("\n").html_safe, type: 'button', class: 'navbar-toggle',
|
226
|
+
data: {toggle: 'collapse', target: "##{navbar_id}"}
|
227
|
+
end
|
228
|
+
|
229
|
+
def render_navbar_body(navbar_id, &block)
|
230
|
+
navbar_builder = Navbar.new self
|
231
|
+
content = capture navbar_builder, &block
|
232
|
+
content_tag :div, content, class: 'collapse navbar-collapse', id: navbar_id
|
233
|
+
end
|
234
|
+
end
|