bh 1.0.1 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 391d2887c75ed952c021d758e428f486de5f5f15
4
- data.tar.gz: 15037d24fab141aaf1d7623e39aad31e44312197
3
+ metadata.gz: a6f8f3688bcb37ed7b85baa2a23cd0182d8733bf
4
+ data.tar.gz: 67f60fe7a5e89f1e6c8cb985521f3d0b14ed145a
5
5
  SHA512:
6
- metadata.gz: b525dc2a2c86b8952d65e078e808a39e3c3cfa8eaa25d3b2d4fac61bb8a412594375a367cc3478d6d0b79a35c8b1ab2a3decd688c356cc0dfd5ddafce0596ccf
7
- data.tar.gz: 5acccce283c5abaae55615bb02c3fece400ffac531c94456cd334893bfa2f1bef71e55949b8faf7d0245c133f6160bebd89bb14f1ca046baa0780b7be3721b72
6
+ metadata.gz: 090b4c224d5b115d9f861f5a67b53ab56ba70be1a009d1496dcf6a50a41d64079865bbec9f1e604774b1cef9726bedee877ca68384b118213a8c02d03a0356f4
7
+ data.tar.gz: eb42afcf33bcab3e145c3f6f1bf7690f260b922e8bdd690e4b50480ea5911da26b2b03709f975ba7cc78a38e3f7fb73ae06d800b2daa4b312275ec2ae5574599
data/.gitignore CHANGED
@@ -20,5 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  _site/
23
- spec/dummy
24
23
  mkmf.log
@@ -0,0 +1,2 @@
1
+ --no-private
2
+ --markup markdown
@@ -6,6 +6,15 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 1.1.0 - 2014-09-20
10
+
11
+ * [FEATURE] Add `icon` helper
12
+ * [FEATURE] Add `font_awesome_css` helper
13
+ * [FEATURE] Add `dropdown` helper
14
+ * [FEATURE] Add `progress_bar` helper
15
+ * [ENHANCEMENT] Add `:fieldset` option to decide whether `fields_for` should wrap fields in a <fieldset> tag
16
+ * [FEATURE] Add `button` helper
17
+
9
18
  ## 1.0.1 - 2014-09-14
10
19
 
11
20
  * [BUGFIX] Remove `form-control` class from `file_field` (#20)
data/README.md CHANGED
@@ -55,7 +55,7 @@ How to install
55
55
 
56
56
  Bh is meant to be included in Rails apps by adding this line to the Gemfile:
57
57
 
58
- gem 'bh', '~> 1.0'
58
+ gem 'bh', '~> 1.1'
59
59
 
60
60
  Since the gem follows [Semantic Versioning](http://semver.org), indicating the
61
61
  version number in your Gemfile in the *'~> major.minor'* format guarantees
@@ -92,7 +92,7 @@ document the changes in CHANGELOG.md and README.md, bump the version, then run
92
92
 
93
93
  Remember that the bh gem follows [Semantic Versioning](http://semver.org).
94
94
 
95
- Any new release that makes backward-compatible bug fixes should bump the *patch* version (1.0.x).
95
+ Any new release that makes backward-compatible bug fixes should bump the *patch* version (1.1.x).
96
96
 
97
97
  Any new release that adds backward-compatible features should bump the *minor* version (1.x.0).
98
98
 
@@ -107,7 +107,11 @@ If you find that a method is missing, fork the project, add the missing code,
107
107
  write the appropriate tests, then submit a pull request, and it will gladly
108
108
  be merged!
109
109
 
110
- To run the tests, simply type `rspec` on the command line.
110
+ To run the tests, simply type `bundle exec rspec` on the command line.
111
+
112
+ To see the HTML generated by helpers in a browser,
113
+ edit the [spec/dummy/index.html file](https://github.com/claudiob/bh/blob/master/spec/dummy/index.html),
114
+ then type `bundle exec middleman` and point your browser to [http://0.0.0.0:4567](http://0.0.0.0:4567).
111
115
 
112
116
  Don’t hesitate to send code comments, issues or pull requests through GitHub
113
- and to spread the love. Thanks! :)
117
+ and to spread the love. And [don’t click here](http://bit.ly/move-to-la)! Thanks! :)
data/bh.gemspec CHANGED
@@ -31,4 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'yard' #, '~> 0.8.0'
32
32
  spec.add_development_dependency 'coveralls' #, '~> 0.7.0'
33
33
  spec.add_development_dependency 'activemodel'
34
+
35
+ # For spec/dummy
36
+ spec.add_development_dependency 'middleman-core' #, '~> 3.3.5'
34
37
  end
@@ -0,0 +1,6 @@
1
+ # If you are developing new helpers and want a quick way to see them in
2
+ # a browser, type `bundle exec middleman` and browse to http://localhost:4567
3
+ # The browser will show the interpolated content of spec/dummy/index.html.erb
4
+ # which you are free to edit as you please to display new helpers.
5
+ set :source, 'spec/dummy'
6
+ activate :bh
data/lib/bh.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bh/railtie' if defined?(Rails)
2
+ require 'bh/middleman' if defined?(Middleman)
2
3
 
3
4
  # Adds Bootstrap styles to Rails helpers
4
5
  module Bh
@@ -49,12 +49,8 @@ module Bh
49
49
  end
50
50
 
51
51
  def alert_class(context = nil)
52
- context = case context.to_s
53
- when 'success', 'notice' then :success
54
- when 'warning' then :warning
55
- when 'danger', 'alert' then :danger
56
- else 'info'
57
- end
52
+ valid_contexts = %w(success info warning danger)
53
+ context = context_for context, default: 'info', valid: valid_contexts
58
54
  "alert alert-#{context}"
59
55
  end
60
56
 
@@ -21,5 +21,19 @@ module Bh
21
21
  block_given? ? args[1] = html_options : args[2] = html_options
22
22
  args
23
23
  end
24
+
25
+ def context_for(context = nil, options = {})
26
+ context = case context.to_s
27
+ when 'notice' then 'success'
28
+ when 'alert' then 'danger'
29
+ else context.to_s
30
+ end
31
+
32
+ if options.fetch(:valid, []).map(&:to_s).include? context
33
+ context
34
+ else
35
+ options.fetch :default, 'default'
36
+ end
37
+ end
24
38
  end
25
39
  end
@@ -0,0 +1,63 @@
1
+ require 'bh/helpers/base_helper'
2
+
3
+ module Bh
4
+ # Provides methods to include buttons.
5
+ # @see http://getbootstrap.com/components/#buttons
6
+ module ButtonHelper
7
+ include BaseHelper
8
+
9
+ # Returns an HTML block tag that follows the Bootstrap documentation
10
+ # on how to display *buttons*.
11
+ #
12
+ # The content of the button can either be passed as the first parameter (in
13
+ # which case, the options are the second parameter), or as a block (in
14
+ # which case, the options are the first paramter).
15
+ # @example An button with plain-text content passed as the first parameter.
16
+ # <%= button 'Your profile was updated!', context: :info %>
17
+ # @example A button with HTML content passed as a block.
18
+ # <%= button context: :info %>
19
+ # <%= glyphicon :star %> Star
20
+ # <% end %>
21
+ #
22
+ # @return [String] an HTML block tag for a button.
23
+ # @param [String] content_or_options_with_block the content to display in
24
+ # the button.
25
+ # @param [Hash] options the display options for the button.
26
+ # @option options [#to_s] :context (:default) the contextual alternative to
27
+ # apply to the button depending on its importance. Can be :default,
28
+ # :primary, :success, :info, :warning, :danger or :link.
29
+ # @option options [#to_s] :size the size of the button.
30
+ # @option options [#to_s] :layout if set to :block, span the button for
31
+ # the full width of the parent.
32
+ def button(content_or_options_with_block = nil, options = nil, &block)
33
+ if block_given?
34
+ button_string capture(&block), content_or_options_with_block || {}
35
+ else
36
+ button_string content_or_options_with_block, options || {}
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def button_string(content = nil, options = {})
43
+ append_class! options, btn_class(options)
44
+ content_tag :button, content, options
45
+ end
46
+
47
+ def btn_class(options = {})
48
+ valid_contexts = %w(primary success info warning danger link)
49
+ context = context_for options.delete(:context), valid: valid_contexts
50
+ "btn btn-#{context}"
51
+
52
+ size = case options.delete(:size).to_s
53
+ when 'lg', 'large' then 'btn-lg'
54
+ when 'sm', 'small' then 'btn-sm'
55
+ when 'xs', 'extra_small' then 'btn-xs'
56
+ end
57
+
58
+ layout = 'btn-block' if options.delete(:layout).to_s == 'block'
59
+
60
+ ['btn', "btn-#{context}", size, layout].compact.join ' '
61
+ end
62
+ end
63
+ end
@@ -21,6 +21,16 @@ module Bh
21
21
  bootstrap_asset options.merge(name: 'bootstrap-theme', extension: 'css')
22
22
  end
23
23
 
24
+ # @return [String] the URL of the Font Awesome CSS file
25
+ # @param [Hash] options the options for which CSS file to retrieve.
26
+ # @option options [String] :version the version of Font Awesome.
27
+ # @option options [String] :scheme the URI scheme to use.
28
+ # @option options [Boolean] :minified whether to use the minified version.
29
+ # @see http://fontawesome.io/get-started/
30
+ def font_awesome_css(options = {})
31
+ font_awesome_asset options.merge(name: 'font-awesome', extension: 'css')
32
+ end
33
+
24
34
  # @return [String] the URL of the Bootstrap JS file
25
35
  # @param [Hash] options the options for which JS file to retrieve.
26
36
  # @option options [String] :version the version of Bootstrap.
@@ -32,19 +42,29 @@ module Bh
32
42
 
33
43
  private
34
44
 
35
- # @return [String] the version of Bootstrap assets to use if unspecified.
36
- def bootstrap_version
37
- '3.2.0'
45
+ # @note if unspecified, the version should match the latest available
46
+ # version. If that's not the case, it's a bug and should be fixed.
47
+ def bootstrap_asset(options = {})
48
+ options[:version] ||= '3.2.0'
49
+ cdn_asset options.merge(library: 'bootstrap')
38
50
  end
39
51
 
40
- def bootstrap_asset(options = {})
41
- version = options.fetch :version, bootstrap_version
52
+ # @note if unspecified, the version should match the latest available
53
+ # version. If that's not the case, it's a bug and should be fixed.
54
+ def font_awesome_asset(options = {})
55
+ options[:version] ||= '4.2.0'
56
+ cdn_asset options.merge(library: 'font-awesome')
57
+ end
58
+
59
+ def cdn_asset(options = {})
60
+ version = options[:version]
42
61
  extension = options[:extension]
43
62
  name = options[:name]
63
+ library = options[:library]
44
64
  name = "#{name}.min" if options.fetch(:minified, true)
45
65
  scheme = "#{options[:scheme]}:" if options[:scheme]
46
66
  host = '//netdna.bootstrapcdn.com'
47
- "#{scheme}#{host}/bootstrap/#{version}/#{extension}/#{name}.#{extension}"
67
+ "#{scheme}#{host}/#{library}/#{version}/#{extension}/#{name}.#{extension}"
48
68
  end
49
69
  end
50
70
  end
@@ -0,0 +1,82 @@
1
+ require 'bh/helpers/base_helper'
2
+
3
+ module Bh
4
+ # Provides methods to include dropdowns.
5
+ # @see http://getbootstrap.com/components/#dropdowns
6
+ # @see http://getbootstrap.com/components/#btn-dropdowns
7
+ module DropdownHelper
8
+ include BaseHelper
9
+
10
+ # Returns an HTML block tag that follows the Bootstrap documentation
11
+ # on how to display *dropdowns*.
12
+ #
13
+ # The skeleton of the dropdown is an unordered list; its content is passed
14
+ # as block to the list of dropdown items.
15
+ # Since the most common use for a dropdown is to display a menu of links, a
16
+ # variable is set inside the block so that every call to +link_to+
17
+ # generates a link *surrounded by a list item* and with the appropriate
18
+ # menu item attributes.
19
+ # @example A right-aligned dropdown with two links.
20
+ # <%= dropdown 'Menu', align: :right do %>
21
+ # <%= link_to 'Home', '/' %>
22
+ # <%= link_to 'Profile', '/profile' %>
23
+ # <% end %>
24
+ #
25
+ # @return [String] an HTML block tag for a dropdown.
26
+ # @param [#to_s] caption the caption for the dropdown button.
27
+ # @param [Hash] options the display options for the dropdown.
28
+ # @option options [Boolean] :groupable (true) if true, uses the "btn-group"
29
+ # class rather than then "dropdown" class, so that multiple dropdown
30
+ # buttons can be aligned in the same row (as a group of buttons).
31
+ # @option options [Boolean] :split (false) if true, creates a split button
32
+ # that only toggles the dropdown when clicked on the rightmost part.
33
+ # @option options [#to_s] :direction if set to :up, the dropdown appears
34
+ # above the button, rather than below.
35
+ # @option options [#to_s] :align if set to :right, the dropdown is aligned
36
+ # to the right-end of the button, rather than to the left-end.
37
+ # @option options [#to_s] :context (:default) the context for the button,
38
+ # which determines its color.
39
+ # @option options [#to_s] :size the size of the button.
40
+ # @yield block the content of the dropdown
41
+ # @see http://getbootstrap.com/components/#dropdowns
42
+ # @see http://getbootstrap.com/components/#btn-dropdowns
43
+ def dropdown(caption, options = {}, &block)
44
+ options ||= {}
45
+ options[:id] ||= "dropdown-#{rand 10**10}"
46
+ options[:caption] = caption
47
+ options[:div_class] = dropdown_div_class options
48
+ options[:button_class] = dropdown_button_class options
49
+ options[:list_class] = dropdown_list_class options
50
+ layout = options[:split] ? 'bh/dropdown_split' : 'bh/dropdown'
51
+ @dropdown_link = true
52
+ dropdown = render layout: layout, locals: options, &block
53
+ dropdown.tap{ @dropdown_link = false }
54
+ end
55
+
56
+ private
57
+
58
+ def dropdown_div_class(options = {})
59
+ group = options.fetch(:groupable, true) ? 'btn-group' : 'dropdown'
60
+ direction = 'dropup' if options[:direction].to_s == 'up'
61
+ [group, direction].compact.join ' '
62
+ end
63
+
64
+ def dropdown_list_class(options = {})
65
+ align = 'dropdown-menu-right' if options[:align].to_s == 'right'
66
+ ['dropdown-menu', align].compact.join ' '
67
+ end
68
+
69
+ def dropdown_button_class(options = {})
70
+ valid_contexts = %w(primary success info warning danger link)
71
+ context = context_for options[:context], valid: valid_contexts
72
+
73
+ size = case options[:size].to_s
74
+ when 'lg', 'large' then 'btn-lg'
75
+ when 'sm', 'small' then 'btn-sm'
76
+ when 'xs', 'extra_small' then 'btn-xs'
77
+ end
78
+
79
+ ['btn', "btn-#{context}", size].compact.join ' '
80
+ end
81
+ end
82
+ end
@@ -14,7 +14,9 @@ module Bh
14
14
  fields_options[:layout] ||= @options[:layout]
15
15
  fields_options[:errors] ||= @options[:errors]
16
16
  title = fields_options.delete(:title) { record_name.to_s.humanize }
17
- fieldset(title) { super record_name, record_object, fields_options, &block }
17
+ wrap_in_fieldset = fields_options.fetch :fieldset, true
18
+ fields = super record_name, record_object, fields_options, &block
19
+ wrap_in_fieldset ? fieldset(title) { fields } : fields
18
20
  end
19
21
  end
20
22
  end
@@ -1,24 +1,24 @@
1
- require 'bh/helpers/base_helper'
1
+ require 'bh/helpers/icon_helper'
2
2
 
3
3
  module Bh
4
4
  # Provides methods to include Glyphicons.
5
5
  # @see http://getbootstrap.com/components/#glyphicons
6
6
  module GlyphiconHelper
7
- include BaseHelper
7
+ include IconHelper
8
8
 
9
9
  # Returns an HTML block tag that follows the Bootstrap documentation
10
10
  # on how to display *glyphicons*.
11
11
  # @return [String] an HTML block tag for a glyphicon.
12
- # @param [#to_s] the name of the icon to display, with either dashes or
13
- # underscores to separate multiple words.
12
+ # @param [#to_s] name the name of the icon to display, with either dashes
13
+ # or underscores to separate multiple words.
14
+ # @param [Hash] options the options passed to the HTML tag that displays
15
+ # the icon.
14
16
  # @example Display the "zoom in" glyphicon
15
17
  # glyphicon :zoom_in
16
18
  # @example Display the "zoom out" glyphicon
17
19
  # glyphicon 'zoom-out'
18
20
  def glyphicon(name = nil, options = {})
19
- append_class! options, 'glyphicon'
20
- append_class! options, "glyphicon-#{name.to_s.gsub '_', '-'}" if name
21
- content_tag :span, nil, options
21
+ icon name, options.merge(library: :glyphicons)
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,41 @@
1
+ require 'bh/helpers/base_helper'
2
+
3
+ module Bh
4
+ # Provides methods to include vector icons from different libraries.
5
+ # @see http://getbootstrap.com/components/#glyphicons
6
+ # @see http://fortawesome.github.io/Font-Awesome/examples/#bootstrap
7
+ module IconHelper
8
+ include BaseHelper
9
+
10
+ # Returns an HTML block tag to display a vector icon.
11
+ # @return [String] an HTML block tag for a vector icon.
12
+ # @param [#to_s] name the name of the icon to display, with either dashes
13
+ # or underscores to separate multiple words.
14
+ # @param [Hash] options the options for the icon tag. The following options
15
+ # are used by the +icon+ method, while the remaining ones are passed
16
+ # to the HTML tag that displays the icon.
17
+ # @option options [#to_s] :library (:glyphicons) the vector icon library
18
+ # to use. Valid values are 'glyphicon', 'glyphicons' (for Glyphicons),
19
+ # 'font-awesome', 'font_awesome' and 'fa' (for Font Awesome).
20
+ # @example Display the "zoom in" glyphicon
21
+ # icon :zoom_in
22
+ # @example Display the "fire" font awesome icon
23
+ # icon 'fire', library: :font_awesome
24
+ def icon(name = nil, options = {})
25
+ prefix = library_prefix_for options.delete(:library)
26
+ append_class! options, prefix
27
+ append_class! options, "#{prefix}-#{name.to_s.gsub '_', '-'}" if name
28
+ content_tag :span, nil, options
29
+ end
30
+
31
+ private
32
+
33
+ def library_prefix_for(name)
34
+ case name.to_s.underscore
35
+ when 'font_awesome' then :fa
36
+ when '', 'glyphicons' then :glyphicon
37
+ else name
38
+ end
39
+ end
40
+ end
41
+ end
@@ -12,10 +12,19 @@ module Bh
12
12
  # Overrides ActionView +link_to+ to be able to add the 'navbar-brand'
13
13
  # class to the link in case the link is inside of an alert.
14
14
  def link_to(*args, &block)
15
- args = add_link_class!('alert-link', *args, &block) if @alert_link
16
- args = add_link_class!('navbar-brand', *args, &block) if @navbar_vertical
17
- link = super *args, &block
18
- @nav_link ? content_tag(:li, link, nav_list_item_options(*args, &block)) : link
15
+ if @alert_link
16
+ super *add_link_class!('alert-link', *args, &block), &block
17
+ elsif @navbar_vertical
18
+ super *add_link_class!('navbar-brand', *args, &block), &block
19
+ elsif @dropdown_link
20
+ content_tag :li, role: :presentation do
21
+ super *add_menu_item_attributes!(*args, &block), &block
22
+ end
23
+ elsif @nav_link
24
+ content_tag :li, super(*args, &block), nav_item_options(*args, &block)
25
+ else
26
+ super *args, &block
27
+ end
19
28
  end
20
29
 
21
30
  private
@@ -24,9 +33,16 @@ module Bh
24
33
  append_class_as! :class, new_class, *args, &block
25
34
  end
26
35
 
27
- def nav_list_item_options(*args, &block)
36
+ def nav_item_options(*args, &block)
28
37
  options = (block_given? ? args[0] : args[1]) || {}
29
38
  {class: 'active'} if current_page? options
30
39
  end
40
+
41
+ def add_menu_item_attributes!(*args, &block)
42
+ html_options = (block_given? ? args[1] : args[2]) || {}
43
+ html_options.reverse_merge! role: 'menuitem', tabindex: '-1'
44
+ block_given? ? args[1] = html_options : args[2] = html_options
45
+ args
46
+ end
31
47
  end
32
48
  end