@alaarab/ogrid-angular-material 2.0.3 → 2.0.5
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/dist/esm/column-header-menu/column-header-menu.component.js +122 -0
- package/dist/esm/datagrid-table/datagrid-table.component.js +115 -27
- package/dist/esm/index.js +1 -0
- package/dist/types/column-header-menu/column-header-menu.component.d.ts +20 -0
- package/dist/types/datagrid-table/datagrid-table.component.d.ts +27 -14
- package/dist/types/index.d.ts +1 -0
- package/dist/types/pagination-controls/pagination-controls.component.d.ts +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
8
|
+
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
|
9
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
10
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
11
|
+
import { COLUMN_HEADER_MENU_ITEMS } from '@alaarab/ogrid-core';
|
|
12
|
+
/**
|
|
13
|
+
* Column header dropdown menu for pin/unpin actions.
|
|
14
|
+
* Uses Angular Material MatMenu.
|
|
15
|
+
*/
|
|
16
|
+
let ColumnHeaderMenuComponent = class ColumnHeaderMenuComponent {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.canPinLeft = true;
|
|
19
|
+
this.canPinRight = true;
|
|
20
|
+
this.canUnpin = false;
|
|
21
|
+
this.pinLeft = new EventEmitter();
|
|
22
|
+
this.pinRight = new EventEmitter();
|
|
23
|
+
this.unpin = new EventEmitter();
|
|
24
|
+
this.menuItems = COLUMN_HEADER_MENU_ITEMS;
|
|
25
|
+
}
|
|
26
|
+
handlePinLeft() {
|
|
27
|
+
if (this.canPinLeft) {
|
|
28
|
+
this.pinLeft.emit();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
handlePinRight() {
|
|
32
|
+
if (this.canPinRight) {
|
|
33
|
+
this.pinRight.emit();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
handleUnpin() {
|
|
37
|
+
if (this.canUnpin) {
|
|
38
|
+
this.unpin.emit();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
__decorate([
|
|
43
|
+
Input()
|
|
44
|
+
], ColumnHeaderMenuComponent.prototype, "columnId", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
Input()
|
|
47
|
+
], ColumnHeaderMenuComponent.prototype, "canPinLeft", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
Input()
|
|
50
|
+
], ColumnHeaderMenuComponent.prototype, "canPinRight", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
Input()
|
|
53
|
+
], ColumnHeaderMenuComponent.prototype, "canUnpin", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
Output()
|
|
56
|
+
], ColumnHeaderMenuComponent.prototype, "pinLeft", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
Output()
|
|
59
|
+
], ColumnHeaderMenuComponent.prototype, "pinRight", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
Output()
|
|
62
|
+
], ColumnHeaderMenuComponent.prototype, "unpin", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
ViewChild(MatMenuTrigger)
|
|
65
|
+
], ColumnHeaderMenuComponent.prototype, "menuTrigger", void 0);
|
|
66
|
+
ColumnHeaderMenuComponent = __decorate([
|
|
67
|
+
Component({
|
|
68
|
+
selector: 'column-header-menu',
|
|
69
|
+
standalone: true,
|
|
70
|
+
imports: [MatMenuModule, MatButtonModule, MatIconModule],
|
|
71
|
+
template: `
|
|
72
|
+
<button
|
|
73
|
+
mat-icon-button
|
|
74
|
+
[matMenuTriggerFor]="menu"
|
|
75
|
+
class="column-header-menu-trigger"
|
|
76
|
+
[attr.aria-label]="'Column options for ' + columnId"
|
|
77
|
+
>
|
|
78
|
+
<mat-icon>more_vert</mat-icon>
|
|
79
|
+
</button>
|
|
80
|
+
|
|
81
|
+
<mat-menu #menu="matMenu">
|
|
82
|
+
<button
|
|
83
|
+
mat-menu-item
|
|
84
|
+
[disabled]="!canPinLeft"
|
|
85
|
+
(click)="handlePinLeft()"
|
|
86
|
+
>
|
|
87
|
+
{{ menuItems[0].label }}
|
|
88
|
+
</button>
|
|
89
|
+
<button
|
|
90
|
+
mat-menu-item
|
|
91
|
+
[disabled]="!canPinRight"
|
|
92
|
+
(click)="handlePinRight()"
|
|
93
|
+
>
|
|
94
|
+
{{ menuItems[1].label }}
|
|
95
|
+
</button>
|
|
96
|
+
<button
|
|
97
|
+
mat-menu-item
|
|
98
|
+
[disabled]="!canUnpin"
|
|
99
|
+
(click)="handleUnpin()"
|
|
100
|
+
>
|
|
101
|
+
{{ menuItems[2].label }}
|
|
102
|
+
</button>
|
|
103
|
+
</mat-menu>
|
|
104
|
+
`,
|
|
105
|
+
styles: [`
|
|
106
|
+
.column-header-menu-trigger {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
transition: opacity 0.15s;
|
|
109
|
+
width: 24px;
|
|
110
|
+
height: 24px;
|
|
111
|
+
line-height: 24px;
|
|
112
|
+
padding: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
:host:hover .column-header-menu-trigger,
|
|
116
|
+
.column-header-menu-trigger:focus {
|
|
117
|
+
opacity: 1;
|
|
118
|
+
}
|
|
119
|
+
`],
|
|
120
|
+
})
|
|
121
|
+
], ColumnHeaderMenuComponent);
|
|
122
|
+
export { ColumnHeaderMenuComponent };
|
|
@@ -4,9 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component, input, computed, effect, ChangeDetectionStrategy, viewChild, } from '@angular/core';
|
|
8
|
-
import { DataGridStateService, ColumnReorderService, VirtualScrollService, buildHeaderRows, CHECKBOX_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, getHeaderFilterConfig, getCellRenderDescriptor, resolveCellDisplayContent, resolveCellStyle, } from '@alaarab/ogrid-angular';
|
|
7
|
+
import { Component, input, signal, computed, effect, ChangeDetectionStrategy, viewChild, } from '@angular/core';
|
|
8
|
+
import { DataGridStateService, ColumnReorderService, VirtualScrollService, MarchingAntsOverlayComponent, buildHeaderRows, CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, getHeaderFilterConfig, getCellRenderDescriptor, resolveCellDisplayContent, resolveCellStyle, } from '@alaarab/ogrid-angular';
|
|
9
9
|
import { ColumnHeaderFilterComponent } from '../column-header-filter/column-header-filter.component';
|
|
10
|
+
import { ColumnHeaderMenuComponent } from '../column-header-menu/column-header-menu.component';
|
|
10
11
|
/**
|
|
11
12
|
* DataGridTable component using native HTML table with Material Design-inspired styling.
|
|
12
13
|
* Standalone component — this is the workhorse of the grid.
|
|
@@ -20,6 +21,7 @@ let DataGridTableComponent = class DataGridTableComponent {
|
|
|
20
21
|
this.columnReorderService = new ColumnReorderService();
|
|
21
22
|
this.virtualScrollService = new VirtualScrollService();
|
|
22
23
|
this.lastMouseShift = false;
|
|
24
|
+
this.columnSizingVersion = signal(0);
|
|
23
25
|
// --- Delegated state ---
|
|
24
26
|
this.state = computed(() => this.stateService.getState());
|
|
25
27
|
this.items = computed(() => this.propsInput()?.items ?? []);
|
|
@@ -32,9 +34,13 @@ let DataGridTableComponent = class DataGridTableComponent {
|
|
|
32
34
|
this.ariaLabel = computed(() => this.propsInput()?.['aria-label'] ?? 'Data grid');
|
|
33
35
|
this.ariaLabelledBy = computed(() => this.propsInput()?.['aria-labelledby']);
|
|
34
36
|
this.emptyState = computed(() => this.propsInput()?.emptyState);
|
|
37
|
+
this.currentPage = computed(() => this.propsInput()?.currentPage ?? 1);
|
|
38
|
+
this.pageSize = computed(() => this.propsInput()?.pageSize ?? 25);
|
|
39
|
+
this.rowNumberOffset = computed(() => this.hasRowNumbersCol() ? (this.currentPage() - 1) * this.pageSize() : 0);
|
|
35
40
|
// State service outputs
|
|
36
41
|
this.visibleCols = computed(() => this.state().layout.visibleCols);
|
|
37
42
|
this.hasCheckboxCol = computed(() => this.state().layout.hasCheckboxCol);
|
|
43
|
+
this.hasRowNumbersCol = computed(() => this.state().layout.hasRowNumbersCol);
|
|
38
44
|
this.colOffset = computed(() => this.state().layout.colOffset);
|
|
39
45
|
this.containerWidth = computed(() => this.state().layout.containerWidth);
|
|
40
46
|
this.minTableWidth = computed(() => this.state().layout.minTableWidth);
|
|
@@ -84,10 +90,13 @@ let DataGridTableComponent = class DataGridTableComponent {
|
|
|
84
90
|
this.columnLayouts = computed(() => {
|
|
85
91
|
const cols = this.visibleCols();
|
|
86
92
|
const fc = this.freezeCols();
|
|
93
|
+
const props = this.propsInput();
|
|
94
|
+
const pinnedCols = props?.pinnedColumns ?? {};
|
|
87
95
|
return cols.map((col, colIdx) => {
|
|
88
96
|
const isFreezeCol = fc != null && fc >= 1 && colIdx < fc;
|
|
89
|
-
const
|
|
90
|
-
const
|
|
97
|
+
const runtimePinned = pinnedCols[col.columnId];
|
|
98
|
+
const pinnedLeft = runtimePinned === 'left' || (isFreezeCol && colIdx === 0);
|
|
99
|
+
const pinnedRight = runtimePinned === 'right';
|
|
91
100
|
const w = this.getColumnWidth(col);
|
|
92
101
|
return {
|
|
93
102
|
col,
|
|
@@ -203,6 +212,7 @@ let DataGridTableComponent = class DataGridTableComponent {
|
|
|
203
212
|
const newWidth = Math.max(minWidth, startWidth + delta);
|
|
204
213
|
const overrides = { ...this.columnSizingOverrides(), [col.columnId]: { widthPx: newWidth } };
|
|
205
214
|
this.state().layout.setColumnSizingOverrides(overrides);
|
|
215
|
+
this.columnSizingVersion.update(v => v + 1);
|
|
206
216
|
};
|
|
207
217
|
const onUp = () => {
|
|
208
218
|
window.removeEventListener('mousemove', onMove);
|
|
@@ -269,12 +279,33 @@ let DataGridTableComponent = class DataGridTableComponent {
|
|
|
269
279
|
onHeaderMouseDown(columnId, event) {
|
|
270
280
|
this.columnReorderService.handleHeaderMouseDown(columnId, event);
|
|
271
281
|
}
|
|
282
|
+
// --- Column pinning methods ---
|
|
283
|
+
onPinColumn(columnId, side) {
|
|
284
|
+
const props = this.propsInput();
|
|
285
|
+
props?.onColumnPinned?.(columnId, side);
|
|
286
|
+
}
|
|
287
|
+
onUnpinColumn(columnId) {
|
|
288
|
+
const props = this.propsInput();
|
|
289
|
+
props?.onColumnPinned?.(columnId, null);
|
|
290
|
+
}
|
|
291
|
+
isPinned(columnId) {
|
|
292
|
+
const props = this.propsInput();
|
|
293
|
+
return props?.pinnedColumns?.[columnId];
|
|
294
|
+
}
|
|
295
|
+
getPinState(columnId) {
|
|
296
|
+
const pinned = this.isPinned(columnId);
|
|
297
|
+
return {
|
|
298
|
+
canPinLeft: pinned !== 'left',
|
|
299
|
+
canPinRight: pinned !== 'right',
|
|
300
|
+
canUnpin: !!pinned,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
272
303
|
};
|
|
273
304
|
DataGridTableComponent = __decorate([
|
|
274
305
|
Component({
|
|
275
306
|
selector: 'ogrid-datagrid-table',
|
|
276
307
|
standalone: true,
|
|
277
|
-
imports: [ColumnHeaderFilterComponent],
|
|
308
|
+
imports: [ColumnHeaderFilterComponent, ColumnHeaderMenuComponent, MarchingAntsOverlayComponent],
|
|
278
309
|
providers: [DataGridStateService],
|
|
279
310
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
280
311
|
template: `
|
|
@@ -319,6 +350,14 @@ DataGridTableComponent = __decorate([
|
|
|
319
350
|
@if (rowIdx === 0 && rowIdx < headerRows().length - 1 && hasCheckboxCol()) {
|
|
320
351
|
<th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th" style="width: 48px; min-width: 48px; padding: 0;"></th>
|
|
321
352
|
}
|
|
353
|
+
@if (rowIdx === headerRows().length - 1 && hasRowNumbersCol()) {
|
|
354
|
+
<th class="ogrid-datagrid-th ogrid-row-number-header" [attr.rowSpan]="headerRows().length > 1 ? 1 : null">
|
|
355
|
+
<div class="ogrid-row-number-header-content">#</div>
|
|
356
|
+
</th>
|
|
357
|
+
}
|
|
358
|
+
@if (rowIdx === 0 && rowIdx < headerRows().length - 1 && hasRowNumbersCol()) {
|
|
359
|
+
<th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th" [style.width.px]="50" [style.min-width.px]="50" style="padding: 0;"></th>
|
|
360
|
+
}
|
|
322
361
|
@for (cell of row; track $index; let cellIdx = $index) {
|
|
323
362
|
@if (cell.isGroup) {
|
|
324
363
|
<th [attr.colSpan]="cell.colSpan" scope="colgroup" class="ogrid-datagrid-th ogrid-datagrid-group-header">
|
|
@@ -329,10 +368,13 @@ DataGridTableComponent = __decorate([
|
|
|
329
368
|
@let colIdx = visibleColIndex(col);
|
|
330
369
|
@let isFreezeCol = freezeCols() != null && (freezeCols() ?? 0) >= 1 && colIdx < (freezeCols() ?? 0);
|
|
331
370
|
@let colW = getColumnWidth(col);
|
|
371
|
+
@let pinned = isPinned(col.columnId);
|
|
372
|
+
@let pinnedLeft = pinned === 'left' || (isFreezeCol && colIdx === 0);
|
|
373
|
+
@let pinnedRight = pinned === 'right';
|
|
332
374
|
<th scope="col"
|
|
333
375
|
class="ogrid-datagrid-th"
|
|
334
|
-
[class.ogrid-datagrid-th--pinned-left]="
|
|
335
|
-
[class.ogrid-datagrid-th--pinned-right]="
|
|
376
|
+
[class.ogrid-datagrid-th--pinned-left]="pinnedLeft"
|
|
377
|
+
[class.ogrid-datagrid-th--pinned-right]="pinnedRight"
|
|
336
378
|
[attr.rowSpan]="headerRows().length > 1 ? headerRows().length - rowIdx : null"
|
|
337
379
|
[attr.data-column-id]="col.columnId"
|
|
338
380
|
[style.minWidth.px]="col.minWidth ?? 80"
|
|
@@ -341,25 +383,37 @@ DataGridTableComponent = __decorate([
|
|
|
341
383
|
[style.cursor]="columnReorderService.isDragging() ? 'grabbing' : 'grab'"
|
|
342
384
|
(mousedown)="onHeaderMouseDown(col.columnId, $event)"
|
|
343
385
|
>
|
|
344
|
-
<
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
386
|
+
<div style="display:flex;align-items:center;gap:4px;">
|
|
387
|
+
<ogrid-column-header-filter
|
|
388
|
+
[columnKey]="col.columnId"
|
|
389
|
+
[columnName]="col.name"
|
|
390
|
+
[filterType]="getFilterConfig(col).filterType"
|
|
391
|
+
[isSorted]="getFilterConfig(col).isSorted"
|
|
392
|
+
[isSortedDescending]="getFilterConfig(col).isSortedDescending"
|
|
393
|
+
[onSort]="getFilterConfig(col).onSort"
|
|
394
|
+
[selectedValues]="getFilterConfig(col).selectedValues"
|
|
395
|
+
[onFilterChange]="getFilterConfig(col).onFilterChange"
|
|
396
|
+
[options]="getFilterConfig(col).options"
|
|
397
|
+
[isLoadingOptions]="getFilterConfig(col).isLoadingOptions ?? false"
|
|
398
|
+
[textValue]="getFilterConfig(col).textValue ?? ''"
|
|
399
|
+
[onTextChange]="getFilterConfig(col).onTextChange"
|
|
400
|
+
[selectedUser]="getFilterConfig(col).selectedUser"
|
|
401
|
+
[onUserChange]="getFilterConfig(col).onUserChange"
|
|
402
|
+
[peopleSearch]="getFilterConfig(col).peopleSearch"
|
|
403
|
+
[dateValue]="getFilterConfig(col).dateValue"
|
|
404
|
+
[onDateChange]="getFilterConfig(col).onDateChange"
|
|
405
|
+
/>
|
|
406
|
+
@let pinState = getPinState(col.columnId);
|
|
407
|
+
<column-header-menu
|
|
408
|
+
[columnId]="col.columnId"
|
|
409
|
+
[onPinLeft]="() => onPinColumn(col.columnId, 'left')"
|
|
410
|
+
[onPinRight]="() => onPinColumn(col.columnId, 'right')"
|
|
411
|
+
[onUnpin]="() => onUnpinColumn(col.columnId)"
|
|
412
|
+
[canPinLeft]="pinState.canPinLeft"
|
|
413
|
+
[canPinRight]="pinState.canPinRight"
|
|
414
|
+
[canUnpin]="pinState.canUnpin"
|
|
415
|
+
/>
|
|
416
|
+
</div>
|
|
363
417
|
<div class="ogrid-datagrid-resize-handle" (mousedown)="onResizeStart($event, col)"></div>
|
|
364
418
|
</th>
|
|
365
419
|
}
|
|
@@ -395,6 +449,13 @@ DataGridTableComponent = __decorate([
|
|
|
395
449
|
</div>
|
|
396
450
|
</td>
|
|
397
451
|
}
|
|
452
|
+
@if (hasRowNumbersCol()) {
|
|
453
|
+
<td class="ogrid-datagrid-td ogrid-row-number-cell">
|
|
454
|
+
<div class="ogrid-row-number-cell-content">
|
|
455
|
+
{{ rowNumberOffset() + rowIndex + 1 }}
|
|
456
|
+
</div>
|
|
457
|
+
</td>
|
|
458
|
+
}
|
|
398
459
|
@for (colLayout of columnLayouts(); track colLayout.col.columnId; let colIdx = $index) {
|
|
399
460
|
<td
|
|
400
461
|
class="ogrid-datagrid-td"
|
|
@@ -487,6 +548,15 @@ DataGridTableComponent = __decorate([
|
|
|
487
548
|
}
|
|
488
549
|
</table>
|
|
489
550
|
|
|
551
|
+
<ogrid-marching-ants-overlay
|
|
552
|
+
[containerEl]="tableContainerEl()"
|
|
553
|
+
[selectionRange]="state().interaction.selectionRange"
|
|
554
|
+
[copyRange]="state().interaction.copyRange"
|
|
555
|
+
[cutRange]="state().interaction.cutRange"
|
|
556
|
+
[colOffset]="state().layout.colOffset"
|
|
557
|
+
[columnSizingVersion]="columnSizingVersion()"
|
|
558
|
+
></ogrid-marching-ants-overlay>
|
|
559
|
+
|
|
490
560
|
@if (showEmptyInGrid() && emptyState()) {
|
|
491
561
|
<div class="ogrid-datagrid-empty">
|
|
492
562
|
<div class="ogrid-datagrid-empty__title">No results found</div>
|
|
@@ -583,9 +653,11 @@ DataGridTableComponent = __decorate([
|
|
|
583
653
|
}
|
|
584
654
|
.ogrid-datagrid-th--pinned-left {
|
|
585
655
|
position: sticky; left: 0; z-index: 9; background: rgba(0,0,0,0.04); will-change: transform;
|
|
656
|
+
border-left: 2px solid var(--mat-sys-primary, #1976d2);
|
|
586
657
|
}
|
|
587
658
|
.ogrid-datagrid-th--pinned-right {
|
|
588
659
|
position: sticky; right: 0; z-index: 9; background: rgba(0,0,0,0.04); will-change: transform;
|
|
660
|
+
border-right: 2px solid var(--mat-sys-primary, #1976d2);
|
|
589
661
|
}
|
|
590
662
|
.ogrid-datagrid-group-header {
|
|
591
663
|
text-align: center; font-weight: 600; border-bottom: 2px solid rgba(0,0,0,0.12); padding: 6px;
|
|
@@ -595,15 +667,28 @@ DataGridTableComponent = __decorate([
|
|
|
595
667
|
max-width: ${CHECKBOX_COLUMN_WIDTH}px; text-align: center;
|
|
596
668
|
}
|
|
597
669
|
.ogrid-datagrid-checkbox-wrapper { display: flex; align-items: center; justify-content: center; }
|
|
670
|
+
.ogrid-row-number-header, .ogrid-row-number-cell {
|
|
671
|
+
width: ${ROW_NUMBER_COLUMN_WIDTH}px; min-width: ${ROW_NUMBER_COLUMN_WIDTH}px;
|
|
672
|
+
max-width: ${ROW_NUMBER_COLUMN_WIDTH}px; text-align: center;
|
|
673
|
+
background: rgba(0,0,0,0.04); font-weight: 600;
|
|
674
|
+
font-variant-numeric: tabular-nums; color: rgba(0,0,0,0.6);
|
|
675
|
+
position: sticky; left: 0; z-index: 3;
|
|
676
|
+
}
|
|
677
|
+
.ogrid-row-number-header { z-index: 4; }
|
|
678
|
+
.ogrid-row-number-header-content, .ogrid-row-number-cell-content {
|
|
679
|
+
display: flex; align-items: center; justify-content: center;
|
|
680
|
+
}
|
|
598
681
|
.ogrid-datagrid-row { }
|
|
599
682
|
.ogrid-datagrid-row:hover { background: rgba(0,0,0,0.04); }
|
|
600
683
|
.ogrid-datagrid-row--selected { background: rgba(25,118,210,0.08); }
|
|
601
684
|
.ogrid-datagrid-td { position: relative; padding: 0; height: 1px; border-bottom: 1px solid rgba(0,0,0,0.06); }
|
|
602
685
|
.ogrid-datagrid-td--pinned-left {
|
|
603
686
|
position: sticky; left: 0; z-index: 6; background: #fff; will-change: transform;
|
|
687
|
+
border-left: 2px solid var(--mat-sys-primary, #1976d2);
|
|
604
688
|
}
|
|
605
689
|
.ogrid-datagrid-td--pinned-right {
|
|
606
690
|
position: sticky; right: 0; z-index: 6; background: #fff; will-change: transform;
|
|
691
|
+
border-right: 2px solid var(--mat-sys-primary, #1976d2);
|
|
607
692
|
}
|
|
608
693
|
.ogrid-datagrid-cell {
|
|
609
694
|
width: 100%; height: 100%; display: flex; align-items: center; min-width: 0;
|
|
@@ -623,7 +708,10 @@ DataGridTableComponent = __decorate([
|
|
|
623
708
|
.ogrid-datagrid-cell--editing { padding: 0; }
|
|
624
709
|
.ogrid-datagrid-editor-input {
|
|
625
710
|
width: 100%; height: 100%; padding: 6px 10px; border: 2px solid var(--ogrid-selection, #217346);
|
|
626
|
-
box-sizing: border-box; font-size: 14px; outline: none;
|
|
711
|
+
box-sizing: border-box; font-size: 14px; outline: none; font-family: inherit; line-height: inherit;
|
|
712
|
+
}
|
|
713
|
+
.ogrid-datagrid-cell--numeric .ogrid-datagrid-editor-input {
|
|
714
|
+
text-align: right;
|
|
627
715
|
}
|
|
628
716
|
.ogrid-datagrid-editor-select {
|
|
629
717
|
width: 100%; height: 100%; padding: 4px 8px; border: 2px solid var(--ogrid-selection, #217346);
|
package/dist/esm/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export { DataGridTableComponent } from './datagrid-table/datagrid-table.componen
|
|
|
6
6
|
export { ColumnHeaderFilterComponent } from './column-header-filter/column-header-filter.component';
|
|
7
7
|
export { ColumnChooserComponent } from './column-chooser/column-chooser.component';
|
|
8
8
|
export { PaginationControlsComponent } from './pagination-controls/pagination-controls.component';
|
|
9
|
+
export { ColumnHeaderMenuComponent } from './column-header-menu/column-header-menu.component';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { MatMenuTrigger } from '@angular/material/menu';
|
|
3
|
+
/**
|
|
4
|
+
* Column header dropdown menu for pin/unpin actions.
|
|
5
|
+
* Uses Angular Material MatMenu.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ColumnHeaderMenuComponent {
|
|
8
|
+
columnId: string;
|
|
9
|
+
canPinLeft: boolean;
|
|
10
|
+
canPinRight: boolean;
|
|
11
|
+
canUnpin: boolean;
|
|
12
|
+
pinLeft: EventEmitter<void>;
|
|
13
|
+
pinRight: EventEmitter<void>;
|
|
14
|
+
unpin: EventEmitter<void>;
|
|
15
|
+
menuTrigger?: MatMenuTrigger;
|
|
16
|
+
readonly menuItems: import("@alaarab/ogrid-core").IColumnHeaderMenuItem[];
|
|
17
|
+
handlePinLeft(): void;
|
|
18
|
+
handlePinRight(): void;
|
|
19
|
+
handleUnpin(): void;
|
|
20
|
+
}
|
|
@@ -12,6 +12,7 @@ export declare class DataGridTableComponent<T> {
|
|
|
12
12
|
readonly columnReorderService: ColumnReorderService<T>;
|
|
13
13
|
readonly virtualScrollService: VirtualScrollService;
|
|
14
14
|
private lastMouseShift;
|
|
15
|
+
private columnSizingVersion;
|
|
15
16
|
constructor();
|
|
16
17
|
private readonly state;
|
|
17
18
|
readonly items: import("@angular/core").Signal<T[]>;
|
|
@@ -29,8 +30,12 @@ export declare class DataGridTableComponent<T> {
|
|
|
29
30
|
message?: string;
|
|
30
31
|
render?: import("@angular/core").TemplateRef<unknown>;
|
|
31
32
|
} | undefined>;
|
|
33
|
+
readonly currentPage: import("@angular/core").Signal<number>;
|
|
34
|
+
readonly pageSize: import("@angular/core").Signal<number>;
|
|
35
|
+
readonly rowNumberOffset: import("@angular/core").Signal<number>;
|
|
32
36
|
readonly visibleCols: import("@angular/core").Signal<IColumnDef<T>[]>;
|
|
33
37
|
readonly hasCheckboxCol: import("@angular/core").Signal<boolean>;
|
|
38
|
+
readonly hasRowNumbersCol: import("@angular/core").Signal<boolean>;
|
|
34
39
|
readonly colOffset: import("@angular/core").Signal<number>;
|
|
35
40
|
readonly containerWidth: import("@angular/core").Signal<number>;
|
|
36
41
|
readonly minTableWidth: import("@angular/core").Signal<number>;
|
|
@@ -46,11 +51,11 @@ export declare class DataGridTableComponent<T> {
|
|
|
46
51
|
columnId: string;
|
|
47
52
|
} | null>;
|
|
48
53
|
readonly pendingEditorValue: import("@angular/core").Signal<unknown>;
|
|
49
|
-
readonly activeCell: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
50
|
-
readonly selectionRange: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
54
|
+
readonly activeCell: import("@angular/core").Signal<import("@alaarab/ogrid-core").IActiveCell | null>;
|
|
55
|
+
readonly selectionRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
51
56
|
readonly hasCellSelection: import("@angular/core").Signal<boolean>;
|
|
52
|
-
readonly cutRange: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
53
|
-
readonly copyRange: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
57
|
+
readonly cutRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
58
|
+
readonly copyRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
54
59
|
readonly canUndo: import("@angular/core").Signal<boolean>;
|
|
55
60
|
readonly canRedo: import("@angular/core").Signal<boolean>;
|
|
56
61
|
readonly isDragging: import("@angular/core").Signal<boolean>;
|
|
@@ -58,37 +63,37 @@ export declare class DataGridTableComponent<T> {
|
|
|
58
63
|
x: number;
|
|
59
64
|
y: number;
|
|
60
65
|
} | null>;
|
|
61
|
-
readonly statusBarConfig: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
66
|
+
readonly statusBarConfig: import("@angular/core").Signal<import("@alaarab/ogrid-core").IStatusBarProps | null>;
|
|
62
67
|
readonly showEmptyInGrid: import("@angular/core").Signal<boolean>;
|
|
63
68
|
readonly headerFilterInput: import("@angular/core").Signal<{
|
|
64
69
|
sortBy?: string;
|
|
65
70
|
sortDirection: "asc" | "desc";
|
|
66
71
|
onColumnSort: (columnKey: string) => void;
|
|
67
|
-
filters: import("@alaarab/ogrid-
|
|
68
|
-
onFilterChange: (key: string, value: import("@alaarab/ogrid-
|
|
72
|
+
filters: import("@alaarab/ogrid-core").IFilters;
|
|
73
|
+
onFilterChange: (key: string, value: import("@alaarab/ogrid-core").FilterValue | undefined) => void;
|
|
69
74
|
filterOptions: Record<string, string[]>;
|
|
70
75
|
loadingFilterOptions: Record<string, boolean>;
|
|
71
|
-
peopleSearch?: (query: string) => Promise<import("@alaarab/ogrid-
|
|
76
|
+
peopleSearch?: (query: string) => Promise<import("@alaarab/ogrid-core").UserLike[]>;
|
|
72
77
|
}>;
|
|
73
78
|
readonly cellDescriptorInput: import("@angular/core").Signal<{
|
|
74
79
|
editingCell: {
|
|
75
80
|
rowId: RowId;
|
|
76
81
|
columnId: string;
|
|
77
82
|
} | null;
|
|
78
|
-
activeCell: import("@alaarab/ogrid-
|
|
79
|
-
selectionRange: import("@alaarab/ogrid-
|
|
80
|
-
cutRange: import("@alaarab/ogrid-
|
|
81
|
-
copyRange: import("@alaarab/ogrid-
|
|
83
|
+
activeCell: import("@alaarab/ogrid-core").IActiveCell | null;
|
|
84
|
+
selectionRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
85
|
+
cutRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
86
|
+
copyRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
82
87
|
colOffset: number;
|
|
83
88
|
itemsLength: number;
|
|
84
89
|
getRowId: (item: T) => RowId;
|
|
85
90
|
editable?: boolean;
|
|
86
|
-
onCellValueChanged?: ((event: import("@alaarab/ogrid-
|
|
91
|
+
onCellValueChanged?: ((event: import("@alaarab/ogrid-core").ICellValueChangedEvent<T>) => void) | undefined;
|
|
87
92
|
isDragging: boolean;
|
|
88
93
|
}>;
|
|
89
94
|
readonly allowOverflowX: import("@angular/core").Signal<boolean>;
|
|
90
95
|
readonly selectionCellCount: import("@angular/core").Signal<number | undefined>;
|
|
91
|
-
readonly headerRows: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
96
|
+
readonly headerRows: import("@angular/core").Signal<import("@alaarab/ogrid-core").HeaderRow<T>[]>;
|
|
92
97
|
readonly columnLayouts: import("@angular/core").Signal<{
|
|
93
98
|
col: IColumnDef<T>;
|
|
94
99
|
pinnedLeft: boolean;
|
|
@@ -127,4 +132,12 @@ export declare class DataGridTableComponent<T> {
|
|
|
127
132
|
onUndo(): void;
|
|
128
133
|
onRedo(): void;
|
|
129
134
|
onHeaderMouseDown(columnId: string, event: MouseEvent): void;
|
|
135
|
+
onPinColumn(columnId: string, side: 'left' | 'right'): void;
|
|
136
|
+
onUnpinColumn(columnId: string): void;
|
|
137
|
+
isPinned(columnId: string): 'left' | 'right' | undefined;
|
|
138
|
+
getPinState(columnId: string): {
|
|
139
|
+
canPinLeft: boolean;
|
|
140
|
+
canPinRight: boolean;
|
|
141
|
+
canUnpin: boolean;
|
|
142
|
+
};
|
|
130
143
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export type { IColumnHeaderFilterProps } from './column-header-filter/column-hea
|
|
|
6
6
|
export { ColumnChooserComponent } from './column-chooser/column-chooser.component';
|
|
7
7
|
export type { IColumnChooserProps } from './column-chooser/column-chooser.component';
|
|
8
8
|
export { PaginationControlsComponent } from './pagination-controls/pagination-controls.component';
|
|
9
|
+
export { ColumnHeaderMenuComponent } from './column-header-menu/column-header-menu.component';
|
|
@@ -10,6 +10,6 @@ export declare class PaginationControlsComponent {
|
|
|
10
10
|
readonly entityLabelPlural: import("@angular/core").InputSignal<string>;
|
|
11
11
|
readonly pageChange: import("@angular/core").OutputEmitterRef<number>;
|
|
12
12
|
readonly pageSizeChange: import("@angular/core").OutputEmitterRef<number>;
|
|
13
|
-
readonly vm: import("@angular/core").Signal<import("@alaarab/ogrid-
|
|
13
|
+
readonly vm: import("@angular/core").Signal<import("@alaarab/ogrid-core").PaginationViewModel | null>;
|
|
14
14
|
onPageSizeSelect(event: Event): void;
|
|
15
15
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-angular-material",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "OGrid Angular Material – MatTable-based data grid with sorting, filtering, pagination, column chooser, and CSV export.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"files": ["dist", "README.md", "LICENSE"],
|
|
23
23
|
"engines": { "node": ">=18" },
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@alaarab/ogrid-angular": "2.0.
|
|
25
|
+
"@alaarab/ogrid-angular": "2.0.5"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@angular/core": "^21.0.0",
|