Fixing dropdown focus/blur behavior and adding animations

This commit is contained in:
Bruno Alves de Faria 2017-03-14 10:22:12 -03:00
parent e83b5348ff
commit 4daf7d8bf8
3 changed files with 52 additions and 38 deletions

View File

@ -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);
}
});
}

View File

@ -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))

View File

@ -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);
});
}
});