foundation_rails_helper 2.0.0 → 4.0.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +3 -6
- data/.rubocop_todo.yml +6 -48
- data/.travis.yml +29 -11
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -0
- data/README.md +49 -50
- data/Rakefile +1 -0
- data/foundation_rails_helper.gemspec +31 -32
- data/lib/foundation_rails_helper.rb +2 -0
- data/lib/foundation_rails_helper/action_view_extension.rb +1 -0
- data/lib/foundation_rails_helper/configuration.rb +4 -1
- data/lib/foundation_rails_helper/flash_helper.rb +43 -16
- data/lib/foundation_rails_helper/form_builder.rb +61 -83
- data/lib/foundation_rails_helper/size_class_calculator.rb +32 -0
- data/lib/foundation_rails_helper/version.rb +2 -1
- data/lib/railtie.rb +1 -0
- data/spec/.rubocop.yml +3 -0
- data/spec/foundation_rails_helper/configuration_spec.rb +30 -3
- data/spec/foundation_rails_helper/flash_helper_spec.rb +37 -23
- data/spec/foundation_rails_helper/form_builder_spec.rb +464 -178
- data/spec/spec_helper.rb +1 -0
- data/spec/support/classes/author.rb +13 -0
- data/spec/support/classes/book.rb +13 -0
- data/spec/support/classes/genre.rb +13 -0
- data/spec/support/mock_rails.rb +64 -100
- metadata +39 -30
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'foundation_rails_helper/version'
|
2
3
|
require 'foundation_rails_helper/configuration'
|
3
4
|
require 'foundation_rails_helper/form_builder'
|
5
|
+
require 'foundation_rails_helper/size_class_calculator'
|
4
6
|
require 'foundation_rails_helper/flash_helper'
|
5
7
|
require 'foundation_rails_helper/action_view_extension'
|
6
8
|
ActiveSupport.on_load(:action_view) do
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FoundationRailsHelper
|
2
3
|
class << self
|
3
4
|
attr_writer :configuration
|
@@ -18,10 +19,12 @@ module FoundationRailsHelper
|
|
18
19
|
class Configuration
|
19
20
|
attr_accessor :button_class
|
20
21
|
attr_accessor :ignored_flash_keys
|
22
|
+
attr_accessor :auto_labels
|
21
23
|
|
22
24
|
def initialize
|
23
|
-
@button_class = '
|
25
|
+
@button_class = 'success button'
|
24
26
|
@ignored_flash_keys = []
|
27
|
+
@auto_labels = true
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
@@ -1,44 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'action_view/helpers'
|
2
3
|
|
3
4
|
module FoundationRailsHelper
|
4
5
|
module FlashHelper
|
5
|
-
# <div class="
|
6
|
+
# <div class="callout [success alert secondary]" data-closable>
|
6
7
|
# This is an alert box.
|
7
|
-
# <
|
8
|
+
# <button name="button" type="submit" class="close-button" data-close="">
|
9
|
+
# <span>×</span>
|
10
|
+
# </button>
|
8
11
|
# </div>
|
9
12
|
DEFAULT_KEY_MATCHING = {
|
10
|
-
alert:
|
11
|
-
notice:
|
12
|
-
info:
|
13
|
+
alert: :alert,
|
14
|
+
notice: :success,
|
15
|
+
info: :info,
|
13
16
|
secondary: :secondary,
|
14
|
-
success:
|
15
|
-
error:
|
16
|
-
warning:
|
17
|
+
success: :success,
|
18
|
+
error: :alert,
|
19
|
+
warning: :warning,
|
20
|
+
primary: :primary
|
17
21
|
}.freeze
|
18
|
-
|
22
|
+
|
23
|
+
# Displays the flash messages found in ActionDispatch's +flash+ hash using
|
24
|
+
# Foundation's +callout+ component.
|
25
|
+
#
|
26
|
+
# Parameters:
|
27
|
+
# * +closable+ - A boolean to determine whether the displayed flash messages
|
28
|
+
# should be closable by the user. Defaults to true.
|
29
|
+
# * +key_matching+ - A Hash of key/value pairs mapping flash keys to the
|
30
|
+
# corresponding class to use for the callout box.
|
31
|
+
def display_flash_messages(closable: true, key_matching: {})
|
19
32
|
key_matching = DEFAULT_KEY_MATCHING.merge(key_matching)
|
20
|
-
key_matching.default = :
|
33
|
+
key_matching.default = :primary
|
21
34
|
|
22
35
|
capture do
|
23
36
|
flash.each do |key, value|
|
24
|
-
next if
|
37
|
+
next if ignored_key?(key.to_sym)
|
38
|
+
|
25
39
|
alert_class = key_matching[key.to_sym]
|
26
|
-
concat alert_box(value, alert_class)
|
40
|
+
concat alert_box(value, alert_class, closable)
|
27
41
|
end
|
28
42
|
end
|
29
43
|
end
|
30
44
|
|
31
45
|
private
|
32
46
|
|
33
|
-
def alert_box(value, alert_class)
|
34
|
-
|
47
|
+
def alert_box(value, alert_class, closable)
|
48
|
+
options = { class: "flash callout #{alert_class}" }
|
49
|
+
options[:data] = { closable: '' } if closable
|
50
|
+
content_tag(:div, options) do
|
35
51
|
concat value
|
36
|
-
concat close_link
|
52
|
+
concat close_link if closable
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
40
56
|
def close_link
|
41
|
-
|
57
|
+
button_tag(
|
58
|
+
class: 'close-button',
|
59
|
+
type: 'button',
|
60
|
+
data: { close: '' },
|
61
|
+
aria: { label: 'Dismiss alert' }
|
62
|
+
) do
|
63
|
+
content_tag(:span, '×'.html_safe, aria: { hidden: true })
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def ignored_key?(key)
|
68
|
+
FoundationRailsHelper.configuration.ignored_flash_keys.include?(key)
|
42
69
|
end
|
43
70
|
end
|
44
71
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'action_view/helpers'
|
2
3
|
|
3
4
|
module FoundationRailsHelper
|
4
5
|
class FormBuilder < ActionView::Helpers::FormBuilder
|
5
6
|
include ActionView::Helpers::TagHelper
|
7
|
+
include ActionView::Helpers::OutputSafetyHelper
|
6
8
|
%w(file_field email_field text_field text_area telephone_field phone_field
|
7
9
|
url_field number_field date_field datetime_field datetime_local_field
|
8
10
|
month_field week_field time_field range_field search_field color_field)
|
@@ -17,21 +19,23 @@ module FoundationRailsHelper
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def label(attribute, text = nil, options = {})
|
20
|
-
if
|
22
|
+
if error?(attribute)
|
21
23
|
options[:class] ||= ''
|
22
|
-
options[:class] += '
|
24
|
+
options[:class] += ' is-invalid-label'
|
23
25
|
end
|
24
26
|
|
25
27
|
super(attribute, (text || '').html_safe, options)
|
26
28
|
end
|
27
29
|
|
30
|
+
# rubocop:disable LineLength
|
28
31
|
def check_box(attribute, options = {}, checked_value = '1', unchecked_value = '0')
|
29
32
|
custom_label(attribute, options[:label], options[:label_options]) do
|
30
33
|
options.delete(:label)
|
31
34
|
options.delete(:label_options)
|
32
35
|
super(attribute, options, checked_value, unchecked_value)
|
33
|
-
end +
|
36
|
+
end + error_and_help_text(attribute, options)
|
34
37
|
end
|
38
|
+
# rubocop:enable LineLength
|
35
39
|
|
36
40
|
def radio_button(attribute, tag_value, options = {})
|
37
41
|
options[:label_options] ||= {}
|
@@ -62,12 +66,14 @@ module FoundationRailsHelper
|
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
69
|
+
# rubocop:disable LineLength
|
65
70
|
def time_zone_select(attribute, priorities = nil, options = {}, html_options = {})
|
66
71
|
field attribute, options, html_options do |html_opts|
|
67
72
|
super(attribute, priorities, options,
|
68
73
|
html_opts.merge(autocomplete: :off))
|
69
74
|
end
|
70
75
|
end
|
76
|
+
# rubocop:enable LineLength
|
71
77
|
|
72
78
|
def select(attribute, choices, options = {}, html_options = {})
|
73
79
|
field attribute, options, html_options do |html_opts|
|
@@ -76,6 +82,7 @@ module FoundationRailsHelper
|
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
85
|
+
# rubocop:disable LineLength, ParameterLists
|
79
86
|
def collection_select(attribute, collection, value_method, text_method, options = {}, html_options = {})
|
80
87
|
field attribute, options, html_options do |html_opts|
|
81
88
|
html_options[:autocomplete] ||= :off
|
@@ -91,6 +98,7 @@ module FoundationRailsHelper
|
|
91
98
|
option_key_method, option_value_method, options, html_opts)
|
92
99
|
end
|
93
100
|
end
|
101
|
+
# rubocop:enable LineLength, ParameterLists
|
94
102
|
|
95
103
|
def autocomplete(attribute, url, options = {})
|
96
104
|
field attribute, options do |opts|
|
@@ -105,71 +113,43 @@ module FoundationRailsHelper
|
|
105
113
|
super(value, options)
|
106
114
|
end
|
107
115
|
|
108
|
-
private
|
109
|
-
|
110
|
-
def has_error?(attribute)
|
111
|
-
object.respond_to?(:errors) && !object.errors[attribute].blank?
|
112
|
-
end
|
113
|
-
|
114
116
|
def error_for(attribute, options = {})
|
115
|
-
|
116
|
-
class_name += " #{options[:class]}" if options[:class]
|
117
|
+
return unless error?(attribute)
|
117
118
|
|
118
|
-
|
119
|
+
class_name = 'form-error is-visible'
|
120
|
+
class_name += " #{options[:class]}" if options[:class]
|
119
121
|
|
120
122
|
error_messages = object.errors[attribute].join(', ')
|
121
123
|
error_messages = error_messages.html_safe if options[:html_safe_errors]
|
122
|
-
content_tag(:small, error_messages,
|
124
|
+
content_tag(:small, error_messages,
|
125
|
+
class: class_name.sub('is-invalid-input', ''))
|
123
126
|
end
|
124
127
|
|
125
|
-
|
126
|
-
return block_given? ? yield.html_safe : ''.html_safe if text == false
|
127
|
-
if text.nil? || text == true
|
128
|
-
text =
|
129
|
-
if object.class.respond_to?(:human_attribute_name)
|
130
|
-
object.class.human_attribute_name(attribute)
|
131
|
-
else
|
132
|
-
attribute.to_s.humanize
|
133
|
-
end
|
134
|
-
end
|
135
|
-
text = yield.html_safe + " #{text}" if block_given?
|
136
|
-
options ||= {}
|
137
|
-
label(attribute, text, options)
|
138
|
-
end
|
128
|
+
private
|
139
129
|
|
140
|
-
def
|
141
|
-
|
142
|
-
classes + ' columns'
|
130
|
+
def error?(attribute)
|
131
|
+
object.respond_to?(:errors) && !object.errors[attribute].blank?
|
143
132
|
end
|
144
133
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
@medium = size_options[:medium]
|
149
|
-
@large = size_options[:large]
|
134
|
+
def default_label_text(object, attribute)
|
135
|
+
if object.class.respond_to?(:human_attribute_name)
|
136
|
+
return object.class.human_attribute_name(attribute)
|
150
137
|
end
|
151
138
|
|
152
|
-
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
private
|
157
|
-
|
158
|
-
def small_class
|
159
|
-
"small-#{@small}" if valid_size(@small)
|
160
|
-
end
|
139
|
+
attribute.to_s.humanize
|
140
|
+
end
|
161
141
|
|
162
|
-
|
163
|
-
|
164
|
-
end
|
142
|
+
def custom_label(attribute, text, options)
|
143
|
+
return block_given? ? yield.html_safe : ''.html_safe if text == false
|
165
144
|
|
166
|
-
|
167
|
-
|
168
|
-
|
145
|
+
text = default_label_text(object, attribute) if text.nil? || text == true
|
146
|
+
text = safe_join([yield, text.html_safe]) if block_given?
|
147
|
+
label(attribute, text, options || {})
|
148
|
+
end
|
169
149
|
|
170
|
-
|
171
|
-
|
172
|
-
|
150
|
+
def column_classes(options)
|
151
|
+
classes = SizeClassCalculator.new(options).classes
|
152
|
+
classes + ' columns'
|
173
153
|
end
|
174
154
|
|
175
155
|
def tag_from_options(name, options)
|
@@ -181,7 +161,7 @@ module FoundationRailsHelper
|
|
181
161
|
end
|
182
162
|
|
183
163
|
def decrement_input_size(input, column, options)
|
184
|
-
return unless options.key?(column)
|
164
|
+
return unless options.present? && options.key?(column)
|
185
165
|
|
186
166
|
input.send("#{column}=",
|
187
167
|
(input.send(column) - options.fetch(column).to_i))
|
@@ -191,15 +171,9 @@ module FoundationRailsHelper
|
|
191
171
|
def calculate_input_size(prefix_options, postfix_options)
|
192
172
|
input_size =
|
193
173
|
OpenStruct.new(changed?: false, small: 12, medium: 12, large: 12)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
end
|
198
|
-
end
|
199
|
-
if postfix_options.present?
|
200
|
-
%w(small medium large).each do |size|
|
201
|
-
decrement_input_size(input_size, size.to_sym, postfix_options)
|
202
|
-
end
|
174
|
+
%w(small medium large).each do |size|
|
175
|
+
decrement_input_size(input_size, size.to_sym, prefix_options)
|
176
|
+
decrement_input_size(input_size, size.to_sym, postfix_options)
|
203
177
|
end
|
204
178
|
|
205
179
|
input_size
|
@@ -213,45 +187,49 @@ module FoundationRailsHelper
|
|
213
187
|
klass = column_classes(input_size.marshal_dump).to_s
|
214
188
|
input = content_tag(:div, block, class: klass)
|
215
189
|
|
216
|
-
|
217
|
-
|
218
|
-
content_tag(:div, prefix + input + postfix, class: 'row collapse')
|
219
|
-
else
|
220
|
-
block
|
221
|
-
end
|
222
|
-
|
223
|
-
html.html_safe
|
190
|
+
return block unless input_size.changed?
|
191
|
+
content_tag(:div, prefix + input + postfix, class: 'row collapse')
|
224
192
|
end
|
225
193
|
|
226
|
-
def
|
194
|
+
def error_and_help_text(attribute, options = {})
|
227
195
|
html = ''
|
228
|
-
|
196
|
+
if options[:help_text]
|
197
|
+
html += content_tag(:p, options[:help_text], class: 'help-text')
|
198
|
+
end
|
229
199
|
html += error_for(attribute, options) || ''
|
230
200
|
html.html_safe
|
231
201
|
end
|
232
202
|
|
203
|
+
def field_label(attribute, options)
|
204
|
+
return ''.html_safe unless auto_labels || options[:label]
|
205
|
+
custom_label(attribute, options[:label], options[:label_options])
|
206
|
+
end
|
207
|
+
|
233
208
|
def field(attribute, options, html_options = nil)
|
234
|
-
|
235
|
-
html = if auto_labels || options[:label]
|
236
|
-
custom_label(attribute, options[:label], options[:label_options])
|
237
|
-
else
|
238
|
-
''.html_safe
|
239
|
-
end
|
209
|
+
html = field_label(attribute, options)
|
240
210
|
class_options = html_options || options
|
241
211
|
|
242
|
-
if
|
212
|
+
if error?(attribute)
|
243
213
|
class_options[:class] = class_options[:class].to_s
|
244
|
-
class_options[:class] += '
|
214
|
+
class_options[:class] += ' is-invalid-input'
|
245
215
|
end
|
246
216
|
|
247
217
|
options.delete(:label)
|
248
218
|
options.delete(:label_options)
|
249
|
-
|
219
|
+
help_text = options.delete(:help_text)
|
250
220
|
prefix = options.delete(:prefix)
|
251
221
|
postfix = options.delete(:postfix)
|
252
222
|
|
253
223
|
html += wrap_prefix_and_postfix(yield(class_options), prefix, postfix)
|
254
|
-
html +
|
224
|
+
html + error_and_help_text(attribute, options.merge(help_text: help_text))
|
225
|
+
end
|
226
|
+
|
227
|
+
def auto_labels
|
228
|
+
if @options[:auto_labels].nil?
|
229
|
+
FoundationRailsHelper.configuration.auto_labels
|
230
|
+
else
|
231
|
+
@options[:auto_labels]
|
232
|
+
end
|
255
233
|
end
|
256
234
|
end
|
257
235
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FoundationRailsHelper
|
3
|
+
class SizeClassCalculator
|
4
|
+
def initialize(size_options)
|
5
|
+
@small = size_options[:small]
|
6
|
+
@medium = size_options[:medium]
|
7
|
+
@large = size_options[:large]
|
8
|
+
end
|
9
|
+
|
10
|
+
def classes
|
11
|
+
[small_class, medium_class, large_class].compact.join(' ')
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def small_class
|
17
|
+
"small-#{@small}" if valid_size(@small)
|
18
|
+
end
|
19
|
+
|
20
|
+
def medium_class
|
21
|
+
"medium-#{@medium}" if valid_size(@medium)
|
22
|
+
end
|
23
|
+
|
24
|
+
def large_class
|
25
|
+
"large-#{@large}" if valid_size(@large)
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_size(value)
|
29
|
+
value.present? && value.to_i < 12
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/railtie.rb
CHANGED
data/spec/.rubocop.yml
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "spec_helper"
|
2
3
|
|
3
4
|
describe FoundationRailsHelper do
|
4
5
|
describe FoundationRailsHelper::Configuration do
|
5
6
|
describe "#button_class" do
|
6
|
-
it "default value is '
|
7
|
+
it "default value is 'success button'" do
|
7
8
|
config = FoundationRailsHelper::Configuration.new
|
8
|
-
expect(config.button_class).to eq("
|
9
|
+
expect(config.button_class).to eq("success button")
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
@@ -32,6 +33,21 @@ describe FoundationRailsHelper do
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
describe "#auto_labels" do
|
37
|
+
it "default value is 'true'" do
|
38
|
+
config = FoundationRailsHelper::Configuration.new
|
39
|
+
expect(config.auto_labels).to be(true)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#auto_labels=" do
|
44
|
+
it "can set the value" do
|
45
|
+
config = FoundationRailsHelper::Configuration.new
|
46
|
+
config.auto_labels = false
|
47
|
+
expect(config.auto_labels).to be(false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
35
51
|
describe ".reset" do
|
36
52
|
it "resets the configured button class" do
|
37
53
|
FoundationRailsHelper.configure do |config|
|
@@ -41,7 +57,7 @@ describe FoundationRailsHelper do
|
|
41
57
|
FoundationRailsHelper.reset
|
42
58
|
|
43
59
|
config = FoundationRailsHelper.configuration
|
44
|
-
expect(config.button_class).to eq("
|
60
|
+
expect(config.button_class).to eq("success button")
|
45
61
|
end
|
46
62
|
|
47
63
|
it "resets the configured ignored flash keys" do
|
@@ -54,6 +70,17 @@ describe FoundationRailsHelper do
|
|
54
70
|
config = FoundationRailsHelper.configuration
|
55
71
|
expect(config.ignored_flash_keys).to eq([])
|
56
72
|
end
|
73
|
+
|
74
|
+
it "resets the configured auto labels" do
|
75
|
+
FoundationRailsHelper.configure do |config|
|
76
|
+
config.auto_labels = false
|
77
|
+
end
|
78
|
+
|
79
|
+
FoundationRailsHelper.reset
|
80
|
+
|
81
|
+
config = FoundationRailsHelper.configuration
|
82
|
+
expect(config.auto_labels).to be(true)
|
83
|
+
end
|
57
84
|
end
|
58
85
|
end
|
59
86
|
end
|