diff --git a/docs/app/templates/public-pages/docs/migrate-8-0-to-9-0.gts b/docs/app/templates/public-pages/docs/migrate-8-0-to-9-0.gts
index 67f565d0..1612997e 100644
--- a/docs/app/templates/public-pages/docs/migrate-8-0-to-9-0.gts
+++ b/docs/app/templates/public-pages/docs/migrate-8-0-to-9-0.gts
@@ -77,6 +77,18 @@ import { LinkTo } from '@ember/routing';
a regular HTML attribute instead.
+
If you are using
diff --git a/src/components/basic-dropdown-content.gts b/src/components/basic-dropdown-content.gts
index aa4269cc..4be495c8 100644
--- a/src/components/basic-dropdown-content.gts
+++ b/src/components/basic-dropdown-content.gts
@@ -175,7 +175,7 @@ export default class BasicDropdownContent<
if (!triggerElement) {
triggerElement = document.querySelector(selector) as HTMLElement;
}
- this.handleRootMouseDown = (e: MouseEvent | TouchEvent) => {
+ this.handleRootMouseDown = (e: MouseEvent | TouchEvent): void => {
const target = (e.composedPath?.()[0] || e.target) as Element;
if (target === null) return;
if (
diff --git a/src/components/basic-dropdown.gts b/src/components/basic-dropdown.gts
index 35e7f917..0b8e2ec8 100644
--- a/src/components/basic-dropdown.gts
+++ b/src/components/basic-dropdown.gts
@@ -3,7 +3,6 @@ import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import calculatePosition from '../utils/calculate-position.ts';
-import { schedule } from '@ember/runloop';
import { hash } from '@ember/helper';
import BasicDropdownTrigger from './basic-dropdown-trigger.gts';
import BasicDropdownContent from './basic-dropdown-content.gts';
@@ -27,7 +26,6 @@ import type {
TRootEventType,
} from '../types.ts';
-const UNINITIALIZED = {};
const IGNORED_STYLES = ['top', 'left', 'right', 'width', 'height'];
export interface BasicDropdownDefaultBlock<
@@ -122,9 +120,10 @@ export default class BasicDropdown<
@tracked width: string | undefined;
@tracked height: string | undefined;
@tracked otherStyles: Record = {};
- @tracked isOpen = this.args.initiallyOpened || false;
@tracked renderInPlace =
this.args.renderInPlace !== undefined ? this.args.renderInPlace : false;
+ @tracked private _isOpen = this.args.initiallyOpened || false;
+
private previousVerticalPosition?: VerticalPosition | undefined;
private previousHorizontalPosition?: HorizontalPosition | undefined;
private triggerElement: HTMLElement | null = null;
@@ -132,25 +131,33 @@ export default class BasicDropdown<
private _uid = guidFor(this);
private _dropdownId: string = `ember-basic-dropdown-content-${this._uid}`;
- private _previousDisabled = UNINITIALIZED;
private _actions: DropdownActions = {
open: this.open.bind(this),
close: this.close.bind(this),
toggle: this.toggle.bind(this),
reposition: this.reposition.bind(this),
+ updatePublicApi: this.updatePublicApi.bind(this),
registerTriggerElement: this.registerTriggerElement.bind(this),
registerDropdownElement: this.registerDropdownElement.bind(this),
getTriggerElement: () => this.triggerElement,
};
- private get horizontalPosition() {
+ private get horizontalPosition(): HorizontalPosition {
return this.args.horizontalPosition || 'auto'; // auto-right | right | center | left
}
- private get verticalPosition() {
+ private get verticalPosition(): VerticalPosition {
return this.args.verticalPosition || 'auto'; // above | below
}
+ get isOpen(): boolean {
+ return !this.disabled && this._isOpen;
+ }
+
+ set isOpen(v: boolean) {
+ this._isOpen = v;
+ }
+
get destination(): string {
return this.args.destination || this._getDestinationId();
}
@@ -179,25 +186,7 @@ export default class BasicDropdown<
}
get disabled(): boolean {
- const newVal = this.args.disabled || false;
- if (
- this._previousDisabled !== UNINITIALIZED &&
- this._previousDisabled !== newVal
- ) {
- // eslint-disable-next-line ember/no-runloop
- schedule('actions', () => {
- if (newVal && this.publicAPI.isOpen) {
- // eslint-disable-next-line ember/no-side-effects
- this.isOpen = false;
- }
- if (this.args.registerAPI) {
- this.args.registerAPI(this.publicAPI);
- }
- });
- }
- // eslint-disable-next-line ember/no-side-effects
- this._previousDisabled = newVal;
- return newVal;
+ return this.args.disabled || false;
}
get publicAPI(): Dropdown {
@@ -337,6 +326,15 @@ export default class BasicDropdown<
return this.applyReposition(triggerElement, dropdownElement, positionData);
}
+ @action
+ updatePublicApi() {
+ if (!this.args.registerAPI) {
+ return;
+ }
+
+ this.args.registerAPI(this.publicAPI);
+ }
+
@action
registerTriggerElement(element: HTMLElement): void {
this.triggerElement = element;
diff --git a/src/modifiers/basic-dropdown-trigger.ts b/src/modifiers/basic-dropdown-trigger.ts
index 751b5eae..550335d1 100644
--- a/src/modifiers/basic-dropdown-trigger.ts
+++ b/src/modifiers/basic-dropdown-trigger.ts
@@ -32,6 +32,8 @@ export default class DropdownTriggerModifier extends Modifier {
desiredEventType!: string;
stopPropagation: boolean | undefined;
+ private _previousDisabled: boolean | undefined = undefined;
+
constructor(owner: Owner, args: ArgsFor) {
super(owner, args);
registerDestructor(this, cleanup);
@@ -51,6 +53,17 @@ export default class DropdownTriggerModifier extends Modifier {
this.setup(element);
this.didSetup = true;
}
+
+ if (this._previousDisabled === undefined) {
+ this._previousDisabled = this.dropdown.disabled;
+ }
+
+ if (this.dropdown.disabled !== this._previousDisabled) {
+ this._previousDisabled = this.dropdown.disabled;
+
+ this.dropdown.actions.updatePublicApi();
+ }
+
this.update(element, positional, named);
}
diff --git a/src/types.ts b/src/types.ts
index 9615fdad..157c286a 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -3,6 +3,7 @@ export interface DropdownActions {
close: (e?: Event, skipFocus?: boolean) => void;
open: (e?: Event) => void;
reposition: () => undefined | RepositionChanges;
+ updatePublicApi: () => void;
registerTriggerElement: (e: HTMLElement) => void;
registerDropdownElement: (e: HTMLElement) => void;
getTriggerElement: () => HTMLElement | null;
diff --git a/tests/integration/components/content-test.gts b/tests/integration/components/content-test.gts
index b5a30575..0b733c5e 100644
--- a/tests/integration/components/content-test.gts
+++ b/tests/integration/components/content-test.gts
@@ -57,6 +57,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -101,6 +102,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -143,6 +145,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -181,6 +184,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -225,6 +229,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -267,6 +272,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -306,6 +312,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -348,6 +355,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -391,6 +399,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -435,6 +444,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -479,6 +489,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -520,6 +531,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -540,6 +552,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -592,6 +605,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -640,6 +654,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -698,6 +713,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -776,6 +792,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -828,6 +845,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -864,6 +882,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
assert.ok(false, 'Reposition is invoked exactly once');
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -899,6 +918,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -997,6 +1017,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1041,6 +1062,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1085,6 +1107,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1129,6 +1152,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1175,6 +1199,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1221,6 +1246,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
done();
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1279,6 +1305,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
repositions++;
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1323,6 +1350,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
@@ -1370,6 +1398,7 @@ module('Integration | Component | basic-dropdown-content', function (hooks) {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {
diff --git a/tests/integration/components/trigger-test.gts b/tests/integration/components/trigger-test.gts
index 5da08690..6374be11 100644
--- a/tests/integration/components/trigger-test.gts
+++ b/tests/integration/components/trigger-test.gts
@@ -63,6 +63,7 @@ const dropdownBase: Dropdown = {
reposition: () => {
return undefined;
},
+ updatePublicApi: () => {},
registerTriggerElement: () => {},
registerDropdownElement: () => {},
getTriggerElement: () => {