mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-02 22:37:58 +00:00
143 lines
3.8 KiB
TypeScript
143 lines
3.8 KiB
TypeScript
![]() |
import Component from '@ember/component';
|
||
|
import { get, set } from '@ember/object';
|
||
|
import { task, TaskInstance, timeout } from 'ember-concurrency';
|
||
|
import { assert } from '@ember/debug';
|
||
|
import { IDropDownOption } from 'wherehows-web/typings/app/dataset-compliance';
|
||
|
import { action } from '@ember-decorators/object';
|
||
|
|
||
|
export default class HoverDropDown<T> extends Component {
|
||
|
classNames = ['nacho-drop-down'];
|
||
|
|
||
|
/**
|
||
|
* Toggle state of the drop-down
|
||
|
* @type {boolean}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
isExpanded: boolean | void;
|
||
|
|
||
|
/**
|
||
|
* Lists the options for the drop down content
|
||
|
* @type {Array<IDropDownOption<T>>}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
dropDownItems: Array<IDropDownOption<T>>;
|
||
|
|
||
|
/**
|
||
|
* References the currently selected drop-down option
|
||
|
* @type {IDropDownOption<T>}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
selectedDropDown: IDropDownOption<T>;
|
||
|
|
||
|
/**
|
||
|
* External action invoked when a drop-down option is selected
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
onSelect: (selected: IDropDownOption<T>) => void;
|
||
|
|
||
|
/**
|
||
|
* References the most recent TaskInstance to hide the drop-down options
|
||
|
* @type {TaskInstance<Promise<void>>}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
mostRecentHideTask: TaskInstance<Promise<void>>;
|
||
|
|
||
|
/**
|
||
|
* Creates an instance of HoverDropDown.
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
constructor() {
|
||
|
super(...arguments);
|
||
|
|
||
|
const typeOfItems = typeof this.dropDownItems;
|
||
|
assert(`Expected prop dropDownItems to be of type Array, got ${typeOfItems}`, Array.isArray(this.dropDownItems));
|
||
|
// defaults the isExpanded flag to false
|
||
|
typeof this.isExpanded === 'boolean' || (this.isExpanded = false);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Task triggers the rendering of the list of drop-down options
|
||
|
* @type TaskProperty<void> & {
|
||
|
perform: (a?: {
|
||
|
actions: {
|
||
|
open: () => void;
|
||
|
};
|
||
|
} | undefined) => TaskInstance<void>}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
showDropDownTask = task(function*(
|
||
|
this: HoverDropDown<T>,
|
||
|
dd: { actions: { open: () => void } }
|
||
|
): IterableIterator<void> {
|
||
|
set(this, 'isExpanded', true);
|
||
|
dd.actions.open();
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Task triggers the occluding of the list of drop-down options
|
||
|
* @type TaskProperty<void> & {
|
||
|
perform: (a?: {
|
||
|
actions: {
|
||
|
open: () => void;
|
||
|
};
|
||
|
} | undefined) => TaskInstance<void>}
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
hideDropDownTask = task(function*(
|
||
|
this: HoverDropDown<T>,
|
||
|
dd: { actions: { close: () => void } }
|
||
|
): IterableIterator<Promise<void>> {
|
||
|
set(this, 'isExpanded', false);
|
||
|
yield timeout(200);
|
||
|
dd.actions.close();
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Action handler to prevent bubbling DOM event action
|
||
|
* @returns
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
@action
|
||
|
prevent() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Handles the DOM onmouseenter event to show list of drop-down options
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
@action
|
||
|
showDropDown() {
|
||
|
const lastHideTask = get(this, 'mostRecentHideTask');
|
||
|
|
||
|
if (lastHideTask) {
|
||
|
lastHideTask.cancel();
|
||
|
}
|
||
|
|
||
|
get(this, 'showDropDownTask').perform(...arguments);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Handles the DOM event onmouseleave to hide the list of drop-down options and
|
||
|
* stores a reference to the last invoked hideDropDownTask TaskInstance
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
@action
|
||
|
hideDropDown() {
|
||
|
set(this, 'mostRecentHideTask', get(this, 'hideDropDownTask').perform(...arguments));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invokes the external action with a reference to the selected drop-down option,
|
||
|
* and sets a reference on this
|
||
|
* @param {IDropDownOption<T>} selected the selected drop-down option, an instance of IDropDownOption<T>
|
||
|
* @memberof HoverDropDown
|
||
|
*/
|
||
|
@action
|
||
|
onDropDownSelect(selected: IDropDownOption<T>) {
|
||
|
if (typeof this.onSelect === 'function') {
|
||
|
this.onSelect(set(this, 'selectedDropDown', selected));
|
||
|
}
|
||
|
}
|
||
|
}
|