diff --git a/examples/bundled-example/main.js b/examples/bundled-example/main.js index 2b9696cc5..84f629fd8 100644 --- a/examples/bundled-example/main.js +++ b/examples/bundled-example/main.js @@ -46,11 +46,11 @@ const uppy = Uppy({ // maxWidth: 350, // maxHeight: 400, inline: false, - disableStatusBar: false, - disableInformer: false, + // disableStatusBar: true, + // disableInformer: true, getMetaFromForm: true, - replaceTargetContent: true, - target: '.MyForm', + // replaceTargetContent: true, + // target: '.MyForm', hideUploadButton: false, closeModalOnClickOutside: false, locale: { diff --git a/src/plugins/Dashboard/ActionBrowseTagline.js b/src/plugins/Dashboard/ActionBrowseTagline.js index c96234b94..c21ee8034 100644 --- a/src/plugins/Dashboard/ActionBrowseTagline.js +++ b/src/plugins/Dashboard/ActionBrowseTagline.js @@ -2,7 +2,7 @@ const html = require('yo-yo') module.exports = (props) => { const input = html` - ` diff --git a/src/plugins/Dashboard/Dashboard.js b/src/plugins/Dashboard/Dashboard.js index 2d1c26d64..add761fd1 100644 --- a/src/plugins/Dashboard/Dashboard.js +++ b/src/plugins/Dashboard/Dashboard.js @@ -58,18 +58,17 @@ module.exports = function Dashboard (props) { aria-label="${!props.inline ? props.i18n('dashboardWindowTitle') : props.i18n('dashboardTitle')}" - role="dialog" - onpaste=${handlePaste} - onload=${() => props.updateDashboardElWidth()}> + onpaste=${handlePaste}> -
+
` : null diff --git a/src/plugins/Dashboard/index.js b/src/plugins/Dashboard/index.js index d7ad1faeb..0768d9c2f 100644 --- a/src/plugins/Dashboard/index.js +++ b/src/plugins/Dashboard/index.js @@ -8,6 +8,20 @@ const { findAllDOMElements } = require('../../core/Utils') const prettyBytes = require('prettier-bytes') const { defaultTabIcon } = require('./icons') +const FOCUSABLE_ELEMENTS = [ + 'a[href]', + 'area[href]', + 'input:not([disabled]):not([type="hidden"])', + 'select:not([disabled])', + 'textarea:not([disabled])', + 'button:not([disabled])', + 'iframe', + 'object', + 'embed', + '[contenteditable]', + '[tabindex]:not([tabindex^="-"])' +] + /** * Modal Dialog & Dashboard */ @@ -77,6 +91,10 @@ module.exports = class DashboardUI extends Plugin { this.actions = this.actions.bind(this) this.hideAllPanels = this.hideAllPanels.bind(this) this.showPanel = this.showPanel.bind(this) + this.getFocusableNodes = this.getFocusableNodes.bind(this) + this.setFocusToFirstNode = this.setFocusToFirstNode.bind(this) + this.maintainFocus = this.maintainFocus.bind(this) + this.initEvents = this.initEvents.bind(this) this.handleEscapeKeyPress = this.handleEscapeKeyPress.bind(this) this.handleClickOutside = this.handleClickOutside.bind(this) @@ -142,6 +160,10 @@ module.exports = class DashboardUI extends Plugin { }) } + // setModalElement (element) { + // this.modal = element + // } + requestCloseModal () { if (this.opts.onRequestCloseModal) { return this.opts.onRequestCloseModal() @@ -150,6 +172,32 @@ module.exports = class DashboardUI extends Plugin { } } + getFocusableNodes () { + const nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS) + return Object.keys(nodes).map((key) => nodes[key]) + } + + setFocusToFirstNode () { + const focusableNodes = this.getFocusableNodes() + console.log(focusableNodes[0]) + if (focusableNodes.length) focusableNodes[0].focus() + } + + maintainFocus (event) { + var focusableNodes = this.getFocusableNodes() + var focusedItemIndex = focusableNodes.indexOf(document.activeElement) + + if (event.shiftKey && focusedItemIndex === 0) { + focusableNodes[focusableNodes.length - 1].focus() + event.preventDefault() + } + + if (!event.shiftKey && focusedItemIndex === focusableNodes.length - 1) { + focusableNodes[0].focus() + event.preventDefault() + } + } + openModal () { this.setPluginState({ isHidden: false @@ -163,12 +211,17 @@ module.exports = class DashboardUI extends Plugin { document.body.classList.add('is-UppyDashboard-open') document.body.style.top = `-${this.savedDocumentScrollPosition}px` - // focus on modal inner block - this.target.querySelector('.UppyDashboard-inner').focus() + this.setFocusToFirstNode() - // this.updateDashboardElWidth() + // focus on modal inner block + // console.log(this.target) + // console.log(this.target.querySelector('.UppyDashboard-focus')) + // console.log(this.modal) + // this.modal.querySelector('.UppyDashboard-focus').focus() + + this.updateDashboardElWidth() // to be sure, sometimes when the function runs, container size is still 0 - setTimeout(this.updateDashboardElWidth, 500) + // setTimeout(this.updateDashboardElWidth, 500) } closeModal () { @@ -432,6 +485,8 @@ module.exports = class DashboardUI extends Plugin { this.initEvents() this.actions() + + this.modal = document.querySelector('.UppyDashboard--modal') } uninstall () { diff --git a/src/plugins/Plugin.js b/src/plugins/Plugin.js index 8d9661a27..d13306de3 100644 --- a/src/plugins/Plugin.js +++ b/src/plugins/Plugin.js @@ -1,5 +1,5 @@ const yo = require('yo-yo') -const nanoraf = require('nanoraf') +// const nanoraf = require('nanoraf') const { findDOMElement } = require('../core/Utils') const getFormData = require('get-form-data') @@ -63,9 +63,12 @@ module.exports = class Plugin { const targetElement = findDOMElement(target) // Set up nanoraf. - this.updateUI = nanoraf((state) => { + // this.updateUI = nanoraf((state) => { + // this.el = yo.update(this.el, this.render(state)) + // }) + this.updateUI = (state) => { this.el = yo.update(this.el, this.render(state)) - }) + } if (targetElement) { this.core.log(`Installing ${callerPluginName} to a DOM element`) diff --git a/src/scss/_utils.scss b/src/scss/_utils.scss index f2a556435..d017ebd3d 100644 --- a/src/scss/_utils.scss +++ b/src/scss/_utils.scss @@ -21,7 +21,7 @@ padding: 0; margin: 0; border: 0; - outline: none; + // outline: none; color: inherit; }