ngx-simple-datatables 1.17.0 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -52
- package/fesm2022/ngx-simple-datatables.mjs +32 -16
- package/fesm2022/ngx-simple-datatables.mjs.map +1 -1
- package/package.json +9 -11
- package/{lib/ngx-simple-datatable.component.d.ts → types/ngx-simple-datatables.d.ts} +34 -6
- package/esm2022/interfaces/column-config.interface.mjs +0 -2
- package/esm2022/lib/ngx-simple-datatable.component.mjs +0 -483
- package/esm2022/lib/ngx-simple-datatable.service.mjs +0 -14
- package/esm2022/ngx-simple-datatables.mjs +0 -5
- package/esm2022/public-api.mjs +0 -6
- package/index.d.ts +0 -5
- package/interfaces/column-config.interface.d.ts +0 -12
- package/lib/ngx-simple-datatable.service.d.ts +0 -6
- package/public-api.d.ts +0 -2
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# NgxSimpleDatatables
|
|
2
2
|
|
|
3
3
|
A lightweight, high-performance Angular data table component with features like virtual scrolling, column freezing, and customizable templates.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- 📊 Virtual scrolling for smooth performance with large datasets
|
|
@@ -15,7 +17,7 @@ A lightweight, high-performance Angular data table component with features like
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
|
-
npm install ngx-simple-
|
|
20
|
+
npm install ngx-simple-datatables --save
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Basic Usage
|
|
@@ -23,12 +25,12 @@ npm install ngx-simple-datatable --save
|
|
|
23
25
|
1. Import the module in your `app.module.ts`:
|
|
24
26
|
|
|
25
27
|
```typescript
|
|
26
|
-
import {
|
|
28
|
+
import { NgxSimpleDatatablesModule } from "ngx-simple-datatables";
|
|
27
29
|
|
|
28
30
|
@NgModule({
|
|
29
31
|
imports: [
|
|
30
32
|
// ... other imports
|
|
31
|
-
|
|
33
|
+
NgxSimpleDatatablesModule,
|
|
32
34
|
],
|
|
33
35
|
})
|
|
34
36
|
export class AppModule {}
|
|
@@ -37,20 +39,20 @@ export class AppModule {}
|
|
|
37
39
|
2. Use the component in your template:
|
|
38
40
|
|
|
39
41
|
```html
|
|
40
|
-
<ngx-simple-
|
|
42
|
+
<ngx-simple-datatables
|
|
41
43
|
[columns]="columns"
|
|
42
44
|
[data]="data"
|
|
43
|
-
[rowHeight]="
|
|
44
|
-
[headerHeight]="
|
|
45
|
+
[rowHeight]="26"
|
|
46
|
+
[headerHeight]="26"
|
|
45
47
|
>
|
|
46
|
-
</ngx-simple-
|
|
48
|
+
</ngx-simple-datatables>
|
|
47
49
|
```
|
|
48
50
|
|
|
49
51
|
3. Define your columns and data in your component:
|
|
50
52
|
|
|
51
53
|
```typescript
|
|
52
54
|
import { Component } from "@angular/core";
|
|
53
|
-
import { ColumnConfig } from "ngx-simple-
|
|
55
|
+
import { ColumnConfig } from "ngx-simple-datatables";
|
|
54
56
|
|
|
55
57
|
interface UserData {
|
|
56
58
|
id: number;
|
|
@@ -85,6 +87,33 @@ export class AppComponent {
|
|
|
85
87
|
}
|
|
86
88
|
```
|
|
87
89
|
|
|
90
|
+
4. add styles in your `styles.css`:
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
:root {
|
|
94
|
+
--ngx-simple-dt-bg: #efefef;
|
|
95
|
+
--ngx-simple-dt-border: 1px solid #e0e0e0;
|
|
96
|
+
--ngx-simple-dt-border-radius: 8px;
|
|
97
|
+
--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
98
|
+
--ngx-simple-dt-transition: all 0.2s ease-in-out;
|
|
99
|
+
|
|
100
|
+
--ngx-simple-dt-header-bg: #98ccff;
|
|
101
|
+
--ngx-simple-dt-header-hover-bg: #e9ecef;
|
|
102
|
+
--ngx-simple-dt-header-border: 1px solid #e0e0e0;
|
|
103
|
+
--ngx-simple-dt-header-text: #495057;
|
|
104
|
+
--ngx-simple-dt-header-height: 48px;
|
|
105
|
+
--ngx-simple-dt-header-font-weight: 600;
|
|
106
|
+
--ngx-simple-dt-header-padding: 0 16px;
|
|
107
|
+
|
|
108
|
+
--ngx-simple-dt-cell-padding: 0 16px;
|
|
109
|
+
--ngx-simple-dt-cell-border: 1px solid #e9ecef;
|
|
110
|
+
--ngx-simple-dt-cell-hover-bg: #f1f3f5;
|
|
111
|
+
--ngx-simple-dt-cell-active-bg: #e9ecef;
|
|
112
|
+
--ngx-simple-dt-cell-font-size: 0.875rem;
|
|
113
|
+
--ngx-simple-dt-cell-line-height: 1.5;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
88
117
|
## Advanced Features
|
|
89
118
|
|
|
90
119
|
### Column Freezing
|
|
@@ -105,7 +134,7 @@ columns: ColumnConfig[] = [
|
|
|
105
134
|
Use Angular templates to customize cell content:
|
|
106
135
|
|
|
107
136
|
```html
|
|
108
|
-
<ngx-simple-
|
|
137
|
+
<ngx-simple-datatables [columns]="columns" [data]="data">
|
|
109
138
|
<ng-template #cellTemplate let-row="row" let-column="column">
|
|
110
139
|
<ng-container [ngSwitch]="column.field">
|
|
111
140
|
<ng-container *ngSwitchCase="'status'">
|
|
@@ -121,7 +150,7 @@ Use Angular templates to customize cell content:
|
|
|
121
150
|
<ng-container *ngSwitchDefault> {{ row[column.field] }} </ng-container>
|
|
122
151
|
</ng-container>
|
|
123
152
|
</ng-template>
|
|
124
|
-
</ngx-simple-
|
|
153
|
+
</ngx-simple-datatables>
|
|
125
154
|
```
|
|
126
155
|
|
|
127
156
|
### Custom Header Templates
|
|
@@ -129,7 +158,7 @@ Use Angular templates to customize cell content:
|
|
|
129
158
|
Customize header appearance and behavior:
|
|
130
159
|
|
|
131
160
|
```html
|
|
132
|
-
<ngx-simple-
|
|
161
|
+
<ngx-simple-datatables [columns]="columns" [data]="data">
|
|
133
162
|
<ng-template #headerTemplate let-column="column">
|
|
134
163
|
<div class="custom-header">
|
|
135
164
|
<i class="fas fa-info-circle" [title]="column.header"></i>
|
|
@@ -137,7 +166,7 @@ Customize header appearance and behavior:
|
|
|
137
166
|
<i class="fas fa-sort" *ngIf="column.sortable"></i>
|
|
138
167
|
</div>
|
|
139
168
|
</ng-template>
|
|
140
|
-
</ngx-simple-
|
|
169
|
+
</ngx-simple-datatables>
|
|
141
170
|
```
|
|
142
171
|
|
|
143
172
|
### Theming
|
|
@@ -147,12 +176,41 @@ Customize the table appearance using CSS custom properties:
|
|
|
147
176
|
```css
|
|
148
177
|
/* styles.css */
|
|
149
178
|
:root {
|
|
150
|
-
--ngx-simple-dt-
|
|
151
|
-
--ngx-simple-dt-
|
|
152
|
-
--ngx-simple-dt-
|
|
179
|
+
--ngx-simple-dt-bg: #efefef;
|
|
180
|
+
--ngx-simple-dt-border: 1px solid #e0e0e0;
|
|
181
|
+
--ngx-simple-dt-border-radius: 8px;
|
|
182
|
+
--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
183
|
+
--ngx-simple-dt-transition: all 0.2s ease-in-out;
|
|
184
|
+
|
|
185
|
+
--ngx-simple-dt-header-bg: #98ccff;
|
|
186
|
+
--ngx-simple-dt-header-hover-bg: #e9ecef;
|
|
187
|
+
--ngx-simple-dt-header-border: 1px solid #e0e0e0;
|
|
188
|
+
--ngx-simple-dt-header-text: #495057;
|
|
189
|
+
--ngx-simple-dt-header-height: 48px;
|
|
190
|
+
--ngx-simple-dt-header-font-weight: 600;
|
|
191
|
+
--ngx-simple-dt-header-padding: 0 16px;
|
|
192
|
+
|
|
193
|
+
--ngx-simple-dt-cell-padding: 0 16px;
|
|
194
|
+
--ngx-simple-dt-cell-border: 1px solid #e9ecef;
|
|
195
|
+
--ngx-simple-dt-cell-hover-bg: #f1f3f5;
|
|
196
|
+
--ngx-simple-dt-cell-active-bg: #e9ecef;
|
|
197
|
+
--ngx-simple-dt-cell-font-size: 0.875rem;
|
|
198
|
+
--ngx-simple-dt-cell-line-height: 1.5;
|
|
199
|
+
|
|
200
|
+
--ngx-simple-dt-row-height: 48px;
|
|
201
|
+
--ngx-simple-dt-row-hover-bg: #f8f9fa;
|
|
153
202
|
--ngx-simple-dt-row-stripe-bg: #f8f9fa;
|
|
203
|
+
--ngx-simple-dt-row-active-bg: #e9ecef;
|
|
154
204
|
--ngx-simple-dt-cell-padding: 0 16px;
|
|
155
205
|
--ngx-simple-dt-cell-border: 1px solid #e9ecef;
|
|
206
|
+
--ngx-simple-dt-cell-font-size: 0.875rem;
|
|
207
|
+
--ngx-simple-dt-cell-line-height: 1.5;
|
|
208
|
+
|
|
209
|
+
--ngx-simple-dt-row-bg: #ffffff;
|
|
210
|
+
--ngx-simple-dt-row-hover-bg: #f8f9fa;
|
|
211
|
+
--ngx-simple-dt-row-stripe-bg: #f8f9fa;
|
|
212
|
+
--ngx-simple-dt-row-active-bg: #e9ecef;
|
|
213
|
+
--ngx-simple-dt-row-border: 1px solid #e9ecef;
|
|
156
214
|
}
|
|
157
215
|
```
|
|
158
216
|
|
|
@@ -170,52 +228,28 @@ Customize the table appearance using CSS custom properties:
|
|
|
170
228
|
|
|
171
229
|
### Column Configuration
|
|
172
230
|
|
|
173
|
-
| Property | Type | Description |
|
|
174
|
-
| ---------- | ---------------------------- | -------------------------------- |
|
|
175
|
-
| `field` | `string` | Property name in the data object |
|
|
176
|
-
| `header` | `string` | Column header text |
|
|
177
|
-
| `width` | `string
|
|
178
|
-
| `freeze` | `'left'
|
|
179
|
-
| `sortable` | `boolean` | Whether the column is sortable |
|
|
180
|
-
| `sortFn` | `(a: any, b: any) => number` | Custom sort function |
|
|
181
|
-
|
|
182
|
-
## Styling
|
|
183
|
-
|
|
184
|
-
You can customize the table appearance by overriding the following CSS custom properties:
|
|
185
|
-
|
|
186
|
-
```css
|
|
187
|
-
.dynamic-table-container {
|
|
188
|
-
--ngx-simple-dt-bg: #ffffff;
|
|
189
|
-
--ngx-simple-dt-border: 1px solid #e0e0e0;
|
|
190
|
-
--ngx-simple-dt-border-radius: 8px;
|
|
191
|
-
--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
192
|
-
--ngx-simple-dt-transition: all 0.2s ease-in-out;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.table-header {
|
|
196
|
-
--ngx-simple-dt-header-bg: #f8f9fa;
|
|
197
|
-
--ngx-simple-dt-header-hover-bg: #e9ecef;
|
|
198
|
-
--ngx-simple-dt-header-border: 1px solid #e0e0e0;
|
|
199
|
-
--ngx-simple-dt-header-text: #495057;
|
|
200
|
-
--ngx-simple-dt-header-height: 48px;
|
|
201
|
-
--ngx-simple-dt-header-font-weight: 600;
|
|
202
|
-
--ngx-simple-dt-header-padding: 0 16px;
|
|
203
|
-
}
|
|
204
|
-
```
|
|
231
|
+
| Property | Type | Description | details |
|
|
232
|
+
| ---------- | ---------------------------- | -------------------------------- | ------------ |
|
|
233
|
+
| `field` | `string` | Property name in the data object | string |
|
|
234
|
+
| `header` | `string` | Column header text | string |
|
|
235
|
+
| `width` | `string \| number` | Column width (px or %) | |
|
|
236
|
+
| `freeze` | `'left' \| 'right'` | Freeze column position | |
|
|
237
|
+
| `sortable` | `boolean` | Whether the column is sortable | true / false |
|
|
238
|
+
| `sortFn` | `(a: any, b: any) => number` | Custom sort function | function |
|
|
205
239
|
|
|
206
240
|
## Development
|
|
207
241
|
|
|
208
|
-
Run `ng build ngx-simple-
|
|
242
|
+
Run `ng build ngx-simple-datatables` to build the library. The build artifacts will be stored in the `dist/` directory.
|
|
209
243
|
|
|
210
244
|
## Publishing
|
|
211
245
|
|
|
212
|
-
After building your library with `ng build ngx-simple-
|
|
246
|
+
After building your library with `ng build ngx-simple-datatables`, go to the dist folder `cd dist/ngx-simple-datatables` and run `npm publish`.
|
|
213
247
|
|
|
214
|
-
After building your library with `ng build ngx-simple-
|
|
248
|
+
After building your library with `ng build ngx-simple-datatables`, go to the dist folder `cd dist/ngx-simple-datatables` and run `npm publish`.
|
|
215
249
|
|
|
216
250
|
## Running unit tests
|
|
217
251
|
|
|
218
|
-
Run `ng test ngx-simple-
|
|
252
|
+
Run `ng test ngx-simple-datatables` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
219
253
|
|
|
220
254
|
## Further help
|
|
221
255
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, PLATFORM_ID, ContentChild, ViewChild, Input, Inject, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
2
|
+
import { Injectable, PLATFORM_ID, ContentChild, ViewChild, Input, Inject, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class NgxSimpleDatatablesService {
|
|
7
7
|
constructor() { }
|
|
8
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
9
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
8
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesService, providedIn: "root" }); }
|
|
10
10
|
}
|
|
11
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
11
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesService, decorators: [{
|
|
12
12
|
type: Injectable,
|
|
13
13
|
args: [{
|
|
14
|
-
providedIn:
|
|
14
|
+
providedIn: "root",
|
|
15
15
|
}]
|
|
16
16
|
}], ctorParameters: () => [] });
|
|
17
17
|
|
|
18
|
-
class
|
|
18
|
+
class NgxSimpleDatatablesComponent {
|
|
19
19
|
constructor(cdr, platformId, ngZone) {
|
|
20
20
|
this.cdr = cdr;
|
|
21
21
|
this.platformId = platformId;
|
|
@@ -47,7 +47,7 @@ class NgxSimpleDatatableComponent {
|
|
|
47
47
|
// Scroll listeners
|
|
48
48
|
this.scrollListener = null;
|
|
49
49
|
this.resizeListener = null;
|
|
50
|
-
this.storageKey = "ngx-simple-
|
|
50
|
+
this.storageKey = "ngx-simple-datatables-column-widths";
|
|
51
51
|
this.scrollRequestId = null;
|
|
52
52
|
this.resizeTimer = null;
|
|
53
53
|
this.mouseMoveHandler = null;
|
|
@@ -83,10 +83,10 @@ class NgxSimpleDatatableComponent {
|
|
|
83
83
|
}
|
|
84
84
|
ngAfterContentInit() {
|
|
85
85
|
// if (!this.headerTemplate) {
|
|
86
|
-
// throw new Error("ngx-simple-
|
|
86
|
+
// throw new Error("ngx-simple-datatables requires a headerTemplate.");
|
|
87
87
|
// }
|
|
88
88
|
// if (!this.cellTemplate) {
|
|
89
|
-
// throw new Error("ngx-simple-
|
|
89
|
+
// throw new Error("ngx-simple-datatables requires a cellTemplate.");
|
|
90
90
|
// }
|
|
91
91
|
}
|
|
92
92
|
initializeColumns() {
|
|
@@ -455,12 +455,12 @@ class NgxSimpleDatatableComponent {
|
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
459
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NgxSimpleDatatableComponent, isStandalone: true, selector: "ngx-simple-datatable", inputs: { columns: "columns", data: "data", rowHeight: "rowHeight", headerHeight: "headerHeight", bufferSize: "bufferSize" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, static: true }, { propertyName: "cellTemplate", first: true, predicate: ["cellTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "tableContainer", first: true, predicate: ["tableContainer"], descendants: true, static: true }, { propertyName: "tableBody", first: true, predicate: ["tableBody"], descendants: true, static: true }, { propertyName: "headerRow", first: true, predicate: ["headerRow"], descendants: true, static: true }, { propertyName: "headeCenterRow", first: true, predicate: ["headeCenterRow"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"dynamic-table-container\" #tableContainer>\n <!-- Sticky Header -->\n <div class=\"table-header\" [style.height.px]=\"headerHeight\">\n <div class=\"header-row\" #headerRow (scroll)=\"onHeaderScroll($event)\">\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\"\n role=\"presentation\">\n <div class=\"header-cell\"\n *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\" [attr.aria-colindex]=\"colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\" #headeCenterRow role=\"presentation\" [ngStyle]=\"{'transform': headerTransform}\">\n <div class=\"header-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-colindex]=\"leftFrozenColumns.length + colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"header-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\" (click)=\"onSort(column)\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Body with Virtual Scrolling -->\n <div class=\"table-body\" #tableBody [style.height]=\"'calc(100% - ' + headerHeight + 'px)'\"\n (scroll)=\"onBodyScroll($event)\">\n <!-- Virtual spacer for total height -->\n <div class=\"virtual-spacer\" [style.height.px]=\"totalHeight\"></div>\n\n <!-- Visible rows container -->\n <div class=\"visible-rows\" [style.transform]=\"'translateY(' + offsetY + 'px)'\">\n <div class=\"table-row\" *ngFor=\"let row of visibleRows; let i = index; trackBy: trackByRowIndex\"\n [style.height.px]=\"rowHeight\">\n\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\">\n <div class=\"table-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":root{--ngx-simple-dt-bg: #ffffff;--ngx-simple-dt-border: 1px solid #e0e0e0;--ngx-simple-dt-border-radius: 8px;--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, .1);--ngx-simple-dt-transition: all .2s ease-in-out;--ngx-simple-dt-header-bg: #f8f9fa;--ngx-simple-dt-header-hover-bg: #e9ecef;--ngx-simple-dt-header-border: 1px solid #e0e0e0;--ngx-simple-dt-header-text: #495057;--ngx-simple-dt-header-height: 98px;--ngx-simple-dt-header-font-weight: 600;--ngx-simple-dt-header-padding: 0 16px;--ngx-simple-dt-cell-hover-bg: #f1f3f5;--ngx-simple-dt-cell-active-bg: #e9ecef;--ngx-simple-dt-row-height: 48px;--ngx-simple-dt-cell-padding: 0 16px;--ngx-simple-dt-cell-border: 1px solid #e9ecef;--ngx-simple-dt-cell-font-size: .875rem;--ngx-simple-dt-cell-line-height: 1.5;--ngx-simple-dt-row-bg: #ffffff;--ngx-simple-dt-row-hover-bg: #f8f9fa;--ngx-simple-dt-row-stripe-bg: #f8f9fa;--ngx-simple-dt-row-active-bg: #e9ecef;--ngx-simple-dt-row-border: 1px solid #e9ecef}.dynamic-table-container{width:100%;height:100%;position:relative;display:flex;flex-direction:column;overflow:hidden;background:var(--ngx-simple-dt-bg);border:var(--ngx-simple-dt-border);border-radius:var(--ngx-simple-dt-border-radius);box-shadow:var(--ngx-simple-dt-box-shadow);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header{position:sticky;top:0;z-index:10;background:var(--ngx-simple-dt-header-bg);border-bottom:var(--ngx-simple-dt-header-border);overflow:hidden;height:var(--ngx-simple-dt-header-height);color:var(--ngx-simple-dt-header-text)}.dynamic-table-container .table-header .header-row{display:flex;min-width:100%;position:relative;height:100%}.dynamic-table-container .table-header .header-row .frozen-left,.dynamic-table-container .table-header .header-row .frozen-right{position:sticky;z-index:12;background:var(--ngx-simple-dt-header-bg);display:flex;box-shadow:2px 0 8px #0000000d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .frozen-left{left:0;border-right:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .center-columns{display:flex;flex:1}.dynamic-table-container .table-header .header-row .frozen-right{right:0;border-left:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .header-cell{display:flex;align-items:center;justify-content:space-between;padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);background:inherit;font-weight:var(--ngx-simple-dt-header-font-weight);position:relative;min-width:0;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);color:inherit;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable:hover{background:var(--ngx-simple-dt-header-hover-bg)}.dynamic-table-container .table-header .header-row .header-cell.sortable:active{background:var(--ngx-simple-dt-cell-active-bg)}.dynamic-table-container .table-header .header-row .header-cell .header-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dynamic-table-container .table-header .header-row .header-cell .sort-icon{margin-left:8px;font-size:12px;color:#6c757d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-asc,.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-desc{color:#0d6efd}.dynamic-table-container .table-header .header-row .header-cell .resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .resize-handle:hover,.dynamic-table-container .table-header .header-row .header-cell .resize-handle:active{background:#0d6efd}.dynamic-table-container .table-body{position:relative;flex:1;overflow:auto;scrollbar-width:thin;scrollbar-color:#ced4da #f8f9fa;-webkit-overflow-scrolling:touch}.dynamic-table-container .table-body::-webkit-scrollbar{width:8px;height:8px}.dynamic-table-container .table-body::-webkit-scrollbar-track{background:#f8f9fa;scroll-margin-left:100px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb{background-color:#ced4da;border-radius:4px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb:hover{background-color:#adb5bd}.dynamic-table-container .table-body .virtual-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none}.dynamic-table-container .table-body .visible-rows{position:absolute;top:0;left:0;right:0;min-width:fit-content}.dynamic-table-container .table-body .visible-rows .table-row{display:flex;min-width:100%;border-bottom:var(--ngx-simple-dt-row-border);background:var(--ngx-simple-dt-row-bg);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-body .visible-rows .table-row:nth-child(2n){background:var(--ngx-simple-dt-row-stripe-bg)}.dynamic-table-container .table-body .visible-rows .table-row:hover{background:var(--ngx-simple-dt-row-hover-bg)}.dynamic-table-container .table-body .visible-rows .table-row:active{background:var(--ngx-simple-dt-row-active-bg)}.dynamic-table-container .table-body .visible-rows .table-row .frozen-left{position:sticky;left:0;z-index:5;background:#fff;border-right:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-left{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .center-columns{display:flex;flex:0 0 auto}.dynamic-table-container .table-body .visible-rows .table-row .frozen-right{position:sticky;right:0;z-index:5;background:#fff;border-left:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-right{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .table-cell{padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);display:flex;align-items:center;transition:var(--ngx-simple-dt-transition);min-width:0}.dynamic-table-container .frozen-left .table-cell,.dynamic-table-container .frozen-right .table-cell{background:inherit;box-shadow:2px 0 8px #0000000d}@media (max-width: 768px){.dynamic-table-container{font-size:14px}.dynamic-table-container .header-cell,.dynamic-table-container .table-cell{padding:0 8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
458
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
459
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgxSimpleDatatablesComponent, isStandalone: false, selector: "ngx-simple-datatables", inputs: { columns: "columns", data: "data", rowHeight: "rowHeight", headerHeight: "headerHeight", bufferSize: "bufferSize" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, static: true }, { propertyName: "cellTemplate", first: true, predicate: ["cellTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "tableContainer", first: true, predicate: ["tableContainer"], descendants: true, static: true }, { propertyName: "tableBody", first: true, predicate: ["tableBody"], descendants: true, static: true }, { propertyName: "headerRow", first: true, predicate: ["headerRow"], descendants: true, static: true }, { propertyName: "headeCenterRow", first: true, predicate: ["headeCenterRow"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"dynamic-table-container\" #tableContainer>\n <!-- Sticky Header -->\n <div class=\"table-header\" [style.height.px]=\"headerHeight\">\n <div class=\"header-row\" #headerRow (scroll)=\"onHeaderScroll($event)\">\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\"\n role=\"presentation\">\n <div class=\"header-cell\"\n *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\" [attr.aria-colindex]=\"colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\" #headeCenterRow role=\"presentation\" [ngStyle]=\"{'transform': headerTransform}\">\n <div class=\"header-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-colindex]=\"leftFrozenColumns.length + colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"header-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\" (click)=\"onSort(column)\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Body with Virtual Scrolling -->\n <div class=\"table-body\" #tableBody [style.height]=\"'calc(100% - ' + headerHeight + 'px)'\"\n (scroll)=\"onBodyScroll($event)\">\n <!-- Virtual spacer for total height -->\n <div class=\"virtual-spacer\" [style.height.px]=\"totalHeight\"></div>\n\n <!-- Visible rows container -->\n <div class=\"visible-rows\" [style.transform]=\"'translateY(' + offsetY + 'px)'\">\n <div class=\"table-row\" *ngFor=\"let row of visibleRows; let i = index; trackBy: trackByRowIndex\"\n [style.height.px]=\"rowHeight\">\n\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\">\n <div class=\"table-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":root{--ngx-simple-dt-bg: #ffffff;--ngx-simple-dt-border: 1px solid #e0e0e0;--ngx-simple-dt-border-radius: 8px;--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, .1);--ngx-simple-dt-transition: all .2s ease-in-out;--ngx-simple-dt-header-bg: #f8f9fa;--ngx-simple-dt-header-hover-bg: #e9ecef;--ngx-simple-dt-header-border: 1px solid #e0e0e0;--ngx-simple-dt-header-text: #495057;--ngx-simple-dt-header-height: 98px;--ngx-simple-dt-header-font-weight: 600;--ngx-simple-dt-header-padding: 0 16px;--ngx-simple-dt-cell-hover-bg: #f1f3f5;--ngx-simple-dt-cell-active-bg: #e9ecef;--ngx-simple-dt-row-height: 48px;--ngx-simple-dt-cell-padding: 0 16px;--ngx-simple-dt-cell-border: 1px solid #e9ecef;--ngx-simple-dt-cell-font-size: .875rem;--ngx-simple-dt-cell-line-height: 1.5;--ngx-simple-dt-row-bg: #ffffff;--ngx-simple-dt-row-hover-bg: #f8f9fa;--ngx-simple-dt-row-stripe-bg: #f8f9fa;--ngx-simple-dt-row-active-bg: #e9ecef;--ngx-simple-dt-row-border: 1px solid #e9ecef}.dynamic-table-container{width:100%;height:100%;position:relative;display:flex;flex-direction:column;overflow:hidden;background:var(--ngx-simple-dt-bg);border:var(--ngx-simple-dt-border);border-radius:var(--ngx-simple-dt-border-radius);box-shadow:var(--ngx-simple-dt-box-shadow);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header{position:sticky;top:0;z-index:10;background:var(--ngx-simple-dt-header-bg);border-bottom:var(--ngx-simple-dt-header-border);overflow:hidden;height:var(--ngx-simple-dt-header-height);color:var(--ngx-simple-dt-header-text)}.dynamic-table-container .table-header .header-row{display:flex;min-width:100%;position:relative;height:100%}.dynamic-table-container .table-header .header-row .frozen-left,.dynamic-table-container .table-header .header-row .frozen-right{position:sticky;z-index:12;background:var(--ngx-simple-dt-header-bg);display:flex;box-shadow:2px 0 8px #0000000d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .frozen-left{left:0;border-right:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .center-columns{display:flex;flex:1}.dynamic-table-container .table-header .header-row .frozen-right{right:0;border-left:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .header-cell{display:flex;align-items:center;justify-content:space-between;padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);background:inherit;font-weight:var(--ngx-simple-dt-header-font-weight);position:relative;min-width:0;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);color:inherit;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable:hover{background:var(--ngx-simple-dt-header-hover-bg)}.dynamic-table-container .table-header .header-row .header-cell.sortable:active{background:var(--ngx-simple-dt-cell-active-bg)}.dynamic-table-container .table-header .header-row .header-cell .header-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dynamic-table-container .table-header .header-row .header-cell .sort-icon{margin-left:8px;font-size:12px;color:#6c757d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-asc,.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-desc{color:#0d6efd}.dynamic-table-container .table-header .header-row .header-cell .resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .resize-handle:hover,.dynamic-table-container .table-header .header-row .header-cell .resize-handle:active{background:#0d6efd}.dynamic-table-container .table-body{position:relative;flex:1;overflow:auto;scrollbar-width:thin;scrollbar-color:#ced4da #f8f9fa}.dynamic-table-container .table-body::-webkit-scrollbar{width:8px;height:8px}.dynamic-table-container .table-body::-webkit-scrollbar-track{background:#f8f9fa;scroll-margin-left:100px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb{background-color:#ced4da;border-radius:4px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb:hover{background-color:#adb5bd}.dynamic-table-container .table-body{-webkit-overflow-scrolling:touch}.dynamic-table-container .table-body .virtual-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none}.dynamic-table-container .table-body .visible-rows{position:absolute;top:0;left:0;right:0;min-width:fit-content}.dynamic-table-container .table-body .visible-rows .table-row{display:flex;min-width:100%;border-bottom:var(--ngx-simple-dt-row-border);background:var(--ngx-simple-dt-row-bg);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-body .visible-rows .table-row:nth-child(2n){background:var(--ngx-simple-dt-row-stripe-bg)}.dynamic-table-container .table-body .visible-rows .table-row:hover{background:var(--ngx-simple-dt-row-hover-bg)}.dynamic-table-container .table-body .visible-rows .table-row:active{background:var(--ngx-simple-dt-row-active-bg)}.dynamic-table-container .table-body .visible-rows .table-row .frozen-left{position:sticky;left:0;z-index:5;background:#fff;border-right:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-left{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .center-columns{display:flex;flex:0 0 auto}.dynamic-table-container .table-body .visible-rows .table-row .frozen-right{position:sticky;right:0;z-index:5;background:#fff;border-left:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-right{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .table-cell{padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);display:flex;align-items:center;transition:var(--ngx-simple-dt-transition);min-width:0}.dynamic-table-container .frozen-left .table-cell,.dynamic-table-container .frozen-right .table-cell{background:inherit;box-shadow:2px 0 8px #0000000d}@media(max-width:768px){.dynamic-table-container{font-size:14px}.dynamic-table-container .header-cell,.dynamic-table-container .table-cell{padding:0 8px}}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
460
460
|
}
|
|
461
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
461
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesComponent, decorators: [{
|
|
462
462
|
type: Component,
|
|
463
|
-
args: [{ selector: "ngx-simple-datatable", standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"dynamic-table-container\" #tableContainer>\n <!-- Sticky Header -->\n <div class=\"table-header\" [style.height.px]=\"headerHeight\">\n <div class=\"header-row\" #headerRow (scroll)=\"onHeaderScroll($event)\">\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\"\n role=\"presentation\">\n <div class=\"header-cell\"\n *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\" [attr.aria-colindex]=\"colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\" #headeCenterRow role=\"presentation\" [ngStyle]=\"{'transform': headerTransform}\">\n <div class=\"header-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-colindex]=\"leftFrozenColumns.length + colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"header-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\" (click)=\"onSort(column)\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Body with Virtual Scrolling -->\n <div class=\"table-body\" #tableBody [style.height]=\"'calc(100% - ' + headerHeight + 'px)'\"\n (scroll)=\"onBodyScroll($event)\">\n <!-- Virtual spacer for total height -->\n <div class=\"virtual-spacer\" [style.height.px]=\"totalHeight\"></div>\n\n <!-- Visible rows container -->\n <div class=\"visible-rows\" [style.transform]=\"'translateY(' + offsetY + 'px)'\">\n <div class=\"table-row\" *ngFor=\"let row of visibleRows; let i = index; trackBy: trackByRowIndex\"\n [style.height.px]=\"rowHeight\">\n\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\">\n <div class=\"table-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":root{--ngx-simple-dt-bg: #ffffff;--ngx-simple-dt-border: 1px solid #e0e0e0;--ngx-simple-dt-border-radius: 8px;--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, .1);--ngx-simple-dt-transition: all .2s ease-in-out;--ngx-simple-dt-header-bg: #f8f9fa;--ngx-simple-dt-header-hover-bg: #e9ecef;--ngx-simple-dt-header-border: 1px solid #e0e0e0;--ngx-simple-dt-header-text: #495057;--ngx-simple-dt-header-height: 98px;--ngx-simple-dt-header-font-weight: 600;--ngx-simple-dt-header-padding: 0 16px;--ngx-simple-dt-cell-hover-bg: #f1f3f5;--ngx-simple-dt-cell-active-bg: #e9ecef;--ngx-simple-dt-row-height: 48px;--ngx-simple-dt-cell-padding: 0 16px;--ngx-simple-dt-cell-border: 1px solid #e9ecef;--ngx-simple-dt-cell-font-size: .875rem;--ngx-simple-dt-cell-line-height: 1.5;--ngx-simple-dt-row-bg: #ffffff;--ngx-simple-dt-row-hover-bg: #f8f9fa;--ngx-simple-dt-row-stripe-bg: #f8f9fa;--ngx-simple-dt-row-active-bg: #e9ecef;--ngx-simple-dt-row-border: 1px solid #e9ecef}.dynamic-table-container{width:100%;height:100%;position:relative;display:flex;flex-direction:column;overflow:hidden;background:var(--ngx-simple-dt-bg);border:var(--ngx-simple-dt-border);border-radius:var(--ngx-simple-dt-border-radius);box-shadow:var(--ngx-simple-dt-box-shadow);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header{position:sticky;top:0;z-index:10;background:var(--ngx-simple-dt-header-bg);border-bottom:var(--ngx-simple-dt-header-border);overflow:hidden;height:var(--ngx-simple-dt-header-height);color:var(--ngx-simple-dt-header-text)}.dynamic-table-container .table-header .header-row{display:flex;min-width:100%;position:relative;height:100%}.dynamic-table-container .table-header .header-row .frozen-left,.dynamic-table-container .table-header .header-row .frozen-right{position:sticky;z-index:12;background:var(--ngx-simple-dt-header-bg);display:flex;box-shadow:2px 0 8px #0000000d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .frozen-left{left:0;border-right:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .center-columns{display:flex;flex:1}.dynamic-table-container .table-header .header-row .frozen-right{right:0;border-left:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .header-cell{display:flex;align-items:center;justify-content:space-between;padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);background:inherit;font-weight:var(--ngx-simple-dt-header-font-weight);position:relative;min-width:0;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);color:inherit;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable:hover{background:var(--ngx-simple-dt-header-hover-bg)}.dynamic-table-container .table-header .header-row .header-cell.sortable:active{background:var(--ngx-simple-dt-cell-active-bg)}.dynamic-table-container .table-header .header-row .header-cell .header-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dynamic-table-container .table-header .header-row .header-cell .sort-icon{margin-left:8px;font-size:12px;color:#6c757d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-asc,.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-desc{color:#0d6efd}.dynamic-table-container .table-header .header-row .header-cell .resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .resize-handle:hover,.dynamic-table-container .table-header .header-row .header-cell .resize-handle:active{background:#0d6efd}.dynamic-table-container .table-body{position:relative;flex:1;overflow:auto;scrollbar-width:thin;scrollbar-color:#ced4da #f8f9fa;-webkit-overflow-scrolling:touch}.dynamic-table-container .table-body::-webkit-scrollbar{width:8px;height:8px}.dynamic-table-container .table-body::-webkit-scrollbar-track{background:#f8f9fa;scroll-margin-left:100px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb{background-color:#ced4da;border-radius:4px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb:hover{background-color:#adb5bd}.dynamic-table-container .table-body .virtual-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none}.dynamic-table-container .table-body .visible-rows{position:absolute;top:0;left:0;right:0;min-width:fit-content}.dynamic-table-container .table-body .visible-rows .table-row{display:flex;min-width:100%;border-bottom:var(--ngx-simple-dt-row-border);background:var(--ngx-simple-dt-row-bg);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-body .visible-rows .table-row:nth-child(2n){background:var(--ngx-simple-dt-row-stripe-bg)}.dynamic-table-container .table-body .visible-rows .table-row:hover{background:var(--ngx-simple-dt-row-hover-bg)}.dynamic-table-container .table-body .visible-rows .table-row:active{background:var(--ngx-simple-dt-row-active-bg)}.dynamic-table-container .table-body .visible-rows .table-row .frozen-left{position:sticky;left:0;z-index:5;background:#fff;border-right:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-left{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .center-columns{display:flex;flex:0 0 auto}.dynamic-table-container .table-body .visible-rows .table-row .frozen-right{position:sticky;right:0;z-index:5;background:#fff;border-left:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-right{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .table-cell{padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);display:flex;align-items:center;transition:var(--ngx-simple-dt-transition);min-width:0}.dynamic-table-container .frozen-left .table-cell,.dynamic-table-container .frozen-right .table-cell{background:inherit;box-shadow:2px 0 8px #0000000d}@media (max-width: 768px){.dynamic-table-container{font-size:14px}.dynamic-table-container .header-cell,.dynamic-table-container .table-cell{padding:0 8px}}\n"] }]
|
|
463
|
+
args: [{ selector: "ngx-simple-datatables", changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"dynamic-table-container\" #tableContainer>\n <!-- Sticky Header -->\n <div class=\"table-header\" [style.height.px]=\"headerHeight\">\n <div class=\"header-row\" #headerRow (scroll)=\"onHeaderScroll($event)\">\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\"\n role=\"presentation\">\n <div class=\"header-cell\"\n *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\" [attr.aria-colindex]=\"colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\" #headeCenterRow role=\"presentation\" [ngStyle]=\"{'transform': headerTransform}\">\n <div class=\"header-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField; let colIndex = index\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\"\n [class.sort-asc]=\"sortState.field === column.field && sortState.direction === 'asc'\"\n [class.sort-desc]=\"sortState.field === column.field && sortState.direction === 'desc'\"\n [attr.role]=\"'columnheader'\" [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-colindex]=\"leftFrozenColumns.length + colIndex + 1\"\n [attr.aria-label]=\"column.header + (column.sortable ? ' (click to sort)' : '')\" (click)=\"onSort(column)\"\n (keydown.enter)=\"onSort(column)\" (keydown.space)=\"onSort(column); $event.preventDefault()\"\n [tabindex]=\"column.sortable ? '0' : '-1'\" [attr.data-column-id]=\"column.field\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"header-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\" [class.sortable]=\"column.sortable\" (click)=\"onSort(column)\">\n <ng-container *ngIf=\"!headerTemplate; else customHeader\">\n <span class=\"header-text\">{{ column.header }}</span>\n </ng-container>\n <ng-template #customHeader>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\n [ngTemplateOutletContext]=\"{ column: column }\"></ng-container>\n </ng-template>\n <span class=\"sort-icon\" *ngIf=\"column.sortable\">{{ getSortIcon(column) }}</span>\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, column)\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Body with Virtual Scrolling -->\n <div class=\"table-body\" #tableBody [style.height]=\"'calc(100% - ' + headerHeight + 'px)'\"\n (scroll)=\"onBodyScroll($event)\">\n <!-- Virtual spacer for total height -->\n <div class=\"virtual-spacer\" [style.height.px]=\"totalHeight\"></div>\n\n <!-- Visible rows container -->\n <div class=\"visible-rows\" [style.transform]=\"'translateY(' + offsetY + 'px)'\">\n <div class=\"table-row\" *ngFor=\"let row of visibleRows; let i = index; trackBy: trackByRowIndex\"\n [style.height.px]=\"rowHeight\">\n\n <!-- Left Frozen Columns -->\n <div class=\"frozen-left\" [style.width.px]=\"getLeftFrozenWidth()\" *ngIf=\"leftFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of leftFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Center Scrollable Columns -->\n <div class=\"center-columns\">\n <div class=\"table-cell\" *ngFor=\"let column of centerColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n\n <!-- Right Frozen Columns -->\n <div class=\"frozen-right\" [style.width.px]=\"getRightFrozenWidth()\" *ngIf=\"rightFrozenColumns.length > 0\">\n <div class=\"table-cell\" *ngFor=\"let column of rightFrozenColumns; trackBy: trackByColumnField\"\n [style.width]=\"getColumnWidth(column)\">\n <ng-container *ngIf=\"!cellTemplate; else customCell\">\n {{ getCellValue(row, column) }}\n </ng-container>\n <ng-template #customCell>\n <ng-container [ngTemplateOutlet]=\"cellTemplate\"\n [ngTemplateOutletContext]=\"{ row: row, column: column }\"></ng-container>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":root{--ngx-simple-dt-bg: #ffffff;--ngx-simple-dt-border: 1px solid #e0e0e0;--ngx-simple-dt-border-radius: 8px;--ngx-simple-dt-box-shadow: 0 2px 8px rgba(0, 0, 0, .1);--ngx-simple-dt-transition: all .2s ease-in-out;--ngx-simple-dt-header-bg: #f8f9fa;--ngx-simple-dt-header-hover-bg: #e9ecef;--ngx-simple-dt-header-border: 1px solid #e0e0e0;--ngx-simple-dt-header-text: #495057;--ngx-simple-dt-header-height: 98px;--ngx-simple-dt-header-font-weight: 600;--ngx-simple-dt-header-padding: 0 16px;--ngx-simple-dt-cell-hover-bg: #f1f3f5;--ngx-simple-dt-cell-active-bg: #e9ecef;--ngx-simple-dt-row-height: 48px;--ngx-simple-dt-cell-padding: 0 16px;--ngx-simple-dt-cell-border: 1px solid #e9ecef;--ngx-simple-dt-cell-font-size: .875rem;--ngx-simple-dt-cell-line-height: 1.5;--ngx-simple-dt-row-bg: #ffffff;--ngx-simple-dt-row-hover-bg: #f8f9fa;--ngx-simple-dt-row-stripe-bg: #f8f9fa;--ngx-simple-dt-row-active-bg: #e9ecef;--ngx-simple-dt-row-border: 1px solid #e9ecef}.dynamic-table-container{width:100%;height:100%;position:relative;display:flex;flex-direction:column;overflow:hidden;background:var(--ngx-simple-dt-bg);border:var(--ngx-simple-dt-border);border-radius:var(--ngx-simple-dt-border-radius);box-shadow:var(--ngx-simple-dt-box-shadow);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header{position:sticky;top:0;z-index:10;background:var(--ngx-simple-dt-header-bg);border-bottom:var(--ngx-simple-dt-header-border);overflow:hidden;height:var(--ngx-simple-dt-header-height);color:var(--ngx-simple-dt-header-text)}.dynamic-table-container .table-header .header-row{display:flex;min-width:100%;position:relative;height:100%}.dynamic-table-container .table-header .header-row .frozen-left,.dynamic-table-container .table-header .header-row .frozen-right{position:sticky;z-index:12;background:var(--ngx-simple-dt-header-bg);display:flex;box-shadow:2px 0 8px #0000000d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .frozen-left{left:0;border-right:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .center-columns{display:flex;flex:1}.dynamic-table-container .table-header .header-row .frozen-right{right:0;border-left:var(--ngx-simple-dt-header-border)}.dynamic-table-container .table-header .header-row .header-cell{display:flex;align-items:center;justify-content:space-between;padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);background:inherit;font-weight:var(--ngx-simple-dt-header-font-weight);position:relative;min-width:0;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);color:inherit;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell.sortable:hover{background:var(--ngx-simple-dt-header-hover-bg)}.dynamic-table-container .table-header .header-row .header-cell.sortable:active{background:var(--ngx-simple-dt-cell-active-bg)}.dynamic-table-container .table-header .header-row .header-cell .header-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dynamic-table-container .table-header .header-row .header-cell .sort-icon{margin-left:8px;font-size:12px;color:#6c757d;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-asc,.dynamic-table-container .table-header .header-row .header-cell .sort-icon.sort-desc{color:#0d6efd}.dynamic-table-container .table-header .header-row .header-cell .resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-header .header-row .header-cell .resize-handle:hover,.dynamic-table-container .table-header .header-row .header-cell .resize-handle:active{background:#0d6efd}.dynamic-table-container .table-body{position:relative;flex:1;overflow:auto;scrollbar-width:thin;scrollbar-color:#ced4da #f8f9fa}.dynamic-table-container .table-body::-webkit-scrollbar{width:8px;height:8px}.dynamic-table-container .table-body::-webkit-scrollbar-track{background:#f8f9fa;scroll-margin-left:100px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb{background-color:#ced4da;border-radius:4px}.dynamic-table-container .table-body::-webkit-scrollbar-thumb:hover{background-color:#adb5bd}.dynamic-table-container .table-body{-webkit-overflow-scrolling:touch}.dynamic-table-container .table-body .virtual-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none}.dynamic-table-container .table-body .visible-rows{position:absolute;top:0;left:0;right:0;min-width:fit-content}.dynamic-table-container .table-body .visible-rows .table-row{display:flex;min-width:100%;border-bottom:var(--ngx-simple-dt-row-border);background:var(--ngx-simple-dt-row-bg);transition:var(--ngx-simple-dt-transition)}.dynamic-table-container .table-body .visible-rows .table-row:nth-child(2n){background:var(--ngx-simple-dt-row-stripe-bg)}.dynamic-table-container .table-body .visible-rows .table-row:hover{background:var(--ngx-simple-dt-row-hover-bg)}.dynamic-table-container .table-body .visible-rows .table-row:active{background:var(--ngx-simple-dt-row-active-bg)}.dynamic-table-container .table-body .visible-rows .table-row .frozen-left{position:sticky;left:0;z-index:5;background:#fff;border-right:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-left{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .center-columns{display:flex;flex:0 0 auto}.dynamic-table-container .table-body .visible-rows .table-row .frozen-right{position:sticky;right:0;z-index:5;background:#fff;border-left:2px solid #ccc;display:flex}.table-row:hover .dynamic-table-container .table-body .visible-rows .table-row .frozen-right{background:#f9f9f9}.dynamic-table-container .table-body .visible-rows .table-row .table-cell{padding:var(--ngx-simple-dt-cell-padding);border-right:var(--ngx-simple-dt-cell-border);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ngx-simple-dt-cell-font-size);line-height:var(--ngx-simple-dt-cell-line-height);display:flex;align-items:center;transition:var(--ngx-simple-dt-transition);min-width:0}.dynamic-table-container .frozen-left .table-cell,.dynamic-table-container .frozen-right .table-cell{background:inherit;box-shadow:2px 0 8px #0000000d}@media(max-width:768px){.dynamic-table-container{font-size:14px}.dynamic-table-container .header-cell,.dynamic-table-container .table-cell{padding:0 8px}}\n"] }]
|
|
464
464
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: Object, decorators: [{
|
|
465
465
|
type: Inject,
|
|
466
466
|
args: [PLATFORM_ID]
|
|
@@ -494,13 +494,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
494
494
|
args: ["cellTemplate", { static: true }]
|
|
495
495
|
}] } });
|
|
496
496
|
|
|
497
|
+
// NgModule wrapper to support Angular 14+ NgModule-based apps
|
|
498
|
+
// This keeps the component standalone while enabling module-style imports.
|
|
499
|
+
class NgxSimpleDatatablesModule {
|
|
500
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
501
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesModule, declarations: [NgxSimpleDatatablesComponent], imports: [CommonModule], exports: [NgxSimpleDatatablesComponent] }); }
|
|
502
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesModule, imports: [CommonModule] }); }
|
|
503
|
+
}
|
|
504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxSimpleDatatablesModule, decorators: [{
|
|
505
|
+
type: NgModule,
|
|
506
|
+
args: [{
|
|
507
|
+
declarations: [NgxSimpleDatatablesComponent],
|
|
508
|
+
imports: [CommonModule],
|
|
509
|
+
exports: [NgxSimpleDatatablesComponent],
|
|
510
|
+
}]
|
|
511
|
+
}] });
|
|
512
|
+
|
|
497
513
|
/*
|
|
498
|
-
* Public API Surface of ngx-simple-
|
|
514
|
+
* Public API Surface of ngx-simple-datatables
|
|
499
515
|
*/
|
|
500
516
|
|
|
501
517
|
/**
|
|
502
518
|
* Generated bundle index. Do not edit.
|
|
503
519
|
*/
|
|
504
520
|
|
|
505
|
-
export {
|
|
521
|
+
export { NgxSimpleDatatablesComponent, NgxSimpleDatatablesModule, NgxSimpleDatatablesService };
|
|
506
522
|
//# sourceMappingURL=ngx-simple-datatables.mjs.map
|