bootstrap5_helper 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d1dd8831d61ec067033a1681a8b91fb1b867fd55f06d36f71aa52488d1733bbf
4
+ data.tar.gz: b5ebdbdedc4454e8de46cf5f871159d671e66e631c660bc58f8046d82f6c5871
5
+ SHA512:
6
+ metadata.gz: 4b89389edc7232c9382e4889ddf8685b8ccf3b1057ae0e0a7a0281126c3046d51560b08f7da716a3c9d03b0eccb9b53ad531d57054e128ebce54bd16b4032a87
7
+ data.tar.gz: ce51660eca95ab8e0d1017eed62493cfdc4b048cd718f5728ea921e9dd9d91ef796a1550d0058c814d3759703cd33eb5f6e00b365b052cd901bd9f72fa910bc2
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Robert David
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,506 @@
1
+ # Bootstrap5Helper
2
+
3
+ Short description and motivation.
4
+
5
+ ## Usage
6
+
7
+ How to use my plugin.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem "bootstrap5_helper"
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```bash
20
+ $ bundle
21
+ ```
22
+
23
+ Or install it yourself as:
24
+
25
+ ```bash
26
+ $ gem install bootstrap5_helper
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ All of the helpers will be available inside your views. If you wish to stop that behavior and only include the helpers on the views of your choosing, pass the following to the `config` object in a intializer:
32
+
33
+ <em>config/initializers/bootstrap5-helper.rb</em>
34
+
35
+ ```ruby
36
+ Bootstrap5Helper.config do |config|
37
+ config.autoload_in_views = false
38
+ end
39
+ ```
40
+
41
+ > Note: Almost all the helpers and their child components support attributes for `id`, `class`, `data` and `aria` HTML attributes.
42
+
43
+ ### Accordion(s):
44
+
45
+ ```ruby
46
+ # @param [Hash] opts
47
+ # @option opts [String] :id
48
+ # @option opts [String] :class
49
+ # @option opts [Hash] :data
50
+ # @option opts [Boolean] :always_open
51
+ # @option opts [Boolean] :flush
52
+ # @return [Accordion]
53
+ #
54
+ def accordion_helper(opts = {}, &block)
55
+ Accordion.new(self, opts, &block)
56
+ end
57
+ ```
58
+
59
+ #### Example:
60
+
61
+ ```erb
62
+ <%= accordion_helper id: 'custom_id' do |a| %>
63
+ <%= a.item expanded: true do |item| %>
64
+ <%= item.header do %>
65
+ // html or ruby here
66
+ <% end %>
67
+ <%= item.body do %>
68
+ // html or ruby here
69
+ <% end %>
70
+ <% end %>
71
+ <%= a.item do |item| %>
72
+ <%= item.header do %>
73
+ // html or ruby here
74
+ <% end %>
75
+ <%= item.body do %>
76
+ // html or ruby here
77
+ <% end %>
78
+ <% end %>
79
+ <% end %>
80
+ ```
81
+
82
+ ### Alerts
83
+
84
+ Alerts use the context helper, where you can pass the context of the object and it will render the appropriate colors.
85
+
86
+ ```ruby
87
+ # @overload alert_helper(context, opts)
88
+ # @param [Symbol|String] context - :primary, :danger etc
89
+ # @param [Hash] opts
90
+ # @option opts [String] :id
91
+ # @option opts [String] :class
92
+ # @option opts [Boolean] :dismissible
93
+ #
94
+ # @overload alert_helper(opts)
95
+ # @param [Hash] opts
96
+ # @option opts [String] :id
97
+ # @option opts [String] :class
98
+ # @option opts [Boolean] :dismissible
99
+ #
100
+ # @return [String]
101
+ #
102
+ def alert_helper(*args, &block)
103
+ Alert.new(self, *args, &block)
104
+ end
105
+ ```
106
+
107
+ #### Example:
108
+
109
+ ```erb
110
+ <%= alert_helper :danger, dismissble: true do %>
111
+ Something went wrong with your model data...
112
+ <% end %>
113
+ ```
114
+
115
+ ### Badges
116
+
117
+ The badge helper will build badges realitively quickly. If you are just passing a String, use the shorter curly brace block syntax. If you plan on building other HTML elements or using other Ruby proceedures, use the do/end method.
118
+
119
+ ```ruby
120
+ # @overload badge_helper(context, opts)
121
+ # @param [Symbol|String] context - :primary, :danger etc
122
+ # @param [Hash] opts
123
+ # @option opts [String] :id
124
+ # @option opts [String] :class
125
+ # @option opts [Hash] : :data
126
+ #
127
+ # @overload badge_helper(opts)
128
+ # @param [Hash] opts
129
+ # @option opts [String] :id
130
+ # @option opts [String] :class
131
+ # @option opts [Hash] : :data
132
+ #
133
+ # @return [String]
134
+ #
135
+ def badge_helper(*args, &block)
136
+ Badge.new(self, *args, &block)
137
+ end
138
+ ```
139
+
140
+ #### Example
141
+
142
+ ```erb
143
+ <li>
144
+ Messages: <%= badge_helper(:primary) { @messages.count } %>
145
+ </li>
146
+ <li>
147
+ Notifications: <%= badge_healper { @notifications.count } %>
148
+ </li>
149
+ <li>
150
+ Users: <%= badge_helper :danger do %> Some HTML / Ruby <% end %>
151
+ </li>
152
+ ```
153
+
154
+ ### Cards
155
+
156
+ Cards support a few methods that make building them easier:
157
+
158
+ - `body`
159
+ - `header`
160
+ - `footer`
161
+ - `image_overlay`
162
+ - `image`
163
+ - `image_cap`
164
+ - `text`
165
+ - `title`
166
+
167
+ For usage on various card sub components, @see https://getbootstrap.com/docs/4.0/components/card/
168
+
169
+ ```ruby
170
+ # @param [Hash] opts
171
+ # @option opts [String] :id
172
+ # @option opts [String] :class
173
+ # @option opts [Hash] :data
174
+ # @return [String]
175
+ #
176
+ def card_helper(opts = {}, &block)
177
+ Card.new(self, opts, &block)
178
+ end
179
+ ```
180
+
181
+ #### Example
182
+
183
+ ```erb
184
+ <%= card_helper do |c| %>
185
+ <%= c.header class: 'text-white bg-primary' do %>
186
+ <h4>This is the header...</h4>
187
+ <% end %>
188
+ <%= c.body do %>
189
+ <%= c.title { 'This is the title' } %>
190
+ <%= c.text { 'This card body' } %>
191
+ <ul>
192
+ <% [1, 2, 3].each do |x| %>
193
+ <li>Item: <%= x %></li>
194
+ <% end %>
195
+ </ul>
196
+ <% end %>
197
+ <%= c.footer do %>
198
+ This is the footer...
199
+ <% end %>
200
+ <% end %>
201
+
202
+ <%# Horizontal %>
203
+
204
+ <div class="row">
205
+ <div class="col-sm mt-3 mb-3">
206
+ <%= card_helper do |c| %>
207
+ <div class="row no-gutters">
208
+ <div class="col-md-4">
209
+ <%= image_tag 'placeholder.svg', class: 'card-img' %>
210
+ </div>
211
+ <div class="col-md-8">
212
+ <%= c.body do %>
213
+ <%= c.title { "Card title" } %>
214
+ <%= c.text { "This is a wider card with supporting text below as a natural lead-in to additional content." } %>
215
+ <%= c.text do %>
216
+ <small class="text-muted">Last updated 3 mins ago</small>
217
+ <% end %>
218
+ <% end %>
219
+ </div>
220
+ </div>
221
+ <% end %>
222
+ </div>
223
+ </div>
224
+ ```
225
+
226
+ ### Dropdowns
227
+
228
+ Dropdowns support the following methods:
229
+
230
+ - `button`
231
+ - `menu`
232
+ - `item` - Use this method when you are using the item in the menu as a trigger for tab content.
233
+ - `link` - Use this method when the item in the menu is nothing more than a hyperlink.
234
+ - `text` - simple text
235
+ - `header` - Is a header item
236
+ - `divider` - A dividing element
237
+
238
+ ```ruby
239
+ # @overload dropdown_helper(type, opts)
240
+ # @param [Symbol|String] type - :dropdown, :dropup, :dropstart, :dropend
241
+ # @param [Hash] opts
242
+ # @option opts [String] :id
243
+ # @option opts [String] :class
244
+ # @option opts [Hash] :data
245
+ # @option opts [Boolean] :split
246
+ #
247
+ # @overload dropdown(opts)
248
+ # @param [Hash] opts
249
+ # @option opts [String] :id
250
+ # @option opts [String] :class
251
+ # @option opts [Hash] :data
252
+ # @option opts [Boolean] :split
253
+ #
254
+ # @return [String]
255
+ #
256
+ def dropdown_helper(*args, &block)
257
+ Dropdown.new(self, *args, &block)
258
+ end
259
+ ```
260
+
261
+ #### Example
262
+
263
+ ```erb
264
+ <%= dropdown_helper do |dropdown| %>
265
+ <%= dropdown.button(:primary) { "Action" } %>
266
+ <%= dropdown.menu do |menu| %>
267
+ <%= menu.link 'Edit', '#' %>
268
+ <%= menu.link 'Delete', '#' %>
269
+ <%= menu.text 'Static text' %>
270
+ <% end %>
271
+ <% end %>
272
+
273
+ <%= dropdown_helper :group, class: 'dropright' do |dropdown| %>
274
+ <button type="button" class="btn btn-danger">Action 2</button>
275
+ <%= dropdown.button(:danger, split: true) %>
276
+ <%= dropdown.menu do |menu| %>
277
+ <%= menu.header "Crud operations" %>
278
+ <%= menu.divider %>
279
+ <%= menu.link 'Edit', 'SOME-URL' %>
280
+ <%= menu.link 'Delete', 'SOME-URL' %>
281
+ <% end %>
282
+ <% end %>
283
+
284
+ <%= dropdown_helper do |dropdown| %>
285
+ <%= dropdown.button :primary do %>
286
+ <i class="fas fa-users"></i> User
287
+ <% end %>
288
+ <%= dropdown.menu do |menu| %>
289
+ <form class="px-4 py-3">
290
+ <div class="form-group">
291
+ <label for="exampleDropdownFormEmail1">Email address</label>
292
+ <input type="email" class="form-control" id="exampleDropdownFormEmail1" placeholder="email@example.com">
293
+ </div>
294
+ <div class="form-group">
295
+ <label for="exampleDropdownFormPassword1">Password</label>
296
+ <input type="password" class="form-control" id="exampleDropdownFormPassword1" placeholder="Password">
297
+ </div>
298
+ <div class="form-group">
299
+ <div class="form-check">
300
+ <input type="checkbox" class="form-check-input" id="dropdownCheck">
301
+ <label class="form-check-label" for="dropdownCheck">
302
+ Remember me
303
+ </label>
304
+ </div>
305
+ </div>
306
+ <button type="submit" class="btn btn-primary">Sign in</button>
307
+ </form>
308
+ <%= menu.divider %>
309
+ <%= menu.link "New around here? Sign up", "#" %>
310
+ <%= menu.link "Forgot password", "#" %>
311
+ <% end %>
312
+ <% end %>
313
+ ```
314
+
315
+ ### Modals
316
+
317
+ ```ruby
318
+ # @param [Hash] opts
319
+ # @option opts [String] :id
320
+ # @option opts [String] :class
321
+ # @option opts [Hash] :data
322
+ # @option opts [Boolean] :scrollable
323
+ # @option opts [Boolean] :vcentered
324
+ # @option opts [Boolean] :static
325
+ # @option opts [Boolean|Symbol] :fullscreen - true, :sm, :lg, :xl etc
326
+ # @option opts [Symbol] :size - :sm, :md, :lg etc
327
+ # @return [String]
328
+ #
329
+ def modal_helper(opts = {}, &block)
330
+ Modal.new(self, opts, &block)
331
+ end
332
+ ```
333
+
334
+ > Note: When the `close_button` is not passed a block, it will default to the X icon.
335
+
336
+ #### Example
337
+
338
+ ```erb
339
+ <%= modal_helper id: 'exampleModal' do |m| %>
340
+ <%= m.header do %>
341
+ <%= m.title { 'Example Modal' } %>
342
+ <%= m.close_button %>
343
+ <% end %>
344
+ <%= m.body do %>
345
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel nisi tempora, eius iste sit nobis
346
+ earum in harum optio dolore explicabo. Eveniet reprehenderit harum itaque ad fuga beatae, quasi
347
+ sequi! Laborum ea porro nihil ipsam repudiandae vel harum voluptates minima corrupti unde quas,
348
+ dolore possimus doloribus voluptatem sint fuga dolores odio dignissimos at molestias earum.
349
+ <% end %>
350
+ <%= m.footer do %>
351
+ <%= m.close_button class: 'btn btn-secondary' do %>
352
+ Close
353
+ <% end %>
354
+ <% end %>
355
+ <% end %>
356
+ ```
357
+
358
+ ### Navs
359
+
360
+ The Nav component has the following methods:
361
+
362
+ - `dropwdown` - @see Dropdown for list of methods
363
+ - `item`
364
+ - `link`
365
+
366
+ ```ruby
367
+ # @overload nav_helper(tag, opts)
368
+ # @param [Symbol|String] tag - :nav, :ul
369
+ # @param [Hash] opts
370
+ # @option opts [String] :id
371
+ # @option opts [String] :class
372
+ # @option opts [Hash] :data
373
+ # @option opts [Hash] :child - data attributes for child, NOT wrapper
374
+ #
375
+ # @overload nav_helper(opts)
376
+ # @param [Hash] opts
377
+ # @option opts [String] :id
378
+ # @option opts [String] :class
379
+ # @option opts [Hash] :data
380
+ # @option opts [Hash] :child - data attributes for child, NOT wrapper
381
+ #
382
+ # @return [String]
383
+ #
384
+ def nav_helper(*args, &block)
385
+ Nav.new(self, *args, &block)
386
+ end
387
+ ```
388
+
389
+ #### Example
390
+
391
+ ```erb
392
+ <%= nav_helper do |nav| %>
393
+ <%= nav.link "Item 1", "https://www.google.com" %>
394
+ <%= nav.link "Item 2", "#" %>
395
+ <%= nav.link "Item 3", "#" %>
396
+ <%= nav.dropdown :more do |menu| %>
397
+ <%= menu.link 'People', '#' %>
398
+ <%= menu.link 'Records', '#' %>
399
+ <% end %>
400
+
401
+ <%= nav.dropdown "More 2" do |menu| %>
402
+ <%= menu.link 'People', '#' %>
403
+ <%= menu.link 'Records', '#' %>
404
+ <% end %>
405
+ <% end %>
406
+ ```
407
+
408
+ ### Tabs
409
+
410
+ ```ruby
411
+ # @overload tab_helper(type, opts)
412
+ # @param [Symbol|String] type - :tabs, :pills
413
+ # @param [Hash] opts
414
+ # @option opts [String] :id
415
+ # @option opts [String] :class
416
+ # @option opts [Hash] :data
417
+ #
418
+ # @overload tab_helper(opts)
419
+ # @param [Hash] opts
420
+ # @option opts [String] :id
421
+ # @option opts [String] :class
422
+ # @option opts [Hash] :data
423
+ #
424
+ # @return [String]
425
+ #
426
+ def tab_helper(*args, &block)
427
+ Tab.new(self, *args, &block)
428
+ end
429
+ ```
430
+
431
+ #### Example
432
+
433
+ ```erb
434
+ <%= tab_helper :pills do |tab| %>
435
+ <%= tab.nav do |nav| %>
436
+ <%= nav.item :item1 do %>
437
+ Item 1
438
+ <% end %>
439
+ <%= nav.item(:item2, class: 'active') { "Item 2" } %>
440
+ <%= nav.item(:item3) { "Item 3" } %>
441
+ <%= nav.item :item4 %>
442
+ <%= nav.dropdown 'More' do |dropdown| %>
443
+ <%= dropdown.item :item5 %>
444
+ <%= dropdown.item(:item6) { 'Item 6' } %>
445
+ <% end %>
446
+ <% end %>
447
+
448
+ <%= tab.content do |content| %>
449
+ <%= content.pane :item1, class: 'mt-3' do %>
450
+ Content 1
451
+ <% end %>
452
+
453
+ <%= content.pane :item2, class: 'active mt-3' do %>
454
+ Content 2
455
+ <% end %>
456
+
457
+ <%= content.pane :item3, class: 'mt-3' do %>
458
+ Content 3
459
+ <% end %>
460
+
461
+ <%= content.pane :item4, class: 'mt-3' do %>
462
+ Content 4
463
+ <% end %>
464
+
465
+ <%= content.pane :item5, class: 'mt-3' do %>
466
+ Content 5
467
+ <% end %>
468
+
469
+ <%= content.pane :item6, class: 'mt-3' do %>
470
+ Content 6
471
+ <% end %>
472
+ <% end %>
473
+ <% end %>
474
+ ```
475
+
476
+ ### Spinners
477
+
478
+ ```ruby
479
+ # @param [Hash] args
480
+ # @option opts [Symbol] :type - :border, :grow
481
+ # @option opts [String] :id
482
+ # @option opts [String] :class
483
+ # @option opts [Hash] :data
484
+ # @return [String]
485
+ #
486
+ def spinner_helper(opts = {}, &block)
487
+ Spinner.new(self, opts, &block)
488
+ end
489
+ ```
490
+
491
+ #### Example
492
+
493
+ ```erb
494
+ <%= spinner_helper class: 'text-warning' %>
495
+ <%= spinner_helper type: :grow, class: 'text-danger', id: 'loadingRecords' %>
496
+ ```
497
+
498
+ ## Contributing
499
+
500
+ If you would like to contribution, by all means, do a PR and send up your suggestions.
501
+
502
+ If there are components you would like to see added, open an issue and I will try to get to them, or you can do a PR and add them yourself :D
503
+
504
+ ## License
505
+
506
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,107 @@
1
+ module Bootstrap5Helper
2
+ class Accordion
3
+ class Item < Component # :nodoc:
4
+ # Take note that if `parent_id` is <tt>NilClass</tt> it is because
5
+ # the <tt>Accordion::Item</tt> is meant to stay open and not close
6
+ # the previous one.
7
+ #
8
+ # @param [ActionView] template
9
+ # @param [String|NilClass] parent_id
10
+ # @param [Hash] opts
11
+ # @option opts [String] :id
12
+ # @option opts [String] :class
13
+ # @option opts [Hash] :data
14
+ #
15
+ def initialize(template, parent_id = nil, opts = {}, &block)
16
+ super(template)
17
+
18
+ @parent = parent_id
19
+ @id = opts.fetch(:id, uuid)
20
+ @class = opts.fetch(:class, '')
21
+ @data = opts.fetch(:data, {})
22
+ @expanded = opts.fetch(:expanded, false)
23
+ @header_id = uuid
24
+ @collapse_id = uuid
25
+ @content = block || proc { '' }
26
+ end
27
+
28
+ # rubocop:disable Metrics/MethodLength
29
+
30
+ # Builds a header component for the accordion.
31
+ #
32
+ # @param [Hash] opts
33
+ # @return [String]
34
+ #
35
+ def header(tag_or_options = nil, opts = {}, &block)
36
+ tag, args = parse_tag_or_options(tag_or_options, opts)
37
+
38
+ @header_id = args.fetch(:id, @header_id)
39
+ klass = args.fetch(:class, '')
40
+ data = args.fetch(:data, {})
41
+
42
+ content_tag(
43
+ tag || config({ accordions: :header }, :h2),
44
+ id: @header_id,
45
+ class: "accordion-header #{klass}",
46
+ data: data
47
+ ) do
48
+ content_tag(
49
+ :button,
50
+ type: :button,
51
+ class: "accordion-button #{@expanded ? '' : 'collapsed'}",
52
+ data: {
53
+ 'bs-toggle' => 'collapse',
54
+ 'bs-target' => "##{@collapse_id}"
55
+ },
56
+ aria: {
57
+ expanded: @expanded,
58
+ controls: @collapse_id
59
+ },
60
+ &block
61
+ )
62
+ end
63
+ end
64
+ # rubocop:enable Metrics/MethodLength
65
+
66
+ # rubocop:disable Metrics/MethodLength
67
+
68
+ # Builds the body component for the accordion.
69
+ #
70
+ # @param [Hash] opts
71
+ # @return [String]
72
+ #
73
+ def body(opts = {}, &block)
74
+ id = opts.fetch(:id, uuid)
75
+ klass = opts.fetch(:class, '')
76
+ data = opts.fetch(:data, {})
77
+
78
+ content_tag(
79
+ :div,
80
+ id: @collapse_id,
81
+ class: "accordion-collapse collapse #{@expanded ? 'show' : ''}",
82
+ aria: { labelledby: @header_id },
83
+ data: { 'bs-parent' => @parent.present? ? "##{@parent}" : nil }
84
+ ) do
85
+ content_tag(
86
+ :div,
87
+ id: id,
88
+ class: "accordion-body #{klass}",
89
+ data: data,
90
+ &block
91
+ )
92
+ end
93
+ end
94
+ # rubocop:enable Metrics/MethodLength
95
+
96
+ # String representation of the object.
97
+ #
98
+ # @return [String]
99
+ #
100
+ def to_s
101
+ content_tag :div, id: @id, class: "accordion-item #{@class}", data: @data do
102
+ @content.call(self)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,46 @@
1
+ module Bootstrap5Helper
2
+ # Builds a Accordion component.
3
+ #
4
+ #
5
+ class Accordion < Component
6
+ # Class constructor
7
+ #
8
+ # @param [ActionView] template
9
+ # @param [Hash] opts
10
+ # @option opts [String] :id
11
+ # @option opts [String] :class
12
+ # @option opts [Hash] :data
13
+ # @option opts [Boolean] :always_open
14
+ # @option opts [Boolean] :flush
15
+ #
16
+ def initialize(template, opts = {}, &block)
17
+ super(template)
18
+
19
+ @id = opts.fetch(:id, uuid)
20
+ @class = opts.fetch(:class, '')
21
+ @data = opts.fetch(:data, {})
22
+ @always_open = opts.fetch(:always_open, false)
23
+ @flush = opts.fetch(:flush, false)
24
+ @content = block || proc { '' }
25
+ end
26
+
27
+ def item(*args, &block)
28
+ Accordion::Item.new(self, (@always_open ? nil : @id), *args, &block)
29
+ end
30
+
31
+ # String representation of the object.
32
+ #
33
+ # @return [String]
34
+ #
35
+ def to_s
36
+ content_tag(
37
+ :div,
38
+ id: @id,
39
+ class: "accordion #{@flush ? 'accordion-flush' : ''} #{@class}",
40
+ data: @data
41
+ ) do
42
+ @content.call(self)
43
+ end
44
+ end
45
+ end
46
+ end