Merge pull request #852 from transloadit/improvement/better-animation

Dashboard open/close animation
This commit is contained in:
Artur Paikin 2018-05-31 12:06:21 -04:00 committed by GitHub
commit 51df805cbe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 111 deletions

View file

@ -125,7 +125,7 @@ To Be Released: 2018-05-31.
- [ ] providers: select files only after “select” is pressed, dont add them right away when they are checked (keep a list of fileIds in state?); better UI + solves issue with autoProceed uploading in background, which is weird; re-read https://github.com/transloadit/uppy/pull/419#issuecomment-345210519 (@arturi, @goto-bus-stop)
- [x] tus: add `filename` and `filetype`, so that tus servers knows what headers to set https://github.com/tus/tus-js-client/commit/ebc5189eac35956c9f975ead26de90c896dbe360 (#844 / @vith)
- [ ] core: look into utilizing https://github.com/que-etc/resize-observer-polyfill for responsive components. See also https://github.com/transloadit/uppy/issues/750
- [x] core: ⚠️ **breaking** removed .run() (to solve issues like #756), update ddocs (#793 / goto-bus-stop)
- [x] core: ⚠️ **breaking** removed .run() (to solve issues like #756), update docs (#793 / goto-bus-stop)
- [ ] core: use Browserslist config to share between PostCSS, Autoprefixer and Babel https://github.com/browserslist/browserslist, https://github.com/amilajack/eslint-plugin-compat (@arturi)
- [ ] core: utilize https://github.com/jonathantneal/postcss-preset-env, maybe https://github.com/jonathantneal/postcss-normalize (@arturi)
- [ ] core: addFile not passing restrictions shouldnt throw when called from UI

View file

@ -23,7 +23,7 @@ const PanelContent = (props) => {
}
const poweredByUppy = (props) => {
return <a href="https://uppy.io" rel="noreferrer noopener" target="_blank" class="uppy-Dashboard-poweredBy">Powered by <svg aria-hidden="true" class="UppyIcon uppy-Dashboard-poweredByIcon" width="11" height="11" viewBox="0 0 11 11" xmlns="http://www.w3.org/2000/svg">
return <a tabindex="-1" href="https://uppy.io" rel="noreferrer noopener" target="_blank" class="uppy-Dashboard-poweredBy">Powered by <svg aria-hidden="true" class="UppyIcon uppy-Dashboard-poweredByIcon" width="11" height="11" viewBox="0 0 11 11" xmlns="http://www.w3.org/2000/svg">
<path d="M7.365 10.5l-.01-4.045h2.612L5.5.806l-4.467 5.65h2.604l.01 4.044h3.718z" fill-rule="evenodd" />
</svg><span class="uppy-Dashboard-poweredByUppy">Uppy</span></a>
}
@ -33,6 +33,8 @@ module.exports = function Dashboard (props) {
{ 'uppy-Root': props.isTargetDOMEl },
'uppy-Dashboard',
{ 'Uppy--isTouchDevice': isTouchDevice() },
{ 'uppy-Dashboard--animateOpenClose': props.animateOpenClose },
{ 'uppy-Dashboard--isClosing': props.isClosing },
{ 'uppy-Dashboard--modal': !props.inline },
{ 'uppy-Dashboard--wide': props.isWide }
)

View file

@ -13,19 +13,22 @@ const { defaultTabIcon } = require('./icons')
// MIT licence, https://github.com/ghosh/micromodal/blob/master/LICENSE.md
// Copyright (c) 2017 Indrashish Ghosh
const FOCUSABLE_ELEMENTS = [
'a[href]',
'area[href]',
'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
'select:not([disabled]):not([aria-hidden])',
'textarea:not([disabled]):not([aria-hidden])',
'button:not([disabled]):not([aria-hidden])',
'iframe',
'object',
'embed',
'[contenteditable]',
'[tabindex]:not([tabindex^="-"])'
'a[href]:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'area[href]:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'input:not([disabled]):not([inert]):not([aria-hidden])',
'select:not([disabled]):not([inert]):not([aria-hidden])',
'textarea:not([disabled]):not([inert]):not([aria-hidden])',
'button:not([disabled]):not([inert]):not([aria-hidden])',
'iframe:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'object:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'embed:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'[contenteditable]:not([tabindex^="-"]):not([inert]):not([aria-hidden])',
'[tabindex]:not([tabindex^="-"]):not([inert]):not([aria-hidden])'
]
const TAB_KEY = 9
const ESC_KEY = 27
/**
* Dashboard UI with previews, metadata editing, tabs for various services and more
*/
@ -106,6 +109,7 @@ module.exports = class Dashboard extends Plugin {
disableInformer: false,
disableThumbnailGenerator: false,
disablePageScrollWhenModalOpen: true,
animateOpenClose: true,
proudlyDisplayPoweredByUppy: true,
onRequestCloseModal: () => this.closeModal(),
locale: defaultLocale
@ -242,23 +246,43 @@ module.exports = class Dashboard extends Plugin {
this.savedActiveElement = document.activeElement
if (this.opts.disablePageScrollWhenModalOpen) {
document.body.classList.add('uppy-Dashboard-isOpen')
document.body.classList.add('uppy-Dashboard-isFixed')
}
// handle ESC and TAB keys in modal dialog
document.addEventListener('keydown', this.onKeydown)
this.rerender(this.uppy.getState())
this.updateDashboardElWidth()
this.setFocusToBrowse()
}
closeModal () {
this.setPluginState({
isHidden: true
})
if (this.opts.disablePageScrollWhenModalOpen) {
document.body.classList.remove('uppy-Dashboard-isOpen')
document.body.classList.remove('uppy-Dashboard-isFixed')
}
if (this.opts.animateOpenClose) {
this.setPluginState({
isClosing: true
})
const handler = () => {
this.setPluginState({
isHidden: true,
isClosing: false
})
this.el.removeEventListener('animationend', handler, false)
}
this.el.addEventListener('animationend', handler, false)
} else {
this.setPluginState({
isHidden: true
})
}
// handle ESC and TAB keys in modal dialog
document.removeEventListener('keydown', this.onKeydown)
this.savedActiveElement.focus()
}
@ -268,9 +292,9 @@ module.exports = class Dashboard extends Plugin {
onKeydown (event) {
// close modal on esc key press
if (event.keyCode === 27) this.requestCloseModal(event)
if (event.keyCode === ESC_KEY) this.requestCloseModal(event)
// maintainFocus on tab key press
if (event.keyCode === 9) this.maintainFocus(event)
if (event.keyCode === TAB_KEY) this.maintainFocus(event)
}
handleClickOutside () {
@ -323,10 +347,6 @@ module.exports = class Dashboard extends Plugin {
this.uppy.log('Dashboard modal trigger not found. Make sure `trigger` is set in Dashboard options unless you are planning to call openModal() method yourself')
}
if (!this.opts.inline) {
document.addEventListener('keydown', this.onKeydown)
}
// Drag Drop
this.removeDragDropListener = dragDrop(this.el, (files) => {
this.handleDrop(files)
@ -342,10 +362,6 @@ module.exports = class Dashboard extends Plugin {
showModalTrigger.forEach(trigger => trigger.removeEventListener('click', this.openModal))
}
if (!this.opts.inline) {
document.removeEventListener('keydown', this.onKeydown)
}
this.removeDragDropListener()
window.removeEventListener('resize', this.updateDashboardElWidth)
}
@ -456,6 +472,8 @@ module.exports = class Dashboard extends Plugin {
totalProgress: state.totalProgress,
acquirers: acquirers,
activePanel: pluginState.activePanel,
animateOpenClose: this.opts.animateOpenClose,
isClosing: pluginState.isClosing,
getPlugin: this.uppy.getPlugin,
progressindicators: progressindicators,
autoProceed: this.uppy.opts.autoProceed,

View file

@ -1,23 +0,0 @@
// Animation
@keyframes zoomOutLeft {
40% {
opacity: 1;
-webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
}
to {
opacity: 0;
-webkit-transform: scale(.1) translate3d(-2000px, 0, 0);
transform: scale(.1) translate3d(-2000px, 0, 0);
-webkit-transform-origin: left center;
transform-origin: left center;
}
}
.UppyAnimation-zoomOutLeft {
animation-name: zoomOutLeft;
animation-duration: 1s;
animation-fill-mode: both;
}

View file

@ -1,17 +1,51 @@
.uppy-Dashboard--modal {
z-index: $zIndex-2;
// transition: transform 0.2s ease-in-out;
// transform: none;
// -webkit-overflow-scrolling: touch;
}
.uppy-Dashboard--modal[aria-hidden=true] {
display: none;
// transform: translateY(-50%);
}
.uppy-Dashboard--modal[aria-hidden=true] {
display: none;
}
// Modal open/close animations
@keyframes uppy-Dashboard-fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes uppy-Dashboard-fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes uppy-Dashboard-slideDownAndFadeIn {
from { transform: translate3d(-50%, -70%, 0); opacity: 0; }
to { transform: translate3d(-50%, -50%, 0); opacity: 1; }
}
@keyframes uppy-Dashboard-slideUpFadeOut {
from { transform: translate3d(-50%, -50%, 0); opacity: 1; }
to { transform: translate3d(-50%, -70%, 0); opacity: 0; }
}
.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose > .uppy-Dashboard-inner {
animation: uppy-Dashboard-slideDownAndFadeIn 0.3s cubic-bezier(0, 0, .2, 1);
}
.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose > .uppy-Dashboard-overlay {
animation: uppy-Dashboard-fadeIn 0.3s cubic-bezier(0, 0, .2, 1);
}
.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose.uppy-Dashboard--isClosing > .uppy-Dashboard-inner {
animation: uppy-Dashboard-slideUpFadeOut 0.3s cubic-bezier(0, 0, .2, 1);
}
.uppy-Dashboard--modal.uppy-Dashboard--animateOpenClose.uppy-Dashboard--isClosing > .uppy-Dashboard-overlay {
animation: uppy-Dashboard-fadeOut 0.3s cubic-bezier(0, 0, .2, 1);
}
// Added to body to prevent the page from scrolling when Modal is open
.uppy-Dashboard-isOpen {
.uppy-Dashboard-isFixed {
overflow: hidden;
height: 100vh;
}
@ -289,48 +323,31 @@
font-size: 16px;
line-height: 50px;
max-width: 300px;
// top: 15px;
}
}
.uppy-DashboardContent-titleFile {
// text-decoration: underline;
}
.uppy-DashboardContent-back {
@include reset-button;
// position: absolute;
// top: 0;
// left: 15px;
font-size: 14px;
// line-height: 40px;
font-weight: 500;
cursor: pointer;
color: $color-cornflower-blue;
.uppy-Dashboard--wide & {
font-size: 15px;
// line-height: 50px;
}
}
// .uppy-DashboardContent-back .UppyIcon {
// position: relative;
// margin-right: 3px;
// }
.uppy-DashboardContent-panel {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transform: translateY(-105%);
transform: translate3d(0, -105%, 0);
transition: transform 0.2s ease-in-out;
will-change: transform;
background-color: darken($color-white, 4%);
box-shadow: 0 0 10px 5px rgba($color-black, 0.15);
// padding: 15px;
padding-top: 40px;
overflow: hidden;
z-index: $zIndex-4;
@ -338,14 +355,10 @@
.uppy-Dashboard--wide & {
padding-top: 50px;
}
// .uppy-Dashboard--modal & {
// z-index: $zIndex-4;
// }
}
.uppy-DashboardContent-panel[aria-hidden=false] {
transform: none;
transform: translate3d(0, 0, 0);
}
// Progress bar placeholder
@ -429,29 +442,6 @@
border-color: darken($color-white, 20%);
}
// .uppy-Dashboard-bgIcon {
// width: 100%;
// max-width: 460px;
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// opacity: 0.7;
// transition: all 0.3s;
// padding: 0 20px;
// }
// .uppy-Dashboard-bgIcon .UppyIcon {
// width: 100%;
// height: 80px;
// fill: none;
// stroke: $color-asphalt-gray;
// .uppy-Dashboard--wide & {
// height: 110px;
// }
// }
.uppy-Dashboard-bgIcon {
height: 100%;
display: flex;
@ -1012,8 +1002,9 @@
//
.uppy-DashboardFileCard {
transform: translateY(0);
transition: all 0.25s ease-in-out;
transform: translate3d(0, 0, 0);
transition: transform 0.2s ease-in-out;
width: 100%;
height: 100%;
position: absolute;
@ -1026,9 +1017,9 @@
background-color: $color-white;
}
.uppy-DashboardFileCard[aria-hidden=true] {
transform: translateY(-105%);
}
.uppy-DashboardFileCard[aria-hidden=true] {
transform: translate3d(0, -105%, 0);
}
.uppy-DashboardFileCard-inner {
display: flex;
@ -1093,3 +1084,6 @@
vertical-align: middle;
width: 78%;
}

View file

@ -138,6 +138,10 @@ Set to true to automatically close the modal when the user clicks outside of it.
By default when Dashboard modal is open, it will disable page scrolling, so when you scroll a list of files in Uppy the website in the background stays still. Set to false to override this behaviour and leave page scrolling intact.
## `animateOpenClose: true`
Add light animations when modal dialog is open or closed, for more satisfying user experience.
### `proudlyDisplayPoweredByUppy: true`
Uppy is provided for the world for free by the [Transloadit team](https://transloadit.com). In return, we ask that you consider keeping a tiny Uppy logo at the bottom of the Dashboard, so that more people can discover and use Uppy.