2017-08-22 10:53:26 +03:00
|
|
|
import Component from '@ember/component';
|
2017-05-29 21:50:03 +03:00
|
|
|
import DropdownMixin from 'ghost-admin/mixins/dropdown-mixin';
|
2022-02-01 12:34:03 +03:00
|
|
|
import classic from 'ember-classic-decorator';
|
|
|
|
import {classNameBindings, classNames} from '@ember-decorators/component';
|
2017-08-22 10:53:26 +03:00
|
|
|
import {computed} from '@ember/object';
|
|
|
|
import {run} from '@ember/runloop';
|
2017-10-30 12:38:01 +03:00
|
|
|
import {inject as service} from '@ember/service';
|
2014-04-07 02:11:22 +04:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
@classic
|
|
|
|
@classNames('dropdown')
|
|
|
|
@classNameBindings('fadeIn:fade-in-scale:fade-out', 'isOpen:open:closed')
|
|
|
|
export default class GhDropdown extends Component.extend(DropdownMixin) {
|
2022-02-01 20:03:45 +03:00
|
|
|
@service dropdown;
|
2018-01-11 20:43:23 +03:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
name = null;
|
|
|
|
closeOnClick = false;
|
2014-10-25 01:09:50 +04:00
|
|
|
|
|
|
|
// Helps track the user re-opening the menu while it's fading out.
|
2022-02-01 12:34:03 +03:00
|
|
|
closing = false;
|
2014-10-25 01:09:50 +04:00
|
|
|
|
|
|
|
// Helps track whether the dropdown is open or closes, or in a transition to either
|
2022-02-01 12:34:03 +03:00
|
|
|
isOpen = false;
|
2014-10-25 01:09:50 +04:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
onClose() {}
|
2021-08-13 20:52:49 +03:00
|
|
|
|
2014-10-25 01:09:50 +04:00
|
|
|
// Managed the toggle between the fade-in and fade-out classes
|
2022-02-01 12:34:03 +03:00
|
|
|
@computed('isOpen', 'closing')
|
|
|
|
get fadeIn() {
|
2019-03-06 16:53:54 +03:00
|
|
|
return this.isOpen && !this.closing;
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2014-09-24 17:36:20 +04:00
|
|
|
|
2018-01-11 20:43:23 +03:00
|
|
|
didInsertElement() {
|
2022-02-01 12:34:03 +03:00
|
|
|
super.didInsertElement(...arguments);
|
2018-01-11 20:43:23 +03:00
|
|
|
|
2020-01-10 18:12:39 +03:00
|
|
|
let dropdownService = this.dropdown;
|
2018-01-11 20:43:23 +03:00
|
|
|
dropdownService.on('close', this, this.close);
|
|
|
|
dropdownService.on('toggle', this, this.toggle);
|
2020-01-10 18:12:39 +03:00
|
|
|
|
|
|
|
this._animationEndHandler = run.bind(this, function (event) {
|
|
|
|
if (event.animationName === 'fade-out' && this.closing) {
|
|
|
|
this.set('isOpen', false);
|
|
|
|
this.set('closing', false);
|
2021-09-06 10:12:43 +03:00
|
|
|
this.onClose?.();
|
2020-01-10 18:12:39 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.element.addEventListener('animationend', this._animationEndHandler);
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2018-01-11 20:43:23 +03:00
|
|
|
|
|
|
|
willDestroyElement() {
|
2022-02-01 12:34:03 +03:00
|
|
|
super.willDestroyElement(...arguments);
|
2018-01-11 20:43:23 +03:00
|
|
|
|
2020-01-10 18:12:39 +03:00
|
|
|
let dropdownService = this.dropdown;
|
2018-01-11 20:43:23 +03:00
|
|
|
dropdownService.off('close', this, this.close);
|
|
|
|
dropdownService.off('toggle', this, this.toggle);
|
2020-01-10 18:12:39 +03:00
|
|
|
|
|
|
|
this.element.removeEventListener('animationend', this._animationEndHandler);
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2014-07-01 22:56:02 +04:00
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
open() {
|
2014-07-01 22:56:02 +04:00
|
|
|
this.set('isOpen', true);
|
2014-09-24 17:36:20 +04:00
|
|
|
this.set('closing', false);
|
2014-08-06 18:32:10 +04:00
|
|
|
this.set('button.isOpen', true);
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2014-10-25 01:09:50 +04:00
|
|
|
|
2015-10-28 14:36:45 +03:00
|
|
|
close() {
|
2014-07-01 22:56:02 +04:00
|
|
|
this.set('closing', true);
|
2019-03-06 16:53:54 +03:00
|
|
|
if (this.button) {
|
2014-08-06 18:32:10 +04:00
|
|
|
this.set('button.isOpen', false);
|
|
|
|
}
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2014-10-25 01:09:50 +04:00
|
|
|
|
|
|
|
// Called by the dropdown service when any dropdown button is clicked.
|
2015-10-28 14:36:45 +03:00
|
|
|
toggle(options) {
|
2019-03-06 16:53:54 +03:00
|
|
|
let isClosing = this.closing;
|
|
|
|
let isOpen = this.isOpen;
|
|
|
|
let name = this.name;
|
2015-10-28 14:36:45 +03:00
|
|
|
let targetDropdownName = options.target;
|
2019-03-06 16:53:54 +03:00
|
|
|
let button = this.button;
|
2014-09-29 15:17:27 +04:00
|
|
|
|
2014-09-28 19:39:25 +04:00
|
|
|
if (name === targetDropdownName && (!isOpen || isClosing)) {
|
2014-08-06 18:32:10 +04:00
|
|
|
if (!button) {
|
|
|
|
button = options.button;
|
|
|
|
this.set('button', button);
|
|
|
|
}
|
2014-07-01 22:56:02 +04:00
|
|
|
this.open();
|
|
|
|
} else if (isOpen) {
|
|
|
|
this.close();
|
|
|
|
}
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|
2014-10-25 01:09:50 +04:00
|
|
|
|
2022-02-01 12:34:03 +03:00
|
|
|
click() {
|
2022-02-01 14:42:42 +03:00
|
|
|
super.click(...arguments);
|
|
|
|
|
2019-03-06 16:53:54 +03:00
|
|
|
if (this.closeOnClick) {
|
2014-07-01 22:56:02 +04:00
|
|
|
return this.close();
|
|
|
|
}
|
2014-05-31 04:07:15 +04:00
|
|
|
}
|
2022-02-01 12:34:03 +03:00
|
|
|
}
|