feat(search): case-appropriate disambiguation picker copy (#763)
A 1-item picker now reads "Meintest du …?" (a single direct match auto-selects and never reaches the picker), while ≥2 keeps the "Person auswählen" framing. The prompt lives in a visible, non-truncated panel heading (the trigger span clips at 320px), and the "(auswählen…)" cue is dropped for the 1-item case. DisambiguationPicker takes heading + showCue props; the page derives both from ambiguousPersons.length. New search_disambiguation_did_you_mean key in de/en/es. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,8 @@ const persons: PersonHint[] = [
|
||||
{ id: 'w2', displayName: 'Walter Müller' }
|
||||
];
|
||||
|
||||
const multiProps = { persons, heading: 'Person auswählen', showCue: true };
|
||||
|
||||
function pressEscape() {
|
||||
(document.activeElement as HTMLElement).dispatchEvent(
|
||||
new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
|
||||
@@ -21,7 +23,7 @@ function pressEscape() {
|
||||
|
||||
describe('DisambiguationPicker', () => {
|
||||
it('opens the picker and shows a select option per ambiguous person', async () => {
|
||||
render(DisambiguationPicker, { persons, onSelect: vi.fn() });
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect: vi.fn() });
|
||||
await page.getByRole('button', { name: /Mehrere Personen gefunden/ }).click();
|
||||
await expect
|
||||
.element(page.getByRole('button', { name: 'Walter Raddatz auswählen' }))
|
||||
@@ -32,7 +34,7 @@ describe('DisambiguationPicker', () => {
|
||||
});
|
||||
|
||||
it('moves focus into the picker list on open', async () => {
|
||||
render(DisambiguationPicker, { persons, onSelect: vi.fn() });
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect: vi.fn() });
|
||||
await page.getByRole('button', { name: /Mehrere Personen gefunden/ }).click();
|
||||
await expect
|
||||
.element(page.getByRole('button', { name: 'Walter Raddatz auswählen' }))
|
||||
@@ -40,7 +42,7 @@ describe('DisambiguationPicker', () => {
|
||||
});
|
||||
|
||||
it('returns focus to the trigger when closed with Escape', async () => {
|
||||
render(DisambiguationPicker, { persons, onSelect: vi.fn() });
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect: vi.fn() });
|
||||
const trigger = page.getByRole('button', { name: /Mehrere Personen gefunden/ });
|
||||
await trigger.click();
|
||||
await expect
|
||||
@@ -52,7 +54,7 @@ describe('DisambiguationPicker', () => {
|
||||
|
||||
it('does not call onSelect when dismissed without choosing', async () => {
|
||||
const onSelect = vi.fn();
|
||||
render(DisambiguationPicker, { persons, onSelect });
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect });
|
||||
await page.getByRole('button', { name: /Mehrere Personen gefunden/ }).click();
|
||||
await expect
|
||||
.element(page.getByRole('button', { name: 'Walter Raddatz auswählen' }))
|
||||
@@ -63,9 +65,35 @@ describe('DisambiguationPicker', () => {
|
||||
|
||||
it('calls onSelect with the chosen person', async () => {
|
||||
const onSelect = vi.fn();
|
||||
render(DisambiguationPicker, { persons, onSelect });
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect });
|
||||
await page.getByRole('button', { name: /Mehrere Personen gefunden/ }).click();
|
||||
await page.getByRole('button', { name: 'Walter Müller auswählen' }).click();
|
||||
expect(onSelect).toHaveBeenCalledWith(persons[1]);
|
||||
});
|
||||
|
||||
it('renders the supplied heading as a visible panel heading', async () => {
|
||||
render(DisambiguationPicker, {
|
||||
persons: [{ id: 'c1', displayName: 'Clara Cramer' }],
|
||||
heading: 'Meintest du Clara Cramer?',
|
||||
showCue: false,
|
||||
onSelect: vi.fn()
|
||||
});
|
||||
await page.getByRole('button', { name: /Mehrere Personen gefunden/ }).click();
|
||||
await expect.element(page.getByText('Meintest du Clara Cramer?')).toBeVisible();
|
||||
});
|
||||
|
||||
it('suppresses the cue when showCue is false', async () => {
|
||||
render(DisambiguationPicker, {
|
||||
persons: [{ id: 'c1', displayName: 'Clara Cramer' }],
|
||||
heading: 'Meintest du Clara Cramer?',
|
||||
showCue: false,
|
||||
onSelect: vi.fn()
|
||||
});
|
||||
await expect.element(page.getByText('(auswählen…)')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows the cue when showCue is true', async () => {
|
||||
render(DisambiguationPicker, { ...multiProps, onSelect: vi.fn() });
|
||||
await expect.element(page.getByText('(auswählen…)')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user