feat(carousel): enhance product list layout with adaptive grid and simple vertical options

This commit is contained in:
2026-07-23 13:41:40 -03:00
parent 37bbd65cfe
commit 5d1ed7efa2
3 changed files with 27 additions and 40 deletions

View File

@@ -53,6 +53,8 @@
class="product-list"
[class.product-list--row]="effectiveLayout() === 'row'"
[class.product-list--column]="effectiveLayout() !== 'row'"
[class.product-list--adaptive]="groupLayout() !== 'simple_vertical'"
[class.product-list--simple-vertical]="groupLayout() === 'simple_vertical'"
>
@for (item of itemData(); track item.id; let index = $index) {
<ng-container

View File

@@ -4,39 +4,34 @@
}
.product-list {
--product-list-item-min-width: 16rem;
display: grid;
width: 100%;
gap: 1.5rem;
&--row {
grid-template-columns: minmax(0, 1fr);
.product-list__item {
width: 100%;
}
--product-list-item-min-width: 32rem;
}
&--column {
container-name: product-list;
container-type: inline-size;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: stretch;
&--adaptive {
grid-template-columns: repeat(
auto-fit,
minmax(min(100%, var(--product-list-item-min-width)), 1fr)
);
}
.product-list__item {
flex: 0 0 100%;
max-width: 100%;
}
&--simple-vertical {
grid-template-columns: minmax(0, 1fr);
}
&__item {
width: 100%;
min-width: 0;
height: 100%;
&--carousel {
width: 100%;
min-width: clamp(15rem, 30vw, 18rem);
height: 100%;
}
&--carousel-row {
@@ -45,27 +40,6 @@
}
}
@container product-list (min-width: 544px) {
.product-list--column .product-list__item {
flex-basis: calc((100% - 1.5rem) / 2);
max-width: calc((100% - 1.5rem) / 2);
}
}
@container product-list (min-width: 828px) {
.product-list--column .product-list__item {
flex-basis: calc((100% - 3rem) / 3);
max-width: calc((100% - 3rem) / 3);
}
}
@container product-list (min-width: 1112px) {
.product-list--column .product-list__item {
flex-basis: calc((100% - 4.5rem) / 4);
max-width: calc((100% - 4.5rem) / 4);
}
}
.product-list__paginator {
margin-top: 1.5rem;
}

View File

@@ -79,11 +79,12 @@ describe('ProductListComponent', () => {
};
}
it('renders every row product at full available width', async () => {
it('renders row products in the adaptive grid', async () => {
const fixture = await render('row');
const element = fixture.nativeElement as HTMLElement;
expect(element.querySelector('.product-list--row')).not.toBeNull();
expect(element.querySelector('.product-list--adaptive')).not.toBeNull();
expect(element.querySelectorAll('app-product-row-card')).toHaveLength(2);
expect(element.querySelector('app-product-column-with-image')).toBeNull();
});
@@ -143,9 +144,19 @@ describe('ProductListComponent', () => {
const element = fixture.nativeElement as HTMLElement;
expect(element.querySelectorAll('app-product-row-card')).toHaveLength(2);
expect(element.querySelector('.product-list--adaptive')).not.toBeNull();
expect(element.querySelector('app-paginator')).toBeNull();
});
it('keeps simple vertical groups to one full-width item per row', async () => {
const fixture = await render('column_with_image', items, 'simple_vertical');
const element = fixture.nativeElement as HTMLElement;
expect(element.querySelector('.product-list--simple-vertical')).not.toBeNull();
expect(element.querySelector('.product-list--adaptive')).toBeNull();
expect(element.querySelectorAll('app-product-column-with-image')).toHaveLength(2);
});
it('renders carousel groups with the reusable carousel', async () => {
const fixture = await render('column_with_image', items, 'carousel');
const element = fixture.nativeElement as HTMLElement;