UNPKG

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
# iB Grid A powerful and flexible data grid component for **Angular** applications with full support for Persian language and RTL layout. [![npm version](https://badge.fury.io/js/ib-grid.svg)](https://badge.fury.io/js/ib-grid) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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 @tailwindcss/postcss postcss --force ``` ## Getting Started ### 1. Import Module ```typescript import { ibGridModule } from 'ib-grid'; @NgModule({ imports: [ ibGridModule ], }) export class AppModule { } ``` ### 2. Component Usage ```typescript import { Component } from '@angular/core'; import { iBGridModel } from 'ib-grid'; @Component({ selector: 'app-users', template: ` <app-ibgrid [configs]="gridConfigs" [data]="gridData()" [totalCount]="totalCount()" [currentPage]="currentPage()" [pageSize]="pageSize()" [loading]="loading()" [currentFilters]="currentFilters()" (onSearch)="handleSearch($event)" (onSort)="handleSort($event)" (onPageChange)="handlePageChange($event)" (onPageSizeChange)="handlePageSizeChange($event)" (onColumnsChange)="handleColumnsChange($event)" (onRowSelect)="handleRowSelect($event)"> </app-ibgrid> ` }) 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'; @Component({ selector: 'app-users', template: ` <app-ibgrid [configs]="gridConfigs" [data]="gridData()" [totalCount]="totalCount()" [currentPage]="currentPage()" [pageSize]="pageSize()" [loading]="loading()" [currentFilters]="currentFilters()" (onSearch)="handleSearch($event)" (onSort)="handleSort($event)" (onPageChange)="handlePageChange($event)" (onPageSizeChange)="handlePageSizeChange($event)" (onColumnsChange)="handleColumnsChange($event)" (onRowSelect)="handleRowSelect($event)"> </app-ibgrid> ` }) 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