bootstrap-shoehorn 1.0.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.
Files changed (58) hide show
  1. data/.gitignore +9 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/README.md +336 -0
  6. data/Rakefile +32 -0
  7. data/lib/shoehorn.rb +15 -0
  8. data/lib/shoehorn/components.rb +17 -0
  9. data/lib/shoehorn/components/alert.rb +69 -0
  10. data/lib/shoehorn/components/badge.rb +38 -0
  11. data/lib/shoehorn/components/base.rb +18 -0
  12. data/lib/shoehorn/components/button.rb +72 -0
  13. data/lib/shoehorn/components/dropdown.rb +55 -0
  14. data/lib/shoehorn/components/form.rb +14 -0
  15. data/lib/shoehorn/components/form/input_field.rb +53 -0
  16. data/lib/shoehorn/components/form/label.rb +8 -0
  17. data/lib/shoehorn/components/form_builder.rb +13 -0
  18. data/lib/shoehorn/components/icon.rb +40 -0
  19. data/lib/shoehorn/components/label.rb +39 -0
  20. data/lib/shoehorn/components/modal.rb +62 -0
  21. data/lib/shoehorn/components/navigation.rb +47 -0
  22. data/lib/shoehorn/components/progress_bar.rb +51 -0
  23. data/lib/shoehorn/engine.rb +19 -0
  24. data/lib/shoehorn/helper_collection.rb +58 -0
  25. data/lib/shoehorn/helper_collection_set.rb +18 -0
  26. data/lib/shoehorn/helpers.rb +14 -0
  27. data/lib/shoehorn/helpers/alert_helpers.rb +37 -0
  28. data/lib/shoehorn/helpers/badge_helpers.rb +38 -0
  29. data/lib/shoehorn/helpers/button_helpers.rb +122 -0
  30. data/lib/shoehorn/helpers/form_helpers.rb +11 -0
  31. data/lib/shoehorn/helpers/icon_helpers.rb +34 -0
  32. data/lib/shoehorn/helpers/label_helpers.rb +37 -0
  33. data/lib/shoehorn/helpers/modal_helpers.rb +43 -0
  34. data/lib/shoehorn/helpers/navigation_helpers.rb +32 -0
  35. data/lib/shoehorn/helpers/progress_bar_helpers.rb +25 -0
  36. data/lib/shoehorn/plugins.rb +6 -0
  37. data/lib/shoehorn/plugins/simple_navigation/renderer/bootstrap_topbar_list.rb +72 -0
  38. data/lib/shoehorn/version.rb +3 -0
  39. data/log/development.log +0 -0
  40. data/shoehorn.gemspec +33 -0
  41. data/spec/helpers/alert_helpers_spec.rb +138 -0
  42. data/spec/helpers/button_helpers_spec.rb +102 -0
  43. data/spec/helpers/form_helpers_spec.rb +136 -0
  44. data/spec/helpers/inline_label_helpers_spec.rb +50 -0
  45. data/spec/helpers/modal_helpers_spec.rb +60 -0
  46. data/spec/helpers/navigation_helpers_spec.rb +61 -0
  47. data/spec/helpers/progress_bar_helpers_spec.rb +34 -0
  48. data/spec/integration/action_view_spec.rb +23 -0
  49. data/spec/integration/readme_spec.rb +14 -0
  50. data/spec/plugins/bootstrap_topbar_list_spec.rb +11 -0
  51. data/spec/spec_helper.rb +11 -0
  52. data/spec/support/bootstrap_button_macros.rb +8 -0
  53. data/spec/support/bootstrap_form_macros.rb +8 -0
  54. data/spec/support/bootstrap_modal_macros.rb +8 -0
  55. data/spec/support/bootstrap_navigation_macros.rb +8 -0
  56. data/spec/support/bootstrap_spec_helper.rb +50 -0
  57. data/spec/support/test_environment.rb +23 -0
  58. metadata +265 -0
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ module Shoehorn::Helpers
4
+ module ModalHelpers
5
+
6
+ # Render a modal popup
7
+ #
8
+ # @param [Hash] options hash containing options (default: { :dom_id => 'twitter-bootstrap-modal', :fade => false, :header_title => '' }):
9
+ # :id - DOM ID of the modal element (mandatory).
10
+ # :fade - if true, add the fade class to the modal DOM element so the modal will be animated when shown.
11
+ # :title - modal title.
12
+ #
13
+ # @example
14
+ # bootstrap_modal(id: "a_dom_id", fade: true, title: "Modal title!") do |modal|
15
+ # modal.body do |c|
16
+ # c.render partial: 'disclamer'
17
+ # end
18
+ # modal.footer do |c|
19
+ # c.bootstrap_button "Close", "#", type: 'danger', html_options: { data: { dismiss: "modal" } }
20
+ # c.bootstrap_button "Accept", accept_request_path(@request),
21
+ # icon_name: 'ok', type: 'success',
22
+ # html_options: { data: { dismiss: "modal" }, method: :put }
23
+ # end
24
+ # end
25
+ #
26
+ # @example To render the button to show the modal use:
27
+ # bootstrap_button "Show Modal", "#a_dom_id", :html_options => { data: { toggle: "modal" }}
28
+ #
29
+ # Returns HTML String for the modal popup
30
+ def bootstrap_modal(options = {})
31
+ elements = Shoehorn::HelperCollectionSet.new(self, [:body, :footer])
32
+
33
+ yield elements
34
+
35
+ Shoehorn::Components::Modal.new(
36
+ elements.collections[:body],
37
+ elements.collections[:footer],
38
+ options
39
+ ).to_s
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module Shoehorn::Helpers
3
+ module NavigationHelpers
4
+
5
+ # Render a navigation list
6
+ #
7
+ # @param [Hash] options hash containing options (default: {}):
8
+ # :type - could be either 'tabs' or 'pills'. Default is 'tabs'.
9
+ # :stacked - if true, renders the navigation list in stacked mode.
10
+ #
11
+ # Examples
12
+ #
13
+ # bootstrap_navigation(:type => "tabs", :stacked => true) do |nav|
14
+ # nav.link_to "Nav1", "/link1", :active_nav => true
15
+ # nav.link_to "Nav2", "/link2"
16
+ # end
17
+ #
18
+ # Returns HTML String for the navigation list
19
+ def bootstrap_navigation(options = {})
20
+ elements = Shoehorn::HelperCollection.new(self)
21
+
22
+ yield elements
23
+
24
+ Shoehorn::Components::Navigation.new(
25
+ elements,
26
+ options
27
+ ).to_s
28
+ end
29
+
30
+ end
31
+ end
32
+
@@ -0,0 +1,25 @@
1
+ module Shoehorn::Helpers
2
+ module ProgressBarHelpers
3
+ # Render a bootstrap progress bar
4
+ #
5
+ # @param [Integer] width percent out of 100 progress on bar
6
+ # @param [Hash] options hash containing options (default: {}):
7
+ # :type - Additional progress type(s). For one, just specify a string, but
8
+ # you can also pass an array (of sym or str) for multiple classes
9
+ # :striped [Boolean] - Additional progress type(s). For one, just specify a string, but
10
+ # you can also pass an array (of sym or str) for multiple classes
11
+ # :html_options - Any additional options you'd like to pass to the content_tag that will be created
12
+ # for this button's a tag (for instance :target can be specified in :html_options).
13
+ #
14
+ # Examples
15
+ #
16
+ # bootstrap_progress_bar(40, type: 'success', striped: true, animated: true)
17
+ #
18
+ def bootstrap_progress_bar(width, options = {})
19
+ Shoehorn::Components::ProgressBar.new(
20
+ width,
21
+ options
22
+ ).to_s
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ module Shoehorn
2
+ module Plugins
3
+ require "shoehorn/plugins/simple_navigation/renderer/bootstrap_topbar_list" if defined?(::SimpleNavigation)
4
+ end
5
+ end
6
+
@@ -0,0 +1,72 @@
1
+ # Renders an ItemContainer as a <ul> element and its containing items as <li> elements.
2
+ # Prepared to use inside the topbar of Twitter Bootstrap http://twitter.github.com/bootstrap/#navigation
3
+ #
4
+ # Examples
5
+ #
6
+ # render_navigation(level: 1..2, renderer: :bootstrap_topbar_list, expand_all: true)
7
+ class SimpleNavigation::Renderer::BootstrapTopbarList < SimpleNavigation::Renderer::Base
8
+
9
+ def render(item_container)
10
+ if options[:is_subnavigation]
11
+ ul_class = "dropdown-menu"
12
+ else
13
+ ul_class = "nav"
14
+ end
15
+
16
+ list_content = item_container.items.inject([]) do |list, item|
17
+ li_options = item.html_options.reject {|k, v| k == :link}
18
+ if include_sub_navigation?(item)
19
+ li_options[:class] = [li_options[:class], "dropdown"].flatten.compact.join(' ')
20
+ end
21
+ li_content = tag_for(item)
22
+ if include_sub_navigation?(item)
23
+ li_content << render_sub_navigation_for(item)
24
+ end
25
+ list << content_tag(:li, li_content, li_options)
26
+ end.join
27
+ if skip_if_empty? && item_container.empty?
28
+ ''
29
+ else
30
+ content_tag(:ul, list_content, { :id => item_container.dom_id, :class => [item_container.dom_class, ul_class].flatten.compact.join(' ') })
31
+ end
32
+ end
33
+
34
+ def render_sub_navigation_for(item)
35
+ item.sub_navigation.render(self.options.merge(:is_subnavigation => true))
36
+ end
37
+
38
+ protected
39
+
40
+ def tag_for(item)
41
+ if item.url.nil?
42
+ content_tag('span', item.name, link_options_for(item).except(:method))
43
+ else
44
+ name = item.name
45
+ name += ' <span class="caret"></span>' if include_sub_navigation?(item)
46
+ link_to(name, item.url, link_options_for(item))
47
+ end
48
+ end
49
+
50
+ # Extracts the options relevant for the generated link
51
+ #
52
+ def link_options_for(item)
53
+ special_options = {:method => item.method}.reject {|k, v| v.nil? }
54
+ link_options = item.html_options[:link] || {}
55
+ opts = special_options.merge(link_options)
56
+ opts[:class] = [link_options[:class], item.selected_class, dropdown_link_class(item)].flatten.compact.join(' ')
57
+ if include_sub_navigation?(item) && !options[:is_subnavigation]
58
+ opts['data-toggle'] = 'dropdown'
59
+ end
60
+ opts.delete(:class) if opts[:class].nil? || opts[:class] == ''
61
+ opts
62
+ end
63
+
64
+ def dropdown_link_class(item)
65
+ if include_sub_navigation?(item) && !options[:is_subnavigation]
66
+ "dropdown-toggle"
67
+ end
68
+ end
69
+ end
70
+
71
+ SimpleNavigation.register_renderer :bootstrap_topbar_list => SimpleNavigation::Renderer::BootstrapTopbarList
72
+
@@ -0,0 +1,3 @@
1
+ module Shoehorn
2
+ VERSION = "1.0.0"
3
+ end
File without changes
data/shoehorn.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/shoehorn/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Matteo Canato"]
6
+ gem.email = ["mcanato@gmail.com"]
7
+ gem.description = %q{Shoehorn: a Twitter Bootstrap 2.0 helper library for Rails - HTML, CSS, and JS toolkit from Twitter}
8
+ gem.summary = %q{Shoehorn: a Twitter Bootstrap 2.0 helper library for Rails - HTML, CSS, and JS toolkit from Twitter}
9
+ gem.homepage = "https://www.github.com/mcanato/shoehorn"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "bootstrap-shoehorn"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Shoehorn::VERSION
17
+ gem.platform = Gem::Platform::RUBY
18
+
19
+ gem.add_dependency "railties", "~> 3.0"
20
+ gem.add_development_dependency "rails", "~> 3.0"
21
+ gem.add_development_dependency "rspec-rails", "~> 2.10"
22
+ gem.add_development_dependency "rspec_tag_matchers", ">= 1.0"
23
+ gem.add_development_dependency "rake"
24
+ gem.add_development_dependency 'yard'
25
+ gem.add_development_dependency 'redcarpet'
26
+ gem.add_development_dependency 'yard-tomdoc'
27
+ gem.add_development_dependency 'simple-navigation'
28
+
29
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE != 'rbx'
30
+ gem.add_development_dependency RUBY_VERSION =~ /^1\.9/ ? "simplecov" : "rcov"
31
+ end
32
+ end
33
+
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Twitter::Bootstrap::Markup::Rails::Helpers::AlertHelpers do
5
+ include BootstrapSpecHelper
6
+
7
+ describe "#bootstrap_alert_tag" do
8
+ before do
9
+ @output_buffer = ''
10
+ end
11
+
12
+ it "has no heading by default" do
13
+ concat bootstrap_alert_tag("Message", :heading => nil)
14
+ output_buffer.should_not have_tag('div strong')
15
+ output_buffer.should_not have_tag('div h4.alert-heading')
16
+ end
17
+
18
+ it "has alert class" do
19
+ concat bootstrap_alert_tag("Message")
20
+ output_buffer.should have_tag("div.alert")
21
+ end
22
+
23
+ it "has a message" do
24
+ concat bootstrap_alert_tag("Message")
25
+ output_buffer.should have_tag('div', /Message/)
26
+ end
27
+
28
+ it "has a close button when :close is true" do
29
+ concat bootstrap_alert_tag("Message", :close => true)
30
+ output_buffer.should have_tag('div a.close', /×/)
31
+ end
32
+
33
+ it "has no close button when :close is false" do
34
+ concat bootstrap_alert_tag("Message", :close => false)
35
+ output_buffer.should_not have_tag('div a.close')
36
+ end
37
+
38
+ it "has a dismiss tag" do
39
+ concat bootstrap_alert_tag("Message")
40
+ output_buffer.should have_tag('div a[data-dismiss="alert"]')
41
+ end
42
+
43
+ it "has a h4 heading when :block is true" do
44
+ concat bootstrap_alert_tag("message", :heading => "heading1", :block => true)
45
+ output_buffer.should have_tag('div h4.alert-heading', /heading1/)
46
+ end
47
+
48
+ it "has a strong heading when :block is false" do
49
+ concat bootstrap_alert_tag("Message", :heading => "Heading1", :block => false)
50
+ output_buffer.should have_tag('div strong', /Heading1/)
51
+ end
52
+
53
+ it "should add html_options to the resulting DIV tag when specified" do
54
+ concat bootstrap_alert_tag("Message", :html_options => {:"data-test" => "42"})
55
+ output_buffer.should have_tag("div[data-test='42']")
56
+ end
57
+ end
58
+
59
+ %w(error success info).each do |type|
60
+ describe "#bootstrap_alert_#{type}_block_tag" do
61
+ before do
62
+ @output_buffer = ''
63
+ end
64
+
65
+ it "has alert class" do
66
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
67
+ output_buffer.should have_tag("div.alert")
68
+ end
69
+
70
+ it "has alert-block class" do
71
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
72
+ output_buffer.should have_tag("div.alert-block")
73
+ end
74
+
75
+ it "has alert-#{type} class" do
76
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
77
+ output_buffer.should have_tag("div.alert-#{type}")
78
+ end
79
+
80
+ it "has a message" do
81
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
82
+ output_buffer.should have_tag('div', /Message/)
83
+ end
84
+
85
+ it "has close button" do
86
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
87
+ output_buffer.should have_tag('div a.close', /×/)
88
+ end
89
+
90
+ it "has dismiss tag" do
91
+ concat send("bootstrap_alert_#{type}_block_tag", "Message")
92
+ output_buffer.should have_tag('div a[data-dismiss="alert"]')
93
+ end
94
+
95
+ it "has a heading" do
96
+ concat send("bootstrap_alert_#{type}_block_tag", "Message", :heading => "Heading1")
97
+ output_buffer.should have_tag('div h4.alert-heading', /Heading1/)
98
+ end
99
+ end
100
+
101
+ describe "#bootstrap_alert_#{type}_tag" do
102
+ before do
103
+ @output_buffer = ''
104
+ end
105
+
106
+ it "has alert class" do
107
+ concat send("bootstrap_alert_#{type}_tag", "Message")
108
+ output_buffer.should have_tag("div.alert")
109
+ end
110
+
111
+ it "has alert-#{type} class" do
112
+ concat send("bootstrap_alert_#{type}_tag", "Message")
113
+ output_buffer.should have_tag("div.alert-#{type}")
114
+ end
115
+
116
+ it "has a message" do
117
+ concat send("bootstrap_alert_#{type}_tag", "Message")
118
+ output_buffer.should have_tag('div', /Message/)
119
+ end
120
+
121
+ it "has close button" do
122
+ concat send("bootstrap_alert_#{type}_tag", "Message")
123
+ output_buffer.should have_tag('div a.close', /×/)
124
+ end
125
+
126
+ it "has dismiss tag" do
127
+ concat send("bootstrap_alert_#{type}_tag", "Message")
128
+ output_buffer.should have_tag('div a[data-dismiss="alert"]')
129
+ end
130
+
131
+ it "has a heading" do
132
+ concat send("bootstrap_alert_#{type}_tag", "Message", :heading => "Heading1")
133
+ output_buffer.should have_tag('div strong', /Heading1/)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Twitter::Bootstrap::Markup::Rails::Helpers::ButtonHelpers do
5
+ include BootstrapSpecHelper
6
+ include BootstrapButtonMacros
7
+
8
+ describe "#bootstrap_button" do
9
+ before do
10
+ @output_buffer = ''
11
+ end
12
+
13
+ it "should create a button with the btn class" do
14
+ concat bootstrap_button("Text", "#")
15
+ output_buffer.should have_tag('a.btn')
16
+ end
17
+
18
+ it "should have text" do
19
+ concat bootstrap_button("Text", "#")
20
+ output_buffer.should have_tag('a', /Text/)
21
+ end
22
+
23
+ it "should link to the specified url" do
24
+ concat bootstrap_button("Text", "http://example.test")
25
+ output_buffer.should have_tag("a[href='http://example.test']")
26
+ end
27
+
28
+ it "should have disabled class when :disabled is true" do
29
+ concat bootstrap_button("Text", "#", :disabled => true)
30
+ output_buffer.should have_tag("a.disabled")
31
+ end
32
+
33
+ it "should add an additional class when :type is a string" do
34
+ concat bootstrap_button("Text", "#", :type => 'test')
35
+ output_buffer.should have_tag("a.test")
36
+ end
37
+
38
+ it "should add additional classes when :type is an array" do
39
+ concat bootstrap_button("Text", "#", :type => ['test1', 'test2'])
40
+ output_buffer.should have_tag("a.test1")
41
+ output_buffer.should have_tag("a.test2")
42
+ end
43
+
44
+ it "should add an icon when :icon is specified" do
45
+ concat bootstrap_button("Text", "#", :icon => 'icon-search')
46
+ output_buffer.should have_tag("a.btn i.icon-search")
47
+ end
48
+
49
+ it "should add a white icon when :icon_white is true" do
50
+ concat bootstrap_button("Text", "#", :icon => 'icon-search', :icon_white => true)
51
+ output_buffer.should have_tag("a.btn i.icon-search")
52
+ output_buffer.should have_tag("a.btn i.icon-white")
53
+ end
54
+
55
+ it "should add an id when :id is specified" do
56
+ concat bootstrap_button("Text", "#", :id => "foo")
57
+ output_buffer.should have_tag("a#foo")
58
+ end
59
+
60
+ it "should add html_options to the resulting a tag when specified" do
61
+ concat bootstrap_button("Text", "#", :html_options => {:target => "_top"})
62
+ output_buffer.should have_tag("a[target='_top']")
63
+ end
64
+ end
65
+
66
+
67
+ describe "#bootstrap_button_dropdown" do
68
+ before do
69
+ @output_buffer = ''
70
+ end
71
+
72
+ it "should create a dropdown button when called with a button and one (or more) links" do
73
+ build_bootstrap_button_dropdown do |d|
74
+ d.bootstrap_button "Button Text", "#"
75
+ d.link_to "Link Text", "#"
76
+ end
77
+
78
+ output_buffer.should have_tag('div.btn-group') do |div|
79
+ div.should have_tag('a.btn')
80
+ div.should have_tag('ul.dropdown-menu a')
81
+ end
82
+ end
83
+
84
+ it "should properly merge html_options into the container div" do
85
+ build_bootstrap_button_dropdown(:html_options => {:id => "foo"}) do |d|
86
+ d.bootstrap_button "Button Text", "#"
87
+ d.link_to "This", "#"
88
+ end
89
+
90
+ output_buffer.should have_tag('div.btn-group#foo')
91
+ end
92
+
93
+ it "should properly add classes from html_options onto the container div" do
94
+ build_bootstrap_button_dropdown(:html_options => {:class => "foo"}) do |d|
95
+ d.bootstrap_button "Button Text", "#"
96
+ d.link_to "This", "#"
97
+ end
98
+
99
+ output_buffer.should have_tag('div.btn-group.foo')
100
+ end
101
+ end
102
+ end