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() {
|
onRendered() {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
const { event, centered, marginTop } = instance.data.options;
|
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
|
// Get the dropdown element to enable position manipulation
|
||||||
const $dropdown = instance.$('.dropdown');
|
const $dropdown = instance.$('.dropdown');
|
||||||
const dropdown = $dropdown[0];
|
const dropdown = $dropdown[0];
|
||||||
const $dropdownMenu = $dropdown.children('.dropdown-menu');
|
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;
|
dropdown.oncontextmenu = () => false;
|
||||||
|
|
||||||
const cssBefore = { 'z-index': 10000 };
|
const cssBefore = { 'z-index': 10000 };
|
||||||
@ -76,13 +92,11 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
|||||||
const $target = $(event.currentTarget);
|
const $target = $(event.currentTarget);
|
||||||
const isDisabled = $target.hasClass('disabled');
|
const isDisabled = $target.hasClass('disabled');
|
||||||
if (isDisabled) {
|
if (isDisabled) {
|
||||||
instance.data.promiseReject();
|
instance.close(false);
|
||||||
} else {
|
} else {
|
||||||
const component = $target.data('component');
|
const component = $target.data('component');
|
||||||
instance.data.promiseResolve(component.actionResult);
|
instance.close(true, component.actionResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.destroyView();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'click .dropdown'(event, instance) {
|
'click .dropdown'(event, instance) {
|
||||||
@ -91,8 +105,7 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
} else {
|
} else {
|
||||||
instance.data.promiseReject();
|
instance.close(false);
|
||||||
instance.destroyView();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -100,8 +113,7 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
|||||||
Meteor.defer(() => {
|
Meteor.defer(() => {
|
||||||
const $focus = $(':focus');
|
const $focus = $(':focus');
|
||||||
if (!$focus.length || !$.contains(event.currentTarget, $focus[0])) {
|
if (!$focus.length || !$.contains(event.currentTarget, $focus[0])) {
|
||||||
instance.data.promiseReject();
|
instance.close(false);
|
||||||
instance.destroyView();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
@import "{ohif:design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.dropdown
|
.dropdown
|
||||||
|
cursor: default
|
||||||
outline: none
|
outline: none
|
||||||
|
|
||||||
ul.dropdown-menu
|
ul.dropdown-menu
|
||||||
|
display: block
|
||||||
|
transform(scale(0))
|
||||||
|
transition(transform 0.3s ease)
|
||||||
|
|
||||||
|
&.dropdown-menu-right
|
||||||
|
transform-origin(100% 0%)
|
||||||
|
|
||||||
li.divider
|
li.divider
|
||||||
margin: 4px 0
|
margin: 4px 0
|
||||||
@ -17,3 +24,6 @@
|
|||||||
max-width: 18px
|
max-width: 18px
|
||||||
max-height: 18px
|
max-height: 18px
|
||||||
vertical-align: middle
|
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 { Template } from 'meteor/templating';
|
||||||
import { ReactiveVar } from 'meteor/reactive-var';
|
|
||||||
import { $ } from 'meteor/jquery';
|
import { $ } from 'meteor/jquery';
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
Template.header.onCreated(() => {
|
Template.header.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
|
||||||
instance.dropdownOpen = new ReactiveVar(false);
|
|
||||||
instance.dropdownItems = [];
|
instance.dropdownItems = [];
|
||||||
instance.autorun(() => {
|
instance.autorun(() => {
|
||||||
OHIF.header.dropdownObserver.depend();
|
OHIF.header.dropdownObserver.depend();
|
||||||
@ -16,22 +13,17 @@ Template.header.onCreated(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.header.events({
|
Template.header.events({
|
||||||
'mousedown .header-menu'(event, instance) {
|
|
||||||
if (instance.dropdownOpen.get()) {
|
|
||||||
event.preventDefault();
|
|
||||||
return $(event.currentTarget).focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'click .header-menu'(event, instance) {
|
'click .header-menu'(event, instance) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (instance.dropdownOpen.get()) return;
|
|
||||||
instance.dropdownOpen.set(true);
|
// Prevent dropdown from being opened if there's one already opened
|
||||||
const closeHandler = () => Meteor.setTimeout(() => instance.dropdownOpen.set(false), 200);
|
if ($(event.currentTarget).find('.dropdown').length) return;
|
||||||
|
|
||||||
|
// Show the dropdown
|
||||||
OHIF.ui.showDropdown(instance.dropdownItems, {
|
OHIF.ui.showDropdown(instance.dropdownItems, {
|
||||||
parentElement: event.currentTarget,
|
parentElement: event.currentTarget,
|
||||||
menuClasses: 'dropdown-menu-right',
|
menuClasses: 'dropdown-menu-right',
|
||||||
marginTop: '25px'
|
marginTop: '25px'
|
||||||
}).then(closeHandler).catch(closeHandler);
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user