govuk_elements_rails 0.2.1 → 0.2.2
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 +4 -4
- data/README.md +13 -7
- data/app/builders/labelling_form_builder.rb +316 -0
- data/lib/govuk_elements_rails/version.rb +1 -1
- data/vendor/assets/javascripts/application.js +134 -0
- data/vendor/assets/javascripts/details.polyfill.js +61 -15
- data/vendor/assets/javascripts/selection-buttons.js +72 -98
- data/vendor/assets/stylesheets/elements-page.scss +48 -3
- data/vendor/assets/stylesheets/elements/_buttons.scss +6 -0
- data/vendor/assets/stylesheets/elements/_details.scss +1 -0
- data/vendor/assets/stylesheets/elements/_forms.scss +6 -2
- data/vendor/assets/stylesheets/elements/_layout.scss +3 -3
- data/vendor/assets/stylesheets/elements/_lists.scss +5 -2
- data/vendor/assets/stylesheets/elements/_tables.scss +12 -1
- data/vendor/assets/stylesheets/elements/forms/_form-block-labels.scss +1 -1
- data/vendor/assets/stylesheets/elements/forms/_form-date.scss +27 -34
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85648682a9e22e34cd2e42af89725178d104b997
|
4
|
+
data.tar.gz: 827a92dcc7d95e073db4e2590bbe28ffbbb4ca22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17519e48bc499d28e907ac48025bb631b06581e87791f3086713ecd9208b69439d9cf8dd4f8a3d390e93e376a465df5faa3c2c8ac8225b0f6ac570ffab48eb87
|
7
|
+
data.tar.gz: e7c7b1fb30e9f189121ff0ea168c694237b3e8354ec007f3c55ed0f3923b2398908666ed73111657095f8a7ca321597c5a297e42278ccd8a6c29997ca8028d5c
|
data/README.md
CHANGED
@@ -15,6 +15,19 @@ If you are installing from git, ensure you enable submodules like so:
|
|
15
15
|
|
16
16
|
gem 'govuk_elements_rails', :git => "https://github.com/ministryofjustice/govuk_elements_rails.git", :submodules => true
|
17
17
|
|
18
|
+
If you are working on the gem itself, clone and download submodules like this:
|
19
|
+
|
20
|
+
git clone https://github.com/ministryofjustice/govuk_elements_rails.git
|
21
|
+
cd govuk_elements_rails
|
22
|
+
git submodule init
|
23
|
+
git submodule update
|
24
|
+
|
25
|
+
To add a javascript file to gem, create new symlink to govuk_elements file like this:
|
26
|
+
|
27
|
+
cd vendor/assets/javascripts/
|
28
|
+
ln -s ../../../govuk_elements/public/javascripts/application.js
|
29
|
+
ls -l
|
30
|
+
|
18
31
|
## Usage
|
19
32
|
|
20
33
|
At the top of a Sass file in your Rails project you should use an `@import` rule
|
@@ -43,13 +56,6 @@ For example here are all the requires possible at present:
|
|
43
56
|
//= require bind
|
44
57
|
//= require selection-buttons
|
45
58
|
|
46
|
-
## Usage of GovukElementsFormBuilder
|
47
|
-
|
48
|
-
To replace the default form builder with a version that generates GOV.UK Elements classed markup, set the following in
|
49
|
-
config/application.rb:
|
50
|
-
|
51
|
-
config.use_govuk_elements_form_builder = true
|
52
|
-
|
53
59
|
## Alternate ways to reuse GOV.UK Elements
|
54
60
|
|
55
61
|
There are other alternate ways to include GOV.UK Elements files in a Rails
|
@@ -0,0 +1,316 @@
|
|
1
|
+
|
2
|
+
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
|
3
|
+
|
4
|
+
include ActionView::Helpers::CaptureHelper
|
5
|
+
include ActionView::Helpers::TagHelper
|
6
|
+
include ActionView::Context
|
7
|
+
|
8
|
+
def text_field_row(attribute, options={})
|
9
|
+
row_input attribute, :text_field, options
|
10
|
+
end
|
11
|
+
|
12
|
+
def text_area_row(attribute, options={})
|
13
|
+
row_input attribute, :text_area, options
|
14
|
+
end
|
15
|
+
|
16
|
+
def moj_date_fieldset attribute, legend, options = {}, example_date = Date.today, explanatory_text = nil
|
17
|
+
df = MojDateFieldset.new(self, attribute, legend, options, example_date, explanatory_text)
|
18
|
+
df.emit
|
19
|
+
end
|
20
|
+
|
21
|
+
# produces an postcode picker widget - this will produce an address/street and postcode attributes for the given object type
|
22
|
+
# @param [String] attribute: the name of the attribute on Claim which is to have the street and postcode attributes (e.g. property, defendant_1)
|
23
|
+
# @param [Hash] options: options to control the way in which the potcode picker is displayed, and what html is generated in the form:
|
24
|
+
# :prefix - the prefix to be applied to each element in the form
|
25
|
+
# :postcode_attr - the name of the postcode attribute if not 'postcode'
|
26
|
+
# :address_attr - the name of the address attribute if not 'street'
|
27
|
+
# :name - the prefix of the name given to the street and postcode attributes if not 'claim['xxxx'] where xxxx is the attribute
|
28
|
+
# :street_hint - and html which is to be inserted as a hint above the street textarea
|
29
|
+
# :vc - list of valid countries: postcodes that return a country not in the supplied list will be marked as invalid.
|
30
|
+
# If not supplied or blank, all countries are valid. Countries should be joined by '+' and spaces in country names should be replaced
|
31
|
+
# by underscores, e.g "england+wales+channel_islands+isle_of_man"
|
32
|
+
# :button_label - the text to use on the Find UK Address button if not 'Find Uk Address'
|
33
|
+
#
|
34
|
+
def moj_postcode_picker attribute, options = {}
|
35
|
+
default_options = {
|
36
|
+
:prefix => "claim_#{attribute}",
|
37
|
+
:postcode_attr => :postcode,
|
38
|
+
:address_attr => :street,
|
39
|
+
:name => "claim[#{attribute}]"
|
40
|
+
}
|
41
|
+
options = default_options.merge(options)
|
42
|
+
mpp = MojPostcodePicker.new(self, options)
|
43
|
+
mpp.emit
|
44
|
+
end
|
45
|
+
|
46
|
+
# Defaults to "Yes" "No" labels on radio inputs
|
47
|
+
def radio_button_fieldset attribute, legend, options={}
|
48
|
+
translation_key = translation_key(attribute)
|
49
|
+
raise "TBD: #{translation_key} #{options[:choice]}" if options[:choice].is_a?(Hash)
|
50
|
+
|
51
|
+
virtual_pageview = options[:data] ? options[:data].delete('virtual-pageview') : nil
|
52
|
+
input_class = options.delete(:input_class)
|
53
|
+
|
54
|
+
set_class_and_id attribute, options
|
55
|
+
|
56
|
+
options[:choice] ||= [ 'Yes', 'No' ]
|
57
|
+
|
58
|
+
options_class = options[:class][/inline/] ? 'inline' : 'options'
|
59
|
+
|
60
|
+
data_reverse = options.delete(:toggle_fieldset) ? ' data-reverse="true"' : ''
|
61
|
+
|
62
|
+
fieldset_tag attribute, legend, options do
|
63
|
+
@template.surround("<div class='#{options_class}'#{data_reverse}>".html_safe, "</div>".html_safe) do
|
64
|
+
options[:choice].map do |choice|
|
65
|
+
radio_button_row(attribute, choice, virtual_pageview, input_class)
|
66
|
+
end.join("\n")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def row attribute, options={}
|
72
|
+
@template.haml_tag haml_tag_text('div option', attribute, options) do
|
73
|
+
yield
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def error_for? attribute
|
78
|
+
# if @object.is_a?(Claim)
|
79
|
+
# subkey = "claim_#{attribute}_error"
|
80
|
+
# base_errors = error_message_for(:base)
|
81
|
+
# base_errors && base_errors.to_h.key?(subkey) && !base_errors.to_h[subkey].empty?
|
82
|
+
# else
|
83
|
+
attribute_errors = error_message_for(attribute)
|
84
|
+
attribute_errors && !attribute_errors.empty?
|
85
|
+
# end
|
86
|
+
end
|
87
|
+
|
88
|
+
def error_span attribute, options={}
|
89
|
+
@template.surround(error_span_open_tag(options), "</span>".html_safe) do
|
90
|
+
error_span_message(attribute)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Creates key for lookup of translation text.
|
95
|
+
# E.g. translation_key(hearing, {:choice=>"No"}) when in possession form
|
96
|
+
# returns "claim.possession.hearing.no"
|
97
|
+
def translation_key attribute, options={}
|
98
|
+
key = "#{ parent_id.gsub('_','.') }.#{attribute}".squeeze('.')
|
99
|
+
key.gsub!(/\.\d+\./, '.')
|
100
|
+
if choice = options[:choice]
|
101
|
+
choice = 'na' if choice == ''
|
102
|
+
key += ".#{choice.downcase}"
|
103
|
+
end
|
104
|
+
key
|
105
|
+
end
|
106
|
+
|
107
|
+
def error_id_for attribute
|
108
|
+
field_id = "#{parent_id}_#{attribute}".squeeze('_')
|
109
|
+
"#{field_id}_error"
|
110
|
+
end
|
111
|
+
|
112
|
+
def parent_id
|
113
|
+
@object_name.to_s.tr('[]','_').squeeze('_')
|
114
|
+
end
|
115
|
+
|
116
|
+
def labelled_check_box attribute, label, yes='Yes', no='No', options={}
|
117
|
+
set_class_and_id attribute, options
|
118
|
+
hidden_input = check_box_input_hidden attribute, options, yes, no
|
119
|
+
|
120
|
+
labeled_input = label(attribute) do
|
121
|
+
check_box_input(attribute, options, yes, no) + label
|
122
|
+
end
|
123
|
+
|
124
|
+
list = [hidden_input]
|
125
|
+
|
126
|
+
if error_for?(attribute)
|
127
|
+
id = error_id_for(attribute)
|
128
|
+
labeled_input.sub!(%Q[id="#{id}"], %Q[id="#{id.sub('_error','')}"])
|
129
|
+
list << hidden_fullstop(options)
|
130
|
+
list << error_span(attribute)
|
131
|
+
end
|
132
|
+
|
133
|
+
list << labeled_input
|
134
|
+
|
135
|
+
list.join("\n").html_safe
|
136
|
+
end
|
137
|
+
|
138
|
+
def set_class_and_id attribute, options
|
139
|
+
options[:class] = css_for(attribute, options)
|
140
|
+
options[:id] = id_for(attribute) unless id_for(attribute).blank?
|
141
|
+
end
|
142
|
+
|
143
|
+
def fieldset_tag(attribute, legend_text, options = {}, &block)
|
144
|
+
fieldset = tag(:fieldset, options_for_fieldset(options), true)
|
145
|
+
|
146
|
+
fieldset.safe_concat legend_for(attribute, legend_text, options) unless legend_text.blank?
|
147
|
+
|
148
|
+
fieldset.concat(capture(&block)) if block_given?
|
149
|
+
fieldset.safe_concat("</fieldset>")
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def fieldset attribute, options={}
|
155
|
+
options.delete(:id) unless options[:id].present?
|
156
|
+
@template.haml_tag haml_tag_text('fieldset', attribute, options) do
|
157
|
+
yield
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def id_for attribute, default=nil
|
162
|
+
error_for?(attribute) ? error_id_for(attribute) : (default || '')
|
163
|
+
end
|
164
|
+
|
165
|
+
def label_content_for attribute, label, options={}
|
166
|
+
label ||= attribute.to_s.humanize
|
167
|
+
label = ["#{label}"]
|
168
|
+
hint = hint_span(options)
|
169
|
+
label << hint if hint
|
170
|
+
if error_for?(attribute)
|
171
|
+
last = label.pop
|
172
|
+
label << ( ends_with_punctuation?(last) ? last : (last + hidden_fullstop(options)) )
|
173
|
+
label << error_span(attribute, options)
|
174
|
+
end
|
175
|
+
label.join(" ").html_safe
|
176
|
+
end
|
177
|
+
|
178
|
+
def hint_span options
|
179
|
+
options[:hint] ? "<span class='hint block'>#{options[:hint]}</span>".html_safe : nil
|
180
|
+
end
|
181
|
+
|
182
|
+
def ends_with_punctuation? span
|
183
|
+
span[/\?<\/span/] || span[/\.<\/span>/] || span[/\.|\?$/]
|
184
|
+
end
|
185
|
+
|
186
|
+
def legend_for attribute, legend_text, options
|
187
|
+
label = label_content_for(attribute, legend_text, hint: options[:hint])
|
188
|
+
content_tag(:legend, label)
|
189
|
+
end
|
190
|
+
|
191
|
+
def hidden_fullstop options
|
192
|
+
'<span class="visuallyhidden">.</span>'.html_safe
|
193
|
+
end
|
194
|
+
|
195
|
+
def error_span_message attribute
|
196
|
+
if @object.is_a? Claim
|
197
|
+
error_message_for(:base).to_h["claim_#{attribute}_error"]
|
198
|
+
else
|
199
|
+
error_message_for(attribute)[0]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def error_span_open_tag options
|
204
|
+
" <span class='error#{error_classes(options)}'#{error_span_id(options)}>".html_safe
|
205
|
+
end
|
206
|
+
|
207
|
+
def error_span_id options
|
208
|
+
options.has_key?(:id)? " id='#{options[:id]}'" : nil
|
209
|
+
end
|
210
|
+
|
211
|
+
def error_classes options
|
212
|
+
' visuallyhidden' if options[:hidden]
|
213
|
+
end
|
214
|
+
|
215
|
+
def options_for_fieldset options
|
216
|
+
options.delete(:class) if options[:class].blank?
|
217
|
+
options = {}.merge(options)
|
218
|
+
options.delete(:hint)
|
219
|
+
options.delete(:choice)
|
220
|
+
options.delete(:date_select_options)
|
221
|
+
options
|
222
|
+
end
|
223
|
+
|
224
|
+
def error_message_for symbol
|
225
|
+
@object.errors.messages[symbol]
|
226
|
+
end
|
227
|
+
|
228
|
+
def check_box_input attribute, options, yes, no
|
229
|
+
html = check_box(attribute, options, yes, no)
|
230
|
+
html.gsub!(/<[^<]*type="hidden"[^>]*>/,'')
|
231
|
+
html.html_safe
|
232
|
+
end
|
233
|
+
|
234
|
+
def check_box_input_hidden attribute, options, yes, no
|
235
|
+
html = check_box(attribute, options, yes, no)
|
236
|
+
html.gsub!(/.*(<[^<]*type="hidden"[^>]*>).*/, '\1')
|
237
|
+
html.html_safe
|
238
|
+
end
|
239
|
+
|
240
|
+
def radio_button_row attribute, choice, virtual_pageview, input_class
|
241
|
+
translation_key = translation_key(attribute, choice: choice)
|
242
|
+
|
243
|
+
translation = I18n.t(translation_key)
|
244
|
+
raise "translation missing: #{translation_key}" if translation[/translation missing/]
|
245
|
+
label = translation unless translation[/translation missing/]
|
246
|
+
|
247
|
+
options = {}
|
248
|
+
options.merge!(class: input_class) if input_class
|
249
|
+
options.merge!(data: { 'virtual_pageview' => virtual_pageview }) if virtual_pageview
|
250
|
+
|
251
|
+
input = radio_button(attribute, choice, options)
|
252
|
+
|
253
|
+
id = input[/id="([^"]+)"/,1]
|
254
|
+
|
255
|
+
@template.surround("<div class='option'>".html_safe, "</div>".html_safe) do
|
256
|
+
@template.surround("<label for='#{id}'>".html_safe, "</label>".html_safe) do
|
257
|
+
# errors = error_span(attribute, {hidden: true}) if error_for?(attribute)
|
258
|
+
[
|
259
|
+
# errors,
|
260
|
+
input,
|
261
|
+
label
|
262
|
+
].compact.join("\n")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def css_for attribute, options
|
268
|
+
css = ''
|
269
|
+
css += " #{options[:class]}" if options[:class].present?
|
270
|
+
css += ' error' if error_for?(attribute)
|
271
|
+
css.strip
|
272
|
+
end
|
273
|
+
|
274
|
+
def haml_tag_text tag, attribute, options
|
275
|
+
tag += " #{css_for(attribute, options)}"
|
276
|
+
haml_tag_text = tag.squeeze(' ').strip.gsub(' ','.')
|
277
|
+
end
|
278
|
+
|
279
|
+
def row_input attribute, input_type, options
|
280
|
+
virtual_pageview = options[:data] ? options[:data].delete('virtual-pageview') : nil
|
281
|
+
css = "form-group #{css_for(attribute, options)}".strip
|
282
|
+
id = id_for(attribute).blank? ? '' : "id='#{id_for(attribute)}' "
|
283
|
+
|
284
|
+
@template.surround("<div #{id}class='#{css}'>".html_safe, "</div>".html_safe) do
|
285
|
+
input_options = options.merge(class: "form-control #{options[:input_class]}".strip)
|
286
|
+
input_options.merge!(data: {'virtual_pageview' => virtual_pageview}) if virtual_pageview
|
287
|
+
input_options.delete(:label)
|
288
|
+
input_options.delete(:input_class)
|
289
|
+
|
290
|
+
labelled_input attribute, input_type, input_options, options[:label]
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def labelled_input attribute, input_type, input_options, label=nil
|
295
|
+
label = label(attribute, label_content_for(attribute, label), class: 'form-label')
|
296
|
+
|
297
|
+
if max_length = max_length(attribute)
|
298
|
+
input_options.merge!(maxlength: max_length)
|
299
|
+
end
|
300
|
+
|
301
|
+
value = send(input_type, attribute, input_options)
|
302
|
+
|
303
|
+
[ label, value ].join("\n").html_safe
|
304
|
+
end
|
305
|
+
|
306
|
+
def max_length attribute
|
307
|
+
if validator = validators(attribute).detect{|x| x.is_a?(ActiveModel::Validations::LengthValidator)}
|
308
|
+
validator.options[:maximum]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def validators attribute
|
313
|
+
@object.class.validators_on(attribute)
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
function ShowHideContent() {
|
2
|
+
var self = this;
|
3
|
+
|
4
|
+
|
5
|
+
self.escapeElementName = function(str) {
|
6
|
+
result = str.replace('[', '\\[').replace(']', '\\]')
|
7
|
+
return(result);
|
8
|
+
};
|
9
|
+
|
10
|
+
self.showHideRadioToggledContent = function () {
|
11
|
+
$(".block-label input[type='radio']").each(function () {
|
12
|
+
|
13
|
+
var $radio = $(this);
|
14
|
+
var $radioGroupName = $radio.attr('name');
|
15
|
+
var $radioLabel = $radio.parent('label');
|
16
|
+
|
17
|
+
var dataTarget = $radioLabel.attr('data-target');
|
18
|
+
|
19
|
+
// Add ARIA attributes
|
20
|
+
|
21
|
+
// If the data-target attribute is defined
|
22
|
+
if (dataTarget) {
|
23
|
+
|
24
|
+
// Set aria-controls
|
25
|
+
$radio.attr('aria-controls', dataTarget);
|
26
|
+
|
27
|
+
$radio.on('click', function () {
|
28
|
+
|
29
|
+
// Select radio buttons in the same group
|
30
|
+
$radio.closest('form').find(".block-label input[name=" + self.escapeElementName($radioGroupName) + "]").each(function () {
|
31
|
+
var $this = $(this);
|
32
|
+
|
33
|
+
var groupDataTarget = $this.parent('label').attr('data-target');
|
34
|
+
var $groupDataTarget = $('#' + groupDataTarget);
|
35
|
+
|
36
|
+
// Hide toggled content
|
37
|
+
$groupDataTarget.hide();
|
38
|
+
// Set aria-expanded and aria-hidden for hidden content
|
39
|
+
$this.attr('aria-expanded', 'false');
|
40
|
+
$groupDataTarget.attr('aria-hidden', 'true');
|
41
|
+
});
|
42
|
+
|
43
|
+
var $dataTarget = $('#' + dataTarget);
|
44
|
+
$dataTarget.show();
|
45
|
+
// Set aria-expanded and aria-hidden for clicked radio
|
46
|
+
$radio.attr('aria-expanded', 'true');
|
47
|
+
$dataTarget.attr('aria-hidden', 'false');
|
48
|
+
|
49
|
+
});
|
50
|
+
|
51
|
+
} else {
|
52
|
+
// If the data-target attribute is undefined for a radio button,
|
53
|
+
// hide visible data-target content for radio buttons in the same group
|
54
|
+
|
55
|
+
$radio.on('click', function () {
|
56
|
+
|
57
|
+
// Select radio buttons in the same group
|
58
|
+
$(".block-label input[name=" + self.escapeElementName($radioGroupName) + "]").each(function () {
|
59
|
+
|
60
|
+
var groupDataTarget = $(this).parent('label').attr('data-target');
|
61
|
+
var $groupDataTarget = $('#' + groupDataTarget);
|
62
|
+
|
63
|
+
// Hide toggled content
|
64
|
+
$groupDataTarget.hide();
|
65
|
+
// Set aria-expanded and aria-hidden for hidden content
|
66
|
+
$(this).attr('aria-expanded', 'false');
|
67
|
+
$groupDataTarget.attr('aria-hidden', 'true');
|
68
|
+
});
|
69
|
+
|
70
|
+
});
|
71
|
+
}
|
72
|
+
|
73
|
+
});
|
74
|
+
}
|
75
|
+
self.showHideCheckboxToggledContent = function () {
|
76
|
+
|
77
|
+
$(".block-label input[type='checkbox']").each(function() {
|
78
|
+
|
79
|
+
var $checkbox = $(this);
|
80
|
+
var $checkboxLabel = $(this).parent();
|
81
|
+
|
82
|
+
var $dataTarget = $checkboxLabel.attr('data-target');
|
83
|
+
|
84
|
+
// Add ARIA attributes
|
85
|
+
|
86
|
+
// If the data-target attribute is defined
|
87
|
+
if (typeof $dataTarget !== 'undefined' && $dataTarget !== false) {
|
88
|
+
|
89
|
+
// Set aria-controls
|
90
|
+
$checkbox.attr('aria-controls', $dataTarget);
|
91
|
+
|
92
|
+
// Set aria-expanded and aria-hidden
|
93
|
+
$checkbox.attr('aria-expanded', 'false');
|
94
|
+
$('#'+$dataTarget).attr('aria-hidden', 'true');
|
95
|
+
|
96
|
+
// For checkboxes revealing hidden content
|
97
|
+
$checkbox.on('click', function() {
|
98
|
+
|
99
|
+
var state = $(this).attr('aria-expanded') === 'false' ? true : false;
|
100
|
+
|
101
|
+
// Toggle hidden content
|
102
|
+
$('#'+$dataTarget).toggle();
|
103
|
+
|
104
|
+
// Update aria-expanded and aria-hidden attributes
|
105
|
+
$(this).attr('aria-expanded', state);
|
106
|
+
$('#'+$dataTarget).attr('aria-hidden', !state);
|
107
|
+
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
});
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
$(document).ready(function() {
|
116
|
+
|
117
|
+
// Turn off jQuery animation
|
118
|
+
jQuery.fx.off = true;
|
119
|
+
|
120
|
+
// Use GOV.UK selection-buttons.js to set selected
|
121
|
+
// and focused states for block labels
|
122
|
+
var $blockLabels = $(".block-label input[type='radio'], .block-label input[type='checkbox']");
|
123
|
+
new GOVUK.SelectionButtons($blockLabels);
|
124
|
+
|
125
|
+
// Details/summary polyfill
|
126
|
+
// See /javascripts/vendor/details.polyfill.js
|
127
|
+
|
128
|
+
// Where .block-label uses the data-target attribute
|
129
|
+
// to toggle hidden content
|
130
|
+
var toggleContent = new ShowHideContent();
|
131
|
+
toggleContent.showHideRadioToggledContent();
|
132
|
+
toggleContent.showHideCheckboxToggledContent();
|
133
|
+
|
134
|
+
});
|
@@ -24,16 +24,21 @@
|
|
24
24
|
|
25
25
|
// Handle cross-modal click events
|
26
26
|
function addClickEvent(node, callback) {
|
27
|
-
|
28
|
-
addEvent(node, '
|
29
|
-
|
27
|
+
// Prevent space(32) from scrolling the page
|
28
|
+
addEvent(node, 'keypress', function (e, target) {
|
29
|
+
if (e.keyCode === 32) {
|
30
|
+
if (e.preventDefault) {
|
31
|
+
e.preventDefault();
|
32
|
+
}
|
33
|
+
else { e.returnValue = false; }
|
34
|
+
}
|
30
35
|
});
|
36
|
+
// When the key comes up - check if it is enter(13) or space(32)
|
31
37
|
addEvent(node, 'keyup', function (e, target) {
|
32
|
-
|
33
|
-
if (e.keyCode === 13) { callback(e, target); }
|
38
|
+
if (e.keyCode === 13 || e.keyCode === 32) { callback(e, target); }
|
34
39
|
});
|
35
|
-
addEvent(node, '
|
36
|
-
|
40
|
+
addEvent(node, 'mouseup', function (e, target) {
|
41
|
+
callback(e, target);
|
37
42
|
});
|
38
43
|
}
|
39
44
|
|
@@ -86,6 +91,9 @@
|
|
86
91
|
details.__content.id = 'details-content-' + i;
|
87
92
|
}
|
88
93
|
|
94
|
+
// Add ARIA role="group" to details
|
95
|
+
details.setAttribute('role', 'group');
|
96
|
+
|
89
97
|
// Add role=button to summary
|
90
98
|
details.__summary.setAttribute('role', 'button');
|
91
99
|
|
@@ -93,30 +101,69 @@
|
|
93
101
|
details.__summary.setAttribute('aria-controls', details.__content.id);
|
94
102
|
|
95
103
|
// Set tabindex so the summary is keyboard accessible
|
96
|
-
details.__summary.setAttribute('tabindex',
|
104
|
+
// details.__summary.setAttribute('tabindex', 0);
|
105
|
+
// http://www.saliences.com/browserBugs/tabIndex.html
|
106
|
+
details.__summary.tabIndex = 0;
|
97
107
|
|
98
108
|
// Detect initial open/closed state
|
99
|
-
|
100
|
-
|
109
|
+
|
110
|
+
// Native support - has 'open' attribute
|
111
|
+
if (details.open === true) {
|
101
112
|
details.__summary.setAttribute('aria-expanded', 'true');
|
102
113
|
details.__content.setAttribute('aria-hidden', 'false');
|
103
|
-
|
114
|
+
details.__content.style.display = 'block';
|
115
|
+
}
|
116
|
+
|
117
|
+
// Native support - doesn't have 'open' attribute
|
118
|
+
if (details.open === false) {
|
104
119
|
details.__summary.setAttribute('aria-expanded', 'false');
|
105
120
|
details.__content.setAttribute('aria-hidden', 'true');
|
106
121
|
details.__content.style.display = 'none';
|
107
122
|
}
|
108
123
|
|
124
|
+
// If this is not a native implementation
|
125
|
+
if (!details.__native) {
|
126
|
+
|
127
|
+
// Add an arrow
|
128
|
+
var twisty = document.createElement('i');
|
129
|
+
|
130
|
+
// Check for the 'open' attribute
|
131
|
+
// If open exists, but isn't supported it won't have a value
|
132
|
+
if (details.getAttribute('open') === "") {
|
133
|
+
details.__summary.setAttribute('aria-expanded', 'true');
|
134
|
+
details.__content.setAttribute('aria-hidden', 'false');
|
135
|
+
}
|
136
|
+
|
137
|
+
// If open doesn't exist - it will be null or undefined
|
138
|
+
if (details.getAttribute('open') == null || details.getAttribute('open') == "undefined" ) {
|
139
|
+
details.__summary.setAttribute('aria-expanded', 'false');
|
140
|
+
details.__content.setAttribute('aria-hidden', 'true');
|
141
|
+
details.__content.style.display = 'none';
|
142
|
+
}
|
143
|
+
|
144
|
+
}
|
145
|
+
|
109
146
|
// Create a circular reference from the summary back to its
|
110
147
|
// parent details element, for convenience in the click handler
|
111
148
|
details.__summary.__details = details;
|
112
149
|
|
113
150
|
// If this is not a native implementation, create an arrow
|
114
|
-
// inside the summary
|
151
|
+
// inside the summary
|
115
152
|
if (!details.__native) {
|
153
|
+
|
116
154
|
var twisty = document.createElement('i');
|
117
|
-
|
118
|
-
|
155
|
+
|
156
|
+
if (details.getAttribute('open') === "") {
|
157
|
+
twisty.className = 'arrow arrow-open';
|
158
|
+
twisty.appendChild(document.createTextNode('\u25bc'));
|
159
|
+
} else {
|
160
|
+
twisty.className = 'arrow arrow-closed';
|
161
|
+
twisty.appendChild(document.createTextNode('\u25ba'));
|
162
|
+
}
|
163
|
+
|
119
164
|
details.__summary.__twisty = details.__summary.insertBefore(twisty, details.__summary.firstChild);
|
165
|
+
details.__summary.__twisty.setAttribute('aria-hidden', 'true');
|
166
|
+
|
120
167
|
}
|
121
168
|
}
|
122
169
|
|
@@ -124,7 +171,6 @@
|
|
124
171
|
// Also update the arrow position
|
125
172
|
function statechange(summary) {
|
126
173
|
|
127
|
-
// Update aria-expanded attribute on click
|
128
174
|
var expanded = summary.__details.__summary.getAttribute('aria-expanded') == 'true';
|
129
175
|
var hidden = summary.__details.__content.getAttribute('aria-hidden') == 'true';
|
130
176
|
|
@@ -1,12 +1,13 @@
|
|
1
1
|
(function () {
|
2
|
-
"use strict"
|
2
|
+
"use strict";
|
3
3
|
var root = this,
|
4
4
|
$ = root.jQuery;
|
5
5
|
|
6
6
|
if (typeof GOVUK === 'undefined') { root.GOVUK = {}; }
|
7
7
|
|
8
|
-
var
|
9
|
-
|
8
|
+
var SelectionButtons = function (elmsOrSelector, opts) {
|
9
|
+
var $elms;
|
10
|
+
|
10
11
|
this.selectedClass = 'selected';
|
11
12
|
this.focusedClass = 'focused';
|
12
13
|
if (opts !== undefined) {
|
@@ -14,124 +15,97 @@
|
|
14
15
|
this[optionName] = optionObj;
|
15
16
|
}.bind(this));
|
16
17
|
}
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
if (typeof elmsOrSelector === 'string') {
|
19
|
+
$elms = $(elmsOrSelector);
|
20
|
+
this.selector = elmsOrSelector;
|
21
|
+
this.setInitialState($(this.selector));
|
22
|
+
} else {
|
23
|
+
this.$elms = elmsOrSelector;
|
24
|
+
this.setInitialState(this.$elms);
|
25
|
+
}
|
26
|
+
this.addEvents();
|
20
27
|
};
|
21
|
-
|
22
|
-
this
|
23
|
-
|
28
|
+
SelectionButtons.prototype.addEvents = function () {
|
29
|
+
if (typeof this.$elms !== 'undefined') {
|
30
|
+
this.addElementLevelEvents();
|
31
|
+
} else {
|
32
|
+
this.addDocumentLevelEvents();
|
33
|
+
}
|
24
34
|
};
|
25
|
-
|
26
|
-
|
35
|
+
SelectionButtons.prototype.setInitialState = function ($elms) {
|
36
|
+
$elms.each(function (idx, elm) {
|
37
|
+
var $elm = $(elm);
|
27
38
|
|
39
|
+
if ($elm.is(':checked')) {
|
40
|
+
this.markSelected($elm);
|
41
|
+
}
|
42
|
+
}.bind(this));
|
43
|
+
};
|
44
|
+
SelectionButtons.prototype.markFocused = function ($elm, state) {
|
28
45
|
if (state === 'focused') {
|
29
46
|
$elm.parent('label').addClass(this.focusedClass);
|
30
47
|
} else {
|
31
48
|
$elm.parent('label').removeClass(this.focusedClass);
|
32
49
|
}
|
33
50
|
};
|
34
|
-
|
35
|
-
var
|
36
|
-
focusEventHandler = this.markFocused.bind(this);
|
51
|
+
SelectionButtons.prototype.markSelected = function ($elm) {
|
52
|
+
var radioName;
|
37
53
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
focusEventHandler($(e.target), state);
|
46
|
-
});
|
47
|
-
};
|
48
|
-
|
49
|
-
var RadioButtons = function ($elms, opts) {
|
50
|
-
BaseButtons.apply(this, arguments);
|
51
|
-
};
|
52
|
-
RadioButtons.prototype.setEventNames = function () {
|
53
|
-
// some browsers fire the 'click' when the selected radio changes by keyboard
|
54
|
-
this.selectionEvents = 'click change';
|
55
|
-
this.focusEvents = 'focus blur';
|
56
|
-
};
|
57
|
-
RadioButtons.prototype.getSelections = function () {
|
58
|
-
var selectionEventHandler = this.markSelected.bind(this);
|
59
|
-
|
60
|
-
this.selections = {};
|
61
|
-
$.each(this.$elms, function (index, elm) {
|
62
|
-
var $elm = $(elm),
|
63
|
-
radioName = $elm.attr('name');
|
64
|
-
|
65
|
-
if (typeof this.selections[radioName] === 'undefined') {
|
66
|
-
this.selections[radioName] = false;
|
67
|
-
}
|
54
|
+
if ($elm.attr('type') === 'radio') {
|
55
|
+
radioName = $elm.attr('name');
|
56
|
+
$($elm[0].form).find('input[name="' + radioName + '"]')
|
57
|
+
.parent('label')
|
58
|
+
.removeClass(this.selectedClass);
|
59
|
+
$elm.parent('label').addClass(this.selectedClass);
|
60
|
+
} else { // checkbox
|
68
61
|
if ($elm.is(':checked')) {
|
69
|
-
|
62
|
+
$elm.parent('label').addClass(this.selectedClass);
|
63
|
+
} else {
|
64
|
+
$elm.parent('label').removeClass(this.selectedClass);
|
70
65
|
}
|
71
|
-
}.bind(this));
|
72
|
-
};
|
73
|
-
RadioButtons.prototype.bindEvents = function () {
|
74
|
-
BaseButtons.prototype.bindEvents.call(this);
|
75
|
-
};
|
76
|
-
RadioButtons.prototype.markSelected = function ($elm) {
|
77
|
-
var radioName = $elm.attr('name'),
|
78
|
-
$previousSelection = this.selections[radioName];
|
79
|
-
|
80
|
-
if ($previousSelection) {
|
81
|
-
$previousSelection.parent('label').removeClass(this.selectedClass);
|
82
66
|
}
|
83
|
-
$elm.parent('label').addClass(this.selectedClass);
|
84
|
-
this.selections[radioName] = $elm;
|
85
67
|
};
|
86
|
-
|
87
|
-
|
68
|
+
SelectionButtons.prototype.addElementLevelEvents = function () {
|
69
|
+
this.clickHandler = this.getClickHandler();
|
70
|
+
this.focusHandler = this.getFocusHandler({ 'level' : 'element' });
|
71
|
+
|
72
|
+
this.$elms
|
73
|
+
.on('click', this.clickHandler)
|
74
|
+
.on('focus blur', this.focusHandler);
|
88
75
|
};
|
76
|
+
SelectionButtons.prototype.addDocumentLevelEvents = function () {
|
77
|
+
this.clickHandler = this.getClickHandler();
|
78
|
+
this.focusHandler = this.getFocusHandler({ 'level' : 'document' });
|
89
79
|
|
90
|
-
|
91
|
-
|
80
|
+
$(document)
|
81
|
+
.on('click', this.selector, this.clickHandler)
|
82
|
+
.on('focus blur', this.selector, this.focusHandler);
|
92
83
|
};
|
93
|
-
|
94
|
-
|
84
|
+
SelectionButtons.prototype.getClickHandler = function () {
|
85
|
+
return function (e) {
|
86
|
+
this.markSelected($(e.target));
|
87
|
+
}.bind(this);
|
95
88
|
};
|
96
|
-
|
97
|
-
var
|
89
|
+
SelectionButtons.prototype.getFocusHandler = function (opts) {
|
90
|
+
var focusEvent = (opts.level === 'document') ? 'focusin' : 'focus';
|
98
91
|
|
99
|
-
|
100
|
-
var
|
92
|
+
return function (e) {
|
93
|
+
var state = (e.type === focusEvent) ? 'focused' : 'blurred';
|
101
94
|
|
102
|
-
|
103
|
-
|
104
|
-
}
|
105
|
-
});
|
95
|
+
this.markFocused($(e.target), state);
|
96
|
+
}.bind(this);
|
106
97
|
};
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
$elm.parent('label').addClass(this.selectedClass);
|
98
|
+
SelectionButtons.prototype.destroy = function () {
|
99
|
+
if (typeof this.selector !== 'undefined') {
|
100
|
+
$(document)
|
101
|
+
.off('click', this.selector, this.clickHandler)
|
102
|
+
.off('focus blur', this.selector, this.focusHandler);
|
113
103
|
} else {
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
CheckboxButtons.prototype.markFocused = function ($elm) {
|
118
|
-
BaseButtons.prototype.markFocused.apply(this, arguments);
|
119
|
-
};
|
120
|
-
|
121
|
-
root.GOVUK.RadioButtons = RadioButtons;
|
122
|
-
root.GOVUK.CheckboxButtons = CheckboxButtons;
|
123
|
-
|
124
|
-
var selectionButtons = function ($elms, opts) {
|
125
|
-
var $radios = $elms.filter('[type=radio]'),
|
126
|
-
$checkboxes = $elms.filter('[type=checkbox]');
|
127
|
-
|
128
|
-
if ($radios) {
|
129
|
-
new GOVUK.RadioButtons($radios, opts);
|
130
|
-
}
|
131
|
-
if ($checkboxes) {
|
132
|
-
new GOVUK.CheckboxButtons($checkboxes, opts);
|
104
|
+
this.$elms
|
105
|
+
.off('click', this.clickHandler)
|
106
|
+
.off('focus blur', this.focusHandler);
|
133
107
|
}
|
134
108
|
};
|
135
109
|
|
136
|
-
root.GOVUK.
|
110
|
+
root.GOVUK.SelectionButtons = SelectionButtons;
|
137
111
|
}).call(this);
|
@@ -94,20 +94,51 @@
|
|
94
94
|
color: $hm-government;
|
95
95
|
}
|
96
96
|
|
97
|
+
// Fix grid layout within example boxes for IE7 and below
|
98
|
+
// where box-sizing isn't supported: http://caniuse.com/#search=box-sizing
|
99
|
+
@mixin example-box-column($width) {
|
100
|
+
width: (($site-width - $gutter) * $width) - $gutter;
|
101
|
+
}
|
102
|
+
|
103
|
+
@include ie-lte(7){
|
104
|
+
|
105
|
+
// Set example box width to 900px (removing left and right padding)
|
106
|
+
$example-box-width: $site-width - ($gutter * 2);
|
107
|
+
width: $example-box-width;
|
108
|
+
|
109
|
+
// Recalculate grid column widths
|
110
|
+
.column-quarter {
|
111
|
+
@include example-box-column( 1/4 );
|
112
|
+
}
|
113
|
+
.column-half {
|
114
|
+
@include example-box-column( 1/2 );
|
115
|
+
}
|
116
|
+
.column-third {
|
117
|
+
@include example-box-column( 1/3 );
|
118
|
+
}
|
119
|
+
.column-two-thirds {
|
120
|
+
@include example-box-column( 2/3 );
|
121
|
+
}
|
122
|
+
|
123
|
+
// Scale images to fit grid columns
|
124
|
+
img {
|
125
|
+
width: 100%;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
97
129
|
}
|
98
130
|
|
99
131
|
|
100
132
|
// 1. Layout
|
101
133
|
// ==========================================================================
|
102
134
|
|
103
|
-
// Grid layout boxes
|
104
135
|
.example-grid p {
|
105
136
|
width: 100%;
|
106
137
|
background: file-url("examples/grid.png") 0 0 repeat;
|
107
|
-
min-height: 30px;
|
108
138
|
margin-bottom: 0;
|
139
|
+
height: 30px;
|
109
140
|
@include media(tablet) {
|
110
|
-
|
141
|
+
height: 60px;
|
111
142
|
}
|
112
143
|
overflow: hidden;
|
113
144
|
text-indent: -999em;
|
@@ -331,3 +362,17 @@ $palette: (
|
|
331
362
|
.example-button ul {
|
332
363
|
padding-bottom: 0;
|
333
364
|
}
|
365
|
+
|
366
|
+
|
367
|
+
// 9. Alpha beta banners
|
368
|
+
// ==========================================================================
|
369
|
+
|
370
|
+
// Alpha
|
371
|
+
.phase-banner-alpha {
|
372
|
+
@include phase-banner($state: alpha);
|
373
|
+
}
|
374
|
+
|
375
|
+
// Beta
|
376
|
+
.phase-banner-beta {
|
377
|
+
@include phase-banner($state: beta);
|
378
|
+
}
|
@@ -45,15 +45,19 @@ fieldset {
|
|
45
45
|
// Labels
|
46
46
|
|
47
47
|
// Form labels, or for legends styled to look like labels
|
48
|
+
.form-label,
|
49
|
+
.form-label-bold {
|
50
|
+
display: block;
|
51
|
+
color: $text-colour;
|
52
|
+
}
|
53
|
+
|
48
54
|
.form-label {
|
49
55
|
@include core-19;
|
50
|
-
display: block;
|
51
56
|
margin-bottom: 5px;
|
52
57
|
}
|
53
58
|
|
54
59
|
.form-label-bold {
|
55
60
|
@include bold-24;
|
56
|
-
display: block;
|
57
61
|
margin-bottom: 0;
|
58
62
|
.form-hint {
|
59
63
|
@include core-19;
|
@@ -9,11 +9,11 @@
|
|
9
9
|
@import "design-patterns/alpha-beta";
|
10
10
|
|
11
11
|
|
12
|
-
//
|
12
|
+
// Content
|
13
13
|
// ==========================================================================
|
14
14
|
|
15
|
-
//
|
16
|
-
#
|
15
|
+
// Content wraps the entire site content block
|
16
|
+
#content {
|
17
17
|
@extend %site-width-container;
|
18
18
|
@extend %contain-floats;
|
19
19
|
padding-bottom: $gutter;
|
@@ -10,13 +10,16 @@ ol {
|
|
10
10
|
// Bulleted lists
|
11
11
|
.list-bullet {
|
12
12
|
list-style-type: disc;
|
13
|
-
|
13
|
+
padding-left: 20px;
|
14
14
|
}
|
15
15
|
|
16
16
|
// Numbered lists
|
17
17
|
.list-number {
|
18
18
|
list-style-type: decimal;
|
19
|
-
|
19
|
+
padding-left: 20px;
|
20
|
+
@include ie-lte(7) {
|
21
|
+
padding-left: 28px;
|
22
|
+
}
|
20
23
|
}
|
21
24
|
|
22
25
|
.list-bullet,
|
@@ -14,7 +14,7 @@ table {
|
|
14
14
|
table th,
|
15
15
|
table td {
|
16
16
|
@include core-16;
|
17
|
-
padding: em(
|
17
|
+
padding: em(12, 16) em(20, 16) em(9, 16) 0;
|
18
18
|
|
19
19
|
text-align: left;
|
20
20
|
color: #0b0c0c;
|
@@ -24,3 +24,14 @@ table td {
|
|
24
24
|
table th {
|
25
25
|
font-weight: 700;
|
26
26
|
}
|
27
|
+
|
28
|
+
// Right align headings for numeric content
|
29
|
+
table th.numeric {
|
30
|
+
text-align: right;
|
31
|
+
}
|
32
|
+
|
33
|
+
// Use tabular numbers for numeric table cells
|
34
|
+
table td.numeric {
|
35
|
+
@include core-16($tabular-numbers: true);
|
36
|
+
text-align: right;
|
37
|
+
}
|
@@ -1,46 +1,39 @@
|
|
1
|
-
// Date
|
1
|
+
// Date pattern
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
// Hide the 'spinner' for webkit
|
4
|
+
// and also for Firefox
|
5
|
+
input::-webkit-outer-spin-button,
|
6
|
+
input::-webkit-inner-spin-button {
|
7
|
+
-webkit-appearance: none;
|
8
|
+
margin: 0
|
6
9
|
}
|
7
|
-
|
8
|
-
|
9
|
-
width: 50px;
|
10
|
-
float: left;
|
11
|
-
margin-right: 20px;
|
12
|
-
margin-bottom: 0;
|
13
|
-
clear: none;
|
10
|
+
input[type=number] {
|
11
|
+
-moz-appearance: textfield
|
14
12
|
}
|
15
13
|
|
16
|
-
.form-date
|
17
|
-
width: 70px;
|
18
|
-
}
|
14
|
+
.form-date {
|
19
15
|
|
20
|
-
.form-
|
21
|
-
|
22
|
-
|
16
|
+
.form-group {
|
17
|
+
float: left;
|
18
|
+
width: 50px;
|
23
19
|
|
20
|
+
margin-right: 20px;
|
21
|
+
margin-bottom: 0;
|
22
|
+
clear: none;
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
label {
|
25
|
+
display: block;
|
26
|
+
margin-bottom: 5px;
|
27
|
+
}
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
29
|
+
input {
|
30
|
+
width: 100%;
|
31
|
+
}
|
32
32
|
|
33
|
-
|
34
|
-
.no-touch .native-date-picker {
|
35
|
-
display: none;
|
36
|
-
}
|
33
|
+
}
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
}
|
35
|
+
.form-group-year {
|
36
|
+
width: 70px;
|
37
|
+
}
|
42
38
|
|
43
|
-
// Set a minimum height for date inputs
|
44
|
-
.touch input[type="date"] {
|
45
|
-
min-height: 36px;
|
46
39
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govuk_elements_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob McKinnon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -50,8 +50,8 @@ dependencies:
|
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 3.2.0
|
53
|
-
description: A gem wrapper around SHA
|
54
|
-
(
|
53
|
+
description: A gem wrapper around SHA caadd5a3bf04d58ab61bab5ec8e00afdba818b18 govuk_elements
|
54
|
+
(remotes/origin/HEAD) that pulls stylesheet and javascript files into a Rails app.
|
55
55
|
email: rob.mckinnon ~@nospam@~ digital.justice.gov.uk
|
56
56
|
executables: []
|
57
57
|
extensions: []
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- LICENCE
|
62
62
|
- README.md
|
63
63
|
- app/builders/govuk_elements_form_builder.rb
|
64
|
+
- app/builders/labelling_form_builder.rb
|
64
65
|
- lib/govuk_elements_rails.rb
|
65
66
|
- lib/govuk_elements_rails/engine.rb
|
66
67
|
- lib/govuk_elements_rails/version.rb
|
@@ -89,6 +90,7 @@ files:
|
|
89
90
|
- vendor/assets/images/icons/player-icon-play.png
|
90
91
|
- vendor/assets/images/icons/player-icon-rewind.png
|
91
92
|
- vendor/assets/images/icons/player-icon-volume.png
|
93
|
+
- vendor/assets/javascripts/application.js
|
92
94
|
- vendor/assets/javascripts/bind.js
|
93
95
|
- vendor/assets/javascripts/details.polyfill.js
|
94
96
|
- vendor/assets/javascripts/selection-buttons.js
|
@@ -140,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
142
|
version: '0'
|
141
143
|
requirements: []
|
142
144
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.4.5
|
144
146
|
signing_key:
|
145
147
|
specification_version: 4
|
146
148
|
summary: A gem wrapper around http://github.com/alphagov/govuk_elements that pulls
|