Skip to content

Commit

Permalink
fix(atomic): don't redirect when hovering a instant result & pressing…
Browse files Browse the repository at this point in the history
… Enter (#4938)

https://coveord.atlassian.net/browse/KIT-3910

We now have a new variable in suggestions-manager that tracks they
keyboard use. When someone press Enter when having a
suggestion/result/recent query selected with the keyboard, it will
trigger it's onClick event.
Whenever we stop using the keyboard and using the mouse it resets again
which will make the Enter event trigger the query in the search box
instead.
 
 I added a lot of tests to write in vitest.
  • Loading branch information
alexprudhomme authored Feb 12, 2025
1 parent 15308ec commit eea90a2
Show file tree
Hide file tree
Showing 15 changed files with 188 additions and 13 deletions.
10 changes: 10 additions & 0 deletions packages/atomic/scripts/dev.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ startServers();

// Watch the src folder for changes
watch('src', {recursive: true}, async (_, filename) => {
// Ignore irrelevant files
if (
filename.endsWith('.mdx') ||
filename.endsWith('.new.stories.tsx') ||
filename.endsWith('.spec.ts') ||
filename.includes('e2e')
) {
return;
}

// Stop all processes if a file changes to prevent multiple builds at once
await stopAllProcesses();
console.log(chalk.cyanBright(`📂 File changed: ${filename}`));
Expand Down
4 changes: 3 additions & 1 deletion packages/atomic/scripts/generate-component.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ async function generateFiles(name, outputDir) {
);
const resolvedOutputDir = path.resolve(outputDir);
const namePascalCase = kebabToPascal(name);
const shorterName = name.replace(/^atomic-/, '').toLowerCase();
const shorterName = namePascalCase
.replace(/^Atomic/, '')
.replace(/^./, (c) => c.toLowerCase());

const files = [
{template: 'component.ts.hbs', output: `${name}.ts`},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
//https://coveord.atlassian.net/browse/KIT-3955
describe('AtomicCommerceSearchBox', () => {
describe('with instant products & suggestions', () => {
describe('when using keyboard navigation', () => {
test('should be able to navigate from the suggestions to the instant results and vice-versa', async () => {});
test('should execute the search after pressing "Enter" on a suggestion', async () => {});
test('should redirect to the result page after pressing "Enter" on an instant result', async () => {});
});

describe('when typing and then hovering a suggestion', () => {
test('should execute the search reflected in the search box', () => {});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,7 @@ export class AtomicCommerceSearchBox

private onSubmit() {
this.isExpanded = false;
if (
this.suggestionManager.isRightPanelInFocus() ||
this.suggestionManager.activeDescendantElement?.part.contains(
'recent-query-title-item'
)
) {
if (this.suggestionManager.keyboardActiveDescendant) {
this.suggestionManager.onSubmit();
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ test.describe('with instant results & query suggestions', () => {
});
});
});

test.describe('when hovering a instant result and pressing Enter', () => {
test('should execute the query in the search box', async ({searchBox}) => {
await searchBox.searchInput.click();
await searchBox.searchInput.fill('a');
await searchBox.instantResult({listSide: 'Right'}).first().hover();
await searchBox.searchInput.press('Enter');
await expect(searchBox.searchInput).toHaveValue('a');
});
});
});

test.describe('with disable-search=true and minimum-query-length=1', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
//https://coveord.atlassian.net/browse/KIT-3957
describe('AtomicCommerceSearchBoxInstantProducts', () => {
describe('when clicking', () => {
test('on a instant product, it should redirect to the product page', async () => {});
test('on the "See all products" button, it should execute the proper search', async () => {});
});

describe('when using keyboard navigation', () => {
test('on instant products, it should redirect to the product page', async () => {});
test('on the "See all products" button, it should execute the proper search', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new product', () => {
test('it should execute the search reflected in the search box', () => {});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
//https://coveord.atlassian.net/browse/KIT-3956
describe('AtomicCommerceSearchBoxQuerySuggestions', () => {
describe('when clicking', () => {
test('it should execute the proper search', async () => {});
});

describe('when using keyboard navigation', () => {
test('it should reflect the proper suggestion in the search box', async () => {});
test('it should execute the proper search after pressing "Enter"', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new suggestion', () => {
test('it should execute the search reflected in the search box', () => {});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
//https://coveord.atlassian.net/browse/KIT-3958
describe('AtomicCommerceSearchBoxRecentQueries', () => {
describe('when clicking', () => {
test('on a recent query, it should execute the proper search', async () => {});
test('on the "Clear" button, it should clear the recent queries', async () => {});
});

describe('when using keyboard navigation', () => {
test('on recent queries, it should reflect the proper query in the search box', async () => {});
test('on recent queries, it should execute the proper search', async () => {});
test('on the "Clear" button, it should clear the recent queries ', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new recent query', () => {
test('it should execute the search reflected in the search box', () => {});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class SuggestionManager<SearchBoxController> {
public triggerSuggestions: () => Promise<void>;
public activeDescendant = '';
public suggestedQuery = '';
public keyboardActiveDescendant = '';

private queryDataAttribute = 'data-query';
private suggestionEvents: SearchBoxSuggestionsEvent<SearchBoxController>[] =
Expand Down Expand Up @@ -114,6 +115,10 @@ export class SuggestionManager<SearchBoxController> {
forceUpdate(this.ownerSearchBoxProps.getHost());
}

public updateKeyboardActiveDescendant(id = '') {
this.keyboardActiveDescendant = id;
}

public clickOnActiveElement() {
this.activeDescendantElement?.click();
this.updateActiveDescendant();
Expand Down Expand Up @@ -187,6 +192,7 @@ export class SuggestionManager<SearchBoxController> {
}

public focusValue(value: HTMLElement) {
this.updateKeyboardActiveDescendant(value.id);
this.updateActiveDescendant(value.id);
this.scrollActiveDescendantIntoView();
this.updateQueryFromSuggestion();
Expand All @@ -198,6 +204,8 @@ export class SuggestionManager<SearchBoxController> {
id: string
) {
const thisPanel = side === 'left' ? this.leftPanel : this.rightPanel;
// When hovering, always reset the keyboard active descendant
this.updateKeyboardActiveDescendant();
if (this.panelInFocus === thisPanel) {
this.updateActiveDescendant(id);
} else {
Expand Down Expand Up @@ -226,6 +234,7 @@ export class SuggestionManager<SearchBoxController> {

public focusPreviousValue() {
if (this.firstValue === this.activeDescendantElement) {
this.updateKeyboardActiveDescendant();
this.updateActiveDescendant();
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
describe('AtomicSearchBox', () => {
describe('with instant results & suggestions', () => {
describe('when using keyboard navigation', () => {
test('should be able to navigate from the suggestions to the instant results and vice-versa', async () => {});
test('should execute the search after pressing "Enter" on a suggestion', async () => {});
test('should redirect to the result page after pressing "Enter" on an instant result', async () => {});
});

describe('when typing and then hovering a suggestion', () => {
test('should execute the search reflected in the search box', () => {});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,7 @@ export class AtomicSearchBox implements InitializableComponent<Bindings> {

private onSubmit() {
this.isExpanded = false;
if (
this.suggestionManager.isRightPanelInFocus() ||
this.suggestionManager.activeDescendantElement?.part.contains(
'recent-query-title-item'
)
) {
if (this.suggestionManager.keyboardActiveDescendant) {
this.suggestionManager.onSubmit();
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ test.describe('with instant results & query suggestions', () => {
});
});
});

test.describe('when hovering a instant result and pressing Enter', () => {
test('should execute the query in the search box', async ({searchBox}) => {
await searchBox.searchInput.click();
await searchBox.searchInput.fill('a');
await searchBox.instantResult({listSide: 'Right'}).first().hover();
await searchBox.searchInput.press('Enter');
await expect(searchBox.searchInput).toHaveValue('a');
});
});
});

test.describe('with disable-search=true and minimum-query-length=1', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
describe('AtomicSearchBoxInstantResults', () => {
describe('when clicking', () => {
test('on a instant result, it should redirect to the result page', async () => {});
test('on the "See all results" button, it should execute the proper search', async () => {});
});

describe('when using keyboard navigation', () => {
test('on instant results, it should redirect to the result page', async () => {});
test('on the "See all results" button, it should execute the proper search', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new result', () => {
test('it should execute the search reflected in the search box', () => {});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
describe('AtomicSearchBoxQuerySuggestions', () => {
describe('when clicking', () => {
test('it should execute the proper search', async () => {});
});

describe('when using keyboard navigation', () => {
test('it should reflect the proper suggestion in the search box', async () => {});
test('it should execute the proper search after pressing "Enter"', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new suggestion', () => {
test('it should execute the search reflected in the search box', () => {});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {describe, test} from 'vitest';

//TODO: Write those tests during the lit migration
describe('AtomicSearchBoxRecentQueries', () => {
describe('when clicking', () => {
test('on a recent query, it should execute the proper search', async () => {});
test('on the "Clear" button, it should clear the recent queries', async () => {});
});

describe('when using keyboard navigation', () => {
test('on recent queries, it should reflect the proper query in the search box', async () => {});
test('on recent queries, it should execute the proper search', async () => {});
test('on the "Clear" button, it should clear the recent queries ', async () => {});
});

describe('when using keyboard navigation and then switching to mouse and hovering a new recent query', () => {
test('it should execute the search reflected in the search box', () => {});
});
});

0 comments on commit eea90a2

Please sign in to comment.