Skip to content

Commit

Permalink
Replace progress - element with sl-progress-bar
Browse files Browse the repository at this point in the history
Replace the default progress - element with the shoelace progress-bar - component, to have a better control over the styling. The progress - element does not allow animations in Chrome anymore.

The server response can take some time. We need to show the user that there is still progress. The indeterminate - attribute is showing an animation, after the upload was finished.
  • Loading branch information
tvdeyen authored and sascha-karnatz committed Dec 14, 2023
1 parent f6f54e8 commit 2f99d20
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 71 deletions.
20 changes: 10 additions & 10 deletions app/assets/stylesheets/alchemy/_custom-properties.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@
--sl-input-label-color: var(--color-text);

--file-upload_background-color: hsla(0deg, 0%, 70%, 0.8);
--file-upload_single-upload-background-color: var(--color-grey_medium);
--file-upload_progress-bar-color: var(--color-blue_very_light);
--file-upload_progress-value-color: var(--color-blue_dark);

--file-upload_progress-value-color-canceled: hsla(0deg, 0%, 60%, 0.8);
--file-upload_progress-value-color-failed: var(--color-red_medium);
--file-upload_progress-value-color-invalid: var(--color-red_medium);
--file-upload_progress-value-color-successful: var(--color-green_medium);
--file-upload_progress-value-color-upload-finished: var(
--color-grey-blue_light
--file-upload_single-upload-background-color: var(--color-grey_light);
--file-upload_progress-track-color: var(--color-blue_very_light);
--file-upload_progress-indicator-color: var(--color-blue_dark);

--file-upload_progress-indicator-color-canceled: hsla(0deg, 0%, 60%, 0.8);
--file-upload_progress-indicator-color-failed: var(--color-red_medium);
--file-upload_progress-indicator-color-invalid: var(--color-red_medium);
--file-upload_progress-indicator-color-successful: var(--color-green_medium);
--file-upload_progress-indicator-color-upload-finished: var(
--color-blue_dark
);
}
86 changes: 36 additions & 50 deletions app/assets/stylesheets/alchemy/upload.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@
position: relative;

&:after {
content: "";
align-items: center;
background-color: rgba($dark-gray, 0.6);
color: rgba(255, 255, 255, 0.6);
content: $ri-upload-cloud-line;
display: flex;
font-family: "remixicon";
font-size: 80px;
justify-content: center;
height: 100%;
left: 0;
pointer-events: none;
position: absolute;
width: 100%;
top: 0;
left: 0;
z-index: 20;
width: 100%;
height: 100%;
background-color: rgba($dark-gray, 0.6);
background-image: url("data:image/svg+xml;utf8,%3Csvg%20style%3D%22enable-background%3Anew%200%200%2064%2046.9%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xml%3Aspace%3D%22preserve%22%20version%3D%221.1%22%20y%3D%220px%22%20x%3D%220px%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20viewBox%3D%220%200%2064%2046.9%22%3E%3Cpath%20fill%3D%22%23ededed%22%20d%3D%22m21.3%2024.5c0-0.3%200.1-0.6%200.3-0.8l11.8-11.7c0.2-0.2%200.5-0.3%200.8-0.3s0.6%200.1%200.8%200.3l11.7%2011.7c0.2%200.3%200.3%200.5%200.3%200.8s-0.1%200.6-0.3%200.8-0.5%200.3-0.8%200.3h-7.5v11.7c0%200.3-0.1%200.5-0.3%200.8-0.2%200.2-0.5%200.3-0.8%200.3h-6.4c-0.3%200-0.5-0.1-0.8-0.3s-0.3-0.5-0.3-0.8v-11.7h-7.5c-0.3%200-0.5-0.1-0.8-0.3s-0.2-0.5-0.2-0.8m-21.3%209.6c0%203.5%201.3%206.6%203.8%209%202.5%202.5%205.5%203.8%209%203.8h36.3c4.1%200%207.6-1.5%2010.6-4.4%202.8-2.9%204.3-6.4%204.3-10.5%200-2.9-0.8-5.6-2.3-8-1.6-2.4-3.6-4.3-6.3-5.5%200-0.7%200.1-1.1%200.1-1.4%200-4.7-1.7-8.7-5-12.1-3.3-3.3-7.4-5-12.1-5-3.5%200-6.6%201-9.5%202.9s-5%204.5-6.3%207.7c-1.6-1.4-3.4-2.1-5.5-2.1-2.4%200-4.4%200.8-6%202.5-1.7%201.7-2.5%203.7-2.5%206%200%201.7%200.5%203.2%201.4%204.6-2.9%200.7-5.3%202.2-7.1%204.5-2%202.4-2.9%205.1-2.9%208%22%2F%3E%3C%2Fsvg%3E");
background-position: center;
background-size: 64px 47px;
background-repeat: no-repeat;
pointer-events: none;
}
}

Expand Down Expand Up @@ -66,30 +68,6 @@ alchemy-upload-progress {
bottom: 0;
opacity: 1;
}
progress {
appearance: none;
background-color: var(--file-upload_progress-bar-color);
border: none;
border-radius: var(--progress-border-radius, var(--border-radius));
height: var(--progress-height, 20px);
margin: auto;
width: 100%;

&::-webkit-progress-bar {
background-color: var(--file-upload_progress-bar-color);
border-radius: var(--progress-border-radius, var(--border-radius));
}

&::-moz-progress-bar {
background-color: var(--file-upload_progress-value-color);
}

&::-webkit-progress-value {
background-color: var(--file-upload_progress-value-color);
background-size: 1rem 1rem;
border-radius: var(--progress-border-radius, var(--border-radius));
}
}

.value-text {
color: white;
Expand All @@ -103,7 +81,7 @@ alchemy-upload-progress {
--padding: var(--spacing-2);
--progress-border-radius: var(--border-radius_medium)
var(--border-radius_medium) 0 0;
--progress-height: var(--spacing-3);
--progress-height: var(--spacing-1);

display: grid;
gap: var(--spacing-2);
Expand Down Expand Up @@ -161,43 +139,51 @@ alchemy-upload-progress {
}
}

progress {
sl-progress-bar {
--height: var(--progress-height);
left: 0;
position: absolute;
top: calc(-1 * var(--progress-height));
top: calc(-1 * var(--progress-height) / 2);
width: 100%;
}
}

sl-progress-bar {
--indicator-color: var(--file-upload_progress-indicator-color);
--sl-border-radius-pill: var(--border-radius);
--track-color: var(--file-upload_progress-track-color);
&::part(base) {
top: calc(50% - var(--height) / 2);
}
}
}

.successful {
--file-upload_progress-value-color: var(
--file-upload_progress-value-color-successful
--file-upload_progress-indicator-color: var(
--file-upload_progress-indicator-color-successful
);
}

.failed {
--file-upload_progress-value-color: var(
--file-upload_progress-value-color-failed
--file-upload_progress-indicator-color: var(
--file-upload_progress-indicator-color-failed
);
}

.canceled {
--file-upload_progress-value-color: var(
--file-upload_progress-value-color-canceled
--file-upload_progress-indicator-color: var(
--file-upload_progress-indicator-color-canceled
);
}

.invalid {
--file-upload_progress-value-color: var(
--file-upload_progress-value-color-invalid
);
--file-upload_progress-bar-color: var(
--file-upload_progress-value-color-invalid
--file-upload_progress-indicator-color: var(
--file-upload_progress-indicator-color-invalid
);
}

.upload-finished {
--file-upload_progress-value-color: var(
--file-upload_progress-value-color-upload-finished
--file-upload_progress-indicator-color: var(
--file-upload_progress-indicator-color-upload-finished
);
}
2 changes: 2 additions & 0 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import "alchemy_admin/components/page_select"
import "alchemy_admin/components/select"
import "alchemy_admin/components/spinner"
import "alchemy_admin/components/tinymce"
import "@shoelace/progress-bar"
import "@shoelace/switch"
import "@shoelace/tab"
import "@shoelace/tab-group"
Expand Down Expand Up @@ -61,6 +62,7 @@ setDefaultAnimation("tooltip.hide", {
}
})


// Global Alchemy object
if (typeof window.Alchemy === "undefined") {
window.Alchemy = {}
Expand Down
17 changes: 12 additions & 5 deletions app/javascript/alchemy_admin/components/uploader/file_upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ export class FileUpload extends AlchemyHTMLElement {

render() {
return `
<progress max="100" value="${this.value}"></progress>
<sl-progress-bar value="${this.value}"></sl-progress-bar>
<div class="description">
<span class="file-name">${this.file?.name}</span>
<span class="loaded-size">${this.loadedSize}</span>
<span class="error-message">${this.errorMessage}</span>
</div>
<button class="icon_button" aria-label="Abort Upload">
<i class="fas fa-times fa-fw"></i>
</button>
<sl-tooltip content="${translate("Abort upload")}">
<button class="icon_button" aria-label="${translate("Abort upload")}">
<i class="icon ri-close-line ri-fw"></i>
</button>
</sl-tooltip>
`
}

Expand Down Expand Up @@ -181,7 +183,7 @@ export class FileUpload extends AlchemyHTMLElement {
* @returns {HTMLProgressElement|undefined}
*/
get progressElement() {
return this.querySelector("progress")
return this.querySelector("sl-progress-bar")
}

/**
Expand Down Expand Up @@ -220,6 +222,11 @@ export class FileUpload extends AlchemyHTMLElement {
set status(status) {
this._status = status
this.className = status

this.progressElement?.toggleAttribute(
"indeterminate",
status === "upload-finished"
)
}

/**
Expand Down
19 changes: 16 additions & 3 deletions app/javascript/alchemy_admin/components/uploader/progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class Progress extends AlchemyHTMLElement {

render() {
return `
<progress max="100" value="0"></progress>
<sl-progress-bar value="0"></sl-progress-bar>
<div class="overall-progress-value value-text"></div>
<div class="single-uploads" style="--progress-columns: ${
this.fileCount > 3 ? 3 : this.fileCount
Expand Down Expand Up @@ -66,7 +66,13 @@ export class Progress extends AlchemyHTMLElement {
this._sumFileProgresses("progressEventLoaded")
)} / ${formatFileSize(this._sumFileProgresses("progressEventTotal"))}`

this.querySelector(`progress`).value = totalProgress
const status = this.status

this.progressElement.value = totalProgress
this.progressElement.toggleAttribute(
"indeterminate",
status === "upload-finished"
)
this.querySelector(`.overall-progress-value`).textContent =
overallProgressValue
this.querySelector(`.overall-upload-value`).textContent = overallUploadSize
Expand All @@ -75,7 +81,7 @@ export class Progress extends AlchemyHTMLElement {
this.onComplete()
}

this.className = this.status
this.className = status
this.visible = true
}

Expand All @@ -93,6 +99,13 @@ export class Progress extends AlchemyHTMLElement {
return this._activeUploads().every((entry) => entry.finished)
}

/**
* @returns {HTMLProgressElement|undefined}
*/
get progressElement() {
return this.querySelector("sl-progress-bar")
}

/**
* get status of file progresses and accumulate the overall status
* @returns {string}
Expand Down
1 change: 1 addition & 0 deletions app/javascript/alchemy_admin/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const en = {
"File type not allowed": "File type not allowed",
"Maximum number of files exceeded": "Maximum number of files exceeded",
"Uploaded bytes exceed file size": "Uploaded bytes exceed file size",
"Abort upload": "Abort upload",
formats: {
datetime: "Y-m-d H:i",
date: "Y-m-d",
Expand Down
1 change: 1 addition & 0 deletions config/importmap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
pin "@shoelace/tab-group", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tab-group/tab-group.js", preload: true
pin "@shoelace/tab-panel", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tab-panel/tab-panel.js", preload: true
pin "@shoelace/tooltip", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tooltip/tooltip.js", preload: true
pin "@shoelace/progress-bar", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/progress-bar/progress-bar.js", preload: true
pin "@rails/ujs", to: "https://ga.jspm.io/npm:@rails/ujs@7.1.2/app/assets/javascripts/rails-ujs.esm.js"

pin "alchemy_admin", to: "alchemy_admin.js", preload: true
Expand Down
4 changes: 3 additions & 1 deletion spec/javascript/alchemy_admin/components/uploader.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ describe("alchemy-uploader", () => {

beforeEach(() => {
component._uploadFiles([firstFile])
progressBar = document.querySelector("alchemy-upload-progress progress")
progressBar = document.querySelector(
"alchemy-upload-progress sl-progress-bar"
)
})

it("shows upload component", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("alchemy-file-upload", () => {
document.body.innerHTML = "" // reset previous content to prevent raise conditions
document.body.append(component)

progressBar = document.querySelector("progress")
progressBar = document.querySelector("sl-progress-bar")
fileName = document.querySelector(".file-name")
loadedSize = document.querySelector(".loaded-size")
cancelButton = document.querySelector("button")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe("alchemy-upload-progress", () => {

document.body.append(component)

progressBar = document.querySelector("progress")
progressBar = document.querySelector("sl-progress-bar")
overallProgressValue = document.querySelector(".overall-progress-value")
overallUploadValue = document.querySelector(".overall-upload-value")

Expand Down

0 comments on commit 2f99d20

Please sign in to comment.