Ghost/ghost/admin/app/components/gh-input-with-select/trigger.js
Kevin Ansfield 5dda8832f2 Added showSearchMessage option to gh-input-with-select/trigger component
refs https://github.com/TryGhost/Team/issues/1290

- when set to `false` prevents the dropdown opening when it would only contain the "Type to search" message
- uses the `@extra` hash param. Would be preferable to be able to use `@searchMessage=""` but ember power select doesn't pass the searchMessage argument through to the trigger
2022-01-27 18:56:13 +00:00

127 lines
3.4 KiB
JavaScript

/* global key */
import Component from '@glimmer/component';
import {action} from '@ember/object';
import {isBlank} from '@ember/utils';
import {inject as service} from '@ember/service';
export default class GhSearchInputTrigger extends Component {
@service dropdown;
inputElem = null;
constructor() {
super(...arguments);
this.dropdown.on('close', this, this.closeFromDropdown);
}
willDestroy() {
super.willDestroy(...arguments);
this.dropdown.off('close', this, this.closeFromDropdown);
}
closeFromDropdown() {
this.args.select.actions.close();
}
@action
registerInput(elem) {
this.inputElem = elem;
if (this.args.extra?.autofocus) {
this.inputElem.focus();
}
}
@action
handleInput(event) {
let term = event.target.value;
// open dropdown if not open and term is present
// close dropdown if open and term is blank
if (isBlank(term) === this.args.select.isOpen) {
isBlank(term) ? this.close() : this.open();
}
this.args.onInput?.(event);
}
// hacky workaround to let Escape clear the input if there's text,
// but still allow it to bubble if there's no text (used for closing modals, etc)
@action
handleKeydown(e) {
if ((e.key === 'Escape' && e.target.value) || e.key === 'Enter') {
this._previousKeyScope = key.getScope();
key.setScope('ignore');
}
}
@action
handleKeyup() {
if (key.getScope() === 'ignore') {
key.setScope(this._previousKeyScope);
}
}
@action
handleFocus() {
if (this.args.extra?.openOnFocus && this.args.select.results.length > 0) {
this.open();
}
this.args.onFocus?.(...arguments);
if (this.args.extra.showSearchMessage === false && this.args.select.results.length === 0) {
this.close();
}
}
@action
handleBlur(event) {
if (event?.relatedTarget) {
const thisInputTrigger = this.inputElem.closest('.ember-basic-dropdown-trigger');
const relatedInputTrigger = event.relatedTarget.closest('.ember-basic-dropdown-trigger');
if (relatedInputTrigger !== thisInputTrigger) {
this.args.select.actions.search('');
this.close();
}
}
if (this.args.extra?.value && this.args.select.searchText === this.args.extra.value) {
this.args.select.actions.search('');
this.close();
}
this.args.onBlur?.(...arguments);
}
@action
closeWhenEmpty() {
if (document.activeElement === this.inputElem) {
if (this.args.extra?.closeWhenEmpty) {
if (this.args.select.results.length > 0) {
this.open();
}
if (this.args.select.results.length === 0) {
this.close();
}
}
}
}
open() {
if (!this.args.select.isOpen) {
// second argument skips ember-basic-dropdown focus
this.args.select.actions.open(null, true);
}
}
close() {
if (this.args.select.isOpen) {
// second argument skips ember-basic-dropdown focus
this.args.select.actions.close(null, true);
}
}
}