et_gds_design_system 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +31 -0
- data/app/assets/config/et_gds_design_system_manifest.js +0 -0
- data/app/helpers/et_gds_design_system/file_dropzone_helper.rb +10 -0
- data/app/javascript/components/DropzoneUploader/preview-template.html +43 -0
- data/app/javascript/components/DropzoneUploader/stylesheet.scss +11 -0
- data/app/javascript/components/DropzoneUploader.js +196 -0
- data/app/javascript/components/RevealOnRadioButton.js +62 -0
- data/app/javascript/components.js +8 -0
- data/app/types/et_gds_design_system/azure_file.rb +11 -0
- data/app/types/et_gds_design_system/date_without_day_type.rb +14 -0
- data/app/views/et_gds_design_system/elements/file_dropzone/_template.html.erb +63 -0
- data/config/initializers/type.rb +4 -0
- data/config/routes.rb +4 -0
- data/lib/et_gds_design_system/api_proxy.rb +25 -0
- data/lib/et_gds_design_system/elements/date.rb +26 -0
- data/lib/et_gds_design_system/elements/file_dropzone.rb +60 -0
- data/lib/et_gds_design_system/engine.rb +7 -0
- data/lib/et_gds_design_system/form/builder.rb +241 -0
- data/lib/et_gds_design_system/version.rb +3 -0
- data/lib/et_gds_design_system.rb +7 -0
- data/lib/tasks/et_gds_design_system_tasks.rake +13 -0
- metadata +221 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6cf13d18b9af22fef35047f273d4f05c7854c48f1b53926cf457748a88cb9b7
|
4
|
+
data.tar.gz: e5601ee34dff079c3eb612fece77676ee7b75858c026bd0660cb223ed387d5e0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 750b75c653b49b7930e102dd165ab28fda0734eef4dd8fcbbfcef3f30ac85780ba3f05bf23b73370cfde2f6826389f3685b3ac2497f4982d074a64b575477a86
|
7
|
+
data.tar.gz: a1296d508552f27b449ef4dd508c238340c9c16cd969a61ac5a2019a0b887f4ee70f0d3d93f39b96f3f31bb5caa4119d31d093bc09a8272d9fb234cbc3743f94
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020 Gary Taylor
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# ET GDS Design System
|
2
|
+
This gem integrates the govuk-frontend npm modules into a rails
|
3
|
+
application that is using webpacker.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
The example application in test/dummy provides many examples
|
8
|
+
on how to use this gem. It is named the 'Kitchen Sink' as it has everything
|
9
|
+
but the kitchen sink !
|
10
|
+
|
11
|
+
Please view the source code in there for more examples, but here
|
12
|
+
is one for a form component
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
<%= form_for @kitchen_sink, builder: EtGdsDesignSystem.form_builder_class do |f| %>
|
16
|
+
<h2>Text Field</h2>
|
17
|
+
<div>
|
18
|
+
<%= f.govuk_text_field :text_field_value, label: { text: 'Text field value label' }, hint_text: 'Hint text' %>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
|
22
|
+
<% end %>
|
23
|
+
```
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
Add this line to your application's Gemfile:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem 'et_gds_design_system', git: 'git@github.com:hmcts/et_gds_design_system.git', tag: 'v0.1.0'
|
30
|
+
```
|
31
|
+
|
32
|
+
And then execute:
|
33
|
+
```bash
|
34
|
+
$ bundle exec rails g et_gds_design_system:install
|
35
|
+
```
|
36
|
+
|
37
|
+
You might want to review what it has done - which will work if you
|
38
|
+
have an application pack in app/javascript/packs/application.js
|
39
|
+
|
40
|
+
Also, you may want to consider changing 'extract_css' to true in
|
41
|
+
your config/webpacker.yml so that your css works when
|
42
|
+
using browsers without javascript.
|
43
|
+
|
44
|
+
## Contributing
|
45
|
+
|
46
|
+
Whilst this gem is wrapping the work done by others in the [gov-uk-frontend](https://www.npmjs.com/package/govuk-frontend) npm
|
47
|
+
module, it is important to always think that it may not always
|
48
|
+
use that, so wrap things accordingly.
|
49
|
+
|
50
|
+
Also, the gem may choose to extend functionality provided by govuk-frontend or event
|
51
|
+
modify functionality, so do not expect the user of this gem to know
|
52
|
+
anything about govuk-frontend.
|
53
|
+
|
54
|
+
When documenting, you can refer to govuk-frontend for various items but
|
55
|
+
because this gem can override things, be careful not to send the
|
56
|
+
user on a wild goose chase when linking to this documentation if the gem
|
57
|
+
has extended or modified functionality.
|
58
|
+
|
59
|
+
For detailed documentation, see [docs/development.md](docs/development.md)
|
60
|
+
|
61
|
+
## License
|
62
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
require_relative 'test/dummy/config/application'
|
9
|
+
load 'rails/tasks/framework.rake'
|
10
|
+
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
13
|
+
rdoc.title = 'EtGdsDesignSystem'
|
14
|
+
rdoc.options << '--line-numbers'
|
15
|
+
rdoc.rdoc_files.include('README.md')
|
16
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
17
|
+
end
|
18
|
+
|
19
|
+
load 'rails/tasks/statistics.rake'
|
20
|
+
|
21
|
+
require 'bundler/gem_tasks'
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
|
25
|
+
Rake::TestTask.new(:test) do |t|
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
task default: :test
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module EtGdsDesignSystem
|
2
|
+
module FileDropzoneHelper
|
3
|
+
def hidden_field_for(key, form_builder:, attribute_name:, builder: )
|
4
|
+
attribute_value = builder.object.send(attribute_name)
|
5
|
+
options = { data: { submit_key: key.to_s } }
|
6
|
+
options[:value] = attribute_value[key.to_s] unless attribute_value.nil? || attribute_value[key.to_s].nil?
|
7
|
+
form_builder.hidden_field(key, options)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
export default `
|
2
|
+
<div class="dz-preview dz-file-previewzzzzzz">
|
3
|
+
<div>
|
4
|
+
<div class="govuk-body-s">
|
5
|
+
<span>File selected:</span>
|
6
|
+
<span data-dz-name></span>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
<div class="dz-progress">
|
10
|
+
<span class="dz-upload" data-dz-uploadprogress></span>
|
11
|
+
</div>
|
12
|
+
<div class="dz-error-message"><span data-dz-errormessage></span></div>
|
13
|
+
<div class="dz-success-mark">
|
14
|
+
<svg
|
15
|
+
width="54"
|
16
|
+
height="54"
|
17
|
+
viewBox="0 0 54 54"
|
18
|
+
fill="white"
|
19
|
+
xmlns="http://www.w3.org/2000/svg"
|
20
|
+
>
|
21
|
+
<path
|
22
|
+
d="M10.2071 29.7929L14.2929 25.7071C14.6834 25.3166 15.3166 25.3166 15.7071 25.7071L21.2929 31.2929C21.6834 31.6834 22.3166 31.6834 22.7071 31.2929L38.2929 15.7071C38.6834 15.3166 39.3166 15.3166 39.7071 15.7071L43.7929 19.7929C44.1834 20.1834 44.1834 20.8166 43.7929 21.2071L22.7071 42.2929C22.3166 42.6834 21.6834 42.6834 21.2929 42.2929L10.2071 31.2071C9.81658 30.8166 9.81658 30.1834 10.2071 29.7929Z"
|
23
|
+
/>
|
24
|
+
</svg>
|
25
|
+
</div>
|
26
|
+
<div class="dz-error-mark">
|
27
|
+
<svg
|
28
|
+
width="54"
|
29
|
+
height="54"
|
30
|
+
viewBox="0 0 54 54"
|
31
|
+
fill="white"
|
32
|
+
xmlns="http://www.w3.org/2000/svg"
|
33
|
+
>
|
34
|
+
<path
|
35
|
+
d="M26.2929 20.2929L19.2071 13.2071C18.8166 12.8166 18.1834 12.8166 17.7929 13.2071L13.2071 17.7929C12.8166 18.1834 12.8166 18.8166 13.2071 19.2071L20.2929 26.2929C20.6834 26.6834 20.6834 27.3166 20.2929 27.7071L13.2071 34.7929C12.8166 35.1834 12.8166 35.8166 13.2071 36.2071L17.7929 40.7929C18.1834 41.1834 18.8166 41.1834 19.2071 40.7929L26.2929 33.7071C26.6834 33.3166 27.3166 33.3166 27.7071 33.7071L34.7929 40.7929C35.1834 41.1834 35.8166 41.1834 36.2071 40.7929L40.7929 36.2071C41.1834 35.8166 41.1834 35.1834 40.7929 34.7929L33.7071 27.7071C33.3166 27.3166 33.3166 26.6834 33.7071 26.2929L40.7929 19.2071C41.1834 18.8166 41.1834 18.1834 40.7929 17.7929L36.2071 13.2071C35.8166 12.8166 35.1834 12.8166 34.7929 13.2071L27.7071 20.2929C27.3166 20.6834 26.6834 20.6834 26.2929 20.2929Z"
|
36
|
+
/>
|
37
|
+
</svg>
|
38
|
+
</div>
|
39
|
+
<button class="govuk-button govuk-button--secondary" data-module="govuk-button" data-dz-remove>
|
40
|
+
Remove File
|
41
|
+
</button>
|
42
|
+
</div>
|
43
|
+
`
|
@@ -0,0 +1,196 @@
|
|
1
|
+
import Dropzone from "dropzone";
|
2
|
+
import axios from "axios";
|
3
|
+
import { v4 as uuidv4 } from 'uuid';
|
4
|
+
import SparkMD5 from 'spark-md5';
|
5
|
+
import previewTemplate from "./DropzoneUploader/preview-template.html";
|
6
|
+
Dropzone.autoDiscover = false
|
7
|
+
|
8
|
+
let uploadKey, dropzoneUploadForm;
|
9
|
+
|
10
|
+
function setUploadUrl(url) {
|
11
|
+
dropzoneUploadForm.options.url = url;
|
12
|
+
}
|
13
|
+
|
14
|
+
function buildUpload(cb) {
|
15
|
+
axios.post(
|
16
|
+
"/api/v2/build_blob",
|
17
|
+
{
|
18
|
+
uuid: uuidv4(),
|
19
|
+
command: "BuildBlob",
|
20
|
+
async: false,
|
21
|
+
data: {
|
22
|
+
preventEmptyData: true
|
23
|
+
}
|
24
|
+
},
|
25
|
+
{
|
26
|
+
responseType: 'json',
|
27
|
+
headers: {
|
28
|
+
'Accept': 'application/json'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
)
|
32
|
+
.then((response) => {
|
33
|
+
cb.apply(this, [response.data]);
|
34
|
+
})
|
35
|
+
.catch(onGetPresignedError)
|
36
|
+
}
|
37
|
+
|
38
|
+
function onGetPresignedError(error) {
|
39
|
+
/* TODO: RST-1220:
|
40
|
+
Anticipate and handle errors:
|
41
|
+
- Network issue to API (no response)
|
42
|
+
- Network issue to/from Azure/S3 (API responds with bad data)
|
43
|
+
*/
|
44
|
+
}
|
45
|
+
|
46
|
+
function hideButton() {
|
47
|
+
document.querySelector("*[data-auto-hide]").style.display = 'none';
|
48
|
+
}
|
49
|
+
|
50
|
+
function showButton() {
|
51
|
+
document.querySelector("*[data-auto-hide]").style.display = '';
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
function setupAzure(file, presignedData, done) {
|
56
|
+
dropzoneUploadForm.options.method = 'put';
|
57
|
+
dropzoneUploadForm.options.headers = {"x-ms-blob-type": "BlockBlob"};
|
58
|
+
getFileHash(file, function (hash) {
|
59
|
+
dropzoneUploadForm.options.headers["Content-MD5"] = hash;
|
60
|
+
uploadKey = presignedData.data.fields.key;
|
61
|
+
setUploadUrl(presignedData.data.url);
|
62
|
+
hideButton();
|
63
|
+
done();
|
64
|
+
})
|
65
|
+
}
|
66
|
+
|
67
|
+
function getFileHash(file, headerCallback) {
|
68
|
+
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
|
69
|
+
chunkSize = 2097152, // Read in chunks of 2MB
|
70
|
+
chunks = Math.ceil(file.size / chunkSize),
|
71
|
+
currentChunk = 0,
|
72
|
+
spark = new SparkMD5.ArrayBuffer(),
|
73
|
+
fileReader = new FileReader();
|
74
|
+
|
75
|
+
fileReader.onload = function (e) {
|
76
|
+
spark.append(e.target.result); // Append array buffer
|
77
|
+
currentChunk++;
|
78
|
+
|
79
|
+
if (currentChunk < chunks) {
|
80
|
+
loadNext();
|
81
|
+
} else {
|
82
|
+
const hash = btoa(spark.end(true));
|
83
|
+
headerCallback(hash);
|
84
|
+
}
|
85
|
+
};
|
86
|
+
|
87
|
+
fileReader.onerror = function () {
|
88
|
+
console.warn('oops, something went wrong.');
|
89
|
+
};
|
90
|
+
|
91
|
+
function loadNext() {
|
92
|
+
let start = currentChunk * chunkSize,
|
93
|
+
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
|
94
|
+
|
95
|
+
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
|
96
|
+
}
|
97
|
+
|
98
|
+
loadNext();
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
*
|
103
|
+
* @param node
|
104
|
+
* @param type - The content type - for ET3 was 'application/rtf'
|
105
|
+
* @param acceptedFiles - The accepted files - for ET3 was ".rtf"
|
106
|
+
* @param removeFileButtonText - Self explanatory
|
107
|
+
* @param attributeName - The attribute name from rails
|
108
|
+
* @returns {}
|
109
|
+
*/
|
110
|
+
const initDropzone = (node, type, acceptedFiles, attributeName) => {
|
111
|
+
let provider;
|
112
|
+
const extractPreviewContent = () => {
|
113
|
+
const templateContainer = node.querySelector('*[data-gds-dropzone-uploader-preview-template]')
|
114
|
+
templateContainer.parentElement.removeChild(templateContainer)
|
115
|
+
return templateContainer.innerHTML
|
116
|
+
}
|
117
|
+
|
118
|
+
const DROPZONE_OPTIONS = {
|
119
|
+
url: '/api/v2/create_blob',
|
120
|
+
init: function () {
|
121
|
+
this.on("maxfilesexceeded", function (file) {
|
122
|
+
// TODO: RST-1220 - Error Handling:
|
123
|
+
// Build a proper warning system for "too many files" warning.
|
124
|
+
alert("Too many files")
|
125
|
+
});
|
126
|
+
this.on("removedfile", function () {
|
127
|
+
node.querySelectorAll("*[data-submit-key]").forEach((inputEl) => inputEl.removeAttribute('value'))
|
128
|
+
});
|
129
|
+
this.on('sending', (file, xhr) => {
|
130
|
+
// Source: https://github.com/enyo/dropzone/issues/590#issuecomment-51498225
|
131
|
+
if (provider === 'azure') {
|
132
|
+
const send = xhr.send;
|
133
|
+
xhr.send = function () {
|
134
|
+
send.call(xhr, file);
|
135
|
+
xhr.send = send;
|
136
|
+
};
|
137
|
+
}
|
138
|
+
});
|
139
|
+
this.on('success', (file, decodedResponse, event) => {
|
140
|
+
uploadKey = decodedResponse.data.key
|
141
|
+
node.querySelector("*[data-submit-key=path]").setAttribute('value', uploadKey)
|
142
|
+
node.querySelector("*[data-submit-key=filename]").setAttribute('value', file.name)
|
143
|
+
node.querySelector("*[data-submit-key=content_type]").setAttribute('value', file.type)
|
144
|
+
showButton();
|
145
|
+
})
|
146
|
+
|
147
|
+
let filenameElement = node.querySelector("*[data-submit-key=filename]");
|
148
|
+
let filenameValue = filenameElement.getAttribute('value');
|
149
|
+
if (filenameValue) {
|
150
|
+
let existingFile = {name: filenameValue, type: type};
|
151
|
+
this.options.addedfile.call(this, existingFile);
|
152
|
+
existingFile.previewElement.classList.add('dz-success');
|
153
|
+
existingFile.previewElement.classList.add('dz-complete');
|
154
|
+
}
|
155
|
+
},
|
156
|
+
// Only one file goes to the bucket via the URL
|
157
|
+
parallelUploads: 1,
|
158
|
+
uploadMultiple: false,
|
159
|
+
// Set acceptance criteria, one .rtf file
|
160
|
+
maxFiles: 1,
|
161
|
+
acceptedFiles: acceptedFiles,
|
162
|
+
clickable: '*[data-gds-dropzone-upload-button]',
|
163
|
+
previewTemplate: extractPreviewContent(),
|
164
|
+
// Use POST by default for AWS
|
165
|
+
// TODO: RST-1676 Default this to 'put' and remove the assignment within the buildUpload if statement
|
166
|
+
method: "post",
|
167
|
+
// Add a link to remove files that were erroneously uploaded
|
168
|
+
addRemoveLinks: false,
|
169
|
+
canceled: function (file) {
|
170
|
+
showButton()
|
171
|
+
node.querySelectorAll("*[data-submit-key]").forEach((inputEl) => inputEl.setAttribute('value', null))
|
172
|
+
}
|
173
|
+
};
|
174
|
+
|
175
|
+
dropzoneUploadForm = new Dropzone(node, DROPZONE_OPTIONS)
|
176
|
+
return dropzoneUploadForm
|
177
|
+
}
|
178
|
+
|
179
|
+
/**
|
180
|
+
* @param uploadKeyId
|
181
|
+
* @param fileNameId
|
182
|
+
* @param type - The content type - for ET3 was 'application/rtf'
|
183
|
+
* @param acceptedFiles - The accepted files - for ET3 was ".rtf"
|
184
|
+
*/
|
185
|
+
const DropzoneUploader = {
|
186
|
+
init: () => {
|
187
|
+
const nodes = Array.from(document.querySelectorAll('[data-module="et-gds-design-system-dropzone-uploader"]'));
|
188
|
+
nodes.forEach((node) => {
|
189
|
+
const type = node.getAttribute('data-type')
|
190
|
+
const acceptedFiles = node.getAttribute('data-accepted-files')
|
191
|
+
const attributeName = node.getAttribute('data-attribute-name')
|
192
|
+
initDropzone(node, type, acceptedFiles, attributeName);
|
193
|
+
})
|
194
|
+
}
|
195
|
+
}
|
196
|
+
export default DropzoneUploader;
|
@@ -0,0 +1,62 @@
|
|
1
|
+
const RevealOnRadioButton = {
|
2
|
+
init: function RevealOnRadioButton() {
|
3
|
+
const nodes = Array.from(document.querySelectorAll('[data-module="et-gds-design-system-reveal-on-radio-button"]'));
|
4
|
+
document.addEventListener('change', function(e) {
|
5
|
+
const nodesToChange = nodes.filter((node) => {
|
6
|
+
return e.target.matches(node.attributes['data-reveal-on-selector'].value);
|
7
|
+
});
|
8
|
+
if (nodesToChange.length == 0) {
|
9
|
+
return;
|
10
|
+
}
|
11
|
+
|
12
|
+
nodesToChange.forEach((node) => {
|
13
|
+
const value = JSON.parse(node.attributes['data-reveal-on-value'].value);
|
14
|
+
if((e.target.value === value || (Array.isArray(value) && value.indexOf(e.target.value) >= 0)) && e.target.checked) {
|
15
|
+
showNode(node);
|
16
|
+
} else {
|
17
|
+
hideNode(node);
|
18
|
+
}
|
19
|
+
});
|
20
|
+
});
|
21
|
+
setInitialStates(nodes);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
*
|
27
|
+
* Hides or shows (reveals) an element based on a radio button group
|
28
|
+
* @param node {Element} The element to hide or show
|
29
|
+
* @param selector {String} A css selector to identify the radio button group
|
30
|
+
* @param value {String} The value that the radio button group must be set to in order to show the element
|
31
|
+
*/
|
32
|
+
export default RevealOnRadioButton
|
33
|
+
function showNode(node) {
|
34
|
+
node.style.display = 'block';
|
35
|
+
}
|
36
|
+
|
37
|
+
function hideNode(node) {
|
38
|
+
node.style.display = 'none';
|
39
|
+
}
|
40
|
+
|
41
|
+
function setInitialStates(nodes) {
|
42
|
+
nodes.forEach((node) => {
|
43
|
+
const selector = node.attributes['data-reveal-on-selector'].value;
|
44
|
+
const value = JSON.parse(node.attributes['data-reveal-on-value'].value);
|
45
|
+
if(isCorrectValue(node, selector, value)) {
|
46
|
+
showNode(node);
|
47
|
+
} else {
|
48
|
+
hideNode(node);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
}
|
52
|
+
|
53
|
+
function isCorrectValue(node, selector, value) {
|
54
|
+
let isChecked = false;
|
55
|
+
document.querySelectorAll(selector).forEach(function(radioButton) {
|
56
|
+
if((radioButton.value === value || value.includes(radioButton.value)) && radioButton.checked) {
|
57
|
+
isChecked = true
|
58
|
+
}
|
59
|
+
|
60
|
+
});
|
61
|
+
return isChecked;
|
62
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import RevealOnRadioButton from './components/RevealOnRadioButton'
|
2
|
+
import DropzoneUploader from "./components/DropzoneUploader";
|
3
|
+
const Components = {
|
4
|
+
RevealOnRadioButton: RevealOnRadioButton,
|
5
|
+
DropzoneUploader: DropzoneUploader
|
6
|
+
};
|
7
|
+
import './components/DropzoneUploader/stylesheet.scss'
|
8
|
+
export default Components;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module EtGdsDesignSystem
|
2
|
+
class AzureFile < ActiveModel::Type::Value
|
3
|
+
private
|
4
|
+
|
5
|
+
def cast_value(value)
|
6
|
+
return nil unless value.is_a?(Hash) && value['filename'].present? && value['path'].present? && value['content_type'].present?
|
7
|
+
|
8
|
+
value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module EtGdsDesignSystem
|
2
|
+
class DateWithoutDayType < ActiveRecord::Type::Date
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
def fallback_string_to_date(string)
|
7
|
+
new_date(*::Date._parse(string, false).values_at(:year, :mon), 1)
|
8
|
+
end
|
9
|
+
|
10
|
+
def value_from_multiparameter_assignment(value)
|
11
|
+
super(value.merge(3 => 1))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<div class="dropzone gds-dropzone-uploader"
|
2
|
+
id="<%= id %>"
|
3
|
+
data-module="et-gds-design-system-dropzone-uploader"
|
4
|
+
data-attribute-name="<%= attribute_name %>"
|
5
|
+
data-type="<%= type %>"
|
6
|
+
data-accepted-files="<%= accepted_files.join(',') %>"
|
7
|
+
>
|
8
|
+
<div class="dz-message">
|
9
|
+
<div>
|
10
|
+
<button type="button" class="govuk-button govuk-button--secondary" data-auto-hide data-gds-dropzone-upload-button>
|
11
|
+
<%= button_text %>
|
12
|
+
</button>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<%= builder.fields_for(attribute_name) do |f| %>
|
16
|
+
<%= hidden_field_for(:path, form_builder: f, builder: builder, attribute_name: attribute_name) %>
|
17
|
+
<%= hidden_field_for(:filename, form_builder: f, builder: builder, attribute_name: attribute_name) %>
|
18
|
+
<%= hidden_field_for(:content_type, form_builder: f, builder: builder, attribute_name: attribute_name) %>
|
19
|
+
<% end %>
|
20
|
+
<div class="gds-dropzone-uploader-preview-template" style="display: none;" data-gds-dropzone-uploader-preview-template>
|
21
|
+
<div class="dz-preview">
|
22
|
+
<div>
|
23
|
+
<div class="govuk-body-s">
|
24
|
+
<span><%= file_selected_text %></span>
|
25
|
+
<span data-dz-name></span>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
<div class="dz-progress">
|
29
|
+
<span class="dz-upload" data-dz-uploadprogress></span>
|
30
|
+
</div>
|
31
|
+
<div class="dz-error-message"><span data-dz-errormessage></span></div>
|
32
|
+
<div class="dz-success-mark">
|
33
|
+
<svg
|
34
|
+
width="54"
|
35
|
+
height="54"
|
36
|
+
viewBox="0 0 54 54"
|
37
|
+
fill="white"
|
38
|
+
xmlns="http://www.w3.org/2000/svg"
|
39
|
+
>
|
40
|
+
<path
|
41
|
+
d="M10.2071 29.7929L14.2929 25.7071C14.6834 25.3166 15.3166 25.3166 15.7071 25.7071L21.2929 31.2929C21.6834 31.6834 22.3166 31.6834 22.7071 31.2929L38.2929 15.7071C38.6834 15.3166 39.3166 15.3166 39.7071 15.7071L43.7929 19.7929C44.1834 20.1834 44.1834 20.8166 43.7929 21.2071L22.7071 42.2929C22.3166 42.6834 21.6834 42.6834 21.2929 42.2929L10.2071 31.2071C9.81658 30.8166 9.81658 30.1834 10.2071 29.7929Z"
|
42
|
+
/>
|
43
|
+
</svg>
|
44
|
+
</div>
|
45
|
+
<div class="dz-error-mark">
|
46
|
+
<svg
|
47
|
+
width="54"
|
48
|
+
height="54"
|
49
|
+
viewBox="0 0 54 54"
|
50
|
+
fill="white"
|
51
|
+
xmlns="http://www.w3.org/2000/svg"
|
52
|
+
>
|
53
|
+
<path
|
54
|
+
d="M26.2929 20.2929L19.2071 13.2071C18.8166 12.8166 18.1834 12.8166 17.7929 13.2071L13.2071 17.7929C12.8166 18.1834 12.8166 18.8166 13.2071 19.2071L20.2929 26.2929C20.6834 26.6834 20.6834 27.3166 20.2929 27.7071L13.2071 34.7929C12.8166 35.1834 12.8166 35.8166 13.2071 36.2071L17.7929 40.7929C18.1834 41.1834 18.8166 41.1834 19.2071 40.7929L26.2929 33.7071C26.6834 33.3166 27.3166 33.3166 27.7071 33.7071L34.7929 40.7929C35.1834 41.1834 35.8166 41.1834 36.2071 40.7929L40.7929 36.2071C41.1834 35.8166 41.1834 35.1834 40.7929 34.7929L33.7071 27.7071C33.3166 27.3166 33.3166 26.6834 33.7071 26.2929L40.7929 19.2071C41.1834 18.8166 41.1834 18.1834 40.7929 17.7929L36.2071 13.2071C35.8166 12.8166 35.1834 12.8166 34.7929 13.2071L27.7071 20.2929C27.3166 20.6834 26.6834 20.6834 26.2929 20.2929Z"
|
55
|
+
/>
|
56
|
+
</svg>
|
57
|
+
</div>
|
58
|
+
<button class="govuk-button govuk-button--secondary" data-module="govuk-button" data-dz-remove>
|
59
|
+
<%= remove_file_button_text %>
|
60
|
+
</button>
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
mount EtGdsDesignSystem::ApiProxy.new(backend: "#{Rails.application.config.et_gds_design_system.api_url}", streaming: false), at: "/api/v2/create_blob"
|
3
|
+
mount EtGdsDesignSystem::ApiProxy.new(backend: "#{Rails.application.config.et_gds_design_system.api_url}", streaming: false), at: "/api/v2/blobs/:signed_id/*filename"
|
4
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rack-proxy'
|
2
|
+
|
3
|
+
module EtGdsDesignSystem
|
4
|
+
class ApiProxy < Rack::Proxy
|
5
|
+
def rewrite_env(env)
|
6
|
+
env.merge 'REQUEST_URI' => correct_host(env['REQUEST_URI']),
|
7
|
+
'HTTP_HOST' => "#{et_api_uri.host}:#{et_api_uri.port}",
|
8
|
+
'PATH_INFO' => ''
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def correct_host(url)
|
14
|
+
uri = URI.parse(url)
|
15
|
+
uri.scheme = et_api_uri.scheme
|
16
|
+
uri.host = et_api_uri.host
|
17
|
+
uri.port = et_api_uri.port
|
18
|
+
uri.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def et_api_uri
|
22
|
+
@et_api_uri ||= URI.parse(Rails.application.config.et_gds_design_system.api_url)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module EtGdsDesignSystem
|
2
|
+
module Elements
|
3
|
+
class Date < ::GOVUKDesignSystemFormBuilder::Elements::Date
|
4
|
+
private
|
5
|
+
|
6
|
+
def value(segment)
|
7
|
+
attribute = @builder.object.try(@attribute_name)
|
8
|
+
attribute ||= @builder.object.read_attribute_before_type_cast(@attribute_name)
|
9
|
+
|
10
|
+
return unless attribute
|
11
|
+
|
12
|
+
if attribute.respond_to?(segment)
|
13
|
+
attribute.send(segment)
|
14
|
+
elsif attribute.respond_to?(:fetch)
|
15
|
+
attribute.fetch(MULTIPARAMETER_KEY[segment]) do
|
16
|
+
warn("No key '#{segment}' found in MULTIPARAMETER_KEY hash. Expected to find #{MULTIPARAMETER_KEY.values}")
|
17
|
+
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
else
|
21
|
+
fail(ArgumentError, "invalid Date-like object: must be a Date, Time, DateTime or Hash in MULTIPARAMETER_KEY format")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'govuk_design_system_formbuilder/base'
|
2
|
+
require 'govuk_design_system_formbuilder/refinements/prefixable_array'
|
3
|
+
require 'govuk_design_system_formbuilder/traits/error'
|
4
|
+
require 'govuk_design_system_formbuilder/traits/hint'
|
5
|
+
require 'govuk_design_system_formbuilder/traits/label'
|
6
|
+
require 'govuk_design_system_formbuilder/traits/supplemental'
|
7
|
+
require 'govuk_design_system_formbuilder/traits/html_attributes'
|
8
|
+
require 'govuk_design_system_formbuilder/containers/form_group'
|
9
|
+
module EtGdsDesignSystem
|
10
|
+
module Elements
|
11
|
+
class FileDropzone < ::GOVUKDesignSystemFormBuilder::Base
|
12
|
+
using ::GOVUKDesignSystemFormBuilder::PrefixableArray
|
13
|
+
|
14
|
+
include ::GOVUKDesignSystemFormBuilder::Traits::Error
|
15
|
+
include ::GOVUKDesignSystemFormBuilder::Traits::Hint
|
16
|
+
include ::GOVUKDesignSystemFormBuilder::Traits::Label
|
17
|
+
include ::GOVUKDesignSystemFormBuilder::Traits::Supplemental
|
18
|
+
include ::GOVUKDesignSystemFormBuilder::Traits::HTMLAttributes
|
19
|
+
|
20
|
+
def initialize(builder, object_name, attribute_name, hint:, label:, button_text: nil, remove_file_button_text: nil, file_selected_text: nil, caption:, form_group:, accepted_files: nil, type: nil, template:, **kwargs, &block)
|
21
|
+
super(builder, object_name, attribute_name, &block)
|
22
|
+
|
23
|
+
@label = label
|
24
|
+
@caption = caption
|
25
|
+
@hint = hint
|
26
|
+
@html_attributes = kwargs
|
27
|
+
@form_group = form_group
|
28
|
+
@accepted_files = accepted_files
|
29
|
+
@button_text = button_text
|
30
|
+
@remove_file_button_text = remove_file_button_text
|
31
|
+
@file_selected_text = file_selected_text
|
32
|
+
@template = template
|
33
|
+
end
|
34
|
+
|
35
|
+
def html
|
36
|
+
::GOVUKDesignSystemFormBuilder::Containers::FormGroup.new(*bound, **@form_group).html do
|
37
|
+
safe_join([label_element, supplemental_content, hint_element, error_element, file])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :template
|
44
|
+
|
45
|
+
def file
|
46
|
+
template.render partial: 'et_gds_design_system/elements/file_dropzone/template',
|
47
|
+
locals: {
|
48
|
+
id: field_id(link_errors: true),
|
49
|
+
attribute_name: @attribute_name,
|
50
|
+
remove_file_button_text: @remove_file_button_text,
|
51
|
+
button_text: @button_text,
|
52
|
+
file_selected_text: @file_selected_text,
|
53
|
+
type: @type,
|
54
|
+
accepted_files: @accepted_files,
|
55
|
+
builder: @builder
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'et_gds_design_system/api_proxy'
|
2
|
+
module EtGdsDesignSystem
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
config.et_gds_design_system = ::Rails::Application::Configuration::Custom.new
|
5
|
+
config.et_gds_design_system.api_url = 'http://api.et.127.0.0.1.nip.io:3100/api'
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "govuk_design_system_formbuilder"
|
4
|
+
require "et_gds_design_system/elements/date"
|
5
|
+
require "et_gds_design_system/elements/file_dropzone"
|
6
|
+
module EtGdsDesignSystem
|
7
|
+
module Form
|
8
|
+
class Builder < SimpleDelegator
|
9
|
+
LABEL_DEFAULTS = { size: 's' }.freeze
|
10
|
+
FIELDSET_LABEL_DEFAULTS = { size: 'm' }
|
11
|
+
CHECK_BOX_LABEL_DEFAULTS = { size: nil }
|
12
|
+
HINT_DEFAULTS = {}.freeze
|
13
|
+
OPTIONAL_I18N_KEY = 'shared.optional'
|
14
|
+
|
15
|
+
def initialize(object_name, object, template, options)
|
16
|
+
@template = template
|
17
|
+
super ::GOVUKDesignSystemFormBuilder::FormBuilder.new(object_name, object, template, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def govuk_date_field(*args, label:, **kw_args)
|
21
|
+
super(*args, legend: label, **kw_args)
|
22
|
+
end
|
23
|
+
deprecate govuk_date_field: 'govuk_date_field is deprecated - please use date_field instead and read the documentation as it makes your code simpler'
|
24
|
+
|
25
|
+
def date_field(attribute, *args, label: true, hint: true, optional: false, caption: {}, date_of_birth: false, omit_day: false, form_group: {}, wildcards: false, **kw_args, &block)
|
26
|
+
Elements::Date.new(self, object_name, attribute, hint: normalize_hint(attribute, hint), legend: normalize_label(attribute, label, optional), caption: caption, date_of_birth: date_of_birth, omit_day: omit_day, form_group: form_group, wildcards: wildcards, **kw_args, &block).html
|
27
|
+
end
|
28
|
+
|
29
|
+
def govuk_collection_radio_buttons(*args, label:, **kw_args)
|
30
|
+
super(*args, legend: label, **kw_args)
|
31
|
+
end
|
32
|
+
deprecate govuk_collection_radio_buttons: 'govuk_collection_radio_buttons is deprecated - please use collection_radio_buttons instead and read the documentation as it makes your code simpler'
|
33
|
+
|
34
|
+
def collection_radio_buttons(attribute, collection = i18n_options_for(attribute), key_method = :first, value_method = :last, *args, label: true, hint: true, optional: false, include_hidden: false, **kw_args)
|
35
|
+
__getobj__.govuk_collection_radio_buttons(attribute, collection, key_method, value_method, *args, legend: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), include_hidden: include_hidden, **kw_args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def collection_select(attribute, collection = i18n_options_for(attribute), key_method = :first, value_method = :last, *args, label: true, hint: true, optional: false, html_options: {}, **kw_args)
|
39
|
+
__getobj__.govuk_collection_select(attribute, collection, key_method, value_method, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), html_options: { class: 'govuk-!-width-two-thirds' }.merge(html_options), **kw_args)
|
40
|
+
end
|
41
|
+
deprecate govuk_collection_select: 'govuk_collection_select is deprecated - please use collection_select instead and read the documentation as it makes your code simpler'
|
42
|
+
|
43
|
+
def govuk_collection_check_boxes(*args, label:, **kw_args)
|
44
|
+
super(*args, legend: label, **kw_args)
|
45
|
+
end
|
46
|
+
deprecate govuk_collection_check_boxes: 'govuk_collection_check_boxes is deprecated - please use collection_check_boxes instead and read the documentation as it makes your code simpler'
|
47
|
+
|
48
|
+
def collection_check_boxes(attribute, collection = i18n_options_for(attribute), key_method = :first, value_method = :last, *args, label: true, hint: true, optional: false, **kw_args)
|
49
|
+
__getobj__.govuk_collection_check_boxes(attribute, collection, key_method, value_method, *args, legend: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), **kw_args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_boxes_fieldset(attribute_name, label: true, caption: {}, hint: true, small: false, classes: nil, form_group: {}, multiple: true, optional: false, include_hidden: true, &block)
|
53
|
+
__getobj__.govuk_check_boxes_fieldset(attribute_name, legend: normalize_label(attribute_name, label, optional), caption: caption, hint: normalize_hint(attribute_name, hint), small: small, classes: classes, form_group: form_group, multiple: multiple, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def singular_check_box(attribute_name, value: true, unchecked_value: false, fieldset_label: true, fieldset_caption: {}, fieldset_hint: true, optional: false, include_hidden: true, label: fieldset_label, hint: false)
|
57
|
+
check_boxes_fieldset(attribute_name, multiple: false, label: fieldset_label, hint: fieldset_hint, include_hidden: include_hidden) do
|
58
|
+
result = []
|
59
|
+
result << __getobj__.hidden_field(attribute_name, value: unchecked_value) if include_hidden
|
60
|
+
result << check_box(attribute_name, value, unchecked_value, multiple: false, label: normalize_check_box_label(attribute_name, label, optional), hint: hint)
|
61
|
+
safe_join(result)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def govuk_fieldset(*args, label:, **kw_args)
|
66
|
+
super(*args, legend: label, **kw_args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fieldset(*args, label:, **kw_args, &block)
|
70
|
+
__getobj__.govuk_fieldset(*args, legend: normalize_fieldset_label(nil, label, false), **kw_args, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def govuk_email_field(*args, **kw_args)
|
74
|
+
super(*args, spellcheck: false, **kw_args)
|
75
|
+
end
|
76
|
+
deprecate govuk_email_field: 'govuk_email_field is deprecated - please use email_field instead and read the documentation as it makes your code simpler'
|
77
|
+
|
78
|
+
def email_field(attribute, *args, label: true, hint: true, width: 'two-thirds', optional: false, **kw_args)
|
79
|
+
__getobj__.govuk_email_field(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), width: width, **kw_args)
|
80
|
+
end
|
81
|
+
|
82
|
+
def govuk_phone_field(*args, **kw_args)
|
83
|
+
super(*args, autocomplete: 'tel', **kw_args)
|
84
|
+
end
|
85
|
+
deprecate govuk_phone_field: 'govuk_phone_field is deprecated - please use phone_field instead and read the documentation as it makes your code simpler'
|
86
|
+
|
87
|
+
def phone_field(attribute, *args, label: true, hint: true, width: 'two-thirds', optional: false, **kw_args)
|
88
|
+
__getobj__.govuk_phone_field(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), width: width, **kw_args)
|
89
|
+
end
|
90
|
+
|
91
|
+
def govuk_text_field(attribute, *args, label: true, hint: true, width: 'two-thirds', optional: false, **kw_args)
|
92
|
+
super(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), width: width, **kw_args)
|
93
|
+
end
|
94
|
+
deprecate govuk_text_field: 'govuk_text_field is deprecated - please use text_field instead and read the documentation as it makes your code simpler'
|
95
|
+
|
96
|
+
def text_field(attribute, *args, label: true, hint: true, width: 'two-thirds', optional: false, **kw_args)
|
97
|
+
__getobj__.govuk_text_field(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), width: width, **kw_args)
|
98
|
+
end
|
99
|
+
|
100
|
+
def text_area(attribute, *args, label: true, hint: true, optional: false, **kw_args)
|
101
|
+
__getobj__.govuk_text_area(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), **kw_args)
|
102
|
+
end
|
103
|
+
deprecate govuk_text_area: 'govuk_text_area is deprecated - please use text_area instead and read the documentation as it makes your code simpler'
|
104
|
+
|
105
|
+
def file_field(attribute, *args, label: true, hint: true, optional: false, **kw_args)
|
106
|
+
__getobj__.govuk_file_field(attribute, *args, label: normalize_label(attribute, label, optional), hint: normalize_hint(attribute, hint), **kw_args)
|
107
|
+
end
|
108
|
+
deprecate govuk_file_field: 'govuk_file_field is deprecated - please use file_field instead and read the documentation as it makes your code simpler'
|
109
|
+
|
110
|
+
def file_dropzone_field(attribute, *args, label: true, hint: true, optional: false, upload_button: true, remove_file_button: true, file_selected_text: true, caption: {}, form_group: {}, accepted_files: nil, type: 'text/csv', **kw_args, &block)
|
111
|
+
Elements::FileDropzone.new(self,
|
112
|
+
object_name,
|
113
|
+
attribute, hint: normalize_hint(attribute, hint),
|
114
|
+
label: normalize_label(attribute, label, optional),
|
115
|
+
button_text: normalize_text_argument(attribute, upload_button, 'button_text'),
|
116
|
+
remove_file_button_text: normalize_text_argument(attribute, remove_file_button, 'remove_file_button_text'),
|
117
|
+
file_selected_text: normalize_text_argument(attribute, file_selected_text, 'file_selected_text'),
|
118
|
+
caption: caption,
|
119
|
+
form_group: form_group,
|
120
|
+
accepted_files: accepted_files,
|
121
|
+
type: type,
|
122
|
+
template: template,
|
123
|
+
**kw_args).html
|
124
|
+
end
|
125
|
+
|
126
|
+
def check_box(attribute, *args, label: true, hint: true, optional: false, **kw_args)
|
127
|
+
__getobj__.govuk_check_box(attribute, *args, label: normalize_check_box_label(attribute, label, optional), hint: normalize_hint(attribute, hint), **kw_args)
|
128
|
+
end
|
129
|
+
deprecate govuk_check_box: 'govuk_check_box is deprecated - please use check_box instead and read the documentation as it makes your code simpler'
|
130
|
+
|
131
|
+
def submit(*args)
|
132
|
+
__getobj__.govuk_submit(*args)
|
133
|
+
end
|
134
|
+
|
135
|
+
def revealed_content(attribute, values:, classes: [], multiple: false, tag: 'div', &block)
|
136
|
+
# div data-reveal-on-selector='input[name="employment[current_situation]"]' data-reveal-on-value="still_employed"
|
137
|
+
name = "#{__field_name_for(attribute)}#{multiple ? '[]' : ''}"
|
138
|
+
content_tag tag, class: classes, data: {
|
139
|
+
'reveal-on-selector': "input[name=\"#{name}\"]",
|
140
|
+
'reveal-on-value': values.to_json,
|
141
|
+
'module': 'et-gds-design-system-reveal-on-radio-button'
|
142
|
+
} do
|
143
|
+
capture(&block)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
attr_reader :template
|
150
|
+
|
151
|
+
def __field_name_for(attribute)
|
152
|
+
text_input = capture do
|
153
|
+
text_field(attribute, label: false, hint: false)
|
154
|
+
end
|
155
|
+
text_input.match(/name="(.*?)"/)[1]
|
156
|
+
end
|
157
|
+
|
158
|
+
def normalize_label(attribute, label, optional)
|
159
|
+
case label
|
160
|
+
when String then LABEL_DEFAULTS.merge(text: __with_optional(label, optional))
|
161
|
+
when Hash then LABEL_DEFAULTS.merge(optional ? label.merge(text: __with_optional(label[:text], optional)) : label)
|
162
|
+
when FalseClass then { text: false }
|
163
|
+
when TrueClass then LABEL_DEFAULTS.merge(text: __with_optional(@template.t(".#{attribute}.label"), optional))
|
164
|
+
else label
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def normalize_check_box_label(attribute, label, optional)
|
169
|
+
case label
|
170
|
+
when String then CHECK_BOX_LABEL_DEFAULTS.merge(text: __with_optional(label, optional))
|
171
|
+
when Hash then CHECK_BOX_LABEL_DEFAULTS.merge(optional ? label.merge(text: __with_optional(label[:text], optional)) : label)
|
172
|
+
when FalseClass then { text: false }
|
173
|
+
when TrueClass then CHECK_BOX_LABEL_DEFAULTS.merge(text: __with_optional(@template.t(".#{attribute}.label"), optional))
|
174
|
+
else label
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def normalize_fieldset_label(attribute, label, optional)
|
179
|
+
case label
|
180
|
+
when String then FIELDSET_LABEL_DEFAULTS.merge(text: __with_optional(label, optional))
|
181
|
+
when Hash then FIELDSET_LABEL_DEFAULTS.merge(optional ? label.merge(text: __with_optional(label[:text], optional)) : label)
|
182
|
+
when FalseClass then { text: false }
|
183
|
+
when TrueClass then FIELDSET_LABEL_DEFAULTS.merge(text: __with_optional(@template.t(".#{attribute}.label"), optional))
|
184
|
+
else label
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def normalize_hint(attribute, hint)
|
189
|
+
case hint
|
190
|
+
when String then HINT_DEFAULTS.merge(text: hint)
|
191
|
+
when Hash then HINT_DEFAULTS.merge(hint)
|
192
|
+
when TrueClass then __hint_hash(attribute)
|
193
|
+
when FalseClass then { text: false }
|
194
|
+
else hint
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def normalize_text_argument(attribute, arg, i18n_key)
|
199
|
+
case arg
|
200
|
+
when TrueClass then @template.t(".#{attribute}.#{i18n_key}", raise: true)
|
201
|
+
when FalseClass then nil
|
202
|
+
else arg
|
203
|
+
end
|
204
|
+
rescue I18n::MissingTranslationData
|
205
|
+
nil
|
206
|
+
end
|
207
|
+
|
208
|
+
def __hint_hash(attribute)
|
209
|
+
hint_text = __hint_text(attribute)
|
210
|
+
return {} if hint_text.nil?
|
211
|
+
|
212
|
+
HINT_DEFAULTS.merge(text: hint_text)
|
213
|
+
end
|
214
|
+
|
215
|
+
def __hint_text(attribute)
|
216
|
+
@template.t(".#{attribute}.hint", raise: true)
|
217
|
+
rescue I18n::MissingTranslationData
|
218
|
+
nil
|
219
|
+
end
|
220
|
+
|
221
|
+
def __upload_button_text(attribute)
|
222
|
+
@template.t(".#{attribute}.button_text", raise: true)
|
223
|
+
rescue I18n::MissingTranslationData
|
224
|
+
nil
|
225
|
+
end
|
226
|
+
|
227
|
+
def __with_optional(label_text, optional)
|
228
|
+
return label_text if label_text.nil? || !optional
|
229
|
+
|
230
|
+
"#{label_text} #{@template.t(OPTIONAL_I18N_KEY)}"
|
231
|
+
end
|
232
|
+
|
233
|
+
def i18n_options_for(attribute)
|
234
|
+
@template.t(".#{attribute}.options").to_a.map do |item|
|
235
|
+
item[0] = item[0].to_s
|
236
|
+
item
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'et_gds_design_system/version'
|
2
|
+
install_template_path = File.expand_path("../../install/template.rb", __dir__).freeze
|
3
|
+
bin_path = ENV["BUNDLE_BIN"] || "./bin"
|
4
|
+
namespace :et_gds_design_system do
|
5
|
+
desc "Installs everything needed into a rails 6+ app"
|
6
|
+
task :install do
|
7
|
+
if Rails::VERSION::MAJOR >= 5
|
8
|
+
exec "#{RbConfig.ruby} #{bin_path}/rails app:template LOCATION=#{install_template_path}"
|
9
|
+
else
|
10
|
+
exec "#{RbConfig.ruby} #{bin_path}/rake rails:template LOCATION=#{install_template_path}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: et_gds_design_system
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 5.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gary Taylor
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-10-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: govuk_design_system_formbuilder
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webpacker
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-proxy
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.6'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: capybara
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: selenium-webdriver
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.142'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.142'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webdrivers
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: capybara-screenshot
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: site_prism
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '3.5'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.5'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: activerecord-nulldb-adapter
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.4'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.4'
|
167
|
+
description: Description of EtGdsDesignSystem.
|
168
|
+
email:
|
169
|
+
- gary.taylor@hismessages.com
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files: []
|
173
|
+
files:
|
174
|
+
- MIT-LICENSE
|
175
|
+
- README.md
|
176
|
+
- Rakefile
|
177
|
+
- app/assets/config/et_gds_design_system_manifest.js
|
178
|
+
- app/helpers/et_gds_design_system/file_dropzone_helper.rb
|
179
|
+
- app/javascript/components.js
|
180
|
+
- app/javascript/components/DropzoneUploader.js
|
181
|
+
- app/javascript/components/DropzoneUploader/preview-template.html
|
182
|
+
- app/javascript/components/DropzoneUploader/stylesheet.scss
|
183
|
+
- app/javascript/components/RevealOnRadioButton.js
|
184
|
+
- app/types/et_gds_design_system/azure_file.rb
|
185
|
+
- app/types/et_gds_design_system/date_without_day_type.rb
|
186
|
+
- app/views/et_gds_design_system/elements/file_dropzone/_template.html.erb
|
187
|
+
- config/initializers/type.rb
|
188
|
+
- config/routes.rb
|
189
|
+
- lib/et_gds_design_system.rb
|
190
|
+
- lib/et_gds_design_system/api_proxy.rb
|
191
|
+
- lib/et_gds_design_system/elements/date.rb
|
192
|
+
- lib/et_gds_design_system/elements/file_dropzone.rb
|
193
|
+
- lib/et_gds_design_system/engine.rb
|
194
|
+
- lib/et_gds_design_system/form/builder.rb
|
195
|
+
- lib/et_gds_design_system/version.rb
|
196
|
+
- lib/tasks/et_gds_design_system_tasks.rake
|
197
|
+
homepage: http://www.google.com
|
198
|
+
licenses:
|
199
|
+
- MIT
|
200
|
+
metadata: {}
|
201
|
+
post_install_message:
|
202
|
+
rdoc_options: []
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
requirements: []
|
216
|
+
rubyforge_project:
|
217
|
+
rubygems_version: 2.7.6
|
218
|
+
signing_key:
|
219
|
+
specification_version: 4
|
220
|
+
summary: Summary of EtGdsDesignSystem.
|
221
|
+
test_files: []
|