bs5 0.0.26 → 0.0.27

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
  SHA256:
3
- metadata.gz: 14b5dca44bb60e64b8eb925c7a617c2e7f6214bf33e1d35a44454b0fc617351c
4
- data.tar.gz: 49dc980ff0a533774090543e1f8920c3ae7d4d4037c9fd84a5aa3425bb1a8faf
3
+ metadata.gz: 5bd6c6c2f823f5b4ba980c7ef01db9381fe5fa6c02e4b82dc101a6765b8bfc22
4
+ data.tar.gz: 16c43758c937dab60f50f331f56e31dd75aa2df4f982c803c340fe449302a346
5
5
  SHA512:
6
- metadata.gz: 2329cc993b4ab1d5930802dfab3f71d878843ce20ebc51bd861c488179e9c4f993b81e48bf1fca791af6886e735de751bbe4ae90f04e641249409e4bade1fc0f
7
- data.tar.gz: ae01cfa6597d19ea0cacff53947b70f3ca8e4c0da463ede006ceef58268efa021a8851684bda0f1702db6a6092b15239fc9b633d62877bed44c2bf330e85b0dd
6
+ metadata.gz: e55c062be7d27cbe65efa1dd098b5ae1e26f4a5fc919ac22e5e8267a4d7c269cfc29fa15077444d3be082ccb9d7211fa27d3b1fbaa63c26e847665fcb0a30279
7
+ data.tar.gz: 13300ddc486bed84d11bae9d30cc2078fc60951a833ace82e07828228865bc3858f416e41dea9ff4e459b7df0912d1c04b0336596bacff8553b941dc8e660854
@@ -0,0 +1,3 @@
1
+ <div class="modal-body">
2
+ <%= content %>
3
+ </div>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ module Modal
5
+ class BodyComponent < ViewComponent::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ module Modal
5
+ class ControllerComponent < ViewComponent::Base
6
+ def initialize(modal_id:)
7
+ @modal_id = modal_id
8
+ end
9
+
10
+ def content
11
+ return nil if @content.blank?
12
+
13
+ if actionable_element?
14
+ set_actionable_element_attributes
15
+ actionable_element.to_html.html_safe # rubocop:disable Rails/OutputSafety
16
+ else
17
+ @content
18
+ end
19
+ end
20
+
21
+ def set_actionable_element_attributes
22
+ actionable_element['data-bs-toggle'] = 'modal'
23
+ actionable_element['data-bs-target'] = "##{@modal_id}"
24
+ end
25
+
26
+ def actionable_element
27
+ @actionable_element ||= begin
28
+ if (elements = Nokogiri::HTML::DocumentFragment.parse(@content).elements).one? &&
29
+ (element = elements.first).name.in?(%w[a button])
30
+ element
31
+ end
32
+ end
33
+ end
34
+
35
+ def actionable_element?
36
+ !!actionable_element
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ <div class="modal-footer">
2
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
3
+ <%= content %>
4
+ </div>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ module Modal
5
+ class FooterComponent < ViewComponent::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ <div class="modal-header">
2
+ <h5 class="modal-title" id="<%= @label_id %>"><%= content %></h5>
3
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
4
+ </div>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ module Modal
5
+ class HeaderComponent < ViewComponent::Base
6
+ attr_reader :title
7
+
8
+ def initialize(title: nil, label_id: nil)
9
+ @title = title
10
+ @label_id = label_id
11
+ end
12
+
13
+ def content
14
+ title || @content
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ <%= controller %>
2
+
3
+ <%= tag.div(modal_attributes) do %>
4
+ <div class="<%= dialog_classes %>">
5
+ <div class="modal-content">
6
+ <%= header %>
7
+ <%= body %>
8
+ <%= footer %>
9
+ </div>
10
+ </div>
11
+ <% end %>
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ class ModalComponent < ViewComponent::Base
5
+ include ViewComponent::SlotableV2
6
+ using HashRefinement
7
+
8
+ MODAL_OPTIONS = %i[backdrop keyboard focus].freeze
9
+
10
+ renders_one :controller, lambda { |_modal_id: nil|
11
+ Bs5::Modal::ControllerComponent.new(modal_id: modal_id)
12
+ }
13
+ renders_one :header, lambda { |_label_id: nil|
14
+ Bs5::Modal::HeaderComponent.new(label_id: label_id)
15
+ }
16
+ renders_one :body, Bs5::Modal::BodyComponent
17
+ renders_one :footer, Bs5::Modal::FooterComponent
18
+
19
+ def initialize(options = {})
20
+ @options = options.symbolize_keys
21
+ extract_options
22
+ end
23
+
24
+ private
25
+
26
+ def extract_options
27
+ @scroll = @options.delete(:scroll)
28
+ @center = @options.delete(:center)
29
+ @size = @options.delete(:size)
30
+ @fullscreen = @options.delete(:fullscreen)
31
+
32
+ extract_modal_options
33
+ end
34
+
35
+ def extract_modal_options
36
+ @modal_options = @options.extract!(*MODAL_OPTIONS)
37
+ end
38
+
39
+ def modal_attributes
40
+ { class: 'modal fade',
41
+ id: modal_id,
42
+ tabindex: -1,
43
+ aria: { labelledby: label_id, hidden: true },
44
+ data: @modal_options.prefix_keys_with_bs }
45
+ end
46
+
47
+ def dialog_classes
48
+ class_names = ['modal-dialog']
49
+ class_names << 'modal-dialog-scrollable' if scroll?
50
+ class_names << 'modal-dialog-centered' if center?
51
+ class_names << "modal-#{@size}" if size?
52
+ class_names << fullscreen_class
53
+
54
+ class_names.join(' ')
55
+ end
56
+
57
+ def fullscreen_class
58
+ return unless fullscreen?
59
+
60
+ class_name = %w[modal fullscreen]
61
+ class_name << [@fullscreen, 'down'] if @fullscreen.is_a?(Symbol)
62
+
63
+ class_name.join('-')
64
+ end
65
+
66
+ def modal_id
67
+ "modal-#{object_id}"
68
+ end
69
+
70
+ def label_id
71
+ "modal-label-#{object_id}"
72
+ end
73
+
74
+ %i[scroll center size fullscreen].each do |name|
75
+ define_method("#{name}?") do
76
+ !instance_variable_get("@#{name}").nil?
77
+ end
78
+ end
79
+ end
80
+ end
@@ -3,7 +3,7 @@
3
3
  module Bs5
4
4
  module ComponentsHelper
5
5
  COMPONENTS = %w[accordion alert badge breadcrumb button_group button_tag button_to button_toolbar close_button
6
- dropdown list_group spinner toast toast_container].freeze
6
+ dropdown list_group modal spinner toast toast_container].freeze
7
7
 
8
8
  COMPONENTS.each do |name|
9
9
  define_method("bs5_#{name}") do |*args, &block|
@@ -0,0 +1,9 @@
1
+ <h2>Examples</h2>
2
+ <h3>Live demo</h3>
3
+ <%= bs5_example(snippet: 'modal/examples/snippet1') %>
4
+ <h3>Static backdrop</h3>
5
+ <%= bs5_example(snippet: 'modal/examples/snippet2') %>
6
+ <h3>Scrolling long content</h3>
7
+ <%= bs5_example(snippet: 'modal/examples/snippet3') %>
8
+ <h3>Vertically centered</h3>
9
+ <%= bs5_example(snippet: 'modal/examples/snippet4') %>
@@ -0,0 +1,2 @@
1
+ <h2>Fullscreen Modal</h2>
2
+ <%= bs5_example(snippet: 'modal/fullscreen/snippet1') %>
@@ -0,0 +1,2 @@
1
+ <h2>Optional sizes</h2>
2
+ <%= bs5_example(snippet: 'modal/optional_sizes/snippet1') %>
@@ -0,0 +1,12 @@
1
+ <%= bs5_modal do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Launch demo modal', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Modal title' } %>
6
+ <%= m.body do %>
7
+ <p>Modal body text goes here.</p>
8
+ <% end %>
9
+ <%= m.footer do %>
10
+ <%= bs5_button_tag('Save changes', type: 'button') %>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <%= bs5_modal(backdrop: :static, keyboard: false) do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Launch demo modal', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Modal title' } %>
6
+ <%= m.body do %>
7
+ <p>I will not close if you click outside me. Don't even try to press escape key.</p>
8
+ <% end %>
9
+ <%= m.footer do %>
10
+ <%= bs5_button_tag('Understood', type: 'button') %>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <%= bs5_modal(scroll: true) do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Launch demo modal', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Modal title' } %>
6
+ <%= m.body do %>
7
+ <% 15.times do %>
8
+ <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
9
+ <% end %>
10
+ <% end %>
11
+ <%= m.footer do %>
12
+ <%= bs5_button_tag('Save changes', type: 'button') %>
13
+ <% end %>
14
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <%= bs5_modal(center: true) do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Launch demo modal', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Modal title' } %>
6
+ <%= m.body do %>
7
+ <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
8
+ <% end %>
9
+ <%= m.footer do %>
10
+ <%= bs5_button_tag('Save changes', type: 'button') %>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,55 @@
1
+ <%= bs5_modal(fullscreen: true) do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Full screen', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Full screen modal' } %>
6
+ <%= m.body do %>
7
+ <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
8
+ <% end %>
9
+ <%= m.footer {} %>
10
+ <% end %>
11
+
12
+ <%= bs5_modal(fullscreen: :sm) do |m| %>
13
+ <%= m.controller do %>
14
+ <%= bs5_button_tag('Full screen below sm', type: 'button') %>
15
+ <% end %>
16
+ <%= m.header { 'Full screen below sm' } %>
17
+ <%= m.body { '...'} %>
18
+ <%= m.footer {} %>
19
+ <% end %>
20
+
21
+ <%= bs5_modal(fullscreen: :md) do |m| %>
22
+ <%= m.controller do %>
23
+ <%= bs5_button_tag('Full screen below md', type: 'button') %>
24
+ <% end %>
25
+ <%= m.header { 'Full screen below md' } %>
26
+ <%= m.body { '...'} %>
27
+ <%= m.footer {} %>
28
+ <% end %>
29
+
30
+ <%= bs5_modal(fullscreen: :lg) do |m| %>
31
+ <%= m.controller do %>
32
+ <%= bs5_button_tag('Full screen below lg', type: 'button') %>
33
+ <% end %>
34
+ <%= m.header { 'Full screen below lg' } %>
35
+ <%= m.body { '...'} %>
36
+ <%= m.footer {} %>
37
+ <% end %>
38
+
39
+ <%= bs5_modal(fullscreen: :xl) do |m| %>
40
+ <%= m.controller do %>
41
+ <%= bs5_button_tag('Full screen below xl', type: 'button') %>
42
+ <% end %>
43
+ <%= m.header { 'Full screen below xl' } %>
44
+ <%= m.body { '...'} %>
45
+ <%= m.footer {} %>
46
+ <% end %>
47
+
48
+ <%= bs5_modal(fullscreen: :xxl) do |m| %>
49
+ <%= m.controller do %>
50
+ <%= bs5_button_tag('Full screen below xxl', type: 'button') %>
51
+ <% end %>
52
+ <%= m.header { 'Full screen below xxl' } %>
53
+ <%= m.body { '...'} %>
54
+ <%= m.footer {} %>
55
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <%= bs5_modal(size: :xl) do |m| %>
2
+ <%= m.controller do %>
3
+ <%= bs5_button_tag('Extra large modal', type: 'button') %>
4
+ <% end %>
5
+ <%= m.header { 'Extra large modal' } %>
6
+ <%= m.body { '...' } %>
7
+ <% end %>
8
+
9
+ <%= bs5_modal(size: :lg) do |m| %>
10
+ <%= m.controller do %>
11
+ <%= bs5_button_tag('Large modal', type: 'button') %>
12
+ <% end %>
13
+ <%= m.header { 'Large modal' } %>
14
+ <%= m.body { '...' } %>
15
+ <% end %>
16
+
17
+ <%= bs5_modal(size: :sm) do |m| %>
18
+ <%= m.controller do %>
19
+ <%= bs5_button_tag('Small modal', type: 'button') %>
20
+ <% end %>
21
+ <%= m.header { 'Small modal' } %>
22
+ <%= m.body { '...' } %>
23
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <h1>Modal</h1>
2
+ <%= render 'bs5/examples/modal/examples' %>
3
+ <%= render 'bs5/examples/modal/optional_sizes' %>
4
+ <%= render 'bs5/examples/modal/fullscreen' %>
@@ -24,6 +24,7 @@
24
24
  <% lg.item(active: current_page?(pages_path('collapse'))) do %><%= link_to 'Collapse', pages_path('collapse') %><% end %>
25
25
  <% lg.item(active: current_page?(pages_path('dropdowns'))) do %><%= link_to 'Dropdowns', pages_path('dropdowns') %><% end %>
26
26
  <% lg.item(active: current_page?(pages_path('list_group'))) do %><%= link_to 'List group', pages_path('list_group') %><% end %>
27
+ <% lg.item(active: current_page?(pages_path('modal'))) do %><%= link_to 'Modal', pages_path('modal') %><% end %>
27
28
  <% lg.item(active: current_page?(pages_path('popovers'))) do %><%= link_to 'Popovers', pages_path('popovers') %><% end %>
28
29
  <% lg.item(active: current_page?(pages_path('spinners'))) do %><%= link_to 'Spinners', pages_path('spinners') %><% end %>
29
30
  <% lg.item(active: current_page?(pages_path('toasts'))) do %><%= link_to 'Toasts', pages_path('toasts') %><% end %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bs5
4
- VERSION = '0.0.26'
4
+ VERSION = '0.0.27'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bs5
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.26
4
+ version: 0.0.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Baselier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-24 00:00:00.000000000 Z
11
+ date: 2020-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -151,6 +151,16 @@ files:
151
151
  - app/components/bs5/example_component.rb
152
152
  - app/components/bs5/list_group_component.html.erb
153
153
  - app/components/bs5/list_group_component.rb
154
+ - app/components/bs5/modal/body_component.html.erb
155
+ - app/components/bs5/modal/body_component.rb
156
+ - app/components/bs5/modal/controller_component.html.erb
157
+ - app/components/bs5/modal/controller_component.rb
158
+ - app/components/bs5/modal/footer_component.html.erb
159
+ - app/components/bs5/modal/footer_component.rb
160
+ - app/components/bs5/modal/header_component.html.erb
161
+ - app/components/bs5/modal/header_component.rb
162
+ - app/components/bs5/modal_component.html.erb
163
+ - app/components/bs5/modal_component.rb
154
164
  - app/components/bs5/spinner_component.html.erb
155
165
  - app/components/bs5/spinner_component.rb
156
166
  - app/components/bs5/toast/body_component.html.erb
@@ -281,6 +291,15 @@ files:
281
291
  - app/views/bs5/examples/list_group/style/default.html.erb
282
292
  - app/views/bs5/examples/list_group/with_badges/_example.html.erb
283
293
  - app/views/bs5/examples/list_group/with_badges/default.html.erb
294
+ - app/views/bs5/examples/modal/_examples.html.erb
295
+ - app/views/bs5/examples/modal/_fullscreen.html.erb
296
+ - app/views/bs5/examples/modal/_optional_sizes.html.erb
297
+ - app/views/bs5/examples/modal/examples/snippet1.html.erb
298
+ - app/views/bs5/examples/modal/examples/snippet2.html.erb
299
+ - app/views/bs5/examples/modal/examples/snippet3.html.erb
300
+ - app/views/bs5/examples/modal/examples/snippet4.html.erb
301
+ - app/views/bs5/examples/modal/fullscreen/snippet1.html.erb
302
+ - app/views/bs5/examples/modal/optional_sizes/snippet1.html.erb
284
303
  - app/views/bs5/examples/popovers/default/_example.html.erb
285
304
  - app/views/bs5/examples/popovers/default/snippet.html.erb
286
305
  - app/views/bs5/examples/popovers/disabled_elements/_example.html.erb
@@ -335,6 +354,7 @@ files:
335
354
  - app/views/bs5/pages/collapse.html.erb
336
355
  - app/views/bs5/pages/dropdowns.html.erb
337
356
  - app/views/bs5/pages/list_group.html.erb
357
+ - app/views/bs5/pages/modal.html.erb
338
358
  - app/views/bs5/pages/popovers.html.erb
339
359
  - app/views/bs5/pages/spinners.html.erb
340
360
  - app/views/bs5/pages/toasts.html.erb