Even though this particular question may be perceived as a duplicate of another, I believe there is value in providing an alternative answer that focuses on improving category handling from a UI/UX perspective.
The proposed solution involves utilizing the Ionic slider component to display categories, with each slide showcasing up to 3 different categories.
Visual Representation:
To implement this design, a toolbar containing a row needs to be added. Within this row, three columns should be included - one for the left arrow, one for the slider itself, and one for the right arrow. It's important to note the usage of slidesPerView="3"
property in the ion-slides
element.
<ion-header>
<ion-navbar color="primary">
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>App Name</ion-title>
</ion-navbar>
<ion-toolbar>
<ion-row class="filters">
<ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1>
<ion-icon *ngIf="showLeftButton" name="arrow-back"></ion-icon>
</ion-col>
<ion-col no-padding col-10>
<ion-slides (ionSlideDidChange)="slideChanged()" slidesPerView="3">
<ion-slide (click)="filterData(category.id)" *ngFor="let category of categories">
<p [class.selected]="selectedCategory?.id === category.id">{{ category.name }}</p>
</ion-slide>
</ion-slides>
</ion-col>
<ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1>
<ion-icon *ngIf="showRightButton" name="arrow-forward"></ion-icon>
</ion-col>
</ion-row>
</ion-toolbar>
</ion-header>
Component Logic:
Additional functionality involves managing category selection and responding to slide changes:
// Angular
import { Component, Injector, ViewChild } from '@angular/core';
// Ionic
import { IonicPage, Slides } from 'ionic-angular';
// Models
import { CategoryModel } from './../../models/category.model';
@Component({ ... })
export class HomePage {
@ViewChild(Slides) slides: Slides;
public selectedCategory: CategoryModel;
public categories: Array<CategoryModel>;
public showLeftButton: boolean;
public showRightButton: boolean;
constructor(public injector: Injector) { ... }
// ...
private initializeCategories(): void {
// Select it by default
this.selectedCategory = this.categories[0];
// Determine display of arrow buttons
this.showLeftButton = false;
this.showRightButton = this.categories.length > 3;
}
public filterData(categoryId: number): void {
// Handle category selection actions
}
// Update buttons visibility when slide changes
public slideChanged(): void {
let currentIndex = this.slides.getActiveIndex();
this.showLeftButton = currentIndex !== 0;
this.showRightButton = currentIndex !== Math.ceil(this.slides.length() / 3);
}
// Navigate to next slide
public slideNext(): void {
this.slides.slideNext();
}
// Navigate to previous slide
public slidePrev(): void {
this.slides.slidePrev();
}
}
CSS Styling:
.filters {
ion-col {
text-align: center;
font-size: 1.6rem;
line-height: 1.6rem;
ion-icon {
color: #ccc;
}
&.col-with-arrow {
display: flex;
justify-content: center;
align-items: center;
}
}
p {
color: #fff;
margin: 0;
font-size: 1.6rem;
line-height: 1.6rem;
}
.selected {
font-weight: 700;
}
}