ib-grid
Version:
A powerful and flexible data grid component for Angular applications with full support for Persian language and RTL layout
655 lines (579 loc) • 16.3 kB
Markdown
# iB Grid
A powerful and flexible data grid component for **Angular** applications with full support for Persian language and RTL layout.
[](https://badge.fury.io/js/ib-grid)
[](https://opensource.org/licenses/MIT)
## Features
- ✅ **Advanced Search & Filtering** - Search across different columns
- ✅ **Sorting** - Single and multiple column sorting
- ✅ **Pagination** - Customizable pagination settings
- ✅ **Row Selection** - Single and multiple row selection
- ✅ **Data Export** - Export to Excel, CSV, and PDF
- ✅ **Custom Buttons** - Header and row action buttons
- ✅ **Sticky Columns** - Pin columns to left or right
- ✅ **Customizable Themes** - Full appearance customization
- ✅ **RTL Support** - Perfect for Persian/Arabic languages
- ✅ **Drag & Drop** - Reorder columns by dragging
- ✅ **Various Data Types** - Text, image, date, currency, status, etc.
- ✅ **Responsive Design** - Mobile-friendly grid layout
- ✅ **Column Visibility** - Show/hide columns dynamically
## Installation
```bash
npm install ib-grid
```
## Dependencies
This package requires Angular and the following peer dependencies:
```bash
npm install tailwindcss /postcss postcss --force
```
## Getting Started
### 1. Import Module
```typescript
import { ibGridModule } from 'ib-grid';
export class AppModule { }
```
### 2. Component Usage
```typescript
import { Component } from '@angular/core';
import { iBGridModel } from 'ib-grid';
export class UsersComponent {
gridConfigs: iBGridModel = {
// Grid configuration
};
// Data management methods
}
```
## Configuration
### Basic Grid Setup
```typescript
const gridConfigs: iBGridModel = {
title: "Users List",
columns: [], // Grid columns
buttons: [], // Header buttons
rowButtons: [], // Row action buttons
options: {}, // Grid options
theme: {}, // Theme settings
pagination: {} // Pagination settings
};
```
### Column Definition
```typescript
columns: [
{
key: "Id",
label: "ID",
type: "text",
width: '10%',
alignment: "center",
sortable: true,
searchable: true,
sticky: 'left' // Pin to left
},
{
key: "Name",
label: "Name",
type: "text",
width: '200px',
minWidth: '150px',
maxWidth: '300px',
alignment: "left",
wrap: true
},
{
key: "Status",
label: "Status",
type: "status",
alignment: "center"
},
{
key: "BirthDate",
label: "Birth Date",
type: "date",
format: "YYYY/MM/DD"
}
]
```
### Column Types
| Type | Description |
|------|-------------|
| `text` | Plain text |
| `image` | Image display |
| `text-image` | Text with image |
| `date` | Date formatting |
| `currency` | Currency formatting |
| `boolean` | Boolean values |
| `status` | Status badges |
| `rate` | Rating display |
| `progress` | Progress bar |
| `actions` | Action buttons |
### Header Buttons
```typescript
buttons: [
{
title: "Add New User",
route: "/users/create",
isShow: true,
showType: 'iconText',
color: 'bg-blue-500',
hoverColor: 'bg-blue-600',
class: "text-white",
icon: "plus",
tooltip: "Create new user"
},
{
title: "Export Data",
isShow: true,
showType: 'icon',
color: 'bg-green-500',
hoverColor: 'bg-green-600',
class: "text-white",
icon: "download",
onClick: () => this.exportData()
}
]
```
### Row Action Buttons
```typescript
rowButtons: [
{
title: "Edit",
route: "/users/edit",
isShow: true,
showType: 'iconText',
color: 'bg-yellow-500',
hoverColor: 'bg-yellow-600',
class: "text-white text-xs px-2 py-1",
icon: "edit",
conditions: "row.status === 'active'" // Conditional display
},
{
title: "Delete",
isShow: true,
showType: 'icon',
color: 'bg-red-500',
hoverColor: 'bg-red-600',
class: "text-white text-xs px-2 py-1",
icon: "trash",
onClick: () => this.deleteUser(),
disabled: (row) => row.status === 'deleted'
}
]
```
### Grid Options
```typescript
options: {
isDragDrop: true, // Column reordering
isRTL: true, // Right-to-left layout
isSort: true, // Enable sorting
isFillter: true, // Enable search/filter
isSelect: true, // Row selection
isPaging: true, // Pagination
isExport: true, // Data export
isColumnsSelectable: true, // Column visibility
showRowNumbers: true, // Row numbering
multiSort: true // Multiple column sorting
}
```
### Theme Customization
```typescript
theme: {
baseColor: "#3b82f6",
secondColor: "#1e40af",
headerBackgroundColor: "#f8fafc",
headerTextColor: "#374151",
rowHoverColor: "#f9fafb",
borderColor: "#e5e7eb"
}
```
### Pagination Settings
```typescript
pagination: {
titleOfShowCountShowRow: "Show",
activePageColor: "#3b82f6",
sumTitle: "Total",
sumResultTitle: "Records",
paginingAlign: "center",
totalAlign: "left",
showPageSize: true,
pageSizeOptions: [5, 10, 20, 50, 100],
showFirstLast: true,
showPageInfo: true,
maxPagesShown: 5
}
```
## Event Handling
### Component Event Methods
```typescript
export class UsersComponent {
// Search handling
handleSearch(searchCriteria: IGridSearchModel[]) {
console.log('Search:', searchCriteria);
// Implement search logic
}
// Sort handling
handleSort(sortCriteria: IGridSortModel[]) {
console.log('Sort:', sortCriteria);
// Implement sort logic
}
// Page change
handlePageChange(page: number) {
console.log('Page changed:', page);
// Load new page data
}
// Page size change
handlePageSizeChange(pageSize: number) {
console.log('Page size changed:', pageSize);
// Update page size
}
// Row selection
handleRowSelect(selectedRows: any[]) {
console.log('Selected rows:', selectedRows);
// Handle selected rows
}
// Column changes
handleColumnsChange(columns: IGridColumnModel[]) {
console.log('Columns changed:', columns);
// Update column configuration
}
}
```
## Complete Example
```typescript
import { Component, signal } from '@angular/core';
import { iBGridModel, IGridSearchModel, IGridSortModel } from 'ib-grid';
export class UsersComponent {
gridData = signal([
{ Id: 1, FirstName: 'John', LastName: 'Doe', Email: 'john@example.com', Status: 'Active' },
{ Id: 2, FirstName: 'Jane', LastName: 'Smith', Email: 'jane@example.com', Status: 'Inactive' }
]);
totalCount = signal(100);
currentPage = signal(1);
pageSize = signal(10);
loading = signal(false);
currentFilters = signal([]);
gridConfigs: iBGridModel = {
title: "Users Management",
columns: [
{
key: "Id",
label: "ID",
type: "text",
width: '80px',
alignment: "center",
sortable: true,
searchable: true,
sticky: 'left'
},
{
key: "FirstName",
label: "First Name",
type: "text",
width: '150px',
alignment: "left",
sortable: true,
searchable: true
},
{
key: "LastName",
label: "Last Name",
type: "text",
width: '150px',
alignment: "left",
sortable: true,
searchable: true
},
{
key: "Email",
label: "Email",
type: "text",
width: '200px',
alignment: "left",
sortable: true,
searchable: true
},
{
key: "Status",
label: "Status",
type: "status",
width: '100px',
alignment: "center",
sortable: true,
searchable: true
}
],
buttons: [
{
title: "Add User",
route: "/users/create",
isShow: true,
showType: 'iconText',
color: 'bg-blue-500',
hoverColor: 'bg-blue-600',
class: "text-white px-4 py-2 rounded",
icon: "plus"
},
{
title: "Export Excel",
isShow: true,
showType: 'iconText',
color: 'bg-green-500',
hoverColor: 'bg-green-600',
class: "text-white px-4 py-2 rounded",
icon: "download",
onClick: () => this.exportData()
}
],
rowButtons: [
{
title: "Edit",
route: "/users/edit",
isShow: true,
showType: 'icon',
color: 'bg-yellow-500',
hoverColor: 'bg-yellow-600',
class: "text-white text-xs px-2 py-1 rounded",
icon: "edit"
},
{
title: "Delete",
isShow: true,
showType: 'icon',
color: 'bg-red-500',
hoverColor: 'bg-red-600',
class: "text-white text-xs px-2 py-1 rounded",
icon: "trash",
onClick: () => this.deleteUser()
},
{
title: "View",
route: "/users/details",
isShow: true,
showType: 'icon',
color: 'bg-blue-500',
hoverColor: 'bg-blue-600',
class: "text-white text-xs px-2 py-1 rounded",
icon: "eye"
}
],
options: {
isDragDrop: true,
isRTL: false, // Set to true for RTL languages
isSort: true,
isFillter: true,
isSelect: true,
isPaging: true,
isExport: true,
isColumnsSelectable: true,
showRowNumbers: true,
multiSort: true
},
theme: {
baseColor: "#3b82f6",
secondColor: "#1e40af",
headerBackgroundColor: "#f8fafc",
headerTextColor: "#374151",
rowHoverColor: "#f9fafb",
borderColor: "#e5e7eb"
},
pagination: {
titleOfShowCountShowRow: "Show",
activePageColor: "#3b82f6",
sumTitle: "Total",
sumResultTitle: "Records",
paginingAlign: "center",
totalAlign: "right",
showPageSize: true,
pageSizeOptions: [5, 10, 20, 50, 100],
showFirstLast: true,
showPageInfo: true,
maxPagesShown: 5
}
};
handleSearch(searchCriteria: IGridSearchModel[]) {
console.log('Search criteria:', searchCriteria);
// Implement your search logic here
this.loadData();
}
handleSort(sortCriteria: IGridSortModel[]) {
console.log('Sort criteria:', sortCriteria);
// Implement your sort logic here
this.loadData();
}
handlePageChange(page: number) {
this.currentPage.set(page);
this.loadData();
}
handlePageSizeChange(pageSize: number) {
this.pageSize.set(pageSize);
this.currentPage.set(1);
this.loadData();
}
handleRowSelect(selectedRows: any[]) {
console.log('Selected rows:', selectedRows);
}
handleColumnsChange(columns: any[]) {
console.log('Columns changed:', columns);
}
exportData() {
// Implement export functionality
console.log('Exporting data...');
}
deleteUser() {
// Implement delete functionality
console.log('Deleting user...');
}
private loadData() {
this.loading.set(true);
// Simulate API call
setTimeout(() => {
// Update gridData, totalCount, etc.
this.loading.set(false);
}, 1000);
}
}
```
## Input Properties
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `configs` | `iBGridModel` | - | Grid configuration object |
| `data` | `any[]` | `[]` | Grid data array |
| `totalCount` | `number` | `0` | Total number of records |
| `currentPage` | `number` | `1` | Current page number |
| `pageSize` | `number` | `10` | Number of records per page |
| `loading` | `boolean` | `false` | Loading state |
| `currentFilters` | `IGridSearchModel[]` | `[]` | Current applied filters |
## Output Events
| Event | Type | Description |
|-------|------|-------------|
| `onSearch` | `IGridSearchModel[]` | Fired when search is performed |
| `onSort` | `IGridSortModel[]` | Fired when sorting changes |
| `onPageChange` | `number` | Fired when page changes |
| `onPageSizeChange` | `number` | Fired when page size changes |
| `onColumnsChange` | `IGridColumnModel[]` | Fired when columns are reordered |
| `onRowSelect` | `any[]` | Fired when rows are selected |
| `onRowClick` | `{row: any, index: number}` | Fired when row is clicked |
| `onRowDoubleClick` | `{row: any, index: number}` | Fired when row is double-clicked |
| `onCellClick` | `{value: any, row: any, column: IGridColumnModel}` | Fired when cell is clicked |
## API Reference
### Interfaces
#### iBGridModel
```typescript
interface iBGridModel {
title: string;
columns: IGridColumnModel[];
buttons: IGridButtonsModel[];
rowButtons: IGridButtonsModel[];
options: iBGridOptionsModel;
theme: iBGridThemeModel;
pagination?: IPagingGridModel;
}
```
#### IGridColumnModel
```typescript
interface IGridColumnModel {
key: string;
label: string;
align?: string;
direction?: 'ltr' | 'rtl';
type?: 'text' | 'image' | 'text-image' | 'rate' | 'progress' | 'status' | 'date' | 'currency' | 'boolean' | 'actions';
sortable?: boolean;
searchable?: boolean;
format?: string;
width?: string | number;
minWidth?: string | number;
maxWidth?: string | number;
sticky?: 'left' | 'right';
alignment?: 'left' | 'center' | 'right';
wrap?: boolean;
render?: (value: any, row: any) => string;
}
```
#### IGridButtonsModel
```typescript
interface IGridButtonsModel {
title: string;
route?: string;
color: string;
showType: 'image' | 'text' | 'icon' | 'imageText' | 'iconText';
hoverColor: string;
isShow: boolean;
class: string;
conditions?: string;
icon?: string;
onClick?: () => void;
disabled?: boolean | (() => boolean);
tooltip?: string;
}
```
#### iBGridOptionsModel
```typescript
interface iBGridOptionsModel {
isDragDrop: boolean;
isRTL: boolean;
isSort: boolean;
isFillter: boolean;
isSelect: boolean;
isPaging: boolean;
isExport: boolean;
isColumnsSelectable: boolean;
showRowNumbers?: boolean;
multiSort?: boolean;
}
```
## Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
If you encounter any issues or have questions, please:
1. To report bugs or request new features, please send an email to
ibteams2000@gmail.com
2. Create a new issue if needed
Made with ❤️ for the Angular community