-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File input new dropzone design #5642
base: spike-enhanced-file-upload
Are you sure you want to change the base?
File input new dropzone design #5642
Conversation
📋 StatsFile sizes
Modules
View stats and visualisations on the review app Action run for ede849e |
JavaScript changes to npm packagediff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
index 4b409f096..2e0a33ee4 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -757,14 +757,20 @@ class FileUpload extends ConfigurableComponent {
}), this.$label = this.findLabel(), this.$root.id = `${this.id}-input`;
const n = document.createElement("div");
n.className = "govuk-file-upload-wrapper";
- const i = document.createElement("button");
- i.classList.add("govuk-file-upload__button"), i.type = "button", i.id = this.id;
- const s = this.$root.getAttribute("aria-describedby");
- s && i.setAttribute("aria-describedby", s);
- const o = document.createElement("span");
- o.className = "govuk-button govuk-button--secondary govuk-file-upload__pseudo-button", o.innerText = this.i18n.t("selectFilesButton"), o.setAttribute("aria-hidden", "true"), i.appendChild(o), i.addEventListener("click", this.onClick.bind(this));
+ const i = document.createElement("span");
+ i.className = "govuk-visually-hidden", i.innerText = ", ";
+ const s = document.createElement("button");
+ s.classList.add("govuk-file-upload__button"), s.type = "button", s.id = this.id;
+ const o = this.$root.getAttribute("aria-describedby");
+ o && s.setAttribute("aria-describedby", o);
const r = document.createElement("span");
- r.className = "govuk-body govuk-file-upload__status", r.innerText = this.i18n.t("filesSelectedDefault"), r.setAttribute("aria-hidden", "true"), i.appendChild(r), i.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")}, ${this.i18n.t("filesSelectedDefault")}`), n.insertAdjacentElement("beforeend", i), this.$root.insertAdjacentElement("afterend", n), this.$root.setAttribute("tabindex", "-1"), this.$root.setAttribute("aria-hidden", "true"), n.insertAdjacentElement("afterbegin", this.$root), this.$wrapper = n, this.$button = i, this.$status = r, this.$root.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$root.addEventListener("change", this.onChange.bind(this)), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$wrapper.insertAdjacentElement("afterend", this.$announcements), this.$wrapper.addEventListener("drop", this.hideDropZone.bind(this)), document.addEventListener("dragenter", this.updateDropzoneVisibility.bind(this)), document.addEventListener("dragenter", (() => {
+ r.className = "govuk-body govuk-file-upload__status", r.innerText = this.i18n.t("filesSelectedDefault"), r.setAttribute("aria-hidden", "true"), r.classList.add("govuk-file-upload__status--empty"), s.appendChild(r), s.appendChild(i.cloneNode(!0));
+ const a = document.createElement("span");
+ a.className = "govuk-file-upload__pseudo-button-container";
+ const l = document.createElement("span");
+ l.className = "govuk-button govuk-button--secondary govuk-file-upload__pseudo-button", l.innerText = this.i18n.t("selectFilesButton"), l.setAttribute("aria-hidden", "true"), a.appendChild(l), a.appendChild(i.cloneNode(!0));
+ const c = document.createElement("span");
+ c.className = "govuk-body govuk-file-upload__instruction", c.innerText = this.i18n.t("instruction"), a.appendChild(c), s.appendChild(a), s.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")} ${this.i18n.t("instruction")}, ${r.innerText}`), s.addEventListener("click", this.onClick.bind(this)), n.insertAdjacentElement("beforeend", s), this.$root.insertAdjacentElement("afterend", n), this.$root.setAttribute("tabindex", "-1"), this.$root.setAttribute("aria-hidden", "true"), n.insertAdjacentElement("afterbegin", this.$root), this.$wrapper = n, this.$button = s, this.$status = r, this.$root.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$wrapper.insertAdjacentElement("afterend", this.$announcements), this.$wrapper.addEventListener("drop", this.hideDropZone.bind(this)), document.addEventListener("dragenter", this.updateDropzoneVisibility.bind(this)), document.addEventListener("dragenter", (() => {
this.enteredAnotherElement = !0
})), document.addEventListener("dragleave", (() => {
this.enteredAnotherElement || this.hideDropZone(), this.enteredAnotherElement = !1
@@ -782,9 +788,9 @@ class FileUpload extends ConfigurableComponent {
}
onChange() {
const t = this.$root.files.length;
- this.$status.innerText = 0 === t ? this.i18n.t("filesSelectedDefault") : 1 === t ? this.$root.files[0].name : this.i18n.t("filesSelected", {
+ 0 === t ? (this.$status.innerText = this.i18n.t("filesSelectedDefault"), this.$status.classList.add("govuk-file-upload__status--empty")) : (this.$status.innerText = 1 === t ? this.$root.files[0].name : this.i18n.t("filesSelected", {
count: t
- }), this.$button.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")}, ${this.$status.innerText}`)
+ }), this.$status.classList.remove("govuk-file-upload__status--empty")), this.$button.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")} ${this.i18n.t("instruction")}, ${this.$status.innerText}`)
}
findLabel() {
const t = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -817,7 +823,8 @@ FileUpload.moduleName = "govuk-file-upload", FileUpload.defaults = Object.freeze
other: "%{count} files chosen"
},
dropZoneEntered: "Entered drop zone",
- dropZoneLeft: "Left drop zone"
+ dropZoneLeft: "Left drop zone",
+ instruction: "or drop file"
}
}), FileUpload.schema = Object.freeze({
properties: {
Action run for ede849e |
Stylesheets changes to npm packagediff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
index 9417707ca..e401932ba 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
@@ -3385,25 +3385,15 @@ screen and (forced-colors:active) {
}
.govuk-file-upload-wrapper {
- display: inline-flex;
- align-items: baseline;
- position: relative
-}
-
-.govuk-file-upload-wrapper--show-dropzone {
- margin: -12px;
- padding: 10px;
- border: 2px dashed #0b0c0c;
+ display: block;
+ position: relative;
+ z-index: 0;
background-color: #fff
}
-.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__pseudo-button,
-.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__status {
- pointer-events: none
-}
-
.govuk-file-upload-wrapper .govuk-file-upload {
position: absolute;
+ z-index: -1;
top: 0;
left: 0;
width: 100%;
@@ -3413,63 +3403,101 @@ screen and (forced-colors:active) {
opacity: 0
}
+.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload {
+ z-index: 1
+}
+
.govuk-file-upload__pseudo-button {
width: auto;
- margin-bottom: 0;
- flex-grow: 0;
+ margin-right: 10px;
+ margin-bottom: 3px;
flex-shrink: 0
}
-.govuk-file-upload__status {
+.govuk-file-upload__instruction {
+ margin-top: 7px;
margin-bottom: 0;
- margin-left: 10px
+ text-align: left
}
-.govuk-file-upload__button:focus {
- outline: none
+.govuk-file-upload__status {
+ display: block;
+ margin-bottom: 10px;
+ padding: 15px 10px;
+ text-align: left
}
-.govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
- outline: 3px solid transparent;
- background-color: #fd0;
- box-shadow: 0 2px 0 #0b0c0c
+.govuk-file-upload__status--empty {
+ color: #0c2d4a;
+ background-color: #bbd4ea
}
-.govuk-file-upload__button:focus .govuk-file-upload__pseudo-button:hover {
- border-color: #fd0;
- outline: 3px solid transparent;
- background-color: #f3f2f1;
- box-shadow: inset 0 0 0 1px #fd0
+.govuk-file-upload__pseudo-button-container {
+ display: flex;
+ align-items: baseline;
+ flex-wrap: wrap
+}
+
+.govuk-file-upload__button {
+ width: 100%;
+ padding: 15px 18px;
+ border: 2px dashed #b1b4b6;
+ background-color: #fff;
+ cursor: pointer
}
-.govuk-file-upload__button:active .govuk-file-upload__pseudo-button:hover {
- background-color: #c2c2c1
+@media (min-width:40.0625em) {
+ .govuk-file-upload__button {
+ padding: 15px 23px
+ }
}
-.govuk-file-upload__button {
- align-items: center;
- display: flex;
- padding: 0;
- border: 0;
- background-color: transparent
+.govuk-file-upload-wrapper:hover .govuk-file-upload__button {
+ border-color: #8e9092
}
-.govuk-file-upload:disabled+.govuk-file-upload__button {
- pointer-events: none
+.govuk-file-upload-wrapper:hover .govuk-file-upload__pseudo-button {
+ background-color: #dbdad9
}
-.govuk-file-upload:disabled+.govuk-file-upload__button .govuk-file-upload__pseudo-button {
- opacity: .5
+.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__button,
+.govuk-file-upload-wrapper:hover .govuk-file-upload__button {
+ background-color: #f3f2f1
+}
+
+.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__status--empty,
+.govuk-file-upload-wrapper:hover .govuk-file-upload__status--empty,
+.govuk-file-upload__button:focus .govuk-file-upload__status--empty {
+ background-color: #d2e2f1
+}
+
+.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__button {
+ border: 2px solid #0b0c0c
}
-.govuk-file-upload:disabled+.govuk-file-upload__button .govuk-file-upload__pseudo-button:hover {
+.govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__pseudo-button {
+ background-color: #fff
+}
+
+.govuk-file-upload__button:active,
+.govuk-file-upload__button:focus {
+ border: 2px solid #0b0c0c;
+ outline: 3px solid #fd0;
+ outline-offset: 0;
background-color: #f3f2f1;
- cursor: not-allowed
+ box-shadow: inset 0 0 0 2px
}
-.govuk-file-upload:disabled+.govuk-file-upload__button .govuk-file-upload__pseudo-button:active {
- top: 0;
- box-shadow: 0 2px 0 #666
+.govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
+ background-color: #fd0;
+ box-shadow: 0 2px 0 #0b0c0c
+}
+
+.govuk-file-upload-wrapper:hover .govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
+ border-color: #fd0;
+ outline: 3px solid transparent;
+ background-color: #f3f2f1;
+ box-shadow: inset 0 0 0 1px #fd0
}
.govuk-footer {
Action run for ede849e |
Other changes to npm packagediff --git a/packages/govuk-frontend/dist/govuk/all.bundle.js b/packages/govuk-frontend/dist/govuk/all.bundle.js
index 68d48e9ac..a58b5df65 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -1686,6 +1686,9 @@
this.$root.id = `${this.id}-input`;
const $wrapper = document.createElement('div');
$wrapper.className = 'govuk-file-upload-wrapper';
+ const commaSpan = document.createElement('span');
+ commaSpan.className = 'govuk-visually-hidden';
+ commaSpan.innerText = ', ';
const $button = document.createElement('button');
$button.classList.add('govuk-file-upload__button');
$button.type = 'button';
@@ -1694,18 +1697,28 @@
if (ariaDescribedBy) {
$button.setAttribute('aria-describedby', ariaDescribedBy);
}
- const buttonSpan = document.createElement('span');
- buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
- buttonSpan.innerText = this.i18n.t('selectFilesButton');
- buttonSpan.setAttribute('aria-hidden', 'true');
- $button.appendChild(buttonSpan);
- $button.addEventListener('click', this.onClick.bind(this));
const $status = document.createElement('span');
$status.className = 'govuk-body govuk-file-upload__status';
$status.innerText = this.i18n.t('filesSelectedDefault');
$status.setAttribute('aria-hidden', 'true');
+ $status.classList.add('govuk-file-upload__status--empty');
$button.appendChild($status);
- $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.i18n.t('filesSelectedDefault')}`);
+ $button.appendChild(commaSpan.cloneNode(true));
+ const containerSpan = document.createElement('span');
+ containerSpan.className = 'govuk-file-upload__pseudo-button-container';
+ const buttonSpan = document.createElement('span');
+ buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
+ buttonSpan.innerText = this.i18n.t('selectFilesButton');
+ buttonSpan.setAttribute('aria-hidden', 'true');
+ containerSpan.appendChild(buttonSpan);
+ containerSpan.appendChild(commaSpan.cloneNode(true));
+ const instructionSpan = document.createElement('span');
+ instructionSpan.className = 'govuk-body govuk-file-upload__instruction';
+ instructionSpan.innerText = this.i18n.t('instruction');
+ containerSpan.appendChild(instructionSpan);
+ $button.appendChild(containerSpan);
+ $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+ $button.addEventListener('click', this.onClick.bind(this));
$wrapper.insertAdjacentElement('beforeend', $button);
this.$root.insertAdjacentElement('afterend', $wrapper);
this.$root.setAttribute('tabindex', '-1');
@@ -1717,7 +1730,6 @@
this.$root.addEventListener('change', this.onChange.bind(this));
this.updateDisabledState();
this.observeDisabledState();
- this.$root.addEventListener('change', this.onChange.bind(this));
this.$announcements = document.createElement('span');
this.$announcements.classList.add('govuk-file-upload-announcements');
this.$announcements.classList.add('govuk-visually-hidden');
@@ -1765,14 +1777,18 @@
const fileCount = this.$root.files.length;
if (fileCount === 0) {
this.$status.innerText = this.i18n.t('filesSelectedDefault');
- } else if (fileCount === 1) {
- this.$status.innerText = this.$root.files[0].name;
+ this.$status.classList.add('govuk-file-upload__status--empty');
} else {
- this.$status.innerText = this.i18n.t('filesSelected', {
- count: fileCount
- });
+ if (fileCount === 1) {
+ this.$status.innerText = this.$root.files[0].name;
+ } else {
+ this.$status.innerText = this.i18n.t('filesSelected', {
+ count: fileCount
+ });
+ }
+ this.$status.classList.remove('govuk-file-upload__status--empty');
}
- this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.$status.innerText}`);
+ this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
}
findLabel() {
const $label = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -1814,7 +1830,8 @@
other: '%{count} files chosen'
},
dropZoneEntered: 'Entered drop zone',
- dropZoneLeft: 'Left drop zone'
+ dropZoneLeft: 'Left drop zone',
+ instruction: 'or drop file'
}
});
FileUpload.schema = Object.freeze({
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index e32972b10..589c4ccf6 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -1680,6 +1680,9 @@ class FileUpload extends ConfigurableComponent {
this.$root.id = `${this.id}-input`;
const $wrapper = document.createElement('div');
$wrapper.className = 'govuk-file-upload-wrapper';
+ const commaSpan = document.createElement('span');
+ commaSpan.className = 'govuk-visually-hidden';
+ commaSpan.innerText = ', ';
const $button = document.createElement('button');
$button.classList.add('govuk-file-upload__button');
$button.type = 'button';
@@ -1688,18 +1691,28 @@ class FileUpload extends ConfigurableComponent {
if (ariaDescribedBy) {
$button.setAttribute('aria-describedby', ariaDescribedBy);
}
- const buttonSpan = document.createElement('span');
- buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
- buttonSpan.innerText = this.i18n.t('selectFilesButton');
- buttonSpan.setAttribute('aria-hidden', 'true');
- $button.appendChild(buttonSpan);
- $button.addEventListener('click', this.onClick.bind(this));
const $status = document.createElement('span');
$status.className = 'govuk-body govuk-file-upload__status';
$status.innerText = this.i18n.t('filesSelectedDefault');
$status.setAttribute('aria-hidden', 'true');
+ $status.classList.add('govuk-file-upload__status--empty');
$button.appendChild($status);
- $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.i18n.t('filesSelectedDefault')}`);
+ $button.appendChild(commaSpan.cloneNode(true));
+ const containerSpan = document.createElement('span');
+ containerSpan.className = 'govuk-file-upload__pseudo-button-container';
+ const buttonSpan = document.createElement('span');
+ buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
+ buttonSpan.innerText = this.i18n.t('selectFilesButton');
+ buttonSpan.setAttribute('aria-hidden', 'true');
+ containerSpan.appendChild(buttonSpan);
+ containerSpan.appendChild(commaSpan.cloneNode(true));
+ const instructionSpan = document.createElement('span');
+ instructionSpan.className = 'govuk-body govuk-file-upload__instruction';
+ instructionSpan.innerText = this.i18n.t('instruction');
+ containerSpan.appendChild(instructionSpan);
+ $button.appendChild(containerSpan);
+ $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+ $button.addEventListener('click', this.onClick.bind(this));
$wrapper.insertAdjacentElement('beforeend', $button);
this.$root.insertAdjacentElement('afterend', $wrapper);
this.$root.setAttribute('tabindex', '-1');
@@ -1711,7 +1724,6 @@ class FileUpload extends ConfigurableComponent {
this.$root.addEventListener('change', this.onChange.bind(this));
this.updateDisabledState();
this.observeDisabledState();
- this.$root.addEventListener('change', this.onChange.bind(this));
this.$announcements = document.createElement('span');
this.$announcements.classList.add('govuk-file-upload-announcements');
this.$announcements.classList.add('govuk-visually-hidden');
@@ -1759,14 +1771,18 @@ class FileUpload extends ConfigurableComponent {
const fileCount = this.$root.files.length;
if (fileCount === 0) {
this.$status.innerText = this.i18n.t('filesSelectedDefault');
- } else if (fileCount === 1) {
- this.$status.innerText = this.$root.files[0].name;
+ this.$status.classList.add('govuk-file-upload__status--empty');
} else {
- this.$status.innerText = this.i18n.t('filesSelected', {
- count: fileCount
- });
+ if (fileCount === 1) {
+ this.$status.innerText = this.$root.files[0].name;
+ } else {
+ this.$status.innerText = this.i18n.t('filesSelected', {
+ count: fileCount
+ });
+ }
+ this.$status.classList.remove('govuk-file-upload__status--empty');
}
- this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.$status.innerText}`);
+ this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
}
findLabel() {
const $label = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -1808,7 +1824,8 @@ FileUpload.defaults = Object.freeze({
other: '%{count} files chosen'
},
dropZoneEntered: 'Entered drop zone',
- dropZoneLeft: 'Left drop zone'
+ dropZoneLeft: 'Left drop zone',
+ instruction: 'or drop file'
}
});
FileUpload.schema = Object.freeze({
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/_index.scss b/packages/govuk-frontend/dist/govuk/components/file-upload/_index.scss
index 4dc478173..1da265081 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/_index.scss
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/_index.scss
@@ -3,6 +3,7 @@
@import "../label/index";
@include govuk-exports("govuk/component/file-upload") {
+ $file-upload-border-width: 2px;
$component-padding: govuk-spacing(1);
.govuk-file-upload {
@@ -48,34 +49,17 @@
}
.govuk-file-upload-wrapper {
- display: inline-flex;
- align-items: baseline;
+ display: block;
position: relative;
- }
-
- .govuk-file-upload-wrapper--show-dropzone {
- $dropzone-padding: govuk-spacing(2);
- $dropzone-offset: $dropzone-padding + $govuk-border-width-form-element;
-
- // Add negative margins to all sides so that content doesn't jump due to
- // the addition of the padding and border.
- margin: -$dropzone-offset;
- padding: $dropzone-padding;
- border: $govuk-border-width-form-element dashed $govuk-input-border-colour;
+ z-index: 0;
background-color: $govuk-body-background-colour;
-
- .govuk-file-upload__pseudo-button,
- .govuk-file-upload__status {
- // When the dropzone is hovered over, make these aspects not accept
- // mouse events, so dropped files fall through to the input beneath them
- pointer-events: none;
- }
}
.govuk-file-upload-wrapper .govuk-file-upload {
+ position: absolute;
// Make the native control take up the entire space of the element, but
// invisible and behind the other elements until we need it
- position: absolute;
+ z-index: -1;
top: 0;
left: 0;
width: 100%;
@@ -85,63 +69,109 @@
opacity: 0;
}
+ .govuk-file-upload-wrapper--show-dropzone .govuk-file-upload {
+ z-index: 1;
+ }
+
.govuk-file-upload__pseudo-button {
width: auto;
- margin-bottom: 0;
- flex-grow: 0;
+ margin-right: govuk-spacing(2);
+ margin-bottom: $govuk-border-width-form-element + 1;
flex-shrink: 0;
}
- .govuk-file-upload__status {
+ .govuk-file-upload__instruction {
+ margin-top: govuk-spacing(2) - ($govuk-border-width-form-element + 1);
margin-bottom: 0;
- margin-left: govuk-spacing(2);
+ text-align: left;
}
-}
-.govuk-file-upload__button:focus {
- outline: none;
-}
+ .govuk-file-upload__status {
+ display: block;
+ margin-bottom: govuk-spacing(2);
+ padding: govuk-spacing(3) govuk-spacing(2);
+ text-align: left;
+ }
-.govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
- outline: 3px solid transparent;
- background-color: $govuk-focus-colour;
- box-shadow: 0 2px 0 govuk-colour("black");
-}
+ .govuk-file-upload__status--empty {
+ color: govuk-shade(govuk-colour("blue"), 60%);
+ background-color: govuk-tint(govuk-colour("blue"), 70%);
+ }
-.govuk-file-upload__button:focus .govuk-file-upload__pseudo-button:hover {
- border-color: $govuk-focus-colour;
- outline: 3px solid transparent;
- background-color: govuk-colour("light-grey");
- box-shadow: inset 0 0 0 1px $govuk-focus-colour;
-}
+ // bugs documented with button using flex
+ // https://github.com/philipwalton/flexbugs#flexbug-9
+ // so we need a container here
+ .govuk-file-upload__pseudo-button-container {
+ display: flex;
+ align-items: baseline;
+ flex-wrap: wrap;
+ }
-.govuk-file-upload__button:active .govuk-file-upload__pseudo-button:hover {
- background-color: govuk-shade(govuk-colour("light-grey"), 20%);
-}
+ .govuk-file-upload__button {
+ width: 100%;
+ // align the padding to be same as notification banner and error summary accounting for the thicker borders
+ padding: govuk-spacing(3) (govuk-spacing(3) + $govuk-border-width - $file-upload-border-width);
+ border: $file-upload-border-width govuk-colour("mid-grey") dashed;
+ background-color: govuk-colour("white");
+ cursor: pointer;
+
+ @include govuk-media-query($from: tablet) {
+ padding: govuk-spacing(3) (govuk-spacing(4) + $govuk-border-width - $file-upload-border-width);
+ }
+ }
-.govuk-file-upload__button {
- align-items: center;
- display: flex;
- padding: 0;
- border: 0;
- background-color: transparent;
-}
+ .govuk-file-upload-wrapper:hover .govuk-file-upload__button {
+ border-color: govuk-shade(govuk-colour("mid-grey"), 20%);
+ }
-.govuk-file-upload:disabled + .govuk-file-upload__button {
- pointer-events: none;
-}
+ .govuk-file-upload-wrapper:hover .govuk-file-upload__pseudo-button {
+ background-color: govuk-shade(govuk-colour("light-grey"), 10%);
+ }
+
+ .govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__button,
+ .govuk-file-upload-wrapper:hover .govuk-file-upload__button {
+ background-color: govuk-colour("light-grey");
+ }
+
+ .govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__status--empty,
+ .govuk-file-upload-wrapper:hover .govuk-file-upload__status--empty,
+ .govuk-file-upload__button:focus .govuk-file-upload__status--empty {
+ background-color: govuk-tint(govuk-colour("blue"), 80%);
+ }
+
+ .govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__button {
+ border: $file-upload-border-width solid govuk-colour("black");
+ }
-.govuk-file-upload:disabled + .govuk-file-upload__button .govuk-file-upload__pseudo-button {
- opacity: (0.5);
+ .govuk-file-upload-wrapper--show-dropzone .govuk-file-upload__pseudo-button {
+ background-color: govuk-colour("white");
+ }
- &:hover {
+ .govuk-file-upload__button:active,
+ .govuk-file-upload__button:focus {
+ border: 2px solid govuk-colour("black");
+ outline: $govuk-focus-width solid $govuk-focus-colour;
+ // Ensure outline appears outside of the element
+ outline-offset: 0;
background-color: govuk-colour("light-grey");
- cursor: not-allowed;
+ // Double the border by adding its width again. Use `box-shadow` for this
+ // instead of changing `border-width` - this is for consistency with
+ // components such as textarea where we avoid changing `border-width` as
+ // it will change the element size. Also, `outline` cannot be utilised
+ // here as it is already used for the yellow focus state.
+ box-shadow: inset 0 0 0 $govuk-border-width-form-element;
}
- &:active {
- top: 0;
- box-shadow: 0 $govuk-border-width-form-element 0 govuk-shade(govuk-colour("white"), 60%); // s0
+ .govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
+ background-color: $govuk-focus-colour;
+ box-shadow: 0 2px 0 govuk-colour("black");
+ }
+
+ .govuk-file-upload-wrapper:hover .govuk-file-upload__button:focus .govuk-file-upload__pseudo-button {
+ border-color: $govuk-focus-colour;
+ outline: 3px solid transparent;
+ background-color: govuk-colour("light-grey");
+ box-shadow: inset 0 0 0 1px $govuk-focus-colour;
}
}
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
index 312098ada..0b4d1db88 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
@@ -513,6 +513,9 @@
this.$root.id = `${this.id}-input`;
const $wrapper = document.createElement('div');
$wrapper.className = 'govuk-file-upload-wrapper';
+ const commaSpan = document.createElement('span');
+ commaSpan.className = 'govuk-visually-hidden';
+ commaSpan.innerText = ', ';
const $button = document.createElement('button');
$button.classList.add('govuk-file-upload__button');
$button.type = 'button';
@@ -521,18 +524,28 @@
if (ariaDescribedBy) {
$button.setAttribute('aria-describedby', ariaDescribedBy);
}
- const buttonSpan = document.createElement('span');
- buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
- buttonSpan.innerText = this.i18n.t('selectFilesButton');
- buttonSpan.setAttribute('aria-hidden', 'true');
- $button.appendChild(buttonSpan);
- $button.addEventListener('click', this.onClick.bind(this));
const $status = document.createElement('span');
$status.className = 'govuk-body govuk-file-upload__status';
$status.innerText = this.i18n.t('filesSelectedDefault');
$status.setAttribute('aria-hidden', 'true');
+ $status.classList.add('govuk-file-upload__status--empty');
$button.appendChild($status);
- $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.i18n.t('filesSelectedDefault')}`);
+ $button.appendChild(commaSpan.cloneNode(true));
+ const containerSpan = document.createElement('span');
+ containerSpan.className = 'govuk-file-upload__pseudo-button-container';
+ const buttonSpan = document.createElement('span');
+ buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
+ buttonSpan.innerText = this.i18n.t('selectFilesButton');
+ buttonSpan.setAttribute('aria-hidden', 'true');
+ containerSpan.appendChild(buttonSpan);
+ containerSpan.appendChild(commaSpan.cloneNode(true));
+ const instructionSpan = document.createElement('span');
+ instructionSpan.className = 'govuk-body govuk-file-upload__instruction';
+ instructionSpan.innerText = this.i18n.t('instruction');
+ containerSpan.appendChild(instructionSpan);
+ $button.appendChild(containerSpan);
+ $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+ $button.addEventListener('click', this.onClick.bind(this));
$wrapper.insertAdjacentElement('beforeend', $button);
this.$root.insertAdjacentElement('afterend', $wrapper);
this.$root.setAttribute('tabindex', '-1');
@@ -544,7 +557,6 @@
this.$root.addEventListener('change', this.onChange.bind(this));
this.updateDisabledState();
this.observeDisabledState();
- this.$root.addEventListener('change', this.onChange.bind(this));
this.$announcements = document.createElement('span');
this.$announcements.classList.add('govuk-file-upload-announcements');
this.$announcements.classList.add('govuk-visually-hidden');
@@ -592,14 +604,18 @@
const fileCount = this.$root.files.length;
if (fileCount === 0) {
this.$status.innerText = this.i18n.t('filesSelectedDefault');
- } else if (fileCount === 1) {
- this.$status.innerText = this.$root.files[0].name;
+ this.$status.classList.add('govuk-file-upload__status--empty');
} else {
- this.$status.innerText = this.i18n.t('filesSelected', {
- count: fileCount
- });
+ if (fileCount === 1) {
+ this.$status.innerText = this.$root.files[0].name;
+ } else {
+ this.$status.innerText = this.i18n.t('filesSelected', {
+ count: fileCount
+ });
+ }
+ this.$status.classList.remove('govuk-file-upload__status--empty');
}
- this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.$status.innerText}`);
+ this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
}
findLabel() {
const $label = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -641,7 +657,8 @@
other: '%{count} files chosen'
},
dropZoneEntered: 'Entered drop zone',
- dropZoneLeft: 'Left drop zone'
+ dropZoneLeft: 'Left drop zone',
+ instruction: 'or drop file'
}
});
FileUpload.schema = Object.freeze({
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
index e759a6c30..ce4dc45ba 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
@@ -507,6 +507,9 @@ class FileUpload extends ConfigurableComponent {
this.$root.id = `${this.id}-input`;
const $wrapper = document.createElement('div');
$wrapper.className = 'govuk-file-upload-wrapper';
+ const commaSpan = document.createElement('span');
+ commaSpan.className = 'govuk-visually-hidden';
+ commaSpan.innerText = ', ';
const $button = document.createElement('button');
$button.classList.add('govuk-file-upload__button');
$button.type = 'button';
@@ -515,18 +518,28 @@ class FileUpload extends ConfigurableComponent {
if (ariaDescribedBy) {
$button.setAttribute('aria-describedby', ariaDescribedBy);
}
- const buttonSpan = document.createElement('span');
- buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
- buttonSpan.innerText = this.i18n.t('selectFilesButton');
- buttonSpan.setAttribute('aria-hidden', 'true');
- $button.appendChild(buttonSpan);
- $button.addEventListener('click', this.onClick.bind(this));
const $status = document.createElement('span');
$status.className = 'govuk-body govuk-file-upload__status';
$status.innerText = this.i18n.t('filesSelectedDefault');
$status.setAttribute('aria-hidden', 'true');
+ $status.classList.add('govuk-file-upload__status--empty');
$button.appendChild($status);
- $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.i18n.t('filesSelectedDefault')}`);
+ $button.appendChild(commaSpan.cloneNode(true));
+ const containerSpan = document.createElement('span');
+ containerSpan.className = 'govuk-file-upload__pseudo-button-container';
+ const buttonSpan = document.createElement('span');
+ buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
+ buttonSpan.innerText = this.i18n.t('selectFilesButton');
+ buttonSpan.setAttribute('aria-hidden', 'true');
+ containerSpan.appendChild(buttonSpan);
+ containerSpan.appendChild(commaSpan.cloneNode(true));
+ const instructionSpan = document.createElement('span');
+ instructionSpan.className = 'govuk-body govuk-file-upload__instruction';
+ instructionSpan.innerText = this.i18n.t('instruction');
+ containerSpan.appendChild(instructionSpan);
+ $button.appendChild(containerSpan);
+ $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+ $button.addEventListener('click', this.onClick.bind(this));
$wrapper.insertAdjacentElement('beforeend', $button);
this.$root.insertAdjacentElement('afterend', $wrapper);
this.$root.setAttribute('tabindex', '-1');
@@ -538,7 +551,6 @@ class FileUpload extends ConfigurableComponent {
this.$root.addEventListener('change', this.onChange.bind(this));
this.updateDisabledState();
this.observeDisabledState();
- this.$root.addEventListener('change', this.onChange.bind(this));
this.$announcements = document.createElement('span');
this.$announcements.classList.add('govuk-file-upload-announcements');
this.$announcements.classList.add('govuk-visually-hidden');
@@ -586,14 +598,18 @@ class FileUpload extends ConfigurableComponent {
const fileCount = this.$root.files.length;
if (fileCount === 0) {
this.$status.innerText = this.i18n.t('filesSelectedDefault');
- } else if (fileCount === 1) {
- this.$status.innerText = this.$root.files[0].name;
+ this.$status.classList.add('govuk-file-upload__status--empty');
} else {
- this.$status.innerText = this.i18n.t('filesSelected', {
- count: fileCount
- });
+ if (fileCount === 1) {
+ this.$status.innerText = this.$root.files[0].name;
+ } else {
+ this.$status.innerText = this.i18n.t('filesSelected', {
+ count: fileCount
+ });
+ }
+ this.$status.classList.remove('govuk-file-upload__status--empty');
}
- this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.$status.innerText}`);
+ this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
}
findLabel() {
const $label = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -635,7 +651,8 @@ FileUpload.defaults = Object.freeze({
other: '%{count} files chosen'
},
dropZoneEntered: 'Entered drop zone',
- dropZoneLeft: 'Left drop zone'
+ dropZoneLeft: 'Left drop zone',
+ instruction: 'or drop file'
}
});
FileUpload.schema = Object.freeze({
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
index acccac3da..cee8c3418 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
@@ -36,6 +36,9 @@ class FileUpload extends ConfigurableComponent {
this.$root.id = `${this.id}-input`;
const $wrapper = document.createElement('div');
$wrapper.className = 'govuk-file-upload-wrapper';
+ const commaSpan = document.createElement('span');
+ commaSpan.className = 'govuk-visually-hidden';
+ commaSpan.innerText = ', ';
const $button = document.createElement('button');
$button.classList.add('govuk-file-upload__button');
$button.type = 'button';
@@ -44,18 +47,28 @@ class FileUpload extends ConfigurableComponent {
if (ariaDescribedBy) {
$button.setAttribute('aria-describedby', ariaDescribedBy);
}
- const buttonSpan = document.createElement('span');
- buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
- buttonSpan.innerText = this.i18n.t('selectFilesButton');
- buttonSpan.setAttribute('aria-hidden', 'true');
- $button.appendChild(buttonSpan);
- $button.addEventListener('click', this.onClick.bind(this));
const $status = document.createElement('span');
$status.className = 'govuk-body govuk-file-upload__status';
$status.innerText = this.i18n.t('filesSelectedDefault');
$status.setAttribute('aria-hidden', 'true');
+ $status.classList.add('govuk-file-upload__status--empty');
$button.appendChild($status);
- $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.i18n.t('filesSelectedDefault')}`);
+ $button.appendChild(commaSpan.cloneNode(true));
+ const containerSpan = document.createElement('span');
+ containerSpan.className = 'govuk-file-upload__pseudo-button-container';
+ const buttonSpan = document.createElement('span');
+ buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
+ buttonSpan.innerText = this.i18n.t('selectFilesButton');
+ buttonSpan.setAttribute('aria-hidden', 'true');
+ containerSpan.appendChild(buttonSpan);
+ containerSpan.appendChild(commaSpan.cloneNode(true));
+ const instructionSpan = document.createElement('span');
+ instructionSpan.className = 'govuk-body govuk-file-upload__instruction';
+ instructionSpan.innerText = this.i18n.t('instruction');
+ containerSpan.appendChild(instructionSpan);
+ $button.appendChild(containerSpan);
+ $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+ $button.addEventListener('click', this.onClick.bind(this));
$wrapper.insertAdjacentElement('beforeend', $button);
this.$root.insertAdjacentElement('afterend', $wrapper);
this.$root.setAttribute('tabindex', '-1');
@@ -67,7 +80,6 @@ class FileUpload extends ConfigurableComponent {
this.$root.addEventListener('change', this.onChange.bind(this));
this.updateDisabledState();
this.observeDisabledState();
- this.$root.addEventListener('change', this.onChange.bind(this));
this.$announcements = document.createElement('span');
this.$announcements.classList.add('govuk-file-upload-announcements');
this.$announcements.classList.add('govuk-visually-hidden');
@@ -115,14 +127,18 @@ class FileUpload extends ConfigurableComponent {
const fileCount = this.$root.files.length;
if (fileCount === 0) {
this.$status.innerText = this.i18n.t('filesSelectedDefault');
- } else if (fileCount === 1) {
- this.$status.innerText = this.$root.files[0].name;
+ this.$status.classList.add('govuk-file-upload__status--empty');
} else {
- this.$status.innerText = this.i18n.t('filesSelected', {
- count: fileCount
- });
+ if (fileCount === 1) {
+ this.$status.innerText = this.$root.files[0].name;
+ } else {
+ this.$status.innerText = this.i18n.t('filesSelected', {
+ count: fileCount
+ });
+ }
+ this.$status.classList.remove('govuk-file-upload__status--empty');
}
- this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')}, ${this.$status.innerText}`);
+ this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
}
findLabel() {
const $label = document.querySelector(`label[for="${this.$root.id}"]`);
@@ -164,7 +180,8 @@ FileUpload.defaults = Object.freeze({
other: '%{count} files chosen'
},
dropZoneEntered: 'Entered drop zone',
- dropZoneLeft: 'Left drop zone'
+ dropZoneLeft: 'Left drop zone',
+ instruction: 'or drop file'
}
});
FileUpload.schema = Object.freeze({
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/fixtures.json b/packages/govuk-frontend/dist/govuk/components/file-upload/fixtures.json
index 09d9a8427..1de2b1191 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/fixtures.json
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/fixtures.json
@@ -207,6 +207,7 @@
"multiple": true,
"javascript": true,
"selectFilesButtonText": "Dewiswch ffeil",
+ "instructionText": "neu ollwng ffeil",
"filesSelectedDefaultText": "Dim ffeiliau wedi'u dewis",
"filesSelectedText": {
"other": "%{count} ffeil wedi'u dewis",
@@ -217,7 +218,7 @@
"description": "",
"previewLayoutModifiers": [],
"screenshot": false,
- "html": "<div class=\"govuk-form-group\">\n <label class=\"govuk-label\" for=\"file-upload-1\">\n Llwythwch ffeil i fyny\n </label>\n <input class=\"govuk-file-upload\" id=\"file-upload-1\" name=\"file-upload-1\" type=\"file\" multiple data-module=\"govuk-file-upload\" data-i18n.select-files-button=\"Dewiswch ffeil\" data-i18n.files-selected-default=\"Dim ffeiliau wedi'u dewis\" data-i18n.files-selected.other=\"%{count} ffeil wedi'u dewis\" data-i18n.files-selected.one=\"%{count} ffeil wedi'i dewis\">\n</div>"
+ "html": "<div class=\"govuk-form-group\">\n <label class=\"govuk-label\" for=\"file-upload-1\">\n Llwythwch ffeil i fyny\n </label>\n <input class=\"govuk-file-upload\" id=\"file-upload-1\" name=\"file-upload-1\" type=\"file\" multiple data-module=\"govuk-file-upload\" data-i18n.select-files-button=\"Dewiswch ffeil\" data-i18n.files-selected-default=\"Dim ffeiliau wedi'u dewis\" data-i18n.files-selected.other=\"%{count} ffeil wedi'u dewis\" data-i18n.files-selected.one=\"%{count} ffeil wedi'i dewis\" data-i18n.instruction=\"neu ollwng ffeil\">\n</div>"
},
{
"name": "with value",
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json b/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
index 8d1e0092e..18bca34d1 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/macro-options.json
@@ -128,6 +128,12 @@
"required": false,
"description": "The text of the button that opens the file picker. JavaScript enhanced version of the component only. Default is \"Choose file\"."
},
+ {
+ "name": "instructionText",
+ "type": "string",
+ "required": false,
+ "description": "The text of the instruction text that follows the button that opens the file picker. JavaScript enhanced version of the component only. Default is \"or drop file\"."
+ },
{
"name": "filesSelected",
"type": "object",
Action run for ede849e |
cb99c32
to
fabd47e
Compare
fabd47e
to
be4ca83
Compare
be4ca83
to
6824061
Compare
6824061
to
789d1dc
Compare
789d1dc
to
d01c7b7
Compare
Cheers Patrick, that's a good start! I've documented a couple of missed details in the design document (internal link).
@CharlotteDowns It's a bit strange to have such variation in padding. Inspecting the Notification Banner on the Design System site, I'm seeing the following paddings:
Similarly on the Error Summary, the padding seems happily at |
@romaricpascal this could be my poor maths but I'm trying to recreate the same visual properties and alignment to the Notification banner and Error summary but working with a 2px border instead of a 5px border (used on those components). Maybe I should refer to the summary card styling instead 🤔, although that seems to only have a 1px border :(. |
d01c7b7
to
ee7639d
Compare
ee7639d
to
f9fa5fd
Compare
f9fa5fd
to
d189988
Compare
Rendered HTML changes to npm packagediff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/template-translated.html b/packages/govuk-frontend/dist/govuk/components/file-upload/template-translated.html
index 8c6060d23..1e275eb58 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/template-translated.html
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/template-translated.html
@@ -2,5 +2,5 @@
<label class="govuk-label" for="file-upload-1">
Llwythwch ffeil i fyny
</label>
- <input class="govuk-file-upload" id="file-upload-1" name="file-upload-1" type="file" multiple data-module="govuk-file-upload" data-i18n.select-files-button="Dewiswch ffeil" data-i18n.files-selected-default="Dim ffeiliau wedi'u dewis" data-i18n.files-selected.other="%{count} ffeil wedi'u dewis" data-i18n.files-selected.one="%{count} ffeil wedi'i dewis">
+ <input class="govuk-file-upload" id="file-upload-1" name="file-upload-1" type="file" multiple data-module="govuk-file-upload" data-i18n.select-files-button="Dewiswch ffeil" data-i18n.files-selected-default="Dim ffeiliau wedi'u dewis" data-i18n.files-selected.other="%{count} ffeil wedi'u dewis" data-i18n.files-selected.one="%{count} ffeil wedi'i dewis" data-i18n.instruction="neu ollwng ffeil">
</div>
Action run for ede849e |
00cb7d9
to
5135aa1
Compare
5135aa1
to
0043a27
Compare
0043a27
to
b55ab3f
Compare
b55ab3f
to
99e8d9d
Compare
99e8d9d
to
2f8e900
Compare
2f8e900
to
dffc168
Compare
dffc168
to
6a4b976
Compare
6a4b976
to
96cd37e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there code-wise I think 🙌🏻 Main issue is a flickering when hovering from the label to the drop zone. I've proposed a workaround, just needs checking with @CharlotteDowns.
Also made note of a couple of small code renamings or moves to tidy things up some more.
Noticed (but couldn't comment) that we listen to the change
even handler twice (probably from a previous merge).
.govuk-file-upload__button:hover, | ||
.govuk-file-upload__button:hover .govuk-file-upload__pseudo-button { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue Using the :hover
selector of the <button>
leads to two undesirable side effects:
- The hover triggers when hovering the
<label>
as it's linked to the button - In turn, when moving the mouse from the
<label>
to the<button>
, there's a white space that's neither of them which causes the hover state to flicker. This space would be even bigger if using the hint or error message.
Screen.Recording.2025-01-28.at.17.38.34.mov
I'd propose to use the .govuk-file-upload-wrapper:hover
to hook the styles if we can, which would only show the hover state when actually hovering the dropzone and not the label, avoiding the flickering. Not that our other form fields have no hover state (as they're not really stuff to click on) so I don't think that'd be jarring if the hover only happened when hovering the drop zone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CharlotteDowns Can you confirm if the hover state happening only when hovering the drop zone itself would be OK, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romaricpascal I'm happy with that suggestion, sounds like it will look better
// the addition of the padding and border. | ||
margin: -$dropzone-offset; | ||
padding: $dropzone-padding; | ||
border: $govuk-border-width-form-element dashed $govuk-input-border-colour; | ||
background-color: $govuk-body-background-colour; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion I think we'd want the wrapper to always have a white background (a bit like our input fields always have a white background as well), in case they end up on something not white, so we can move that background inside govuk-file-upload-wrapper
.
.govuk-file-upload__pseudo-button-container > * { | ||
margin-bottom: 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Could this be regrouped with the .govuk-file-upload__pseudo-button-container
selector so both bits related to that element are in the same area?
$button.appendChild($status) | ||
$button.appendChild(commaSpan.cloneNode(true)) | ||
|
||
const buttonParentSpan = document.createElement('span') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion To align with the CSS naming, could this be:
const buttonParentSpan = document.createElement('span') | |
const containerSpan = document.createElement('span') |
fileCount === 1 | ||
) { | ||
this.$status.innerText = this.$root.files[0].name | ||
this.$status.classList.add('govuk-tag--light-blue') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Should this be the following, instead of using the styles of the Tag component?
this.$status.classList.add('govuk-tag--light-blue') | |
this.$status.classList.add('govuk-file-upload__status--empty') |
96cd37e
to
78b83f4
Compare
78b83f4
to
8c41fd8
Compare
8c41fd8
to
afe1ae7
Compare
afe1ae7
to
21c6ecf
Compare
Button creation of file upload needs to be changed in line with the new design. Includes new `instruction span` which has been added to the i18n configuration.
New styles for file upload component. Includes adjusting the `z-index` when the dropzone is toggled.
21c6ecf
to
ede849e
Compare
What
Implement the new file input design.
Why
Fixes #5611