fix(library): picker choice lost — Obsidian close() precedes onChooseItem, defer dismiss-settle

This commit is contained in:
afiqzudinhadi 2026-08-05 19:11:53 +08:00
parent 1e4567e844
commit 83bf8323e2
2 changed files with 13 additions and 1 deletions

View file

@ -55,7 +55,10 @@ export class CandidatePickerModal extends FuzzySuggestModal<PickerItem> {
}
onClose(): void {
this.settle(null); // dismissed without choosing -> treat as skip
// Obsidian's selectSuggestion() calls close() BEFORE onChooseItem(), so settling here
// synchronously would discard a real choice. Defer one tick: a choice made in the same
// tick settles first and this becomes a no-op; a genuine dismissal settles as skip.
window.setTimeout(() => this.settle(null), 0);
this.contentEl.empty();
}

View file

@ -117,4 +117,13 @@ describe('CandidatePickerModal', () => {
modal.onClose(); // Obsidian calls onClose() after a choice too -- must not clobber the resolved value
expect(await result).toBe(0);
});
test('REAL Obsidian order — close() fires BEFORE onChooseItem: choice still wins over dismiss-skip', async () => {
const modal = new CandidatePickerModal(fakeApp(), 'Some Note.md', CANDIDATES);
const result = modal.pick();
// selectSuggestion() in Obsidian calls close() (→ onClose) first, THEN onChooseItem
modal.onClose();
modal.onChooseItem({ label: 'Foo (2020)', index: 0 }, {} as MouseEvent);
expect(await result).toBe(0);
});
});