diff --git a/ghost/admin/app/components/gh-basic-dropdown.js b/ghost/admin/app/components/gh-basic-dropdown.js index 699c5165ef..59b7b623fa 100644 --- a/ghost/admin/app/components/gh-basic-dropdown.js +++ b/ghost/admin/app/components/gh-basic-dropdown.js @@ -1,5 +1,5 @@ import BasicDropdown from 'ember-basic-dropdown/components/basic-dropdown'; -import templateLayout from 'ember-basic-dropdown/templates/components/basic-dropdown'; +import templateLayout from '../templates/components/gh-basic-dropdown'; import {layout} from '@ember-decorators/component'; import {inject as service} from '@ember/service'; @@ -7,13 +7,13 @@ import {inject as service} from '@ember/service'; class GhBasicDropdown extends BasicDropdown { @service dropdown - onInit() { + constructor() { + super(...arguments); this.dropdown.on('close', this, this.close); } willDestroy() { this.dropdown.off('close', this, this.close); - super.willDestroyElement(...arguments); } } diff --git a/ghost/admin/app/components/gh-power-select/trigger.js b/ghost/admin/app/components/gh-power-select/trigger.js new file mode 100644 index 0000000000..0a8a0e7ebf --- /dev/null +++ b/ghost/admin/app/components/gh-power-select/trigger.js @@ -0,0 +1,8 @@ +import PowerSelectTrigger from 'ember-power-select/components/power-select/trigger'; +import templateLayout from '../../templates/components/gh-power-select/trigger'; +import {layout} from '@ember-decorators/component'; + +@layout(templateLayout) +export default class Trigger extends PowerSelectTrigger { + +} diff --git a/ghost/admin/app/components/gh-search-input-trigger.js b/ghost/admin/app/components/gh-search-input-trigger.js index 7e7b9c9fc8..995db4c4d8 100644 --- a/ghost/admin/app/components/gh-search-input-trigger.js +++ b/ghost/admin/app/components/gh-search-input-trigger.js @@ -1,60 +1,59 @@ /* global key */ -import Component from '@ember/component'; +import Component from '@glimmer/component'; +import {action} from '@ember/object'; import {isBlank} from '@ember/utils'; -export default Component.extend({ - actions: { - captureMouseDown(e) { - e.stopPropagation(); - }, +export default class GhSearchInputTrigger extends Component { + @action + registerInput(elem) { + this.inputElem = elem; + } - search(term) { - // open dropdown if not open and term is present - // close dropdown if open and term is blank - if (isBlank(term) === this.select.isOpen) { - isBlank(term) ? this.close() : this.open(); + @action + captureMousedown(e) { + e.stopPropagation(); + } - // ensure focus isn't lost when dropdown is closed - if (isBlank(term)) { - this._focusInput(); - } - } + @action + search(event) { + let term = event.target.value; - this.select.actions.search(term); - }, + // 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(); - focusInput() { - this._focusInput(); - }, - - // hacky workaround to let Escape clear the input if there's text, - // but still allow it to close the search modal if there's no text - handleKeydown(e) { - if ((e.key === 'Escape' && e.target.value) || e.key === 'Enter') { - this._previousKeyScope = key.getScope(); - key.setScope('ignore'); - } - }, - - handleKeyup() { - if (key.getScope() === 'ignore') { - key.setScope(this._previousKeyScope); + // ensure focus isn't lost when dropdown is closed + if (isBlank(term) && this.inputElem) { + this.inputElem.focus(); } } - }, - open() { - this.select.actions.open(); - }, + this.args.select.actions.search(term); + } - close() { - this.select.actions.close(); - }, - - _focusInput() { - let input = this.element && this.element.querySelector('input'); - if (input) { - input.focus(); + // hacky workaround to let Escape clear the input if there's text, + // but still allow it to close the search modal if there's no text + @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); + } + } + + open() { + this.args.select.actions.open(); + } + + close() { + this.args.select.actions.close(); + } +} diff --git a/ghost/admin/app/components/gh-token-input/select-multiple.js b/ghost/admin/app/components/gh-token-input/select-multiple.js index 65fb12e673..5b2e4f7b29 100644 --- a/ghost/admin/app/components/gh-token-input/select-multiple.js +++ b/ghost/admin/app/components/gh-token-input/select-multiple.js @@ -13,7 +13,9 @@ const END_ACTIONS = 'click.ghToken mouseup.ghToken touchend.ghToken'; // could be the start of a drag and disable the default focus behaviour until // we get another event signalling the end of a drag -export default @tagName('div') @layout(templateLayout) class GhTokenInputSelectMultiple extends PowerSelectMultiple { +@tagName('div') +@layout(templateLayout) +class GhTokenInputSelectMultiple extends PowerSelectMultiple { _canFocus = true; willDestroyElement() { @@ -64,3 +66,5 @@ export default @tagName('div') @layout(templateLayout) class GhTokenInputSelectM this._allowFocusListener = null; } } + +export default GhTokenInputSelectMultiple; diff --git a/ghost/admin/app/components/gh-token-input/suggested-option.js b/ghost/admin/app/components/gh-token-input/suggested-option.js deleted file mode 100644 index 041ba0ad19..0000000000 --- a/ghost/admin/app/components/gh-token-input/suggested-option.js +++ /dev/null @@ -1,5 +0,0 @@ -import Component from '@ember/component'; - -export default Component.extend({ - tagName: '' -}); diff --git a/ghost/admin/app/components/gh-token-input/trigger.js b/ghost/admin/app/components/gh-token-input/trigger.js index 215599cdfa..35e6995e81 100644 --- a/ghost/admin/app/components/gh-token-input/trigger.js +++ b/ghost/admin/app/components/gh-token-input/trigger.js @@ -7,7 +7,7 @@ export default class Trigger extends EmberPowerSelectMultipleTrigger { @action handleOptionMouseDown(event) { if (!event.target.closest('[data-selected-index]')) { - let optionMouseDown = this.get('extra.optionMouseDown'); + let optionMouseDown = this.args.extra.optionMouseDown; if (optionMouseDown) { return optionMouseDown(event); } @@ -18,7 +18,7 @@ export default class Trigger extends EmberPowerSelectMultipleTrigger { @action handleOptionTouchStart(event) { - let optionTouchStart = this.get('extra.optionTouchStart'); + let optionTouchStart = this.args.extra.optionTouchStart; if (optionTouchStart) { return optionTouchStart(event); } @@ -29,32 +29,32 @@ export default class Trigger extends EmberPowerSelectMultipleTrigger { // ember-drag-drop's sortable-objects has two-way bindings and will // update EPS' selected value directly. We have to create a copy // after sorting in order to force the onchange action to be triggered - let selectedCopy = this.select.selected.slice(); - this.select.actions.select(selectedCopy); + let selectedCopy = this.args.select.selected.slice(); + this.args.select.actions.select(selectedCopy); } // copied directly from EPS, the default behaviour of stopping propagation // of keydown events prevents our shortcuts from being triggered @action handleKeydown(e) { - if (this.onKeydown && this.onKeydown(e) === false) { + if (this.args.onKeydown && this.args.onKeydown(e) === false) { e.stopPropagation(); return false; } if (e.keyCode === 8) { e.stopPropagation(); if (isBlank(e.target.value)) { - let lastSelection = this.select.selected[this.select.selected.length - 1]; + let lastSelection = this.args.select.selected[this.args.select.selected.length - 1]; if (lastSelection) { - this.select.actions.select(this.get('buildSelection')(lastSelection, this.select), e); + this.args.select.actions.select(this.args.buildSelection(lastSelection, this.args.select), e); if (typeof lastSelection === 'string') { - this.select.actions.search(lastSelection); + this.args.select.actions.search(lastSelection); } else { let searchField = this.get('searchField'); assert('`{{power-select-multiple}}` requires a `searchField` when the options are not strings to remove options using backspace', searchField); - this.select.actions.search(get(lastSelection, searchField)); + this.args.select.actions.search(get(lastSelection, searchField)); } - this.select.actions.open(e); + this.args.select.actions.open(e); } } } diff --git a/ghost/admin/app/components/power-select-vertical-collection-options.js b/ghost/admin/app/components/power-select-vertical-collection-options.js index 8ea931feb6..f108fc74b7 100644 --- a/ghost/admin/app/components/power-select-vertical-collection-options.js +++ b/ghost/admin/app/components/power-select-vertical-collection-options.js @@ -1,6 +1,6 @@ import OptionsComponent from 'ember-power-select/components/power-select/options'; -import layout from '../templates/components/power-select-vertical-collection-options'; +import templateLayout from '../templates/components/power-select-vertical-collection-options'; +import {layout} from '@ember-decorators/component'; -export default OptionsComponent.extend({ - layout -}); +@layout(templateLayout) +export default class PowerSelectVerticalCollectionOptions extends OptionsComponent {} diff --git a/ghost/admin/app/components/power-select/trigger.js b/ghost/admin/app/components/power-select/trigger.js deleted file mode 100644 index 4c05732802..0000000000 --- a/ghost/admin/app/components/power-select/trigger.js +++ /dev/null @@ -1,6 +0,0 @@ -import layout from '../../templates/components/power-select/trigger'; -import trigger from 'ember-power-select/components/power-select/trigger'; - -export default trigger.extend({ - layout -}); diff --git a/ghost/admin/app/modifiers/autofocus.js b/ghost/admin/app/modifiers/autofocus.js new file mode 100644 index 0000000000..2309202b09 --- /dev/null +++ b/ghost/admin/app/modifiers/autofocus.js @@ -0,0 +1,3 @@ +import {modifier} from 'ember-modifier'; + +export default modifier(element => element.focus()); diff --git a/ghost/admin/app/templates/components/gh-basic-dropdown.hbs b/ghost/admin/app/templates/components/gh-basic-dropdown.hbs new file mode 100644 index 0000000000..ed06086116 --- /dev/null +++ b/ghost/admin/app/templates/components/gh-basic-dropdown.hbs @@ -0,0 +1,39 @@ +{{!-- no changes from upstream --}} +{{#with + (hash + uniqueId=this.publicAPI.uniqueId + isOpen=this.publicAPI.isOpen + disabled=this.publicAPI.disabled + actions=this.publicAPI.actions + Trigger=(component + (or @triggerComponent "basic-dropdown-trigger") + dropdown=(readonly this.publicAPI) + hPosition=(readonly this.hPosition) + renderInPlace=(readonly this.renderInPlace) + vPosition=(readonly this.vPosition) + ) + Content=(component + (or @contentComponent "basic-dropdown-content") + dropdown=(readonly this.publicAPI) + hPosition=(readonly this.hPosition) + renderInPlace=(readonly this.renderInPlace) + preventScroll=(readonly @preventScroll) + rootEventType=(or @rootEventType "click") + vPosition=(readonly this.vPosition) + destination=(readonly this.destination) + top=(readonly this.top) + left=(readonly this.left) + right=(readonly this.right) + width=(readonly this.width) + height=(readonly this.height) + otherStyles=(readonly this.otherStyles) + ) + ) +as |api| +}} + {{#if this.renderInPlace}} +