@alaarab/ogrid-angular-radix 2.0.4 → 2.0.6
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/datagrid-table/datagrid-table.component.js +14 -256
- package/dist/types/datagrid-table/datagrid-table.component.d.ts +7 -122
- package/package.json +14 -4
- package/jest-mocks/angular-cdk-overlay.cjs.js +0 -38
- package/jest-mocks/style-mock.js +0 -1
- package/jest.config.js +0 -43
- package/scripts/compile-styles.js +0 -53
- package/src/__tests__/column-chooser.component.spec.ts.skip +0 -195
- package/src/__tests__/column-header-filter.component.spec.ts.skip +0 -401
- package/src/__tests__/datagrid-table.component.spec.ts.skip +0 -417
- package/src/__tests__/exports.test.ts +0 -54
- package/src/__tests__/ogrid.component.spec.ts.skip +0 -236
- package/src/__tests__/pagination-controls.component.spec.ts.skip +0 -190
- package/src/column-chooser/column-chooser.component.ts +0 -204
- package/src/column-header-filter/column-header-filter.component.ts +0 -528
- package/src/datagrid-table/datagrid-table.component.scss +0 -289
- package/src/datagrid-table/datagrid-table.component.ts +0 -636
- package/src/index.ts +0 -16
- package/src/ogrid/ogrid.component.ts +0 -78
- package/src/pagination-controls/pagination-controls.component.ts +0 -187
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -21
|
@@ -4,272 +4,29 @@ 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,
|
|
8
|
-
import {
|
|
7
|
+
import { Component, input, viewChild, ChangeDetectionStrategy, } from '@angular/core';
|
|
8
|
+
import { BaseDataGridTableComponent, DataGridStateService, StatusBarComponent, GridContextMenuComponent, MarchingAntsOverlayComponent, EmptyStateComponent, } from '@alaarab/ogrid-angular';
|
|
9
9
|
import { ColumnHeaderFilterComponent } from '../column-header-filter/column-header-filter.component';
|
|
10
10
|
/**
|
|
11
11
|
* DataGridTable component for Angular Radix using native HTML table.
|
|
12
12
|
* Standalone component with lightweight styling and CSS variables.
|
|
13
13
|
*/
|
|
14
|
-
let DataGridTableComponent = class DataGridTableComponent {
|
|
14
|
+
let DataGridTableComponent = class DataGridTableComponent extends BaseDataGridTableComponent {
|
|
15
15
|
constructor() {
|
|
16
|
+
super();
|
|
16
17
|
this.propsInput = input.required({ alias: 'props' });
|
|
17
18
|
this.wrapperRef = viewChild('wrapperEl');
|
|
18
19
|
this.tableContainerRef = viewChild('tableContainerEl');
|
|
19
|
-
this.
|
|
20
|
-
this.columnReorderService = new ColumnReorderService();
|
|
21
|
-
this.virtualScrollService = new VirtualScrollService();
|
|
22
|
-
this.lastMouseShift = false;
|
|
23
|
-
this.columnSizingVersion = signal(0);
|
|
24
|
-
// --- Delegated state ---
|
|
25
|
-
this.state = computed(() => this.stateService.getState());
|
|
26
|
-
this.items = computed(() => this.propsInput()?.items ?? []);
|
|
27
|
-
this.getRowId = computed(() => this.propsInput()?.getRowId ?? ((item) => item['id']));
|
|
28
|
-
this.isLoading = computed(() => this.propsInput()?.isLoading ?? false);
|
|
29
|
-
this.loadingMessage = computed(() => 'Loading\u2026');
|
|
30
|
-
this.freezeRows = computed(() => this.propsInput()?.freezeRows);
|
|
31
|
-
this.freezeCols = computed(() => this.propsInput()?.freezeCols);
|
|
32
|
-
this.layoutModeFit = computed(() => (this.propsInput()?.layoutMode ?? 'fill') === 'content');
|
|
33
|
-
this.ariaLabel = computed(() => this.propsInput()?.['aria-label'] ?? 'Data grid');
|
|
34
|
-
this.ariaLabelledBy = computed(() => this.propsInput()?.['aria-labelledby']);
|
|
35
|
-
this.emptyState = computed(() => this.propsInput()?.emptyState);
|
|
36
|
-
// State service outputs
|
|
37
|
-
this.visibleCols = computed(() => this.state().layout.visibleCols);
|
|
38
|
-
this.hasCheckboxCol = computed(() => this.state().layout.hasCheckboxCol);
|
|
39
|
-
this.colOffset = computed(() => this.state().layout.colOffset);
|
|
40
|
-
this.containerWidth = computed(() => this.state().layout.containerWidth);
|
|
41
|
-
this.minTableWidth = computed(() => this.state().layout.minTableWidth);
|
|
42
|
-
this.desiredTableWidth = computed(() => this.state().layout.desiredTableWidth);
|
|
43
|
-
this.columnSizingOverrides = computed(() => this.state().layout.columnSizingOverrides);
|
|
44
|
-
this.selectedRowIds = computed(() => this.state().rowSelection.selectedRowIds);
|
|
45
|
-
this.allSelected = computed(() => this.state().rowSelection.allSelected);
|
|
46
|
-
this.someSelected = computed(() => this.state().rowSelection.someSelected);
|
|
47
|
-
this.editingCell = computed(() => this.state().editing.editingCell);
|
|
48
|
-
this.pendingEditorValue = computed(() => this.state().editing.pendingEditorValue);
|
|
49
|
-
this.activeCell = computed(() => this.state().interaction.activeCell);
|
|
50
|
-
this.selectionRange = computed(() => this.state().interaction.selectionRange);
|
|
51
|
-
this.hasCellSelection = computed(() => this.state().interaction.hasCellSelection);
|
|
52
|
-
this.cutRange = computed(() => this.state().interaction.cutRange);
|
|
53
|
-
this.copyRange = computed(() => this.state().interaction.copyRange);
|
|
54
|
-
this.canUndo = computed(() => this.state().interaction.canUndo);
|
|
55
|
-
this.canRedo = computed(() => this.state().interaction.canRedo);
|
|
56
|
-
this.isDragging = computed(() => this.state().interaction.isDragging);
|
|
57
|
-
this.menuPosition = computed(() => this.state().contextMenu.menuPosition);
|
|
58
|
-
this.statusBarConfig = computed(() => this.state().viewModels.statusBarConfig);
|
|
59
|
-
this.showEmptyInGrid = computed(() => this.state().viewModels.showEmptyInGrid);
|
|
60
|
-
this.headerFilterInput = computed(() => this.state().viewModels.headerFilterInput);
|
|
61
|
-
this.cellDescriptorInput = computed(() => this.state().viewModels.cellDescriptorInput);
|
|
62
|
-
this.allowOverflowX = computed(() => {
|
|
63
|
-
const p = this.propsInput();
|
|
64
|
-
if (p?.suppressHorizontalScroll)
|
|
65
|
-
return false;
|
|
66
|
-
const cw = this.containerWidth();
|
|
67
|
-
const mtw = this.minTableWidth();
|
|
68
|
-
const dtw = this.desiredTableWidth();
|
|
69
|
-
return cw > 0 && (mtw > cw || dtw > cw);
|
|
70
|
-
});
|
|
71
|
-
this.selectionCellCount = computed(() => {
|
|
72
|
-
const sr = this.selectionRange();
|
|
73
|
-
if (!sr)
|
|
74
|
-
return undefined;
|
|
75
|
-
return (Math.abs(sr.endRow - sr.startRow) + 1) * (Math.abs(sr.endCol - sr.startCol) + 1);
|
|
76
|
-
});
|
|
77
|
-
// Header rows from column definition
|
|
78
|
-
this.headerRows = computed(() => {
|
|
79
|
-
const p = this.propsInput();
|
|
80
|
-
if (!p)
|
|
81
|
-
return [];
|
|
82
|
-
return buildHeaderRows(p.columns, p.visibleColumns);
|
|
83
|
-
});
|
|
84
|
-
// Pre-computed column layouts
|
|
85
|
-
this.columnLayouts = computed(() => {
|
|
86
|
-
const cols = this.visibleCols();
|
|
87
|
-
const fc = this.freezeCols();
|
|
88
|
-
return cols.map((col, colIdx) => {
|
|
89
|
-
const isFreezeCol = fc != null && fc >= 1 && colIdx < fc;
|
|
90
|
-
const pinnedLeft = col.pinned === 'left' || (isFreezeCol && colIdx === 0);
|
|
91
|
-
const pinnedRight = col.pinned === 'right';
|
|
92
|
-
const w = this.getColumnWidth(col);
|
|
93
|
-
return {
|
|
94
|
-
col,
|
|
95
|
-
pinnedLeft,
|
|
96
|
-
pinnedRight,
|
|
97
|
-
minWidth: col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH,
|
|
98
|
-
width: w,
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
// Wire props and wrapper element to state service
|
|
103
|
-
effect(() => {
|
|
104
|
-
const p = this.propsInput();
|
|
105
|
-
if (p)
|
|
106
|
-
this.stateService.props.set(p);
|
|
107
|
-
});
|
|
108
|
-
effect(() => {
|
|
109
|
-
const el = this.wrapperRef()?.nativeElement;
|
|
110
|
-
if (el) {
|
|
111
|
-
this.stateService.wrapperEl.set(el);
|
|
112
|
-
this.columnReorderService.wrapperEl.set(el);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
// Wire column reorder service inputs
|
|
116
|
-
effect(() => {
|
|
117
|
-
const p = this.propsInput();
|
|
118
|
-
if (p) {
|
|
119
|
-
const cols = this.visibleCols();
|
|
120
|
-
this.columnReorderService.columns.set(cols);
|
|
121
|
-
this.columnReorderService.columnOrder.set(p.columnOrder);
|
|
122
|
-
this.columnReorderService.onColumnOrderChange.set(p.onColumnOrderChange);
|
|
123
|
-
this.columnReorderService.enabled.set(!!p.onColumnOrderChange);
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
// Wire virtual scroll service inputs
|
|
127
|
-
effect(() => {
|
|
128
|
-
const p = this.propsInput();
|
|
129
|
-
if (p) {
|
|
130
|
-
this.virtualScrollService.totalRows.set(p.items.length);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
20
|
+
this.initBase();
|
|
133
21
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return colDef;
|
|
22
|
+
getProps() {
|
|
23
|
+
return this.propsInput();
|
|
137
24
|
}
|
|
138
|
-
|
|
139
|
-
return this.
|
|
25
|
+
getWrapperRef() {
|
|
26
|
+
return this.wrapperRef();
|
|
140
27
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const override = overrides[col.columnId];
|
|
144
|
-
if (override)
|
|
145
|
-
return override.widthPx;
|
|
146
|
-
return col.defaultWidth ?? col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
|
|
147
|
-
}
|
|
148
|
-
getFilterConfig(col) {
|
|
149
|
-
return getHeaderFilterConfig(col, this.headerFilterInput());
|
|
150
|
-
}
|
|
151
|
-
getCellDescriptor(item, col, rowIndex, colIdx) {
|
|
152
|
-
return getCellRenderDescriptor(item, col, rowIndex, colIdx, this.cellDescriptorInput());
|
|
153
|
-
}
|
|
154
|
-
resolveCellContent(col, item, displayValue) {
|
|
155
|
-
return resolveCellDisplayContent(col, item, displayValue);
|
|
156
|
-
}
|
|
157
|
-
resolveCellStyleFn(col, item) {
|
|
158
|
-
return resolveCellStyle(col, item);
|
|
159
|
-
}
|
|
160
|
-
getSelectValues(col) {
|
|
161
|
-
const params = col.cellEditorParams;
|
|
162
|
-
if (params && typeof params === 'object' && 'values' in params) {
|
|
163
|
-
return params.values.map(String);
|
|
164
|
-
}
|
|
165
|
-
return [];
|
|
166
|
-
}
|
|
167
|
-
formatDateForInput(value) {
|
|
168
|
-
if (!value)
|
|
169
|
-
return '';
|
|
170
|
-
const d = new Date(String(value));
|
|
171
|
-
if (Number.isNaN(d.getTime()))
|
|
172
|
-
return '';
|
|
173
|
-
return d.toISOString().split('T')[0];
|
|
174
|
-
}
|
|
175
|
-
// --- Event handlers ---
|
|
176
|
-
onWrapperMouseDown(event) {
|
|
177
|
-
this.lastMouseShift = event.shiftKey;
|
|
178
|
-
}
|
|
179
|
-
onGridKeyDown(event) {
|
|
180
|
-
this.state().interaction.handleGridKeyDown(event);
|
|
181
|
-
}
|
|
182
|
-
onCellMouseDown(event, rowIndex, globalColIndex) {
|
|
183
|
-
this.state().interaction.handleCellMouseDown(event, rowIndex, globalColIndex);
|
|
184
|
-
}
|
|
185
|
-
onCellClick(rowIndex, globalColIndex) {
|
|
186
|
-
this.state().interaction.setActiveCell({ rowIndex, columnIndex: globalColIndex });
|
|
187
|
-
}
|
|
188
|
-
onCellContextMenu(event) {
|
|
189
|
-
this.state().contextMenu.handleCellContextMenu(event);
|
|
190
|
-
}
|
|
191
|
-
onCellDblClick(rowId, columnId) {
|
|
192
|
-
this.state().editing.setEditingCell({ rowId, columnId });
|
|
193
|
-
}
|
|
194
|
-
onFillHandleMouseDown(event) {
|
|
195
|
-
this.state().interaction.handleFillHandleMouseDown(event);
|
|
196
|
-
}
|
|
197
|
-
onResizeStart(event, col) {
|
|
198
|
-
event.preventDefault();
|
|
199
|
-
const startX = event.clientX;
|
|
200
|
-
const startWidth = this.getColumnWidth(col);
|
|
201
|
-
const minWidth = col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
|
|
202
|
-
const onMove = (e) => {
|
|
203
|
-
const delta = e.clientX - startX;
|
|
204
|
-
const newWidth = Math.max(minWidth, startWidth + delta);
|
|
205
|
-
const overrides = { ...this.columnSizingOverrides(), [col.columnId]: { widthPx: newWidth } };
|
|
206
|
-
this.state().layout.setColumnSizingOverrides(overrides);
|
|
207
|
-
this.columnSizingVersion.update(v => v + 1);
|
|
208
|
-
};
|
|
209
|
-
const onUp = () => {
|
|
210
|
-
window.removeEventListener('mousemove', onMove);
|
|
211
|
-
window.removeEventListener('mouseup', onUp);
|
|
212
|
-
const finalWidth = this.getColumnWidth(col);
|
|
213
|
-
this.state().layout.onColumnResized?.(col.columnId, finalWidth);
|
|
214
|
-
};
|
|
215
|
-
window.addEventListener('mousemove', onMove);
|
|
216
|
-
window.addEventListener('mouseup', onUp);
|
|
217
|
-
}
|
|
218
|
-
onSelectAllChange(event) {
|
|
219
|
-
const checked = event.target.checked;
|
|
220
|
-
this.state().rowSelection.handleSelectAll(!!checked);
|
|
221
|
-
}
|
|
222
|
-
onRowClick(event, rowId) {
|
|
223
|
-
const p = this.propsInput();
|
|
224
|
-
if (p?.rowSelection !== 'single')
|
|
225
|
-
return;
|
|
226
|
-
const ids = this.selectedRowIds();
|
|
227
|
-
this.state().rowSelection.updateSelection(ids.has(rowId) ? new Set() : new Set([rowId]));
|
|
228
|
-
}
|
|
229
|
-
onRowCheckboxChange(rowId, event, rowIndex) {
|
|
230
|
-
const checked = event.target.checked;
|
|
231
|
-
this.state().rowSelection.handleRowCheckboxChange(rowId, checked, rowIndex, this.lastMouseShift);
|
|
232
|
-
}
|
|
233
|
-
commitEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex) {
|
|
234
|
-
this.state().editing.commitCellEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex);
|
|
235
|
-
}
|
|
236
|
-
cancelEdit() {
|
|
237
|
-
this.state().editing.setEditingCell(null);
|
|
238
|
-
}
|
|
239
|
-
onEditorKeydown(event, item, columnId, oldValue, rowIndex, globalColIndex) {
|
|
240
|
-
if (event.key === 'Enter') {
|
|
241
|
-
event.preventDefault();
|
|
242
|
-
const newValue = event.target.value;
|
|
243
|
-
this.commitEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex);
|
|
244
|
-
}
|
|
245
|
-
else if (event.key === 'Escape') {
|
|
246
|
-
event.preventDefault();
|
|
247
|
-
this.cancelEdit();
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
closeContextMenu() {
|
|
251
|
-
this.state().contextMenu.closeContextMenu();
|
|
252
|
-
}
|
|
253
|
-
handleCopy() {
|
|
254
|
-
this.state().interaction.handleCopy();
|
|
255
|
-
}
|
|
256
|
-
handleCut() {
|
|
257
|
-
this.state().interaction.handleCut();
|
|
258
|
-
}
|
|
259
|
-
handlePaste() {
|
|
260
|
-
void this.state().interaction.handlePaste();
|
|
261
|
-
}
|
|
262
|
-
handleSelectAllCells() {
|
|
263
|
-
this.state().interaction.handleSelectAllCells();
|
|
264
|
-
}
|
|
265
|
-
onUndo() {
|
|
266
|
-
this.state().interaction.onUndo?.();
|
|
267
|
-
}
|
|
268
|
-
onRedo() {
|
|
269
|
-
this.state().interaction.onRedo?.();
|
|
270
|
-
}
|
|
271
|
-
onHeaderMouseDown(columnId, event) {
|
|
272
|
-
this.columnReorderService.handleHeaderMouseDown(columnId, event);
|
|
28
|
+
getTableContainerRef() {
|
|
29
|
+
return this.tableContainerRef();
|
|
273
30
|
}
|
|
274
31
|
};
|
|
275
32
|
DataGridTableComponent = __decorate([
|
|
@@ -320,7 +77,7 @@ DataGridTableComponent = __decorate([
|
|
|
320
77
|
</th>
|
|
321
78
|
}
|
|
322
79
|
@if (rowIdx === 0 && rowIdx < headerRows().length - 1 && hasCheckboxCol()) {
|
|
323
|
-
<th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th
|
|
80
|
+
<th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th ogrid-datagrid-checkbox-spacer"></th>
|
|
324
81
|
}
|
|
325
82
|
@for (cell of row; track $index; let cellIdx = $index) {
|
|
326
83
|
@if (cell.isGroup) {
|
|
@@ -341,7 +98,8 @@ DataGridTableComponent = __decorate([
|
|
|
341
98
|
[style.minWidth.px]="col.minWidth ?? 80"
|
|
342
99
|
[style.width.px]="colW"
|
|
343
100
|
[style.maxWidth.px]="colW"
|
|
344
|
-
[
|
|
101
|
+
[class.ogrid-datagrid-th--reorderable]="!columnReorderService.isDragging()"
|
|
102
|
+
[class.ogrid-datagrid-th--dragging]="columnReorderService.isDragging()"
|
|
345
103
|
(mousedown)="onHeaderMouseDown(col.columnId, $event)"
|
|
346
104
|
>
|
|
347
105
|
<column-header-filter
|
|
@@ -1,131 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { ElementRef } from '@angular/core';
|
|
2
|
+
import { BaseDataGridTableComponent } from '@alaarab/ogrid-angular';
|
|
3
|
+
import type { IOGridDataGridProps } from '@alaarab/ogrid-angular';
|
|
3
4
|
/**
|
|
4
5
|
* DataGridTable component for Angular Radix using native HTML table.
|
|
5
6
|
* Standalone component with lightweight styling and CSS variables.
|
|
6
7
|
*/
|
|
7
|
-
export declare class DataGridTableComponent<T> {
|
|
8
|
+
export declare class DataGridTableComponent<T> extends BaseDataGridTableComponent<T> {
|
|
8
9
|
readonly propsInput: import("@angular/core").InputSignal<IOGridDataGridProps<T>>;
|
|
9
10
|
private readonly wrapperRef;
|
|
10
11
|
private readonly tableContainerRef;
|
|
11
|
-
private readonly stateService;
|
|
12
|
-
readonly columnReorderService: ColumnReorderService<T>;
|
|
13
|
-
readonly virtualScrollService: VirtualScrollService;
|
|
14
|
-
private lastMouseShift;
|
|
15
|
-
private columnSizingVersion;
|
|
16
12
|
constructor();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
readonly isLoading: import("@angular/core").Signal<boolean>;
|
|
21
|
-
readonly loadingMessage: import("@angular/core").Signal<string>;
|
|
22
|
-
readonly freezeRows: import("@angular/core").Signal<number | undefined>;
|
|
23
|
-
readonly freezeCols: import("@angular/core").Signal<number | undefined>;
|
|
24
|
-
readonly layoutModeFit: import("@angular/core").Signal<boolean>;
|
|
25
|
-
readonly ariaLabel: import("@angular/core").Signal<string>;
|
|
26
|
-
readonly ariaLabelledBy: import("@angular/core").Signal<string | undefined>;
|
|
27
|
-
readonly emptyState: import("@angular/core").Signal<{
|
|
28
|
-
onClearAll: () => void;
|
|
29
|
-
hasActiveFilters: boolean;
|
|
30
|
-
message?: string;
|
|
31
|
-
render?: import("@angular/core").TemplateRef<unknown>;
|
|
32
|
-
} | undefined>;
|
|
33
|
-
readonly visibleCols: import("@angular/core").Signal<IColumnDef<T>[]>;
|
|
34
|
-
readonly hasCheckboxCol: import("@angular/core").Signal<boolean>;
|
|
35
|
-
readonly colOffset: import("@angular/core").Signal<number>;
|
|
36
|
-
readonly containerWidth: import("@angular/core").Signal<number>;
|
|
37
|
-
readonly minTableWidth: import("@angular/core").Signal<number>;
|
|
38
|
-
readonly desiredTableWidth: import("@angular/core").Signal<number>;
|
|
39
|
-
readonly columnSizingOverrides: import("@angular/core").Signal<Record<string, {
|
|
40
|
-
widthPx: number;
|
|
41
|
-
}>>;
|
|
42
|
-
readonly selectedRowIds: import("@angular/core").Signal<Set<RowId>>;
|
|
43
|
-
readonly allSelected: import("@angular/core").Signal<boolean>;
|
|
44
|
-
readonly someSelected: import("@angular/core").Signal<boolean>;
|
|
45
|
-
readonly editingCell: import("@angular/core").Signal<{
|
|
46
|
-
rowId: RowId;
|
|
47
|
-
columnId: string;
|
|
48
|
-
} | null>;
|
|
49
|
-
readonly pendingEditorValue: import("@angular/core").Signal<unknown>;
|
|
50
|
-
readonly activeCell: import("@angular/core").Signal<import("@alaarab/ogrid-core").IActiveCell | null>;
|
|
51
|
-
readonly selectionRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
52
|
-
readonly hasCellSelection: import("@angular/core").Signal<boolean>;
|
|
53
|
-
readonly cutRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
54
|
-
readonly copyRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
55
|
-
readonly canUndo: import("@angular/core").Signal<boolean>;
|
|
56
|
-
readonly canRedo: import("@angular/core").Signal<boolean>;
|
|
57
|
-
readonly isDragging: import("@angular/core").Signal<boolean>;
|
|
58
|
-
readonly menuPosition: import("@angular/core").Signal<{
|
|
59
|
-
x: number;
|
|
60
|
-
y: number;
|
|
61
|
-
} | null>;
|
|
62
|
-
readonly statusBarConfig: import("@angular/core").Signal<import("@alaarab/ogrid-core").IStatusBarProps | null>;
|
|
63
|
-
readonly showEmptyInGrid: import("@angular/core").Signal<boolean>;
|
|
64
|
-
readonly headerFilterInput: import("@angular/core").Signal<{
|
|
65
|
-
sortBy?: string;
|
|
66
|
-
sortDirection: "asc" | "desc";
|
|
67
|
-
onColumnSort: (columnKey: string) => void;
|
|
68
|
-
filters: import("@alaarab/ogrid-core").IFilters;
|
|
69
|
-
onFilterChange: (key: string, value: import("@alaarab/ogrid-core").FilterValue | undefined) => void;
|
|
70
|
-
filterOptions: Record<string, string[]>;
|
|
71
|
-
loadingFilterOptions: Record<string, boolean>;
|
|
72
|
-
peopleSearch?: (query: string) => Promise<import("@alaarab/ogrid-core").UserLike[]>;
|
|
73
|
-
}>;
|
|
74
|
-
readonly cellDescriptorInput: import("@angular/core").Signal<{
|
|
75
|
-
editingCell: {
|
|
76
|
-
rowId: RowId;
|
|
77
|
-
columnId: string;
|
|
78
|
-
} | null;
|
|
79
|
-
activeCell: import("@alaarab/ogrid-core").IActiveCell | null;
|
|
80
|
-
selectionRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
81
|
-
cutRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
82
|
-
copyRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
83
|
-
colOffset: number;
|
|
84
|
-
itemsLength: number;
|
|
85
|
-
getRowId: (item: T) => RowId;
|
|
86
|
-
editable?: boolean;
|
|
87
|
-
onCellValueChanged?: ((event: import("@alaarab/ogrid-core").ICellValueChangedEvent<T>) => void) | undefined;
|
|
88
|
-
isDragging: boolean;
|
|
89
|
-
}>;
|
|
90
|
-
readonly allowOverflowX: import("@angular/core").Signal<boolean>;
|
|
91
|
-
readonly selectionCellCount: import("@angular/core").Signal<number | undefined>;
|
|
92
|
-
readonly headerRows: import("@angular/core").Signal<import("@alaarab/ogrid-core").HeaderRow<T>[]>;
|
|
93
|
-
readonly columnLayouts: import("@angular/core").Signal<{
|
|
94
|
-
col: IColumnDef<T>;
|
|
95
|
-
pinnedLeft: boolean;
|
|
96
|
-
pinnedRight: boolean;
|
|
97
|
-
minWidth: number;
|
|
98
|
-
width: number;
|
|
99
|
-
}[]>;
|
|
100
|
-
asColumnDef(colDef: unknown): IColumnDef<T>;
|
|
101
|
-
visibleColIndex(col: IColumnDef<T>): number;
|
|
102
|
-
getColumnWidth(col: IColumnDef<T>): number;
|
|
103
|
-
getFilterConfig(col: IColumnDef<T>): HeaderFilterConfig;
|
|
104
|
-
getCellDescriptor(item: T, col: IColumnDef<T>, rowIndex: number, colIdx: number): CellRenderDescriptor;
|
|
105
|
-
resolveCellContent(col: IColumnDef<T>, item: T, displayValue: unknown): string;
|
|
106
|
-
resolveCellStyleFn(col: IColumnDef<T>, item: T): Record<string, string> | undefined;
|
|
107
|
-
getSelectValues(col: IColumnDef<T>): string[];
|
|
108
|
-
formatDateForInput(value: unknown): string;
|
|
109
|
-
onWrapperMouseDown(event: MouseEvent): void;
|
|
110
|
-
onGridKeyDown(event: KeyboardEvent): void;
|
|
111
|
-
onCellMouseDown(event: MouseEvent, rowIndex: number, globalColIndex: number): void;
|
|
112
|
-
onCellClick(rowIndex: number, globalColIndex: number): void;
|
|
113
|
-
onCellContextMenu(event: MouseEvent): void;
|
|
114
|
-
onCellDblClick(rowId: RowId, columnId: string): void;
|
|
115
|
-
onFillHandleMouseDown(event: MouseEvent): void;
|
|
116
|
-
onResizeStart(event: MouseEvent, col: IColumnDef<T>): void;
|
|
117
|
-
onSelectAllChange(event: Event): void;
|
|
118
|
-
onRowClick(event: MouseEvent, rowId: RowId): void;
|
|
119
|
-
onRowCheckboxChange(rowId: RowId, event: Event, rowIndex: number): void;
|
|
120
|
-
commitEdit(item: T, columnId: string, oldValue: unknown, newValue: unknown, rowIndex: number, globalColIndex: number): void;
|
|
121
|
-
cancelEdit(): void;
|
|
122
|
-
onEditorKeydown(event: KeyboardEvent, item: T, columnId: string, oldValue: unknown, rowIndex: number, globalColIndex: number): void;
|
|
123
|
-
closeContextMenu(): void;
|
|
124
|
-
handleCopy(): void;
|
|
125
|
-
handleCut(): void;
|
|
126
|
-
handlePaste(): void;
|
|
127
|
-
handleSelectAllCells(): void;
|
|
128
|
-
onUndo(): void;
|
|
129
|
-
onRedo(): void;
|
|
130
|
-
onHeaderMouseDown(columnId: string, event: MouseEvent): void;
|
|
13
|
+
protected getProps(): IOGridDataGridProps<T> | undefined;
|
|
14
|
+
protected getWrapperRef(): ElementRef<HTMLElement> | undefined;
|
|
15
|
+
protected getTableContainerRef(): ElementRef<HTMLElement> | undefined;
|
|
131
16
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-angular-radix",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "OGrid Angular Radix – Lightweight data grid with sorting, filtering, pagination, column chooser, and CSV export. Built with Angular CDK.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
6
7
|
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"import": "./dist/esm/index.js",
|
|
12
|
+
"require": "./dist/esm/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
16
|
+
"sideEffects": false,
|
|
7
17
|
"keywords": ["ogrid", "datagrid", "angular", "angular-cdk", "data-table", "spreadsheet", "grid"],
|
|
8
18
|
"author": "Ala Arab",
|
|
9
19
|
"license": "MIT",
|
|
@@ -17,7 +27,7 @@
|
|
|
17
27
|
"test": "jest"
|
|
18
28
|
},
|
|
19
29
|
"dependencies": {
|
|
20
|
-
"@alaarab/ogrid-angular": "2.0.
|
|
30
|
+
"@alaarab/ogrid-angular": "2.0.6",
|
|
21
31
|
"@angular/cdk": "^21.0.0"
|
|
22
32
|
},
|
|
23
33
|
"peerDependencies": {
|
|
@@ -28,8 +38,8 @@
|
|
|
28
38
|
"@types/jest": "^29.5.0",
|
|
29
39
|
"jest": "^29.7.0",
|
|
30
40
|
"rimraf": "^5.0.0",
|
|
31
|
-
"sass": "^1.
|
|
32
|
-
"typescript": "^5.
|
|
41
|
+
"sass": "^1.97.3",
|
|
42
|
+
"typescript": "^5.9.3"
|
|
33
43
|
},
|
|
34
44
|
"publishConfig": {
|
|
35
45
|
"access": "public"
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// Mock for @angular/cdk/overlay in tests
|
|
2
|
-
class MockOverlay {
|
|
3
|
-
position() {
|
|
4
|
-
return {
|
|
5
|
-
flexibleConnectedTo() {
|
|
6
|
-
return {
|
|
7
|
-
withPositions() {
|
|
8
|
-
return this;
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
create(config) {
|
|
16
|
-
return {
|
|
17
|
-
attach: jest.fn(),
|
|
18
|
-
detach: jest.fn(),
|
|
19
|
-
dispose: jest.fn(),
|
|
20
|
-
backdropClick: () => ({
|
|
21
|
-
subscribe: jest.fn()
|
|
22
|
-
})
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class MockComponentPortal {
|
|
28
|
-
constructor(component) {
|
|
29
|
-
this.component = component;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
module.exports = {
|
|
34
|
-
Overlay: MockOverlay,
|
|
35
|
-
OverlayModule: class MockOverlayModule {},
|
|
36
|
-
ComponentPortal: MockComponentPortal,
|
|
37
|
-
CdkOverlayOrigin: class MockCdkOverlayOrigin {},
|
|
38
|
-
};
|
package/jest-mocks/style-mock.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {};
|
package/jest.config.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/** @type {import('jest').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
testEnvironment: 'jsdom',
|
|
4
|
-
roots: ['<rootDir>/src'],
|
|
5
|
-
testMatch: [
|
|
6
|
-
'**/__tests__/**/*.test.ts',
|
|
7
|
-
'**/__tests__/**/*.test.tsx',
|
|
8
|
-
'**/__tests__/**/*.spec.ts',
|
|
9
|
-
],
|
|
10
|
-
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
|
11
|
-
transform: {
|
|
12
|
-
'^.+\\.tsx?$': [
|
|
13
|
-
'ts-jest',
|
|
14
|
-
{
|
|
15
|
-
useESM: false,
|
|
16
|
-
tsconfig: {
|
|
17
|
-
esModuleInterop: true,
|
|
18
|
-
allowSyntheticDefaultImports: true,
|
|
19
|
-
module: 'commonjs',
|
|
20
|
-
target: 'es2019',
|
|
21
|
-
types: ['jest', 'node'],
|
|
22
|
-
experimentalDecorators: true,
|
|
23
|
-
useDefineForClassFields: false,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
moduleNameMapper: {
|
|
29
|
-
'^@alaarab/ogrid-core$': '<rootDir>/../core/src/index.ts',
|
|
30
|
-
'^@alaarab/ogrid-core/testing$': '<rootDir>/../core/src/testing/index.ts',
|
|
31
|
-
'^@alaarab/ogrid-angular$': '<rootDir>/../angular/src/index.ts',
|
|
32
|
-
'^@angular/core/testing$': '<rootDir>/../angular/jest-mocks/angular-core-testing.cjs.js',
|
|
33
|
-
'^@angular/core$': '<rootDir>/../angular/jest-mocks/angular-core.cjs.js',
|
|
34
|
-
'^@angular/common$': '<rootDir>/../angular/jest-mocks/angular-common.cjs.js',
|
|
35
|
-
'^@angular/platform-browser$': '<rootDir>/../angular/jest-mocks/angular-platform-browser.cjs.js',
|
|
36
|
-
'^@angular/cdk/overlay$': '<rootDir>/jest-mocks/angular-cdk-overlay.cjs.js',
|
|
37
|
-
'\\.scss$': '<rootDir>/jest-mocks/style-mock.js',
|
|
38
|
-
},
|
|
39
|
-
transformIgnorePatterns: [
|
|
40
|
-
'node_modules/(?!(@angular|primeng)/)',
|
|
41
|
-
],
|
|
42
|
-
testTimeout: 10000,
|
|
43
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiles all .module.scss files to .module.css and rewrites dist JS imports.
|
|
3
|
-
*/
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const sass = require('sass');
|
|
7
|
-
|
|
8
|
-
const SRC_DIR = path.join(__dirname, '..', 'src');
|
|
9
|
-
const DIST_ESM = path.join(__dirname, '..', 'dist', 'esm');
|
|
10
|
-
|
|
11
|
-
function* walkDir(dir, base = dir) {
|
|
12
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
13
|
-
for (const e of entries) {
|
|
14
|
-
const full = path.join(dir, e.name);
|
|
15
|
-
const rel = path.relative(base, full);
|
|
16
|
-
if (e.isDirectory()) {
|
|
17
|
-
yield* walkDir(full, base);
|
|
18
|
-
} else if (e.isFile() && e.name.endsWith('.module.scss')) {
|
|
19
|
-
yield { full, rel };
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
for (const { full, rel } of walkDir(SRC_DIR)) {
|
|
25
|
-
const outRel = rel.replace(/\.scss$/, '.css');
|
|
26
|
-
const outPath = path.join(DIST_ESM, outRel);
|
|
27
|
-
const outDir = path.dirname(outPath);
|
|
28
|
-
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
|
|
29
|
-
const result = sass.compile(full);
|
|
30
|
-
fs.writeFileSync(outPath, result.css, 'utf8');
|
|
31
|
-
console.log('Compiled:', rel, '→', outRel);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function* walkJs(dir) {
|
|
35
|
-
if (!fs.existsSync(dir)) return;
|
|
36
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
37
|
-
for (const e of entries) {
|
|
38
|
-
const full = path.join(dir, e.name);
|
|
39
|
-
if (e.isDirectory()) yield* walkJs(full);
|
|
40
|
-
else if (e.isFile() && e.name.endsWith('.js')) yield full;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
for (const jsPath of walkJs(DIST_ESM)) {
|
|
45
|
-
let content = fs.readFileSync(jsPath, 'utf8');
|
|
46
|
-
if (content.includes('.module.scss')) {
|
|
47
|
-
content = content.replace(/\.module\.scss/g, '.module.css');
|
|
48
|
-
fs.writeFileSync(jsPath, content, 'utf8');
|
|
49
|
-
console.log('Rewrote imports:', path.relative(DIST_ESM, jsPath));
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
console.log('Styles compiled and dist JS imports updated.');
|