Skip to content

Commit 47d1b97

Browse files
fix(atomic): prevent facets from closing when active values are selected (#6208)
1 parent eace955 commit 47d1b97

File tree

2 files changed

+125
-12
lines changed

2 files changed

+125
-12
lines changed

packages/atomic/src/components/commerce/atomic-commerce-facets/atomic-commerce-facets.spec.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,110 @@ describe('atomic-commerce-facets', () => {
371371
expect(categoryFacet).not.toBeInTheDocument();
372372
expect(timeframeFacet).not.toBeInTheDocument();
373373
});
374+
375+
describe('#shouldCollapseFacet', () => {
376+
it('should not collapse facets with active values even when exceeding collapseFacetsAfter', async () => {
377+
mockedRegularFacet = buildFakeRegularFacet({
378+
state: {
379+
displayName: 'Regular Facet',
380+
hasActiveValues: true,
381+
},
382+
});
383+
mockedNumericFacet = buildFakeNumericFacet({
384+
state: {
385+
displayName: 'Numeric Facet',
386+
hasActiveValues: false,
387+
},
388+
});
389+
mockedCategoryFacet = buildFakeCategoryFacet({
390+
state: {
391+
displayName: 'Category Facet',
392+
hasActiveValues: true,
393+
},
394+
});
395+
mockedDateFacet = buildFakeDateFacet({
396+
state: {
397+
displayName: 'Date Facet',
398+
hasActiveValues: false,
399+
},
400+
});
401+
402+
mockedFacetGenerator = buildFakeFacetGenerator({
403+
state: [
404+
mockedRegularFacet,
405+
mockedNumericFacet,
406+
mockedCategoryFacet,
407+
mockedDateFacet,
408+
].map((facet) => facet.state.facetId),
409+
implementation: {
410+
facets: [
411+
mockedRegularFacet,
412+
mockedNumericFacet,
413+
mockedCategoryFacet,
414+
mockedDateFacet,
415+
],
416+
},
417+
});
418+
419+
const {header} = await renderCommerceFacets({
420+
collapseFacetsAfter: 2,
421+
isAppLoaded: true,
422+
});
423+
424+
// First facet has active values, should stay expanded
425+
await expect
426+
.element(header('Regular Facet'))
427+
.toHaveAttribute('aria-expanded', 'true');
428+
// Second facet has no active values, should stay expanded (within limit)
429+
await expect
430+
.element(header('Numeric Facet'))
431+
.toHaveAttribute('aria-expanded', 'true');
432+
// Third facet has active values, should stay expanded even though it exceeds the limit
433+
await expect
434+
.element(header('Category Facet'))
435+
.toHaveAttribute('aria-expanded', 'true');
436+
// Fourth facet has no active values and exceeds limit, should collapse
437+
await expect
438+
.element(header('Date Facet'))
439+
.toHaveAttribute('aria-expanded', 'false');
440+
});
441+
442+
it('should keep all facets with active values expanded when collapseFacetsAfter is 0', async () => {
443+
mockedRegularFacet = buildFakeRegularFacet({
444+
state: {
445+
displayName: 'Regular Facet',
446+
hasActiveValues: true,
447+
},
448+
});
449+
mockedNumericFacet = buildFakeNumericFacet({
450+
state: {
451+
displayName: 'Numeric Facet',
452+
hasActiveValues: false,
453+
},
454+
});
455+
456+
mockedFacetGenerator = buildFakeFacetGenerator({
457+
state: [mockedRegularFacet, mockedNumericFacet].map(
458+
(facet) => facet.state.facetId
459+
),
460+
implementation: {
461+
facets: [mockedRegularFacet, mockedNumericFacet],
462+
},
463+
});
464+
465+
const {header} = await renderCommerceFacets({
466+
collapseFacetsAfter: 0,
467+
isAppLoaded: true,
468+
});
469+
470+
// Facet with active values should stay expanded even when collapseFacetsAfter is 0
471+
await expect
472+
.element(header('Regular Facet'))
473+
.toHaveAttribute('aria-expanded', 'true');
474+
// Facet without active values should collapse
475+
await expect
476+
.element(header('Numeric Facet'))
477+
.toHaveAttribute('aria-expanded', 'false');
478+
});
479+
});
374480
});

packages/atomic/src/components/commerce/atomic-commerce-facets/atomic-commerce-facets.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import '../atomic-commerce-facet/atomic-commerce-facet';
2828
import type {CommerceBindings} from '../atomic-commerce-interface/atomic-commerce-interface';
2929
import '../atomic-commerce-numeric-facet/atomic-commerce-numeric-facet';
3030
import '../atomic-commerce-timeframe-facet/atomic-commerce-timeframe-facet';
31+
import type {
32+
FacetType,
33+
MappedGeneratedFacetController,
34+
} from '@coveo/headless/commerce';
3135
import {keyed} from 'lit/directives/keyed.js';
3236
import {bindStateToController} from '@/src/decorators/bind-state';
3337
import {LightDomMixin} from '@/src/mixins/light-dom';
@@ -92,8 +96,11 @@ export class AtomicCommerceFacets
9296
});
9397
}
9498

95-
private shouldCollapseFacet(index: number): boolean {
96-
if (this.collapseFacetsAfter === -1) {
99+
private shouldCollapseFacet(
100+
index: number,
101+
facet: MappedGeneratedFacetController[FacetType]
102+
): boolean {
103+
if (this.collapseFacetsAfter === -1 || facet.state.hasActiveValues) {
97104
return false;
98105
}
99106
return this.collapseFacetsAfter
@@ -106,8 +113,8 @@ export class AtomicCommerceFacets
106113
Array.from({length: this.collapseFacetsAfter}),
107114
() =>
108115
html`<atomic-facet-placeholder
109-
value-count="8"
110-
></atomic-facet-placeholder>`
116+
value-count="8"
117+
></atomic-facet-placeholder>`
111118
);
112119
}
113120

@@ -117,20 +124,20 @@ export class AtomicCommerceFacets
117124
return nothing;
118125
}
119126

120-
const isCollapsed = this.shouldCollapseFacet(index);
127+
const isCollapsed = this.shouldCollapseFacet(index, facet);
121128

122129
switch (facet.state.type) {
123130
case 'regular':
124131
return html`${keyed(
125132
facet.state.facetId,
126133
html`
127-
<atomic-commerce-facet
128-
.isCollapsed=${isCollapsed}
129-
.summary=${this.summary}
130-
.facet=${facet as RegularFacet}
131-
.field=${facet.state.field}
132-
></atomic-commerce-facet>
133-
`
134+
<atomic-commerce-facet
135+
.isCollapsed=${isCollapsed}
136+
.summary=${this.summary}
137+
.facet=${facet as RegularFacet}
138+
.field=${facet.state.field}
139+
></atomic-commerce-facet>
140+
`
134141
)} `;
135142
case 'numericalRange':
136143
return html`${keyed(

0 commit comments

Comments
 (0)