diff --git a/Packages/ohif-core/client/components/base/mixins/dropdown.js b/Packages/ohif-core/client/components/base/mixins/dropdown.js index ce2cd94c7..627f72ae8 100644 --- a/Packages/ohif-core/client/components/base/mixins/dropdown.js +++ b/Packages/ohif-core/client/components/base/mixins/dropdown.js @@ -13,27 +13,43 @@ OHIF.mixins.dropdown = new OHIF.Mixin({ onRendered() { const instance = Template.instance(); const { event, centered, marginTop } = instance.data.options; - - // Destroy the Blaze created view (either created with template calls or with renderWithData) - instance.destroyView = () => { - if (typeof instance.data.destroyView === 'function') { - instance.data.destroyView(); - } else { - Blaze.remove(instance.view); - } - }; - - // Stop here and destroy the view if no items was given - if (!instance.data.items.length) { - instance.data.promiseReject(); - return instance.destroyView(); - } - // Get the dropdown element to enable position manipulation const $dropdown = instance.$('.dropdown'); const dropdown = $dropdown[0]; const $dropdownMenu = $dropdown.children('.dropdown-menu'); + // Destroy the Blaze created view (either created with template calls or with renderWithData) + instance.destroyView = () => { + const destroyHandle = () => { + if (typeof instance.data.destroyView === 'function') { + instance.data.destroyView(); + } else { + Blaze.remove(instance.view); + } + }; + + const timeout = setTimeout(destroyHandle, 500); + $dropdownMenu.one('transitionend', () => { + destroyHandle(); + clearTimeout(timeout); + }); + $dropdown.removeClass('open'); + }; + + // Destroy the view when the promise is fullfilled + instance.data.promise.then(instance.destroyView, instance.destroyView); + + // Close the dropdown resolving or rejecting the promise + instance.close = (isResolve, result) => { + const method = instance.data[isResolve ? 'promiseResolve' : 'promiseReject']; + method(result); + }; + + // Stop here and destroy the view if no items was given + if (!instance.data.items.length) { + return instance.close(false); + } + dropdown.oncontextmenu = () => false; const cssBefore = { 'z-index': 10000 }; @@ -76,13 +92,11 @@ OHIF.mixins.dropdown = new OHIF.Mixin({ const $target = $(event.currentTarget); const isDisabled = $target.hasClass('disabled'); if (isDisabled) { - instance.data.promiseReject(); + instance.close(false); } else { const component = $target.data('component'); - instance.data.promiseResolve(component.actionResult); + instance.close(true, component.actionResult); } - - instance.destroyView(); }, 'click .dropdown'(event, instance) { @@ -91,8 +105,7 @@ OHIF.mixins.dropdown = new OHIF.Mixin({ event.preventDefault(); event.stopPropagation(); } else { - instance.data.promiseReject(); - instance.destroyView(); + instance.close(false); } }, @@ -100,8 +113,7 @@ OHIF.mixins.dropdown = new OHIF.Mixin({ Meteor.defer(() => { const $focus = $(':focus'); if (!$focus.length || !$.contains(event.currentTarget, $focus[0])) { - instance.data.promiseReject(); - instance.destroyView(); + instance.close(false); } }); } diff --git a/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl b/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl index fa065b9d4..e8eff5d31 100644 --- a/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl +++ b/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl @@ -1,9 +1,16 @@ @import "{ohif:design}/app" .dropdown + cursor: default outline: none ul.dropdown-menu + display: block + transform(scale(0)) + transition(transform 0.3s ease) + + &.dropdown-menu-right + transform-origin(100% 0%) li.divider margin: 4px 0 @@ -17,3 +24,6 @@ max-width: 18px max-height: 18px vertical-align: middle + + &.open ul.dropdown-menu + transform(scale(1)) diff --git a/Packages/ohif-header/client/components/header/header.js b/Packages/ohif-header/client/components/header/header.js index acdbc1b3d..f86dad512 100644 --- a/Packages/ohif-header/client/components/header/header.js +++ b/Packages/ohif-header/client/components/header/header.js @@ -1,13 +1,10 @@ -import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; import { $ } from 'meteor/jquery'; import { OHIF } from 'meteor/ohif:core'; Template.header.onCreated(() => { const instance = Template.instance(); - instance.dropdownOpen = new ReactiveVar(false); instance.dropdownItems = []; instance.autorun(() => { OHIF.header.dropdownObserver.depend(); @@ -16,22 +13,17 @@ Template.header.onCreated(() => { }); Template.header.events({ - 'mousedown .header-menu'(event, instance) { - if (instance.dropdownOpen.get()) { - event.preventDefault(); - return $(event.currentTarget).focus(); - } - }, - 'click .header-menu'(event, instance) { event.preventDefault(); - if (instance.dropdownOpen.get()) return; - instance.dropdownOpen.set(true); - const closeHandler = () => Meteor.setTimeout(() => instance.dropdownOpen.set(false), 200); + + // Prevent dropdown from being opened if there's one already opened + if ($(event.currentTarget).find('.dropdown').length) return; + + // Show the dropdown OHIF.ui.showDropdown(instance.dropdownItems, { parentElement: event.currentTarget, menuClasses: 'dropdown-menu-right', marginTop: '25px' - }).then(closeHandler).catch(closeHandler); + }); } });