Skip to content

Commit

Permalink
Merge pull request #5705 from alphagov/file-upload-css-refactoring
Browse files Browse the repository at this point in the history
Improve naming of File Upload classes and regroup state styles
  • Loading branch information
romaricpascal authored Feb 10, 2025
2 parents a4d6adf + 8fec1e1 commit a3f96d5
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 116 deletions.
167 changes: 90 additions & 77 deletions packages/govuk-frontend/src/govuk/components/file-upload/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
}
}

.govuk-file-upload-wrapper {
.govuk-drop-zone {
display: block;
position: relative;
z-index: 0;
Expand All @@ -58,11 +58,11 @@
// required because disabling pointer events
// on the button means that the cursor style
// be applied on the button itself
.govuk-file-upload-wrapper--disabled {
.govuk-drop-zone--disabled {
cursor: not-allowed;
}

.govuk-frontend-supported .govuk-file-upload-wrapper .govuk-file-upload {
.govuk-file-upload--enhanced {
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
Expand All @@ -76,46 +76,41 @@
opacity: 0;
}

.govuk-frontend-supported .govuk-file-upload-wrapper .govuk-file-upload--dragging {
.govuk-file-upload--dragging {
z-index: 1;
}

.govuk-file-upload__pseudo-button {
.govuk-file-upload-button__pseudo-button {
width: auto;
margin-right: govuk-spacing(2);
margin-bottom: $govuk-border-width-form-element + 1;
flex-shrink: 0;
}

.govuk-file-upload__instruction {
.govuk-file-upload-button__instruction {
margin-top: govuk-spacing(2) - ($govuk-border-width-form-element + 1);
margin-bottom: 0;
text-align: left;
}

.govuk-file-upload__status {
.govuk-file-upload-button__status {
display: block;
margin-bottom: govuk-spacing(2);
padding: govuk-spacing(3) govuk-spacing(2);
background-color: govuk-colour("white");
text-align: left;
}

.govuk-file-upload__button--empty .govuk-file-upload__status {
color: govuk-shade(govuk-colour("blue"), 60%);
background-color: govuk-tint(govuk-colour("blue"), 70%);
}

// 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 {
.govuk-file-upload-button__pseudo-button-container {
display: flex;
align-items: baseline;
flex-wrap: wrap;
}

.govuk-file-upload__button {
.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-border-width - $file-upload-border-width);
Expand All @@ -126,84 +121,102 @@
@include govuk-media-query($from: tablet) {
padding: (govuk-spacing(4) + $govuk-border-width - $file-upload-border-width);
}
}

.govuk-file-upload__button--empty {
border-style: dashed;
background-color: govuk-colour("white");
}
.govuk-file-upload-button__pseudo-button {
background-color: govuk-colour("white");
}

.govuk-file-upload__button.govuk-file-upload__button--empty:hover {
background-color: govuk-colour("light-grey");
}
&:hover {
background-color: govuk-tint(govuk-colour("mid-grey"), 20%);

.govuk-file-upload__button:disabled {
pointer-events: none;
opacity: 0.5;
}
.govuk-file-upload-button__pseudo-button {
background-color: govuk-shade(govuk-colour("light-grey"), 10%);
}

.govuk-file-upload__button--dragging.govuk-file-upload__button,
.govuk-file-upload__button:hover {
background-color: govuk-tint(govuk-colour("mid-grey"), 20%);
}
.govuk-file-upload-button__status {
background-color: govuk-tint(govuk-colour("blue"), 80%);
}
}

.govuk-file-upload__button--dragging.govuk-file-upload__button--empty {
background-color: govuk-colour("light-grey");
}
&:active,
&:focus {
border: $file-upload-border-width 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-tint(govuk-colour("mid-grey"), 20%);
// 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;

.govuk-file-upload-button__pseudo-button {
background-color: $govuk-focus-colour;
box-shadow: 0 2px 0 govuk-colour("black");
}

&:hover .govuk-file-upload-button__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;
}
}

.govuk-file-upload__button--dragging:not(:disabled) {
border-color: govuk-shade(govuk-colour("mid-grey"), 20%);
&:disabled {
pointer-events: none;
opacity: 0.5;
}
}

.govuk-file-upload__button--dragging:not(:disabled) .govuk-file-upload__pseudo-button,
.govuk-file-upload__button:hover .govuk-file-upload__pseudo-button {
background-color: govuk-shade(govuk-colour("light-grey"), 10%);
}
.govuk-file-upload-button--empty {
border-style: dashed;
background-color: govuk-colour("white");

.govuk-file-upload__button--empty.govuk-file-upload__button--dragging:not(:disabled) .govuk-file-upload__status,
.govuk-file-upload__button--empty:hover .govuk-file-upload__status,
.govuk-file-upload__button--empty:focus .govuk-file-upload__status {
background-color: govuk-tint(govuk-colour("blue"), 80%);
}
.govuk-file-upload-button__pseudo-button {
background-color: govuk-colour("light-grey");
}

.govuk-file-upload__button .govuk-file-upload__pseudo-button,
.govuk-file-upload__button--empty.govuk-file-upload__button--dragging .govuk-file-upload__pseudo-button {
background-color: govuk-colour("white");
}
.govuk-file-upload-button__status {
color: govuk-shade(govuk-colour("blue"), 60%);
background-color: govuk-tint(govuk-colour("blue"), 70%);
}

.govuk-file-upload__button--empty .govuk-file-upload__pseudo-button {
background-color: govuk-colour("light-grey");
}
&:hover,
&:focus,
&:active {
background-color: govuk-colour("light-grey");

.govuk-file-upload__button:active,
.govuk-file-upload__button:focus {
border: $file-upload-border-width 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-tint(govuk-colour("mid-grey"), 20%);
// 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;
.govuk-file-upload-button__status {
background-color: govuk-tint(govuk-colour("blue"), 80%);
}
}
}

.govuk-file-upload__button--empty:active,
.govuk-file-upload__button--empty:focus {
background-color: govuk-colour("light-grey");
}
.govuk-file-upload-button--dragging {
// extra specificity to apply when
// empty
&.govuk-file-upload-button {
background-color: govuk-tint(govuk-colour("mid-grey"), 20%);
}

.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-button--empty {
background-color: govuk-colour("light-grey");
}

.govuk-file-upload__button:focus:hover .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;
&:not(:disabled) {
border-color: govuk-shade(govuk-colour("mid-grey"), 20%);

.govuk-file-upload-button__pseudo-button {
background-color: govuk-shade(govuk-colour("light-grey"), 10%);
}
}

&.govuk-file-upload-button--empty:not(:disabled) .govuk-file-upload-button__status,
&.govuk-file-upload-button--empty .govuk-file-upload-button__pseudo-button {
background-color: govuk-colour("white");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ export class FileUpload extends ConfigurableComponent {

// Create the file selection button
const $button = document.createElement('button')
$button.classList.add('govuk-file-upload__button')
$button.classList.add('govuk-file-upload-button')
$button.type = 'button'
$button.id = this.id
$button.classList.add('govuk-file-upload__button--empty')
$button.classList.add('govuk-file-upload-button--empty')

// Copy `aria-describedby` if present so hints and errors
// are associated to the `<button>`
Expand All @@ -104,7 +104,7 @@ export class FileUpload extends ConfigurableComponent {

// Create status element that shows what/how many files are selected
const $status = document.createElement('span')
$status.className = 'govuk-body govuk-file-upload__status'
$status.className = 'govuk-body govuk-file-upload-button__status'
$status.innerText = this.i18n.t('noFileChosen')

$button.appendChild($status)
Expand All @@ -117,11 +117,12 @@ export class FileUpload extends ConfigurableComponent {
$button.appendChild(commaSpan)

const containerSpan = document.createElement('span')
containerSpan.className = 'govuk-file-upload__pseudo-button-container'
containerSpan.className =
'govuk-file-upload-button__pseudo-button-container'

const buttonSpan = document.createElement('span')
buttonSpan.className =
'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button'
'govuk-button govuk-button--secondary govuk-file-upload-button__pseudo-button'
buttonSpan.innerText = this.i18n.t('chooseFilesButton')

containerSpan.appendChild(buttonSpan)
Expand All @@ -131,7 +132,8 @@ export class FileUpload extends ConfigurableComponent {
containerSpan.insertAdjacentText('beforeend', ' ')

const instructionSpan = document.createElement('span')
instructionSpan.className = 'govuk-body govuk-file-upload__instruction'
instructionSpan.className =
'govuk-body govuk-file-upload-button__instruction'
instructionSpan.innerText = this.i18n.t('dropInstruction')

containerSpan.appendChild(instructionSpan)
Expand All @@ -148,6 +150,8 @@ export class FileUpload extends ConfigurableComponent {

this.$input.setAttribute('tabindex', '-1')
this.$input.setAttribute('aria-hidden', 'true')
this.$input.classList.remove('govuk-file-upload')
this.$input.classList.add('govuk-file-upload--enhanced')

// Make all these new variables available to the module
this.$button = $button
Expand Down Expand Up @@ -227,7 +231,7 @@ export class FileUpload extends ConfigurableComponent {
// to avoid repeated announcements on NVDA (2024.4) + Firefox (133)
if (
!this.$button.classList.contains(
'govuk-file-upload__button--dragging'
'govuk-file-upload-button--dragging'
)
) {
this.showDraggingState()
Expand All @@ -239,7 +243,7 @@ export class FileUpload extends ConfigurableComponent {
// left the drop zone when they enter the page but haven't reached yet
// the file upload component
if (
this.$button.classList.contains('govuk-file-upload__button--dragging')
this.$button.classList.contains('govuk-file-upload-button--dragging')
) {
this.hideDraggingState()
this.$announcements.innerText = this.i18n.t('leftDropZone')
Expand All @@ -252,15 +256,15 @@ export class FileUpload extends ConfigurableComponent {
* Show the drop zone visually
*/
showDraggingState() {
this.$button.classList.add('govuk-file-upload__button--dragging')
this.$button.classList.add('govuk-file-upload-button--dragging')
this.$input.classList.add('govuk-file-upload--dragging')
}

/**
* Hides the drop zone visually
*/
hideDraggingState() {
this.$button.classList.remove('govuk-file-upload__button--dragging')
this.$button.classList.remove('govuk-file-upload-button--dragging')
this.$input.classList.remove('govuk-file-upload--dragging')
}

Expand Down Expand Up @@ -291,7 +295,7 @@ export class FileUpload extends ConfigurableComponent {
if (fileCount === 0) {
// If there are no files, show the default selection text
this.$status.innerText = this.i18n.t('noFileChosen')
this.$button.classList.add('govuk-file-upload__button--empty')
this.$button.classList.add('govuk-file-upload-button--empty')
} else {
if (
// If there is 1 file, just show the file name
Expand All @@ -305,7 +309,7 @@ export class FileUpload extends ConfigurableComponent {
})
}

this.$button.classList.remove('govuk-file-upload__button--empty')
this.$button.classList.remove('govuk-file-upload-button--empty')
}
}

Expand Down Expand Up @@ -364,9 +368,9 @@ export class FileUpload extends ConfigurableComponent {
this.$button.disabled = this.$input.disabled

if (this.$button.disabled) {
this.$root.classList.add('govuk-file-upload-wrapper--disabled')
this.$root.classList.add('govuk-drop-zone--disabled')
} else {
this.$root.classList.remove('govuk-file-upload-wrapper--disabled')
this.$root.classList.remove('govuk-drop-zone--disabled')
}
}

Expand Down
Loading

0 comments on commit a3f96d5

Please sign in to comment.