From 2437cde6e1325321748e747756411935225ffaae Mon Sep 17 00:00:00 2001 From: silverwind Date: Tue, 12 Nov 2024 20:02:07 +0100 Subject: [PATCH] Move dropzone CSS to first-party and fix color issues --- web_src/css/features/dropzone.css | 273 ++++++++++++++++++++++++++++-- web_src/css/index.css | 1 - web_src/js/features/dropzone.ts | 2 +- 3 files changed, 262 insertions(+), 14 deletions(-) diff --git a/web_src/css/features/dropzone.css b/web_src/css/features/dropzone.css index cbc32df203..37618b648b 100644 --- a/web_src/css/features/dropzone.css +++ b/web_src/css/features/dropzone.css @@ -1,3 +1,264 @@ +@keyframes passing-through { + 0% { opacity: 0; transform: translateY(40px); } + 30%, 70% { opacity: 1; transform: translateY(0); } + 100% { opacity: 0; transform: translateY(-40px); } +} + +@keyframes slide-in { + 0% { opacity: 0; transform: translateY(40px); } + 30% { opacity: 1; transform: translateY(0); } +} + +@keyframes pulse { + 0% { transform: scale(1); } + 10% { transform: scale(1.1); } + 20% { transform: scale(1); } +} + +.dropzone { + min-height: 150px; + border-radius: 5px; + padding: 20px; +} + +.dropzone.dz-clickable { + cursor: pointer; +} + +.dropzone.dz-clickable * { + cursor: default; +} + +.dropzone.dz-clickable .dz-message, +.dropzone.dz-clickable .dz-message * { + cursor: pointer; +} + +.dropzone.dz-started .dz-message { + display: none; +} + +.dropzone.dz-drag-hover { + border-style: solid; +} + +.dropzone.dz-drag-hover .dz-message { + opacity: .5; +} + +.dropzone .dz-message { + text-align: center; + margin: 10px 0; +} + +.dropzone .dz-message .dz-button { + background: none; + color: inherit; + border: none; + padding: 0; + font: inherit; + cursor: pointer; + outline: inherit; +} + +.dropzone .dz-preview { + position: relative; + display: inline-block; + vertical-align: top; + margin: 16px; + min-height: 100px; +} + +.dropzone .dz-preview:hover { + z-index: 1000; +} + +.dropzone .dz-preview:hover .dz-details { + opacity: 1; +} + +.dropzone .dz-preview.dz-file-preview .dz-details { + opacity: 1; +} + +.dropzone .dz-preview .dz-remove { + font-size: 14px; + text-align: center; + display: block; + cursor: pointer; + border: none; +} + +.dropzone .dz-preview .dz-remove:hover { + text-decoration: underline; +} + +.dropzone .dz-preview .dz-details { + z-index: 20; + position: absolute; + top: 0; + left: 0; + opacity: 0; + font-size: 13px; + min-width: 100%; + max-width: 100%; + padding: 2em 1em; + text-align: center; + color: var(--color-text); + line-height: 150%; +} + +.dropzone .dz-preview .dz-details .dz-size { + margin-bottom: 1em; + font-size: 16px; +} + +.dropzone .dz-preview .dz-details .dz-filename { + white-space: nowrap; +} + +.dropzone .dz-preview .dz-details .dz-filename:not(:hover) { + overflow: hidden; + text-overflow: ellipsis; +} + +.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span { + border: 1px solid transparent; +} + +.dropzone .dz-preview .dz-details .dz-filename span, +.dropzone .dz-preview .dz-details .dz-size span { + padding: 0 0.4em; + border-radius: 3px; +} + +.dropzone .dz-preview:hover .dz-image img { + transform: scale(1.05, 1.05); + filter: opacity(0.5); +} + +.dropzone .dz-preview .dz-image { + border-radius: 20px; + overflow: hidden; + width: 120px; + height: 120px; + position: relative; + display: block; + z-index: 10; +} + +.dropzone .dz-preview .dz-image img { + display: block; +} + +.dropzone .dz-preview.dz-success .dz-success-mark { + animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); +} + +.dropzone .dz-preview.dz-error .dz-error-mark { + opacity: 1; + animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); +} + +.dropzone .dz-preview .dz-success-mark, +.dropzone .dz-preview .dz-error-mark { + pointer-events: none; + opacity: 0; + z-index: 500; + position: absolute; + display: block; + top: 50%; + left: 50%; + margin-left: -27px; + margin-top: -27px; + border-radius: 50%; +} + +.dropzone .dz-preview .dz-success-mark svg, +.dropzone .dz-preview .dz-error-mark svg { + display: block; + width: 54px; + height: 54px; + fill: var(--color-text); +} + +.dropzone .dz-preview.dz-processing .dz-progress { + opacity: 1; + transition: all 0.2s linear; +} + +.dropzone .dz-preview.dz-complete .dz-progress { + opacity: 0; + transition: opacity 0.4s ease-in; +} + +.dropzone .dz-preview:not(.dz-processing) .dz-progress { + animation: pulse 6s ease infinite; +} + +.dropzone .dz-preview .dz-progress { + opacity: 1; + z-index: 1000; + pointer-events: none; + position: absolute; + height: 20px; + top: 50%; + margin-top: -10px; + left: 15%; + right: 15%; + border: 3px solid transparent; + border-radius: 10px; + overflow: hidden; +} + +.dropzone .dz-preview .dz-progress .dz-upload { + display: block; + position: relative; + height: 100%; + width: 0; + transition: width 300ms ease-in-out; + border-radius: 17px; +} + +.dropzone .dz-preview.dz-error .dz-error-message { + display: block; +} + +.dropzone .dz-preview.dz-error:hover .dz-error-message { + opacity: 1; + pointer-events: auto; +} + +.dropzone .dz-preview .dz-error-message { + pointer-events: none; + z-index: 1000; + position: absolute; + display: block; + display: none; + opacity: 0; + transition: opacity 0.3s ease; + border-radius: 8px; + font-size: 13px; + top: 130px; + left: -10px; + width: 140px; + background: var(--color-red); + padding: 0.5em 1em; + color: var(--color-white); +} + +.dropzone .dz-preview .dz-error-message::after { + content: ""; + position: absolute; + top: -6px; + left: 64px; + width: 0; + height: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid var(--color-red); +} + .ui .field .dropzone { border: 2px dashed var(--color-secondary); background: none; @@ -7,10 +268,6 @@ min-height: 0; } -.ui .field .dropzone .dz-message { - margin: 10px 0; -} - .dropzone .dz-button { color: var(--color-text-light) !important; } @@ -36,22 +293,14 @@ object-fit: contain !important; } -.dropzone .dz-preview.dz-image-preview, .dropzone-attachments .thumbnails img { background: transparent !important; -} - -.dropzone-attachments .thumbnails img { height: 120px !important; width: 120px !important; object-fit: contain !important; margin-bottom: 0 !important; } -.dropzone .dz-preview:hover .dz-image img { - filter: opacity(0.5) !important; -} - .ui .field .dropzone .dz-preview .dz-progress { /* by default the progress-bar is vertically centered (top: 50%), it's better to put it after the "details (size, filename)", then the layout from top to bottom is: size, filename, progress */ diff --git a/web_src/css/index.css b/web_src/css/index.css index 817f6997da..9ff92cbfd4 100644 --- a/web_src/css/index.css +++ b/web_src/css/index.css @@ -33,7 +33,6 @@ @import "./shared/repoorg.css"; @import "./shared/settings.css"; -@import "./features/dropzone.css"; @import "./features/gitgraph.css"; @import "./features/heatmap.css"; @import "./features/imagediff.css"; diff --git a/web_src/js/features/dropzone.ts b/web_src/js/features/dropzone.ts index c9b0149df5..8acee820d9 100644 --- a/web_src/js/features/dropzone.ts +++ b/web_src/js/features/dropzone.ts @@ -17,7 +17,7 @@ export const DropzoneCustomEventUploadDone = 'dropzone-custom-upload-done'; async function createDropzone(el, opts) { const [{Dropzone}] = await Promise.all([ import(/* webpackChunkName: "dropzone" */'dropzone'), - import(/* webpackChunkName: "dropzone" */'dropzone/dist/dropzone.css'), + import(/* webpackChunkName: "dropzone" */'../../css/features/dropzone.css'), ]); return new Dropzone(el, opts); }