bs5 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/bs5/alert_component.rb +2 -0
  3. data/app/components/bs5/badge_component.rb +2 -0
  4. data/app/components/bs5/button_tag_component.rb +121 -0
  5. data/app/helpers/bs5/components_helper.rb +9 -18
  6. data/app/validators/style_validator.rb +2 -4
  7. data/app/views/bs5/examples/_buttons.html.erb +7 -0
  8. data/app/views/bs5/examples/buttons/block_buttons/_example.html.erb +5 -0
  9. data/app/views/bs5/examples/buttons/block_buttons/block_buttons.html.erb +4 -0
  10. data/app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_1.html.erb +4 -0
  11. data/app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_2.html.erb +4 -0
  12. data/app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_3.html.erb +4 -0
  13. data/app/views/bs5/examples/buttons/default/_example.html.erb +2 -0
  14. data/app/views/bs5/examples/buttons/default/snippet.html.erb +15 -0
  15. data/app/views/bs5/examples/buttons/outline/_example.html.erb +2 -0
  16. data/app/views/bs5/examples/buttons/outline/snippet.html.erb +19 -0
  17. data/app/views/bs5/examples/buttons/size/_example.html.erb +3 -0
  18. data/app/views/bs5/examples/buttons/size/large.html.erb +3 -0
  19. data/app/views/bs5/examples/buttons/size/small.html.erb +3 -0
  20. data/app/views/bs5/examples/buttons/style/_example.html.erb +2 -0
  21. data/app/views/bs5/examples/buttons/style/snippet.html.erb +19 -0
  22. data/app/views/bs5/examples/buttons/toggle_states/_example.html.erb +2 -0
  23. data/app/views/bs5/examples/buttons/toggle_states/snippet.html.erb +3 -0
  24. data/app/views/bs5/examples/index.html.erb +2 -0
  25. data/config/definitions.rb +31 -0
  26. data/config/locales/en.yml +6 -0
  27. data/lib/bs5/version.rb +1 -1
  28. metadata +21 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77c7e79d854010df72b9492702bd2983468fb9237d3aecf619f3f6267db8c6fd
4
- data.tar.gz: cc4cc0afd6b51f9c7b59ce3b38842255b7b4131640104aa297e9f10a655be51d
3
+ metadata.gz: 54b572156c8e8680ba3937031736fe9cdb6e2aeaf2ea88cb49b6e26c18e02c35
4
+ data.tar.gz: 4a4650ceee8e21d32f6a905f00c398e072bb407a4f118cd95488454f9ef61121
5
5
  SHA512:
6
- metadata.gz: 0cc7b7a7c486b2b7783fbe4970900b9ec009ffcdb32bb9271fce6d15b24ef6ed7a407e6a67bb3a3056d7f3fdd64b1861b58f9baa6e012962ccdd0237d51063de
7
- data.tar.gz: 6f5bad0ae1ce081d539855c2249292b2e2dbce5de4ece7d983aba5d31caf6414ff0b8f790a83927653db2c33c02845271ec222bceca6d01d9a5b90dc6f4c7e20
6
+ metadata.gz: c3be0fb1a7839cafbd9673ee974879fd2e95c13e25c5a0f73a27c278c0f2abb1d4305d7eaf965999e5c5fcd390079d116c9aea297e63c1ce5530fdc3e455deb8
7
+ data.tar.gz: 73f164bfd36774c565a358e23e294d49b8f386db1450e92a9e73cefd81fa2951b7560705c6e098607a5005e50bf071c094a23d1eacfadf304be61c07995771df
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Bs5
4
4
  class AlertComponent < ViewComponent::Base
5
+ STYLES = %i[primary secondary success danger warning info light dark].freeze
6
+
5
7
  attr_reader :style, :is_dismissable
6
8
 
7
9
  include ActiveModel::Validations
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Bs5
4
4
  class BadgeComponent < ViewComponent::Base
5
+ STYLES = %i[primary secondary success danger warning info light dark].freeze
6
+
5
7
  attr_reader :text, :style
6
8
 
7
9
  include ActiveModel::Validations
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bs5
4
+ class ButtonTagComponent < ViewComponent::Base
5
+ STYLES = %i[primary secondary success danger warning info light dark link].freeze
6
+ SIZES = %i[small large].freeze
7
+
8
+ attr_reader :content_or_options, :options, :size
9
+
10
+ include ActiveModel::Validations
11
+ validates :style, style: true
12
+ validates :size, inclusion: { in: SIZES, valid_sizes: SIZES.to_sentence, allow_nil: true }
13
+
14
+ def initialize(content_or_options = nil, options = nil)
15
+ @content_or_options = content_or_options.dup
16
+ @options = options.dup
17
+
18
+ extract_custom_options
19
+ merge_default_options
20
+ end
21
+
22
+ def before_render
23
+ raise errors.full_messages.to_sentence if invalid?
24
+ end
25
+
26
+ def call
27
+ if content
28
+ button_tag(content_or_options, options) { content }
29
+ else
30
+ button_tag(content_or_options, options)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def extract_custom_options
37
+ extract_style
38
+ extract_outline
39
+ extract_size
40
+ end
41
+
42
+ def extract_style
43
+ if @content_or_options.is_a? Hash
44
+ @style = @content_or_options.delete(:style)
45
+ @content_or_options = nil if @content_or_options.empty?
46
+ elsif @options.is_a? Hash
47
+ @style = @options.delete(:style)
48
+ @options = nil if @options.empty?
49
+ end
50
+ end
51
+
52
+ def extract_outline
53
+ if @content_or_options.is_a? Hash
54
+ @outline = @content_or_options.delete(:outline)
55
+ @content_or_options = nil if @content_or_options.empty?
56
+ elsif @options.is_a? Hash
57
+ @outline = @options.delete(:outline)
58
+ @options = nil if @options.empty?
59
+ end
60
+ end
61
+
62
+ def extract_size
63
+ if @content_or_options.is_a? Hash
64
+ @size = @content_or_options.delete(:size)
65
+ @content_or_options = nil if @content_or_options.empty?
66
+ elsif @options.is_a? Hash
67
+ @size = @options.delete(:size)
68
+ @options = nil if @options.empty?
69
+ end
70
+ end
71
+
72
+ def merge_default_options
73
+ if @content_or_options.is_a? Hash
74
+ deep_merge_and_join @content_or_options, default_options
75
+ else
76
+ @options ||= {}
77
+ deep_merge_and_join @options, default_options
78
+ end
79
+ end
80
+
81
+ def default_options
82
+ {
83
+ class: button_class
84
+ }
85
+ end
86
+
87
+ def button_class
88
+ ['btn', contextual_class, size_class].compact.join(' ')
89
+ end
90
+
91
+ def contextual_class
92
+ ['btn', outline? ? 'outline' : nil, style].compact.join('-')
93
+ end
94
+
95
+ def size_class
96
+ return unless size?
97
+
98
+ x = { large: 'lg', small: 'sm' }[@size]
99
+
100
+ "btn-#{x}"
101
+ end
102
+
103
+ def style
104
+ (@style || 'primary').to_sym
105
+ end
106
+
107
+ def outline?
108
+ !!@outline
109
+ end
110
+
111
+ def size?
112
+ !!@size
113
+ end
114
+
115
+ def deep_merge_and_join(h1, h2)
116
+ h1.deep_merge!(h2) do |key, this_val, other_val|
117
+ [this_val, other_val].join(' ').strip
118
+ end
119
+ end
120
+ end
121
+ end
@@ -2,29 +2,20 @@
2
2
 
3
3
  module Bs5
4
4
  module ComponentsHelper
5
- def bs5_accordion(*args)
6
- render AccordionComponent.new(*args) do |accordion|
7
- yield accordion if block_given?
8
- end
9
- end
5
+ COMPONENTS = %w[accordion alert badge close_button breadcrumb button_tag].freeze
10
6
 
11
- def bs5_alert(*args)
12
- render AlertComponent.new(*args) do
13
- yield if block_given?
7
+ COMPONENTS.each do |name|
8
+ define_method("bs5_#{name}") do |*args, &block|
9
+ clazz = "Bs5::#{name.classify}Component".constantize
10
+ render_component(clazz, *args, &block)
14
11
  end
15
12
  end
16
13
 
17
- def bs5_badge(*args)
18
- render BadgeComponent.new(*args)
19
- end
20
-
21
- def bs5_close_button(*args)
22
- render CloseButtonComponent.new(*args)
23
- end
14
+ private
24
15
 
25
- def bs5_breadcrumb(*args)
26
- render BreadcrumbComponent.new(*args) do |breadcrumb|
27
- yield breadcrumb if block_given?
16
+ def render_component(component_clazz, *args)
17
+ render component_clazz.new(*args) do |c|
18
+ yield c if block_given?
28
19
  end
29
20
  end
30
21
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class StyleValidator < ActiveModel::EachValidator
4
- STYLES = %i[primary secondary success danger warning info light dark].freeze
5
-
6
4
  def validate_each(record, attribute, value)
7
- return if value.in?(STYLES)
5
+ return if value.in?(valid_styles = record.class::STYLES)
8
6
 
9
- record.errors.add(attribute, :inclusion, valid_styles: STYLES.to_sentence)
7
+ record.errors.add(attribute, :inclusion, valid_styles: valid_styles.to_sentence)
10
8
  end
11
9
  end
@@ -0,0 +1,7 @@
1
+ <h2>Buttons</h2>
2
+ <%= render 'bs5/examples/buttons/default/example' %>
3
+ <%= render 'bs5/examples/buttons/style/example' %>
4
+ <%= render 'bs5/examples/buttons/outline/example' %>
5
+ <%= render 'bs5/examples/buttons/size/example' %>
6
+ <%= render 'bs5/examples/buttons/block_buttons/example' %>
7
+ <%= render 'bs5/examples/buttons/toggle_states/example' %>
@@ -0,0 +1,5 @@
1
+ <h3>Block buttons</h3>
2
+ <%= bs5_example(snippet: 'buttons/block_buttons/block_buttons') %>
3
+ <%= bs5_example(snippet: 'buttons/block_buttons/responsive_block_buttons_1') %>
4
+ <%= bs5_example(snippet: 'buttons/block_buttons/responsive_block_buttons_2') %>
5
+ <%= bs5_example(snippet: 'buttons/block_buttons/responsive_block_buttons_3') %>
@@ -0,0 +1,4 @@
1
+ <div class="d-grid gap-2">
2
+ <%= bs5_button_tag %>
3
+ <%= bs5_button_tag %>
4
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="d-grid gap-2 d-md-block">
2
+ <%= bs5_button_tag %>
3
+ <%= bs5_button_tag %>
4
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="d-grid gap-2 col-6 mx-auto">
2
+ <%= bs5_button_tag %>
3
+ <%= bs5_button_tag %>
4
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="d-grid gap-2 d-md-flex justify-content-md-end">
2
+ <%= bs5_button_tag('Button', class: 'mr-md-2') %>
3
+ <%= bs5_button_tag %>
4
+ </div>
@@ -0,0 +1,2 @@
1
+ <h3>Example</h3>
2
+ <%= bs5_example(snippet: 'buttons/default/snippet') %>
@@ -0,0 +1,15 @@
1
+ <%= bs5_button_tag %>
2
+
3
+ <%= bs5_button_tag 'Reset', type: 'reset' %>
4
+
5
+ <%= bs5_button_tag 'Button', type: 'button' %>
6
+
7
+ <%= bs5_button_tag 'Reset', type: 'reset', disabled: true %>
8
+
9
+ <%= bs5_button_tag(type: 'button') do %>
10
+ <%= content_tag(:strong, 'Ask me!') %>
11
+ <% end %>
12
+
13
+ <%= bs5_button_tag 'Save', data: { confirm: 'Are you sure?' } %>
14
+
15
+ <%= bs5_button_tag 'Checkout', data: { disable_with: 'Please wait...' } %>
@@ -0,0 +1,2 @@
1
+ <h3>Outline</h3>
2
+ <%= bs5_example(snippet: 'buttons/outline/snippet') %>
@@ -0,0 +1,19 @@
1
+ <%= bs5_button_tag 'Primary', style: :primary, outline: true %>
2
+
3
+ <%= bs5_button_tag 'Secondary', style: :secondary, outline: true %>
4
+
5
+ <%= bs5_button_tag 'Success', style: :success, outline: true %>
6
+
7
+ <%= bs5_button_tag 'Danger', style: :danger, outline: true %>
8
+
9
+ <%= bs5_button_tag(style: :warning, outline: true, type: 'button') do %>
10
+ <%= content_tag(:strong, 'Warning') %>
11
+ <% end %>
12
+
13
+ <%= bs5_button_tag 'Info', style: :info, outline: true %>
14
+
15
+ <%= bs5_button_tag 'Light', style: :light, outline: true %>
16
+
17
+ <%= bs5_button_tag 'Dark', style: :dark, outline: true %>
18
+
19
+ <%= bs5_button_tag 'Link', style: :link, outline: true %>
@@ -0,0 +1,3 @@
1
+ <h3>Sizes</h3>
2
+ <%= bs5_example(snippet: 'buttons/size/large') %>
3
+ <%= bs5_example(snippet: 'buttons/size/small') %>
@@ -0,0 +1,3 @@
1
+ <%= bs5_button_tag 'Large button', style: :primary, size: :large %>
2
+
3
+ <%= bs5_button_tag 'Large button', style: :secondary, size: :large %>
@@ -0,0 +1,3 @@
1
+ <%= bs5_button_tag 'Small button', style: :primary, size: :small %>
2
+
3
+ <%= bs5_button_tag 'Small button', style: :secondary, size: :small %>
@@ -0,0 +1,2 @@
1
+ <h3>Style</h3>
2
+ <%= bs5_example(snippet: 'buttons/style/snippet') %>
@@ -0,0 +1,19 @@
1
+ <%= bs5_button_tag 'Primary', style: :primary %>
2
+
3
+ <%= bs5_button_tag 'Secondary', style: :secondary %>
4
+
5
+ <%= bs5_button_tag 'Success', style: :success %>
6
+
7
+ <%= bs5_button_tag 'Danger', style: :danger %>
8
+
9
+ <%= bs5_button_tag(style: :warning, type: 'button') do %>
10
+ <%= content_tag(:strong, 'Warning') %>
11
+ <% end %>
12
+
13
+ <%= bs5_button_tag 'Info', style: :info %>
14
+
15
+ <%= bs5_button_tag 'Light', style: :light %>
16
+
17
+ <%= bs5_button_tag 'Dark', style: :dark %>
18
+
19
+ <%= bs5_button_tag 'Link', style: :link %>
@@ -0,0 +1,2 @@
1
+ <h3>Toggle states</h3>
2
+ <%= bs5_example(snippet: 'buttons/toggle_states/snippet') %>
@@ -0,0 +1,3 @@
1
+ <%= bs5_button_tag('Toggle button', data: { toggle: 'button' }, autocomplete: 'off') %>
2
+ <%= bs5_button_tag('Active toggle button', class: 'active', data: { toggle: 'button' }, autocomplete: 'off', aria: { pressed: true }) %>
3
+ <%= bs5_button_tag('Disabled toggle button', data: { toggle: 'button' }, autocomplete: 'off', disabled: true) %>
@@ -7,6 +7,7 @@
7
7
  <li>Badge</li>
8
8
  <li>Close button</li>
9
9
  <li>Breadcrumb</li>
10
+ <li>Buttons</li>
10
11
  </ul>
11
12
  </div>
12
13
  </div>
@@ -17,5 +18,6 @@
17
18
  <%= render 'badge' %>
18
19
  <%= render 'close_button' %>
19
20
  <%= render 'breadcrumb' %>
21
+ <%= render 'buttons' %>
20
22
  </div>
21
23
  </div>
@@ -0,0 +1,31 @@
1
+ # The following comments fill some of the gaps in Solargraph's understanding of
2
+ # Rails apps. Since they're all in YARD, they get mapped in Solargraph but
3
+ # ignored at runtime.
4
+ #
5
+ # You can put this file anywhere in the project, as long as it gets included in
6
+ # the workspace maps. It's recommended that you keep it in a standalone file
7
+ # instead of pasting it into an existing one.
8
+ #
9
+ # @!parse
10
+ # class ActionController::Base
11
+ # include ActionController::MimeResponds
12
+ # extend ActiveSupport::Callbacks::ClassMethods
13
+ # extend AbstractController::Callbacks::ClassMethods
14
+ # end
15
+ # class ActiveRecord::Base
16
+ # extend ActiveRecord::QueryMethods
17
+ # extend ActiveRecord::FinderMethods
18
+ # extend ActiveRecord::Associations::ClassMethods
19
+ # extend ActiveRecord::Inheritance::ClassMethods
20
+ # include ActiveRecord::Persistence
21
+ # end
22
+ # @!override ActiveRecord::FinderMethods#find
23
+ # @overload find(id)
24
+ # @param id [Integer]
25
+ # @return [self]
26
+ # @overload find(list)
27
+ # @param list [Array]
28
+ # @return [Array<self>]
29
+ # @overload find(*args)
30
+ # @return [Array<self>]
31
+ # @return [self, Array<self>]
@@ -6,3 +6,9 @@ en:
6
6
  attributes:
7
7
  style:
8
8
  inclusion: "is not included in the list: %{valid_styles}."
9
+ bs5/button_tag_component:
10
+ attributes:
11
+ style:
12
+ inclusion: "is not included in the list: %{valid_styles}."
13
+ size:
14
+ inclusion: "is not included in the list: %{valid_sizes}."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bs5
4
- VERSION = '0.0.8'
4
+ VERSION = '0.0.9'
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.8
4
+ version: 0.0.9
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-11-22 00:00:00.000000000 Z
11
+ date: 2020-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -134,6 +134,7 @@ files:
134
134
  - app/components/bs5/badge_component.rb
135
135
  - app/components/bs5/breadcrumb_component.html.erb
136
136
  - app/components/bs5/breadcrumb_component.rb
137
+ - app/components/bs5/button_tag_component.rb
137
138
  - app/components/bs5/close_button_component.html.erb
138
139
  - app/components/bs5/close_button_component.rb
139
140
  - app/components/bs5/example_component.html.erb
@@ -149,6 +150,7 @@ files:
149
150
  - app/views/bs5/examples/_alert.html.erb
150
151
  - app/views/bs5/examples/_badge.html.erb
151
152
  - app/views/bs5/examples/_breadcrumb.html.erb
153
+ - app/views/bs5/examples/_buttons.html.erb
152
154
  - app/views/bs5/examples/_close_button.html.erb
153
155
  - app/views/bs5/examples/accordion/default/_example.html.erb
154
156
  - app/views/bs5/examples/accordion/default/snippet.html.erb
@@ -170,6 +172,22 @@ files:
170
172
  - app/views/bs5/examples/badge/style/snippet.html.erb
171
173
  - app/views/bs5/examples/breadcrumb/default/_example.html.erb
172
174
  - app/views/bs5/examples/breadcrumb/default/snippet.html.erb
175
+ - app/views/bs5/examples/buttons/block_buttons/_example.html.erb
176
+ - app/views/bs5/examples/buttons/block_buttons/block_buttons.html.erb
177
+ - app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_1.html.erb
178
+ - app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_2.html.erb
179
+ - app/views/bs5/examples/buttons/block_buttons/responsive_block_buttons_3.html.erb
180
+ - app/views/bs5/examples/buttons/default/_example.html.erb
181
+ - app/views/bs5/examples/buttons/default/snippet.html.erb
182
+ - app/views/bs5/examples/buttons/outline/_example.html.erb
183
+ - app/views/bs5/examples/buttons/outline/snippet.html.erb
184
+ - app/views/bs5/examples/buttons/size/_example.html.erb
185
+ - app/views/bs5/examples/buttons/size/large.html.erb
186
+ - app/views/bs5/examples/buttons/size/small.html.erb
187
+ - app/views/bs5/examples/buttons/style/_example.html.erb
188
+ - app/views/bs5/examples/buttons/style/snippet.html.erb
189
+ - app/views/bs5/examples/buttons/toggle_states/_example.html.erb
190
+ - app/views/bs5/examples/buttons/toggle_states/snippet.html.erb
173
191
  - app/views/bs5/examples/close_button/default/_example.html.erb
174
192
  - app/views/bs5/examples/close_button/default/snippet.html.erb
175
193
  - app/views/bs5/examples/close_button/disabled/_example.html.erb
@@ -178,6 +196,7 @@ files:
178
196
  - app/views/bs5/examples/close_button/white/snippet.html.erb
179
197
  - app/views/bs5/examples/index.html.erb
180
198
  - app/views/layouts/bs5/application.html.erb
199
+ - config/definitions.rb
181
200
  - config/locales/en.yml
182
201
  - config/routes.rb
183
202
  - lib/bs5.rb