@alaarab/ogrid-angular-primeng 2.0.7 → 2.0.9

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.
@@ -9,6 +9,7 @@ import { BaseDataGridTableComponent, DataGridStateService, StatusBarComponent, G
9
9
  import { ColumnHeaderFilterComponent } from '../column-header-filter/column-header-filter.component';
10
10
  import { ColumnHeaderMenuComponent } from '../column-header-menu/column-header-menu.component';
11
11
  import { InlineCellEditorComponent } from './inline-cell-editor.component';
12
+ import { PopoverCellEditorComponent } from './popover-cell-editor.component';
12
13
  let DataGridTableComponent = class DataGridTableComponent extends BaseDataGridTableComponent {
13
14
  constructor() {
14
15
  super();
@@ -125,7 +126,8 @@ let DataGridTableComponent = class DataGridTableComponent extends BaseDataGridTa
125
126
  }
126
127
  resolveCellDisplay(col, item) {
127
128
  const value = getCellValue(item, col);
128
- return resolveCellDisplayContent(col, item, value);
129
+ const result = resolveCellDisplayContent(col, item, value);
130
+ return result != null ? String(result) : '';
129
131
  }
130
132
  getCellStyleObj(col, item) {
131
133
  return resolveCellStyle(col, item) ?? null;
@@ -140,6 +142,26 @@ let DataGridTableComponent = class DataGridTableComponent extends BaseDataGridTa
140
142
  return false;
141
143
  return editing.rowId === this.getRowIdInput()(item) && editing.columnId === col.columnId;
142
144
  }
145
+ isEditingCellInline(item, col) {
146
+ return this.isEditingCell(item, col) && typeof col.cellEditor !== 'function';
147
+ }
148
+ isEditingCellPopover(item, col) {
149
+ return this.isEditingCell(item, col) && typeof col.cellEditor === 'function';
150
+ }
151
+ buildPopoverEditorPropsForPrimeng(item, col, rowIndex, colIdx) {
152
+ const oldValue = getCellValue(item, col);
153
+ const pendingValue = this.pendingEditorValue();
154
+ const displayValue = pendingValue !== undefined ? pendingValue : oldValue;
155
+ return {
156
+ value: displayValue,
157
+ onValueChange: (value) => this.setPendingEditorValue(value),
158
+ item,
159
+ column: col,
160
+ rowIndex,
161
+ onCommit: (newValue) => this.onCellEditorCommit(item, col, rowIndex, colIdx, newValue),
162
+ onCancel: () => this.cancelEdit(),
163
+ };
164
+ }
143
165
  getEditorType(col, _item) {
144
166
  if (col.cellEditor === 'text' || col.cellEditor === 'select' || col.cellEditor === 'checkbox' || col.cellEditor === 'date' || col.cellEditor === 'richSelect') {
145
167
  return col.cellEditor;
@@ -290,6 +312,7 @@ DataGridTableComponent = __decorate([
290
312
  ColumnHeaderFilterComponent,
291
313
  ColumnHeaderMenuComponent,
292
314
  InlineCellEditorComponent,
315
+ PopoverCellEditorComponent,
293
316
  ],
294
317
  changeDetection: ChangeDetectionStrategy.OnPush,
295
318
  providers: [DataGridStateService],
@@ -310,6 +333,7 @@ DataGridTableComponent = __decorate([
310
333
  (contextmenu)="$event.preventDefault()"
311
334
  (keydown)="onGridKeyDown($event)"
312
335
  (mousedown)="onWrapperMouseDown($event)"
336
+ (scroll)="onWrapperScroll($event)"
313
337
  style="flex:1;min-height:0;overflow:auto;outline:none;position:relative;font-size:13px;color:var(--ogrid-fg, #242424)"
314
338
  [style.--data-table-column-count]="state().layout.totalColCount"
315
339
  [style.--data-table-width]="tableWidthStyle()"
@@ -424,7 +448,11 @@ DataGridTableComponent = __decorate([
424
448
 
425
449
  @if (!showEmptyInGrid()) {
426
450
  <tbody>
427
- @for (item of items(); track trackByRowId($index, item); let rowIndex = $index) {
451
+ @if (vsEnabled() && vsTopSpacerHeight() > 0) {
452
+ <tr [style.height.px]="vsTopSpacerHeight()"></tr>
453
+ }
454
+ @for (item of vsVisibleItems(); track trackByRowId($index, item); let localIdx = $index) {
455
+ @let rowIndex = vsStartIndex() + localIdx;
428
456
  @let rowId = getRowIdInput()(item);
429
457
  @let isSelected = selectedRowIds().has(rowId);
430
458
  <tr
@@ -465,7 +493,7 @@ DataGridTableComponent = __decorate([
465
493
  [style.max-width.px]="getColumnWidth(col)"
466
494
  [style.text-align]="col.type === 'numeric' ? 'right' : col.type === 'boolean' ? 'center' : null"
467
495
  >
468
- @if (isEditingCell(item, col)) {
496
+ @if (isEditingCellInline(item, col)) {
469
497
  <ogrid-primeng-inline-cell-editor
470
498
  [value]="getCellValueFn(item, col)"
471
499
  [item]="item"
@@ -475,6 +503,17 @@ DataGridTableComponent = __decorate([
475
503
  (commit)="onCellEditorCommit(item, col, rowIndex, colIdx, $event)"
476
504
  (cancel)="cancelEdit()"
477
505
  ></ogrid-primeng-inline-cell-editor>
506
+ } @else if (isEditingCellPopover(item, col)) {
507
+ @let editorProps = buildPopoverEditorPropsForPrimeng(item, col, rowIndex, colIdx);
508
+ <ogrid-primeng-popover-cell-editor
509
+ [item]="item"
510
+ [column]="col"
511
+ [rowIndex]="rowIndex"
512
+ [globalColIndex]="colIdx + colOffset()"
513
+ [displayValue]="getCellValueFn(item, col)"
514
+ [editorProps]="editorProps"
515
+ [onCancel]="() => cancelEdit()"
516
+ ></ogrid-primeng-popover-cell-editor>
478
517
  } @else {
479
518
  <div
480
519
  [attr.data-row-index]="rowIndex"
@@ -502,6 +541,9 @@ DataGridTableComponent = __decorate([
502
541
  }
503
542
  </tr>
504
543
  }
544
+ @if (vsEnabled() && vsBottomSpacerHeight() > 0) {
545
+ <tr [style.height.px]="vsBottomSpacerHeight()"></tr>
546
+ }
505
547
  </tbody>
506
548
  }
507
549
  </table>
@@ -0,0 +1,99 @@
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, ChangeDetectionStrategy, signal, effect, viewChild, Injector, createComponent, EnvironmentInjector, inject, } from '@angular/core';
8
+ /**
9
+ * PopoverCellEditor component for Angular PrimeNG.
10
+ * Renders custom popover editor when anchor element is set.
11
+ */
12
+ let PopoverCellEditorComponent = class PopoverCellEditorComponent {
13
+ constructor() {
14
+ this.item = input.required();
15
+ this.column = input.required();
16
+ this.rowIndex = input.required();
17
+ this.globalColIndex = input.required();
18
+ this.displayValue = input.required();
19
+ this.editorProps = input.required();
20
+ this.onCancel = input.required();
21
+ this.anchorRef = viewChild('anchorEl');
22
+ this.editorContainerRef = viewChild('editorContainer');
23
+ this.injector = inject(Injector);
24
+ this.envInjector = inject(EnvironmentInjector);
25
+ this.showEditor = signal(false);
26
+ // Show editor after anchor is rendered
27
+ effect(() => {
28
+ const anchor = this.anchorRef();
29
+ if (anchor) {
30
+ setTimeout(() => this.showEditor.set(true), 0);
31
+ }
32
+ });
33
+ // Render custom editor component when container is available
34
+ effect(() => {
35
+ const container = this.editorContainerRef();
36
+ const props = this.editorProps();
37
+ const col = this.column();
38
+ if (!container || !this.showEditor() || typeof col.cellEditor !== 'function')
39
+ return;
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ const EditorComponent = col.cellEditor; // ComponentType
42
+ const componentRef = createComponent(EditorComponent, {
43
+ environmentInjector: this.envInjector,
44
+ elementInjector: this.injector,
45
+ });
46
+ // Pass props to component instance
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ Object.assign(componentRef.instance, props);
49
+ componentRef.changeDetectorRef.detectChanges();
50
+ // Append to DOM
51
+ container.nativeElement.appendChild(componentRef.location.nativeElement);
52
+ // Cleanup on destroy
53
+ return () => componentRef.destroy();
54
+ });
55
+ }
56
+ handleOverlayClick() {
57
+ this.onCancel()();
58
+ }
59
+ };
60
+ PopoverCellEditorComponent = __decorate([
61
+ Component({
62
+ selector: 'ogrid-primeng-popover-cell-editor',
63
+ standalone: true,
64
+ changeDetection: ChangeDetectionStrategy.OnPush,
65
+ template: `
66
+ <div #anchorEl
67
+ class="ogrid-popover-anchor"
68
+ [attr.data-row-index]="rowIndex()"
69
+ [attr.data-col-index]="globalColIndex()"
70
+ >
71
+ {{ displayValue() }}
72
+ </div>
73
+ @if (showEditor()) {
74
+ <div class="ogrid-popover-editor-overlay" (click)="handleOverlayClick()">
75
+ <div class="ogrid-popover-editor-content" #editorContainer></div>
76
+ </div>
77
+ }
78
+ `,
79
+ styles: [`
80
+ :host { display: contents; }
81
+ .ogrid-popover-anchor {
82
+ padding: 6px 10px; min-height: 20px; cursor: default; overflow: hidden;
83
+ text-overflow: ellipsis; white-space: nowrap;
84
+ outline: 2px solid var(--ogrid-selection, #217346); outline-offset: -2px;
85
+ }
86
+ .ogrid-popover-editor-overlay {
87
+ position: fixed; inset: 0; z-index: 1000;
88
+ background: rgba(0,0,0,0.3);
89
+ display: flex; align-items: center; justify-content: center;
90
+ }
91
+ .ogrid-popover-editor-content {
92
+ background: #fff; border-radius: 4px; padding: 16px;
93
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
94
+ max-width: 90vw; max-height: 90vh; overflow: auto;
95
+ }
96
+ `],
97
+ })
98
+ ], PopoverCellEditorComponent);
99
+ export { PopoverCellEditorComponent };
package/dist/esm/index.js CHANGED
@@ -4,6 +4,7 @@ export * from '@alaarab/ogrid-angular';
4
4
  export { OGridComponent } from './ogrid/ogrid.component';
5
5
  export { DataGridTableComponent } from './datagrid-table/datagrid-table.component';
6
6
  export { InlineCellEditorComponent } from './datagrid-table/inline-cell-editor.component';
7
+ export { PopoverCellEditorComponent } from './datagrid-table/popover-cell-editor.component';
7
8
  export { ColumnHeaderFilterComponent } from './column-header-filter/column-header-filter.component';
8
9
  export { ColumnChooserComponent } from './column-chooser/column-chooser.component';
9
10
  export { PaginationControlsComponent } from './pagination-controls/pagination-controls.component';
@@ -1,4 +1,9 @@
1
1
  import type { IColumnDefinition } from '@alaarab/ogrid-angular';
2
+ export interface IColumnChooserProps {
3
+ columns: IColumnDefinition[];
4
+ visibleColumns: Set<string>;
5
+ onVisibilityChange: (columnKey: string, visible: boolean) => void;
6
+ }
2
7
  export declare class ColumnChooserComponent {
3
8
  readonly columns: import("@angular/core").InputSignal<IColumnDefinition[]>;
4
9
  readonly visibleColumns: import("@angular/core").InputSignal<Set<string>>;
@@ -1,5 +1,24 @@
1
1
  import { ElementRef } from '@angular/core';
2
2
  import type { ColumnFilterType, IDateFilterValue, UserLike } from '@alaarab/ogrid-angular';
3
+ export interface IColumnHeaderFilterProps {
4
+ columnKey: string;
5
+ columnName: string;
6
+ filterType: ColumnFilterType;
7
+ isSorted?: boolean;
8
+ isSortedDescending?: boolean;
9
+ onSort?: () => void;
10
+ selectedValues?: string[];
11
+ onFilterChange?: (values: string[]) => void;
12
+ options?: string[];
13
+ isLoadingOptions?: boolean;
14
+ textValue?: string;
15
+ onTextChange?: (value: string) => void;
16
+ selectedUser?: UserLike;
17
+ onUserChange?: (user: UserLike | undefined) => void;
18
+ peopleSearch?: (query: string) => Promise<UserLike[]>;
19
+ dateValue?: IDateFilterValue;
20
+ onDateChange?: (value: IDateFilterValue | undefined) => void;
21
+ }
3
22
  export declare class ColumnHeaderFilterComponent {
4
23
  private destroyRef;
5
24
  readonly columnKey: import("@angular/core").InputSignal<string>;
@@ -86,6 +86,9 @@ export declare class DataGridTableComponent<T = unknown> extends BaseDataGridTab
86
86
  getCellStyleObj(col: IColumnDef<T>, item: T): Record<string, string> | null;
87
87
  canEditCell(col: IColumnDef<T>, item: T): boolean;
88
88
  isEditingCell(item: T, col: IColumnDef<T>): boolean;
89
+ isEditingCellInline(item: T, col: IColumnDef<T>): boolean;
90
+ isEditingCellPopover(item: T, col: IColumnDef<T>): boolean;
91
+ buildPopoverEditorPropsForPrimeng(item: T, col: IColumnDef<T>, rowIndex: number, colIdx: number): unknown;
89
92
  getEditorType(col: IColumnDef<T>, _item: T): 'text' | 'select' | 'checkbox' | 'date' | 'richSelect';
90
93
  isActiveCell(rowIndex: number, colIdx: number): boolean;
91
94
  isInSelectionRange(rowIndex: number, colIdx: number): boolean;
@@ -0,0 +1,21 @@
1
+ import type { IColumnDef, ICellEditorProps } from '@alaarab/ogrid-core';
2
+ /**
3
+ * PopoverCellEditor component for Angular PrimeNG.
4
+ * Renders custom popover editor when anchor element is set.
5
+ */
6
+ export declare class PopoverCellEditorComponent<T> {
7
+ readonly item: import("@angular/core").InputSignal<T>;
8
+ readonly column: import("@angular/core").InputSignal<IColumnDef<T>>;
9
+ readonly rowIndex: import("@angular/core").InputSignal<number>;
10
+ readonly globalColIndex: import("@angular/core").InputSignal<number>;
11
+ readonly displayValue: import("@angular/core").InputSignal<unknown>;
12
+ readonly editorProps: import("@angular/core").InputSignal<ICellEditorProps<T>>;
13
+ readonly onCancel: import("@angular/core").InputSignal<() => void>;
14
+ private readonly anchorRef;
15
+ private readonly editorContainerRef;
16
+ private readonly injector;
17
+ private readonly envInjector;
18
+ protected readonly showEditor: import("@angular/core").WritableSignal<boolean>;
19
+ constructor();
20
+ protected handleOverlayClick(): void;
21
+ }
@@ -2,7 +2,10 @@ export * from '@alaarab/ogrid-angular';
2
2
  export { OGridComponent } from './ogrid/ogrid.component';
3
3
  export { DataGridTableComponent } from './datagrid-table/datagrid-table.component';
4
4
  export { InlineCellEditorComponent } from './datagrid-table/inline-cell-editor.component';
5
+ export { PopoverCellEditorComponent } from './datagrid-table/popover-cell-editor.component';
5
6
  export { ColumnHeaderFilterComponent } from './column-header-filter/column-header-filter.component';
7
+ export type { IColumnHeaderFilterProps } from './column-header-filter/column-header-filter.component';
6
8
  export { ColumnChooserComponent } from './column-chooser/column-chooser.component';
9
+ export type { IColumnChooserProps } from './column-chooser/column-chooser.component';
7
10
  export { PaginationControlsComponent } from './pagination-controls/pagination-controls.component';
8
11
  export { ColumnHeaderMenuComponent } from './column-header-menu/column-header-menu.component';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid-angular-primeng",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "OGrid PrimeNG – PrimeNG Table-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",
@@ -16,13 +16,26 @@
16
16
  "build": "rimraf dist && tsc -p tsconfig.build.json",
17
17
  "test": "jest --passWithNoTests"
18
18
  },
19
- "keywords": ["ogrid", "angular", "primeng", "datatable", "typescript", "grid"],
19
+ "keywords": [
20
+ "ogrid",
21
+ "angular",
22
+ "primeng",
23
+ "datatable",
24
+ "typescript",
25
+ "grid"
26
+ ],
20
27
  "author": "Ala Arab",
21
28
  "license": "MIT",
22
- "files": ["dist", "README.md", "LICENSE"],
23
- "engines": { "node": ">=18" },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "engines": {
35
+ "node": ">=18"
36
+ },
24
37
  "dependencies": {
25
- "@alaarab/ogrid-angular": "2.0.7"
38
+ "@alaarab/ogrid-angular": "2.0.9"
26
39
  },
27
40
  "peerDependencies": {
28
41
  "@angular/core": "^21.0.0",
@@ -42,5 +55,7 @@
42
55
  "typescript": "^5.9.3"
43
56
  },
44
57
  "sideEffects": false,
45
- "publishConfig": { "access": "public" }
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
46
61
  }