Skip to content

Commit 28a86be

Browse files
committed
chore: updated the strategy to include the dependency controller
1 parent 73473ab commit 28a86be

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

packages/picker/src/InteractionController.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ export class InteractionController implements ReactiveController {
4646
* Set `open`
4747
*/
4848
public set open(open: boolean) {
49+
if (this._open === open) return;
4950
this._open = open;
5051
if (this.overlay) {
5152
// If there already is an Overlay, apply the value of `open` directly.
52-
this.overlay.open = open;
53+
if (this.host.dependencyManager.loaded) {
54+
this.overlay.open = open;
55+
}
5356
this.host.open = open;
5457
return;
5558
}
@@ -68,7 +71,10 @@ export class InteractionController implements ReactiveController {
6871
'@spectrum-web-components/overlay/src/Overlay.js'
6972
);
7073
this.overlay = new Overlay();
71-
this.overlay.open = true;
74+
this.host.requestUpdate();
75+
if (this.host.dependencyManager.loaded) {
76+
this.overlay.open = open;
77+
}
7278
this.host.open = true;
7379
});
7480
import('@spectrum-web-components/overlay/sp-overlay.js');
@@ -95,6 +101,7 @@ export class InteractionController implements ReactiveController {
95101
) {
96102
this.target = target;
97103
this.host = host;
104+
this.host.addController(this);
98105
this.init();
99106
}
100107

@@ -175,4 +182,14 @@ export class InteractionController implements ReactiveController {
175182
hostDisconnected(): void {
176183
this.abortController?.abort();
177184
}
185+
186+
public hostUpdated(): void {
187+
if (
188+
this.overlay &&
189+
this.host.dependencyManager.loaded &&
190+
this.host.open
191+
) {
192+
this.overlay.open = true;
193+
}
194+
}
178195
}

packages/picker/src/Picker.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,15 @@ export const DESCRIPTION_ID = 'option-picker';
7171
export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
7272
public isMobile = new MatchMediaController(this, IS_MOBILE);
7373

74-
public strategy?: DesktopController | MobileController;
74+
public strategy!: DesktopController | MobileController;
7575

7676
@state()
7777
appliedLabel?: string;
7878

7979
@query('#button')
8080
public button!: HTMLButtonElement;
8181

82-
private dependencyManager = new DependencyManagerController(this);
82+
public dependencyManager = new DependencyManagerController(this);
8383

8484
private deprecatedMenu: Menu | null = null;
8585

@@ -217,6 +217,7 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
217217
} else {
218218
// Non-cancelable "change" events announce a selection with no value
219219
// change that should close the Picker element.
220+
this.open = false;
220221
if (this.strategy) {
221222
this.strategy.open = false;
222223
}
@@ -249,6 +250,7 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
249250
item: MenuItem,
250251
menuChangeEvent?: Event
251252
): Promise<void> {
253+
this.open = false;
252254
// should always close when "setting" a value
253255
if (this.strategy) {
254256
this.strategy.open = false;
@@ -278,6 +280,7 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
278280
}
279281
this.selectedItem = oldSelectedItem;
280282
this.value = oldValue;
283+
this.open = true;
281284
if (this.strategy) {
282285
this.strategy.open = true;
283286
}
@@ -304,9 +307,9 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
304307
if (this.readonly || this.pending) {
305308
return;
306309
}
310+
this.open = typeof target !== 'undefined' ? target : !this.open;
307311
if (this.strategy) {
308-
this.strategy.open =
309-
typeof target !== 'undefined' ? target : !this.open;
312+
this.strategy.open = this.open;
310313
}
311314
}
312315

@@ -315,6 +318,7 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
315318
return;
316319
}
317320
if (this.strategy) {
321+
this.open = false;
318322
this.strategy.open = false;
319323
}
320324
}
@@ -456,6 +460,9 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
456460
};
457461

458462
protected renderOverlay(menu: TemplateResult): TemplateResult {
463+
if (this.strategy?.overlay === undefined) {
464+
return menu;
465+
}
459466
const container = this.renderContainer(menu);
460467
render(container, this.strategy?.overlay as unknown as HTMLElement, {
461468
host: this,
@@ -517,11 +524,13 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
517524
}
518525
if (changes.has('disabled') && this.disabled) {
519526
if (this.strategy) {
527+
this.open = false;
520528
this.strategy.open = false;
521529
}
522530
}
523531
if (changes.has('pending') && this.pending) {
524532
if (this.strategy) {
533+
this.open = false;
525534
this.strategy.open = false;
526535
}
527536
}
@@ -580,6 +589,13 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
580589
this.button.addEventListener('keydown', this.handleKeydown);
581590
}
582591

592+
protected override updated(changes: PropertyValues<this>): void {
593+
super.updated(changes);
594+
if (changes.has('open')) {
595+
this.strategy.open = this.open;
596+
}
597+
}
598+
583599
protected override firstUpdated(changes: PropertyValues<this>): void {
584600
super.firstUpdated(changes);
585601
this.bindButtonKeydownListener();
@@ -658,6 +674,9 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
658674
this.open ||
659675
!!this.deprecatedMenu;
660676
if (this.hasRenderedOverlay) {
677+
if (this.dependencyManager.loaded) {
678+
this.dependencyManager.add('sp-overlay');
679+
}
661680
return this.renderOverlay(menu);
662681
}
663682
return menu;
@@ -765,7 +784,6 @@ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
765784

766785
protected bindEvents(): void {
767786
this.strategy?.abort();
768-
this.strategy = undefined;
769787
if (this.isMobile.matches) {
770788
this.strategy = new strategies['mobile'](this.button, this);
771789
} else {

packages/picker/test/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ export function runPickerTests(): void {
316316
option2.innerHTML = 'Invert Selection';
317317
await itemUpdated;
318318
await elementUpdated(el);
319+
await aTimeout(150);
319320
expect(el.value).to.equal('option-2');
320321
expect((el.button.textContent || '').trim()).to.include(
321322
'Invert Selection'
@@ -619,6 +620,8 @@ export function runPickerTests(): void {
619620
expect(el.value).to.equal(thirdItem.value);
620621
});
621622
it('opens/closes multiple times', async () => {
623+
await nextFrame();
624+
await nextFrame();
622625
expect(el.open).to.be.false;
623626
const boundingRect = el.button.getBoundingClientRect();
624627
let opened = oneEvent(el, 'sp-opened');

0 commit comments

Comments
 (0)