Fixing dropdown focus/blur behavior and adding animations
This commit is contained in:
parent
e83b5348ff
commit
4daf7d8bf8
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user