From 4624b29cd0f2d8ea874f1a6400ee85fa5203fa84 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Thu, 7 Dec 2023 11:50:57 +0100 Subject: [PATCH] Replace progress - element with sl-progress-bar 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. --- .../alchemy/_custom-properties.scss | 18 +++--- app/assets/stylesheets/alchemy/upload.scss | 64 +++++++------------ app/javascript/alchemy_admin.js | 1 + .../components/uploader/file_upload.js | 9 ++- .../components/uploader/progress.js | 19 +++++- config/importmap.rb | 1 + .../components/uploader/progress.spec.js | 2 +- 7 files changed, 59 insertions(+), 55 deletions(-) diff --git a/app/assets/stylesheets/alchemy/_custom-properties.scss b/app/assets/stylesheets/alchemy/_custom-properties.scss index df38db84cf..e43fc9b577 100644 --- a/app/assets/stylesheets/alchemy/_custom-properties.scss +++ b/app/assets/stylesheets/alchemy/_custom-properties.scss @@ -66,14 +66,14 @@ --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_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 ); } diff --git a/app/assets/stylesheets/alchemy/upload.scss b/app/assets/stylesheets/alchemy/upload.scss index ac64117824..e8b7237d99 100644 --- a/app/assets/stylesheets/alchemy/upload.scss +++ b/app/assets/stylesheets/alchemy/upload.scss @@ -66,30 +66,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; @@ -103,7 +79,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); @@ -161,43 +137,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 ); } diff --git a/app/javascript/alchemy_admin.js b/app/javascript/alchemy_admin.js index 5aa2e424c5..1fbaf54d74 100644 --- a/app/javascript/alchemy_admin.js +++ b/app/javascript/alchemy_admin.js @@ -36,6 +36,7 @@ import "alchemy_admin/components/tooltip" import "@shoelace/tab" import "@shoelace/tab-group" import "@shoelace/tab-panel" +import "@shoelace/progress-bar" // Global Alchemy object if (typeof window.Alchemy === "undefined") { diff --git a/app/javascript/alchemy_admin/components/uploader/file_upload.js b/app/javascript/alchemy_admin/components/uploader/file_upload.js index 61fd460b2d..07ee9d6d8c 100644 --- a/app/javascript/alchemy_admin/components/uploader/file_upload.js +++ b/app/javascript/alchemy_admin/components/uploader/file_upload.js @@ -25,7 +25,7 @@ export class FileUpload extends AlchemyHTMLElement { render() { return ` - +
${this.file?.name} ${this.loadedSize} @@ -181,7 +181,7 @@ export class FileUpload extends AlchemyHTMLElement { * @returns {HTMLProgressElement|undefined} */ get progressElement() { - return this.querySelector("progress") + return this.querySelector("sl-progress-bar") } /** @@ -220,6 +220,11 @@ export class FileUpload extends AlchemyHTMLElement { set status(status) { this._status = status this.className = status + + this.progressElement.toggleAttribute( + "indeterminate", + status === "upload-finished" + ) } /** diff --git a/app/javascript/alchemy_admin/components/uploader/progress.js b/app/javascript/alchemy_admin/components/uploader/progress.js index 4228ab4ca0..47fd9b4fa1 100644 --- a/app/javascript/alchemy_admin/components/uploader/progress.js +++ b/app/javascript/alchemy_admin/components/uploader/progress.js @@ -23,7 +23,7 @@ export class Progress extends AlchemyHTMLElement { render() { return ` - +
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} diff --git a/config/importmap.rb b/config/importmap.rb index e36adb9249..2193973152 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -7,6 +7,7 @@ pin "@shoelace/tab", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.9.0/cdn/components/tab/tab.js", preload: true pin "@shoelace/tab-group", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.9.0/cdn/components/tab-group/tab-group.js", preload: true pin "@shoelace/tab-panel", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.9.0/cdn/components/tab-panel/tab-panel.js", preload: true +pin "@shoelace/progress-bar", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.9.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 diff --git a/spec/javascript/alchemy_admin/components/uploader/progress.spec.js b/spec/javascript/alchemy_admin/components/uploader/progress.spec.js index 46d28ac989..a6d0f09ef7 100644 --- a/spec/javascript/alchemy_admin/components/uploader/progress.spec.js +++ b/spec/javascript/alchemy_admin/components/uploader/progress.spec.js @@ -33,7 +33,7 @@ describe("alchemy-upload-progress", () => { document.body.innerHTML = "" // reset previous content to prevent raise conditions 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")