bootstrap5_helper 1.0.0 → 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.
@@ -0,0 +1,34 @@
1
+ module Bootstrap5Helper
2
+ # Builds a Dropdown component that can be used in other components.
3
+ #
4
+ #
5
+ class Dropup < Overlay
6
+ # Class constructor
7
+ #
8
+ # @overload initialize(template, tag, opts)
9
+ # @param [ActionView] template
10
+ # @param [Symbol|String] tag - The HTML element to use to wrap the component.
11
+ # @param [Hash] opts
12
+ # @option opts [String] :id
13
+ # @option opts [String] :class
14
+ # @option opts [Hash] :data
15
+ # @option opts [Boolea] :split
16
+ # @option opts [Boolean] :centered
17
+ #
18
+ # @overload initialize(template, opts)
19
+ # @param [ActionView] template
20
+ # @param [Hash] opts
21
+ # @option opts [String] :id
22
+ # @option opts [String] :class
23
+ # @option opts [Hash] :data
24
+ # @option opts [Boolea] :split
25
+ # @option opts [Boolean] :centered
26
+ #
27
+ # @return [Dropup]
28
+ #
29
+ def initialize(template, *tag_or_options, &block)
30
+ super(template, *tag_or_options, &block)
31
+ @type = :dropup
32
+ end
33
+ end
34
+ end
@@ -27,7 +27,7 @@ module Bootstrap5Helper
27
27
  @scrollable = opts.fetch(:scrollable, false)
28
28
  @vcentered = opts.fetch(:vcentered, false)
29
29
  @static = opts.fetch(:static, false)
30
- @fullscreen = opts.fetch(:fullscreen, true)
30
+ @fullscreen = opts.fetch(:fullscreen, false)
31
31
  @size = opts.fetch(:size, nil)
32
32
  @content = block || proc { '' }
33
33
  end
@@ -208,12 +208,12 @@ module Bootstrap5Helper
208
208
  # @return [String]
209
209
  #
210
210
  def size
211
- case @size
212
- when :xlarge
211
+ case @size.to_s
212
+ when 'xlarge', 'xl'
213
213
  'modal-xl'
214
- when :large
214
+ when 'large', 'lg'
215
215
  'modal-lg'
216
- when :small
216
+ when 'small', 'sm'
217
217
  'modal-sm'
218
218
  else
219
219
  ''
@@ -11,20 +11,20 @@ module Bootstrap5Helper
11
11
  # @option opts [String] :id
12
12
  # @option opts [String] :class
13
13
  # @option opts [Hash] :data
14
- # @option opts [Hash] :child
14
+ # @option opts [Array] :dropdown
15
+ # @option opts []
15
16
  #
16
- def initialize(template, tag_or_options = nil, opts = {}, &block)
17
+ def initialize(template, *tag_or_options, &block)
17
18
  super(template)
18
19
 
19
- @tag, args = parse_tag_or_options(tag_or_options, opts)
20
+ @tag, args = parse_tag_or_options(*tag_or_options, {})
20
21
  @tag ||= config({ navs: :base }, :ul)
21
22
 
22
- @id = args.fetch(:id, uuid)
23
- @class = args.fetch(:class, '')
24
- @data = args.fetch(:data, {})
25
- @child = args.fetch(:child, {})
26
- @content = block || proc { '' }
27
-
23
+ @id = args.fetch(:id, uuid)
24
+ @class = args.fetch(:class, '')
25
+ @data = args.fetch(:data, {})
26
+ @child = args.fetch(:child, {})
27
+ @content = block || proc { '' }
28
28
  @dropdown = Dropdown.new(@template)
29
29
  end
30
30
 
@@ -78,6 +78,8 @@ module Bootstrap5Helper
78
78
  end
79
79
  end
80
80
 
81
+ # rubocop:disable Metrics/MethodLength
82
+
81
83
  # Creates a dropdown menu for the nav.
82
84
  #
83
85
  # @param [NilClass|Symbol|String] name
@@ -91,21 +93,24 @@ module Bootstrap5Helper
91
93
  def dropdown(name, opts = {}, &block)
92
94
  id = opts.fetch(:id, nil)
93
95
  klass = opts.fetch(:class, '')
94
- data = opts.fetch(:data, {})
96
+ data = opts.fetch(:data, {}).merge('bs-toggle' => 'dropdown')
95
97
  aria = opts.fetch(:aria, {}).merge(haspopup: true, expanded: false)
96
98
 
99
+ data.merge!('bs-display' => 'static') if @child[:data]&.key?('bs-display')
100
+
97
101
  nav_item_wrapper id: id, class: 'dropdown', data: data do
98
102
  content_tag(
99
103
  :a,
100
104
  name,
101
105
  class: "nav-link dropdown-toggle #{klass}",
102
106
  href: '#',
103
- data: { 'bs-toggle' => 'dropdown' },
107
+ data: data,
104
108
  role: 'button',
105
109
  aria: aria
106
110
  ) + @dropdown.menu(opts, &block).to_s.html_safe
107
111
  end
108
112
  end
113
+ # rubocop:enable Metrics/MethodLength
109
114
 
110
115
  # String representation of the object.
111
116
  #
@@ -119,7 +124,7 @@ module Bootstrap5Helper
119
124
 
120
125
  private
121
126
 
122
- # Decorator for elements require a wrapper component.
127
+ # Decorator for elements requiring a wrapper component.
123
128
  #
124
129
  # @return [String]
125
130
  #
@@ -19,6 +19,7 @@ module Bootstrap5Helper
19
19
  @aria = opts.fetch(:aria, {})
20
20
  @scrollable = opts.fetch(:scrollable, false)
21
21
  @position = opts.fetch(:position, 'start')
22
+ @backdrop = opts.fetch(:backdrop, true)
22
23
  @content = block || proc { '' }
23
24
  end
24
25
 
@@ -1,28 +1,30 @@
1
1
  module Bootstrap5Helper
2
- class Dropdown
2
+ class Overlay
3
3
  # Builds a menu component for use in dropdowns.
4
4
  #
5
5
  #
6
6
  class Menu < Component
7
7
  # Class constructor
8
8
  #
9
- # @param [ActionView] template
10
- # @param [Hash] opts
9
+ # @param [ActionView] template
10
+ # @param [Symbol|Hash] tag_or_options
11
+ # @param [Hash] opts
11
12
  # @option opts [String] :id
12
13
  # @option opts [String] :class
13
14
  # @option opts [Hash] :data
14
15
  #
15
- def initialize(template, opts = {}, &block)
16
+ def initialize(template, *tag_or_options, &block)
16
17
  super(template)
17
18
 
18
- @id = opts.fetch(:id, uuid)
19
- @class = opts.fetch(:class, '')
20
- @data = opts.fetch(:data, {})
21
- @content = block || proc { '' }
19
+ @tag, opts = parse_tag_or_options(*tag_or_options, {})
20
+ @id = opts.fetch(:id, uuid)
21
+ @class = opts.fetch(:class, '')
22
+ @data = opts.fetch(:data, {})
23
+ @content = block || proc { '' }
22
24
  end
23
25
 
24
- # Use this method when the `item`, `link` in the item in the menu is nothing
25
- # more than a hyperlink.
26
+ # Use this method when the menu `item` is nothing more than a
27
+ # hyperlink.
26
28
  #
27
29
  # @param [String] name
28
30
  # @param [Hash] options
@@ -33,11 +35,15 @@ module Bootstrap5Helper
33
35
  html_options ||= {}
34
36
  html_options[:class] = (html_options[:class] || '') << ' dropdown-item'
35
37
 
36
- @template.link_to(name, options, html_options, &block)
38
+ nav_item_wrapper do
39
+ @template.link_to(name, options, html_options, &block)
40
+ end
37
41
  end
38
42
 
39
- # Use this method when you are using the item in the menu as trigger for tab
40
- # content.
43
+ # rubocop:disable Metrics/MethodLength
44
+
45
+ # Use this method when you are using the item in the menu as trigger for
46
+ # something like tab content.
41
47
  #
42
48
  # @param [Symbol|String] target
43
49
  # @param [Hash] opts
@@ -53,17 +59,20 @@ module Bootstrap5Helper
53
59
  data = opts.fetch(:data, {}).merge('bs-toggle' => 'tab')
54
60
  aria = opts.fetch(:aria, {})
55
61
 
56
- content_tag(
57
- :a,
58
- id: id,
59
- class: "dropdown-item #{klass}",
60
- href: "##{target}",
61
- aria: aria,
62
- data: data
63
- ) do
64
- block_given? ? yield : target.to_s.titleize
62
+ nav_item_wrapper do
63
+ content_tag(
64
+ :a,
65
+ id: id,
66
+ class: "dropdown-item #{klass}",
67
+ href: "##{target}",
68
+ aria: aria,
69
+ data: data
70
+ ) do
71
+ block_given? ? yield : target.to_s.titleize
72
+ end
65
73
  end
66
74
  end
75
+ # rubocop:enable Metrics/MethodLength
67
76
 
68
77
  # Builds a Text component
69
78
  #
@@ -75,13 +84,15 @@ module Bootstrap5Helper
75
84
  # @return [String]
76
85
  #
77
86
  def text(text, opts = {}, &block)
78
- build_sub_component(
79
- config({ dropdown_menus: :text }, :span),
80
- text,
81
- 'item-text',
82
- opts,
83
- &block
84
- )
87
+ nav_item_wrapper do
88
+ build_sub_component(
89
+ config({ overlay_menus: :text }, :span),
90
+ text,
91
+ 'item-text',
92
+ opts,
93
+ &block
94
+ )
95
+ end
85
96
  end
86
97
 
87
98
  # Builds a Header component
@@ -94,13 +105,15 @@ module Bootstrap5Helper
94
105
  # @return [String]
95
106
  #
96
107
  def header(text, opts = {}, &block)
97
- build_sub_component(
98
- config({ dropdown_menus: :header }, :h6),
99
- text,
100
- 'header',
101
- opts,
102
- &block
103
- )
108
+ nav_item_wrapper do
109
+ build_sub_component(
110
+ config({ overlay_menus: :header }, :h6),
111
+ text,
112
+ 'header',
113
+ opts,
114
+ &block
115
+ )
116
+ end
104
117
  end
105
118
 
106
119
  # Builds a divider element
@@ -108,11 +121,13 @@ module Bootstrap5Helper
108
121
  # @return [String]
109
122
  #
110
123
  def divider
111
- content_tag(
112
- config({ dropdown_menus: :divider }, :div),
113
- '',
114
- class: 'dropdown-divider'
115
- )
124
+ nav_item_wrapper do
125
+ content_tag(
126
+ config({ overlay_menus: :divider }, :div),
127
+ '',
128
+ class: 'dropdown-divider'
129
+ )
130
+ end
116
131
  end
117
132
 
118
133
  # String representation of the object.
@@ -120,13 +135,31 @@ module Bootstrap5Helper
120
135
  # @return [String]
121
136
  #
122
137
  def to_s
123
- content_tag :div, id: @id, class: "dropdown-menu #{@class}", data: @data do
138
+ content_tag(
139
+ @tag || config({ overlay_menus: :base }, :div),
140
+ id: @id,
141
+ class: "dropdown-menu #{@class}",
142
+ data: @data
143
+ ) do
124
144
  @content.call(self)
125
145
  end
126
146
  end
127
147
 
128
148
  private
129
149
 
150
+ # Decorator for elements requiring a wrapper component.
151
+ #
152
+ # @return [String]
153
+ #
154
+ def nav_item_wrapper(&block)
155
+ case @tag
156
+ when :div, nil
157
+ block.call
158
+ when :ul
159
+ content_tag(:li, &block)
160
+ end
161
+ end
162
+
130
163
  # Used to build specific components.
131
164
  #
132
165
  # @param [Symbol] tag
@@ -0,0 +1,138 @@
1
+ module Bootstrap5Helper
2
+ # Builds a Overlay component that can be used in other components.
3
+ #
4
+ #
5
+ class Overlay < Component
6
+ # Class constructor
7
+ #
8
+ # @overload initialize(template, tag, opts)
9
+ # @param [ActionView] template
10
+ # @param [Symbol|String] tag - The HTML element to use to wrap the component.
11
+ # @param [Hash] opts
12
+ # @option opts [String] :id
13
+ # @option opts [String] :class
14
+ # @option opts [Hash] :data
15
+ # @option opts [Boolean] :centered
16
+ #
17
+ # @overload initialize(template, opts)
18
+ # @param [ActionView] template
19
+ # @param [Hash] opts
20
+ # @option opts [String] :id
21
+ # @option opts [String] :class
22
+ # @option opts [Hash] :data
23
+ # @option opts [Boolean] :centered
24
+ #
25
+ # @return [Overlay]
26
+ #
27
+ def initialize(template, *tag_or_options, &block)
28
+ super(template)
29
+
30
+ @tag, args = parse_tag_or_options(*tag_or_options, {})
31
+ @split = args.fetch(:split, false)
32
+ @centered = args.fetch(:centered, false)
33
+ @id = args.fetch(:id, uuid)
34
+ @class = args.fetch(:class, '')
35
+ @data = args.fetch(:data, {})
36
+
37
+ @content = block || proc { '' }
38
+ end
39
+
40
+ # Used to generate a button for the dropdown. This button just
41
+ # opens the coresponding dropdown menu.
42
+ #
43
+ # @param [Symbol] context
44
+ # @param [Hash] opts
45
+ # @option opts [String] :id
46
+ # @option opts [String] :class
47
+ # @option opts [Hash] :data
48
+ # @return [String]
49
+ #
50
+ def button(context = :primary, opts = {}, &block)
51
+ id = opts.fetch(:id, nil)
52
+ klass = opts.fetch(:class, '')
53
+ data = opts.fetch(:data, {}).merge(
54
+ 'bs-toggle' => 'dropdown',
55
+ 'bs-display' => 'static'
56
+ )
57
+
58
+ content_tag(
59
+ :button,
60
+ id: id,
61
+ type: 'button',
62
+ class: "dropdown-toggle btn btn-#{context} #{klass}",
63
+ data: data,
64
+ aria: { haspopup: true, expanded: false },
65
+ &block
66
+ )
67
+ end
68
+
69
+ # Used to generate a button with just the caret, to open the dropdown.
70
+ #
71
+ # @param [Symbol] context
72
+ # @param [Hash] opts
73
+ # @option opts [String] :id
74
+ # @option opts [String] :class
75
+ # @option opts [Hash] :data
76
+ # @return [String]
77
+ #
78
+ def caret(context = :primary, opts = {})
79
+ id = opts.fetch(:id, nil)
80
+ klass = opts.fetch(:class, '')
81
+ data = opts.fetch(:data, {}).merge('bs-toggle' => 'dropdown')
82
+
83
+ content_tag(
84
+ :button,
85
+ id: id,
86
+ type: 'button',
87
+ class: "dropdown-toggle btn btn-#{context} #{klass} dropdown-toggle-split",
88
+ data: data,
89
+ aria: { haspopup: true, expanded: false }
90
+ ) do
91
+ content_tag(:span, 'Toggle Dropdown', class: 'visually-hidden')
92
+ end
93
+ end
94
+
95
+ # Used to create a new <tt>Dropdown::Menu</tt>
96
+ #
97
+ # @param [Hash] opts
98
+ # @option opts [String] :id
99
+ # @option opts [String] :class
100
+ # @option opts [Hash] :data
101
+ # @yield [Menu]
102
+ # @return [Menu]
103
+ #
104
+ def menu(*tag_or_options, &block)
105
+ Menu.new(@template, *tag_or_options, &block)
106
+ end
107
+
108
+ # String reprentation of the object.
109
+ #
110
+ # @return [String]
111
+ #
112
+ def to_s
113
+ content_tag(
114
+ @tag || :div,
115
+ id: @id,
116
+ class: "#{@type} #{alignment_type_class} #{@class}",
117
+ data: @data
118
+ ) do
119
+ @content.call(self)
120
+ end
121
+ end
122
+
123
+ private
124
+
125
+ # Returns the alignment class for the dropdown component.
126
+ #
127
+ # @return [String]
128
+ #
129
+ def alignment_type_class
130
+ case @type
131
+ when :dropdown, :dropup
132
+ @centered ? "#{@type}-center" : ''
133
+ else
134
+ ''
135
+ end
136
+ end
137
+ end
138
+ end
@@ -24,14 +24,26 @@ module Bootstrap5Helper
24
24
 
25
25
  # Builds a custom Nav component for the tabs.
26
26
  #
27
- # @param [Symbol|Hash] tag_or_options
28
- # @param [Hash] opts
29
- # @option opts [String] :class
30
- # @option opts [Hash] :data
27
+ # @overload nav(tag, opts)
28
+ # @param [Symbol|String] tag - :nav, :ul
29
+ # @param [Hash] opts
30
+ # @option opts [String] :id
31
+ # @option opts [String] :class
32
+ # @option opts [Hash] :data
33
+ # @option opts [Hash] :child - data attributes for child, NOT wrapper
34
+ #
35
+ # @overload nav(opts)
36
+ # @param [Hash] opts
37
+ # @option opts [String] :id
38
+ # @option opts [String] :class
39
+ # @option opts [Hash] :data
40
+ # @option opts [Hash] :child - data attributes for child, NOT wrapper
41
+ #
42
+ # @yield [Nav]
31
43
  # @return [Nav]
32
44
  #
33
- def nav(tag_or_options = nil, opts = {}, &block)
34
- tag, args = parse_tag_or_options(tag_or_options, opts)
45
+ def nav(*tag_or_options, &block)
46
+ tag, args = parse_tag_or_options(*tag_or_options, {})
35
47
 
36
48
  args[:class] = (args[:class] || '') << " nav-#{@type}"
37
49
  args[:data] = (args[:data] || {}).merge('bs-toggle' => 'tab')
@@ -1,3 +1,3 @@
1
1
  module Bootstrap5Helper
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end