import Plugin from './Plugin' import Utils from '../core/Utils' /** * Modal * */ export default class Modal extends Plugin { constructor (core, opts) { super(core, opts) this.type = 'orchestrator' // set default options const defaultOptions = { defaultTabIcon: ` `, panelSelectorPrefix: 'UppyModalContent-panel' } this.tabPanels = [] this.isModalVisible = false // merge default options with the ones set by user this.opts = Object.assign({}, defaultOptions, opts) this.initTabs = this.initTabs.bind(this) this.hideModal = this.hideModal.bind(this) this.showModal = this.showModal.bind(this) this.install = this.install.bind(this) } prepareTarget (callerPlugin) { const callerPluginId = callerPlugin.constructor.name const callerPluginName = callerPlugin.name || callerPluginId const callerPluginIcon = callerPlugin.icon || this.opts.defaultTabIcon switch (callerPlugin.type) { case 'progressindicator': return '.UppyModal-progressBarContainer' case 'presenter': return '.UppyModal-presenter' case 'acquirer': // add tab panel, where plugin will render const modalContent = document.querySelector('.UppyModalContent') const nodeForPlugin = document.createElement('div') modalContent.appendChild(nodeForPlugin) nodeForPlugin.outerHTML = ` ` // add tab switch button const modalTabs = document.querySelector('.UppyModalTabs') const modalTab = document.createElement('div') modalTabs.appendChild(modalTab) modalTab.outerHTML = `
  • ` return `.${this.opts.panelSelectorPrefix}--${callerPluginId}` default: let msg = 'Error: Modal can only be used by plugins of types: acquirer, progressindicator' this.core.log(msg) break } } allDone () { this.hideAllTabPanels() } render () { // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog return ` ` } hideModal () { this.isModalVisible = false this.modalEl.setAttribute('aria-hidden', 'true') this.core.emitter.emit('reset') } showModal () { this.isModalVisible = true this.modalEl.removeAttribute('aria-hidden') this.initTabs() } hideAllTabPanels () { this.tabPanels.forEach((tabPanel) => tabPanel.setAttribute('aria-hidden', true)) this.tabs.forEach((tab) => tab.removeAttribute('aria-selected')) } showTabPanel (pluginSelector, pluginName) { this.hideAllTabPanels() const tab = document.querySelector(`[aria-controls="${pluginName}"]`) const tabPanel = document.querySelector(`.${pluginSelector}`) tabPanel.removeAttribute('aria-hidden') tab.setAttribute('aria-selected', 'true') this.core.log(pluginName) this.core.getPlugin(pluginName).focus() } events () { // Listen for allDone event to close all tabs this.core.emitter.on('allDone', () => this.allDone()) // this.core.emitter.on('file-add', (data) => { // this.nextButton.classList.add('is-active') // // const files = Object.keys(this.core.state.selectedFiles) // const selectedFileCount = files.length // this.nextButton.innerHTML = this.core.i18n('uploadFiles', {'smart_count': selectedFileCount}) // }) // this.core.emitter.on('reset', () => this.nextButton.classList.remove('is-active')) // Close the Modal on esc key press document.body.addEventListener('keyup', (event) => { if (event.keyCode === 27) { this.hideModal() } }) // Close on click outside modal or close buttons document.addEventListener('click', (e) => { if (e.target.classList.contains('js-UppyModal-close')) { this.hideModal() } }) } initTabs () { // Get all tab buttons and loop through them, to determine which // tabPanel they trigger, set events this.tabs = Utils.qsa('.UppyModalTab-btn') this.tabs.forEach((tab) => { const pluginSelector = tab.getAttribute('data-open') const pluginName = tab.getAttribute('aria-controls') const tabPanel = document.querySelector(`.${pluginSelector}`) this.tabPanels.push(tabPanel) tab.addEventListener('click', (event) => { event.preventDefault() this.showTabPanel(pluginSelector, pluginName) }) }) // Select first tab right away this.tabs[0].click() } install () { const node = document.createElement('div') document.body.appendChild(node) node.outerHTML = this.render() this.modalEl = document.querySelector('.UppyModal') // Add events for opening and closing the modal // const hideModalTrigger = Utils.qsa('.js-UppyModal-close') this.showModalTrigger = document.querySelector(this.opts.trigger) this.showModalTrigger.addEventListener('click', this.showModal) // When `next` (upload) button is clicked, emit `next` event, // so that plugins can proceed to the next stage // this.nextButton = document.querySelector('.UppyModal-next') // this.nextButton.addEventListener('click', () => this.core.emitter.emit('next')) this.events() } }