bs5 0.0.18 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/bs5_manifest.js +1 -0
  3. data/app/assets/javascripts/bs5/application.js +13 -0
  4. data/app/components/bs5/accordion_component.html.erb +1 -1
  5. data/app/components/bs5/accordion_component.rb +7 -3
  6. data/app/components/bs5/alert_component.rb +5 -5
  7. data/app/components/bs5/badge_component.rb +6 -6
  8. data/app/components/bs5/breadcrumb_component.html.erb +1 -1
  9. data/app/components/bs5/breadcrumb_component.rb +6 -3
  10. data/app/components/bs5/button_tag_component.rb +8 -8
  11. data/app/components/bs5/button_to_component.rb +8 -8
  12. data/app/components/bs5/example_component.html.erb +2 -1
  13. data/app/components/bs5/list_group_component.html.erb +2 -2
  14. data/app/components/bs5/list_group_component.rb +16 -9
  15. data/app/components/bs5/spinner_component.html.erb +5 -0
  16. data/app/components/bs5/spinner_component.rb +65 -0
  17. data/app/helpers/bs5/components_helper.rb +1 -1
  18. data/app/views/bs5/examples/accordion/default/snippet.html.erb +4 -4
  19. data/app/views/bs5/examples/accordion/flush/snippet.html.erb +4 -4
  20. data/app/views/bs5/examples/alert/additional_content/snippet.html.erb +1 -1
  21. data/app/views/bs5/examples/alert/color/_example.html.erb +1 -0
  22. data/app/views/bs5/examples/alert/{style → color}/snippet.html.erb +8 -8
  23. data/app/views/bs5/examples/alert/dismissable/snippet.html.erb +1 -1
  24. data/app/views/bs5/examples/badge/color/_example.html.erb +2 -0
  25. data/app/views/bs5/examples/badge/color/snippet.html.erb +8 -0
  26. data/app/views/bs5/examples/badge/default/_example.html.erb +2 -1
  27. data/app/views/bs5/examples/badge/default/button.html.erb +3 -0
  28. data/app/views/bs5/examples/badge/pill/snippet.html.erb +8 -8
  29. data/app/views/bs5/examples/breadcrumb/default/snippet.html.erb +9 -9
  30. data/app/views/bs5/examples/button_group/button_toolbar/snippet.html.erb +4 -4
  31. data/app/views/bs5/examples/button_group/button_toolbar/snippet2.html.erb +8 -8
  32. data/app/views/bs5/examples/button_group/sizing/snippet.html.erb +9 -9
  33. data/app/views/bs5/examples/button_group/vertical/snippet.html.erb +6 -6
  34. data/app/views/bs5/examples/buttons/button_tag/outline/snippet.html.erb +9 -9
  35. data/app/views/bs5/examples/buttons/button_tag/size/large.html.erb +2 -2
  36. data/app/views/bs5/examples/buttons/button_tag/size/small.html.erb +2 -2
  37. data/app/views/bs5/examples/buttons/button_tag/style/snippet.html.erb +9 -9
  38. data/app/views/bs5/examples/buttons/button_to/default/snippet.html.erb +3 -3
  39. data/app/views/bs5/examples/list_group/actionable/button.html.erb +5 -5
  40. data/app/views/bs5/examples/list_group/actionable/snippet.html.erb +5 -5
  41. data/app/views/bs5/examples/list_group/active/snippet.html.erb +5 -5
  42. data/app/views/bs5/examples/list_group/checkboxes_and_radios/default.html.erb +5 -5
  43. data/app/views/bs5/examples/list_group/checkboxes_and_radios/with_labels.html.erb +5 -5
  44. data/app/views/bs5/examples/list_group/custom_content/default.html.erb +3 -3
  45. data/app/views/bs5/examples/list_group/default/snippet.html.erb +5 -5
  46. data/app/views/bs5/examples/list_group/disabled/snippet.html.erb +5 -5
  47. data/app/views/bs5/examples/list_group/flush/snippet.html.erb +5 -5
  48. data/app/views/bs5/examples/list_group/horizontal/snippet.html.erb +18 -18
  49. data/app/views/bs5/examples/list_group/style/actionable.html.erb +9 -9
  50. data/app/views/bs5/examples/list_group/style/default.html.erb +9 -9
  51. data/app/views/bs5/examples/list_group/with_badges/default.html.erb +6 -6
  52. data/app/views/bs5/examples/popovers/default/snippet.html.erb +1 -1
  53. data/app/views/bs5/examples/popovers/four_directions/snippet.html.erb +4 -4
  54. data/app/views/bs5/examples/spinners/border/_example.html.erb +2 -0
  55. data/app/views/bs5/examples/spinners/border/snippet.html.erb +1 -0
  56. data/app/views/bs5/examples/spinners/buttons/_example.html.erb +2 -0
  57. data/app/views/bs5/examples/spinners/buttons/snippet.html.erb +15 -0
  58. data/app/views/bs5/examples/spinners/colors/_example.html.erb +2 -0
  59. data/app/views/bs5/examples/spinners/colors/snippet.html.erb +16 -0
  60. data/app/views/bs5/examples/spinners/growing/_example.html.erb +3 -0
  61. data/app/views/bs5/examples/spinners/growing/colors.html.erb +16 -0
  62. data/app/views/bs5/examples/spinners/growing/snippet.html.erb +1 -0
  63. data/app/views/bs5/examples/spinners/options/_example.html.erb +10 -0
  64. data/app/views/bs5/examples/spinners/options/floats.html.erb +3 -0
  65. data/app/views/bs5/examples/spinners/options/margin.html.erb +1 -0
  66. data/app/views/bs5/examples/spinners/options/placement_flex1.html.erb +3 -0
  67. data/app/views/bs5/examples/spinners/options/placement_flex2.html.erb +4 -0
  68. data/app/views/bs5/examples/spinners/options/text_align.html.erb +3 -0
  69. data/app/views/bs5/examples/spinners/size/_example.html.erb +3 -0
  70. data/app/views/bs5/examples/spinners/size/size1.html.erb +7 -0
  71. data/app/views/bs5/examples/spinners/size/size2.html.erb +3 -0
  72. data/app/views/bs5/examples/tooltips/default/buttons.html.erb +5 -5
  73. data/app/views/bs5/pages/alert.html.erb +1 -1
  74. data/app/views/bs5/pages/badge.html.erb +1 -1
  75. data/app/views/bs5/pages/spinners.html.erb +7 -0
  76. data/app/views/layouts/bs5/pages.html.erb +13 -11
  77. data/lib/bs5/engine.rb +6 -0
  78. data/lib/bs5/version.rb +1 -1
  79. metadata +31 -22
  80. data/app/views/bs5/examples/alert/style/_example.html.erb +0 -2
  81. data/app/views/bs5/examples/badge/style/_example.html.erb +0 -2
  82. data/app/views/bs5/examples/badge/style/snippet.html.erb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e7ed0ecd3b82a680eae723045c2c24020920a4942b4dfa5460951042be2a5c1
4
- data.tar.gz: 4217f3cd7e572d702deb22988f772c0653da8709c39c8a2bff3796747990a4b0
3
+ metadata.gz: fde2cc4be44c7ef1b396e7761904765ee31f1801acb7a88b1f4507cf302994c2
4
+ data.tar.gz: d69a795e889ece4139479843c7e2e5f6ffa48df347f0463529513060c1401214
5
5
  SHA512:
6
- metadata.gz: 3e520e4f93b185a7aa46cba4bf5c43b24655c03b8d75576eca3edf2b6740e0384caff3b413e9a3b18abadfda4edf1464be4ea4fb21eb66a67617b0f5268ed49c
7
- data.tar.gz: 38fd799067d2148b0cd44f323dc41d0a4130771edc2e8de6fade8af6aaab4f2a19c22d5dba6abc77f84d1189a9e6f5529c471f903796f07dc47cc40dab769b2a
6
+ metadata.gz: 4474fe20875677d9e8f45ca929d8e3ee95d6919a65065d472d2e12d9b74b765c6f491398b7691b8bf85b8a35d2b4cdc807839648f007a4836c47768ab865ac74
7
+ data.tar.gz: d70751a40bda629d0ba59324cab991b94dca962248ec22625edd36344750476830ed655a4fd21c3b3e3a7b133609217c33267c96df3af39125a3600f3be5539b
@@ -1 +1,2 @@
1
1
  //= link_directory ../stylesheets/bs5 .css
2
+ //= link_directory ../javascripts/bs5 .js
@@ -0,0 +1,13 @@
1
+ window.addEventListener("load", initBs5);
2
+ window.addEventListener("turbolinks:load", initBs5);
3
+
4
+ function initBs5(event) {
5
+ document.querySelectorAll('[data-bs5="copy"]').forEach(function (item) {
6
+ item.addEventListener("click", handleBs5CopyButtonClick);
7
+ });
8
+ }
9
+
10
+ function handleBs5CopyButtonClick(event) {
11
+ var code = event.target.closest("div").querySelector("code").innerText;
12
+ navigator.clipboard.writeText(code);
13
+ }
@@ -17,7 +17,7 @@
17
17
  data-bs-parent="#<%= id %>"
18
18
  >
19
19
  <div class="accordion-body">
20
- <%= item.content %>
20
+ <%= item %>
21
21
  </div>
22
22
  </div>
23
23
  </div>
@@ -3,9 +3,9 @@
3
3
  module Bs5
4
4
  class AccordionComponent < ViewComponent::Base
5
5
  include ComponentsHelper
6
- include ViewComponent::Slotable
6
+ include ViewComponent::SlotableV2
7
7
 
8
- with_slot :item, collection: true, class_name: 'Item'
8
+ renders_many :items, 'ItemComponent'
9
9
 
10
10
  def initialize(flush: false)
11
11
  @flush = flush
@@ -25,7 +25,7 @@ module Bs5
25
25
  class_names.join(' ')
26
26
  end
27
27
 
28
- class Item < ViewComponent::Slot
28
+ class ItemComponent < ViewComponent::Base
29
29
  attr_reader :title
30
30
 
31
31
  def initialize(title:, collapsed: true)
@@ -33,6 +33,10 @@ module Bs5
33
33
  @collapsed = collapsed
34
34
  end
35
35
 
36
+ def call
37
+ content
38
+ end
39
+
36
40
  def id
37
41
  object_id
38
42
  end
@@ -4,13 +4,13 @@ module Bs5
4
4
  class AlertComponent < ViewComponent::Base
5
5
  STYLES = %i[primary secondary success danger warning info light dark].freeze
6
6
 
7
- attr_reader :style, :is_dismissable
7
+ attr_reader :color, :is_dismissable
8
8
 
9
9
  include ActiveModel::Validations
10
- validates :style, style: true
10
+ validates :color, style: true
11
11
 
12
- def initialize(style: :primary, is_dismissable: false)
13
- @style = style.to_sym
12
+ def initialize(color: :primary, is_dismissable: false)
13
+ @color = color.to_sym
14
14
  @is_dismissable = is_dismissable
15
15
  end
16
16
 
@@ -31,7 +31,7 @@ module Bs5
31
31
  end
32
32
 
33
33
  def contextual_class
34
- "alert-#{@style}"
34
+ "alert-#{@color}"
35
35
  end
36
36
  end
37
37
  end
@@ -4,14 +4,14 @@ module Bs5
4
4
  class BadgeComponent < ViewComponent::Base
5
5
  STYLES = %i[primary secondary success danger warning info light dark].freeze
6
6
 
7
- attr_reader :text, :style
7
+ attr_reader :text, :color
8
8
 
9
9
  include ActiveModel::Validations
10
- validates :style, style: true
10
+ validates :color, style: true
11
11
 
12
- def initialize(text:, style: :secondary, pill: false)
12
+ def initialize(text:, color: :secondary, pill: false)
13
13
  @text = text
14
- @style = style.to_sym
14
+ @color = color.to_sym
15
15
  @pill = pill
16
16
  end
17
17
 
@@ -32,8 +32,8 @@ module Bs5
32
32
  end
33
33
 
34
34
  def contextual_class
35
- class_names = ["bg-#{@style}"]
36
- class_names << %w[text-dark] if style.in?(%i[warning info light])
35
+ class_names = ["bg-#{@color}"]
36
+ class_names << %w[text-dark] if color.in?(%i[warning info light])
37
37
  class_names.join(' ')
38
38
  end
39
39
  end
@@ -2,7 +2,7 @@
2
2
  <nav aria-label="breadcrumb">
3
3
  <ol class="breadcrumb">
4
4
  <% items.each do |item| %>
5
- <li class="breadcrumb-item <%= item == items.last ? 'active' : '' %>" <%= item == items.last ? 'aria-current=page' : '' %>><%= item.content %></li>
5
+ <li class="breadcrumb-item <%= item == items.last ? 'active' : '' %>" <%= item == items.last ? 'aria-current=page' : '' %>><%= item %></li>
6
6
  <% end %>
7
7
  </ol>
8
8
  </nav>
@@ -2,11 +2,14 @@
2
2
 
3
3
  module Bs5
4
4
  class BreadcrumbComponent < ViewComponent::Base
5
- include ViewComponent::Slotable
5
+ include ViewComponent::SlotableV2
6
6
 
7
- with_slot :item, collection: true, class_name: 'Item'
7
+ renders_many :items, 'ItemComponent'
8
8
 
9
- class Item < ViewComponent::Slot
9
+ class ItemComponent < ViewComponent::Base
10
+ def call
11
+ content
12
+ end
10
13
  end
11
14
  end
12
15
  end
@@ -3,14 +3,14 @@
3
3
  module Bs5
4
4
  class ButtonTagComponent < ViewComponent::Base
5
5
  STYLES = %i[primary secondary success danger warning info light dark link].freeze
6
- DEFAULT_STYLE = :primary
6
+ DEFAULT_COLOR = :primary
7
7
  SIZES = { small: :sm, large: :lg }.freeze
8
8
  CLASS_PREFIX = 'btn'
9
9
 
10
10
  attr_reader :content_or_options, :size
11
11
 
12
12
  include ActiveModel::Validations
13
- validates :style, style: true
13
+ validates :color, style: true
14
14
  validates :size, inclusion: { in: SIZES.keys, valid_sizes: SIZES.keys.to_sentence, allow_nil: true }
15
15
 
16
16
  def initialize(content_or_options = nil, options = nil)
@@ -44,13 +44,13 @@ module Bs5
44
44
  end
45
45
 
46
46
  def extract_custom_options
47
- extract_style
47
+ extract_color
48
48
  extract_outline
49
49
  extract_size
50
50
  end
51
51
 
52
- def extract_style
53
- @style = @options.delete(:style)
52
+ def extract_color
53
+ @color = @options.delete(:color)
54
54
  end
55
55
 
56
56
  def extract_outline
@@ -76,7 +76,7 @@ module Bs5
76
76
  end
77
77
 
78
78
  def contextual_class
79
- [CLASS_PREFIX, outline? ? 'outline' : nil, style].compact.join('-')
79
+ [CLASS_PREFIX, outline? ? 'outline' : nil, color].compact.join('-')
80
80
  end
81
81
 
82
82
  def size_class
@@ -85,8 +85,8 @@ module Bs5
85
85
  [CLASS_PREFIX, SIZES[size]].join('-')
86
86
  end
87
87
 
88
- def style
89
- (@style || DEFAULT_STYLE).to_sym
88
+ def color
89
+ (@color || DEFAULT_COLOR).to_sym
90
90
  end
91
91
 
92
92
  def outline?
@@ -3,14 +3,14 @@
3
3
  module Bs5
4
4
  class ButtonToComponent < ViewComponent::Base
5
5
  STYLES = %i[primary secondary success danger warning info light dark link].freeze
6
- DEFAULT_STYLE = :primary
6
+ DEFAULT_COLOR = :primary
7
7
  SIZES = { small: :sm, large: :lg }.freeze
8
8
  CLASS_PREFIX = 'btn'
9
9
 
10
10
  attr_reader :size
11
11
 
12
12
  include ActiveModel::Validations
13
- validates :style, style: true
13
+ validates :color, style: true
14
14
  validates :size, inclusion: { in: SIZES.keys, valid_sizes: SIZES.keys.to_sentence, allow_nil: true }
15
15
 
16
16
  def initialize(name = nil, options = nil, html_options = nil)
@@ -53,13 +53,13 @@ module Bs5
53
53
  end
54
54
 
55
55
  def extract_custom_options
56
- extract_style
56
+ extract_color
57
57
  extract_outline
58
58
  extract_size
59
59
  end
60
60
 
61
- def extract_style
62
- @style = @button_to_options.delete(:style)
61
+ def extract_color
62
+ @color = @button_to_options.delete(:color)
63
63
  end
64
64
 
65
65
  def extract_outline
@@ -85,7 +85,7 @@ module Bs5
85
85
  end
86
86
 
87
87
  def contextual_class
88
- [CLASS_PREFIX, outline? ? 'outline' : nil, style].compact.join('-')
88
+ [CLASS_PREFIX, outline? ? 'outline' : nil, color].compact.join('-')
89
89
  end
90
90
 
91
91
  def size_class
@@ -94,8 +94,8 @@ module Bs5
94
94
  [CLASS_PREFIX, SIZES[size]].join('-')
95
95
  end
96
96
 
97
- def style
98
- (@style || DEFAULT_STYLE).to_sym
97
+ def color
98
+ (@color || DEFAULT_COLOR).to_sym
99
99
  end
100
100
 
101
101
  def outline?
@@ -2,7 +2,8 @@
2
2
  <div class="border rounded-2 p-4">
3
3
  <%= render template: snippet %>
4
4
  </div>
5
- <div class="highlight p-4">
5
+ <div class="highlight p-4 position-relative">
6
+ <%= bs5_button_tag('Copy', color: :primary, outline: true, size: :small, class: 'position-absolute top-0 end-0 mt-2 me-2', data: { bs5: 'copy' }) %>
6
7
  <pre class='mb-0'><code><%= highlight %></code></pre>
7
8
  </div>
8
9
  </div>
@@ -2,14 +2,14 @@
2
2
  <% if actionables? %>
3
3
  <div class="<%= component_class %>">
4
4
  <% items.each do |item| %>
5
- <%= item.decorated_content %>
5
+ <%= item %>
6
6
  <% end %>
7
7
  </div>
8
8
  <% else %>
9
9
  <ul class="<%= component_class %>">
10
10
  <% items.each do |item| %>
11
11
  <%= tag.li(**item.options) do %>
12
- <%= item.content %>
12
+ <%= item %>
13
13
  <% end %>
14
14
  <% end %>
15
15
  </ul>
@@ -6,9 +6,9 @@ module Bs5
6
6
  CLASS_NAME_FLUSH = "#{CLASS_NAME_BASE}-flush"
7
7
  CLASS_NAME_HORIZONTAL = "#{CLASS_NAME_BASE}-horizontal"
8
8
 
9
- include ViewComponent::Slotable
9
+ include ViewComponent::SlotableV2
10
10
 
11
- with_slot :item, collection: true, class_name: 'Item'
11
+ renders_many :items, 'Item'
12
12
 
13
13
  def initialize(flush: false, horizontal: false)
14
14
  @flush = flush
@@ -22,7 +22,10 @@ module Bs5
22
22
  end
23
23
 
24
24
  def actionables?
25
- items.any?(&:actionable?)
25
+ items.any? do |item|
26
+ elements = Nokogiri::HTML::DocumentFragment.parse(item.to_s).elements
27
+ elements.one? && elements.first.name.in?(%w[a button label])
28
+ end
26
29
  end
27
30
 
28
31
  def horizontal?
@@ -48,7 +51,7 @@ module Bs5
48
51
  class_names.join('-')
49
52
  end
50
53
 
51
- class Item < ViewComponent::Slot
54
+ class Item < ViewComponent::Base
52
55
  CLASS_NAME_BASE = 'list-group-item'
53
56
  CLASS_NAME_ACTION = "#{CLASS_NAME_BASE}-action"
54
57
 
@@ -59,11 +62,15 @@ module Bs5
59
62
 
60
63
  @active = @options.delete(:active) || false
61
64
  @disabled = @options.delete(:disabled) || false
62
- @style = @options.delete(:style)
65
+ @color = @options.delete(:color)
63
66
 
64
67
  set_attributes
65
68
  end
66
69
 
70
+ def call
71
+ actionable? ? decorated_content : content
72
+ end
73
+
67
74
  def actionable?
68
75
  !!actionable_element
69
76
  end
@@ -118,7 +125,7 @@ module Bs5
118
125
  class_names = [CLASS_NAME_BASE]
119
126
  class_names << 'active' if active?
120
127
  class_names << 'disabled' if disabled?
121
- class_names << contextual_class if style?
128
+ class_names << contextual_class if color?
122
129
 
123
130
  class_names
124
131
  end
@@ -131,12 +138,12 @@ module Bs5
131
138
  !!@disabled
132
139
  end
133
140
 
134
- def style?
135
- !!@style
141
+ def color?
142
+ !!@color
136
143
  end
137
144
 
138
145
  def contextual_class
139
- [CLASS_NAME_BASE, @style].join('-')
146
+ [CLASS_NAME_BASE, @color].join('-')
140
147
  end
141
148
  end
142
149
  end
@@ -0,0 +1,5 @@
1
+ <%= tag.div(**component_attributes) do %>
2
+ <%- if text %>
3
+ <span class="visually-hidden"><%= text %></span>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ class SpinnerComponent < ViewComponent::Base
5
+ STYLES = %i[primary secondary success danger warning info light dark].freeze
6
+ SIZES = { small: :sm, large: :lg }.freeze
7
+
8
+ attr_reader :text, :color, :size, :options
9
+
10
+ include ActiveModel::Validations
11
+ validates :color, style: true, if: -> { color }
12
+
13
+ def initialize(options = {})
14
+ @options = options.symbolize_keys
15
+
16
+ @text = @options.delete(:text)
17
+ @color = @options.delete(:color)&.to_sym
18
+ @grow = @options.delete(:grow)
19
+ @size = @options.delete(:size)&.to_sym
20
+ end
21
+
22
+ def before_render
23
+ raise errors.full_messages.to_sentence if invalid?
24
+ end
25
+
26
+ def component_attributes
27
+ options[:class] = component_class
28
+ options[:role] = 'status'
29
+ options
30
+ end
31
+
32
+ def component_class
33
+ class_names = Array(options[:class])
34
+ class_names << shape_class
35
+ class_names << contextual_class
36
+ class_names << size_class
37
+
38
+ class_names.compact.join(' ')
39
+ end
40
+
41
+ private
42
+
43
+ def shape_class
44
+ grow? ? 'spinner-grow' : 'spinner-border'
45
+ end
46
+
47
+ def contextual_class
48
+ "text-#{@color}" if color
49
+ end
50
+
51
+ def size_class
52
+ return unless size?
53
+
54
+ [shape_class, SIZES[size]].join('-')
55
+ end
56
+
57
+ def grow?
58
+ !!@grow
59
+ end
60
+
61
+ def size?
62
+ !!size
63
+ end
64
+ end
65
+ end
@@ -3,7 +3,7 @@
3
3
  module Bs5
4
4
  module ComponentsHelper
5
5
  COMPONENTS = %w[accordion alert badge close_button breadcrumb button_group button_tag button_to button_toolbar
6
- list_group].freeze
6
+ list_group spinner].freeze
7
7
 
8
8
  COMPONENTS.each do |name|
9
9
  define_method("bs5_#{name}") do |*args, &block|