@alaarab/ogrid-angular-material 2.1.2 → 2.1.4

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/index.js CHANGED
@@ -1,15 +1,1312 @@
1
- // Re-export all from base package for consumer convenience.
2
- // Note: This prevents tree-shaking of unused utilities.
3
- // Consider explicit named exports in a future major version.
4
- export * from '@alaarab/ogrid-angular';
5
- // Components
6
- export { OGridComponent } from './ogrid/ogrid.component';
7
- export { DataGridTableComponent } from './datagrid-table/datagrid-table.component';
8
- export { ColumnHeaderFilterComponent } from './column-header-filter/column-header-filter.component';
9
- // IColumnHeaderFilterProps is now exported from @alaarab/ogrid-angular (base class)
10
- export { ColumnChooserComponent } from './column-chooser/column-chooser.component';
11
- // IColumnChooserProps is now exported from @alaarab/ogrid-angular (base class)
12
- export { PaginationControlsComponent } from './pagination-controls/pagination-controls.component';
13
- export { ColumnHeaderMenuComponent } from './column-header-menu/column-header-menu.component';
14
- export { InlineCellEditorComponent } from './datagrid-table/inline-cell-editor.component';
15
- export { PopoverCellEditorComponent } from './datagrid-table/popover-cell-editor.component';
1
+ import { INLINE_CELL_EDITOR_STYLES, INLINE_CELL_EDITOR_TEMPLATE, POPOVER_CELL_EDITOR_OVERLAY_STYLES, POPOVER_CELL_EDITOR_TEMPLATE, OGRID_THEME_VARS_CSS, CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DataGridStateService, ColumnReorderService, VirtualScrollService, StatusBarComponent, GridContextMenuComponent, MarchingAntsOverlayComponent, EmptyStateComponent, OGridService, OGridLayoutComponent, BaseColumnHeaderFilterComponent, getColumnHeaderMenuItems, BaseInlineCellEditorComponent, BasePopoverCellEditorComponent, BaseDataGridTableComponent, BaseColumnChooserComponent, BasePaginationControlsComponent, BaseOGridComponent } from '@alaarab/ogrid-angular';
2
+ export { AUTOSIZE_EXTRA_PX, AUTOSIZE_MAX_PX, BaseColumnChooserComponent, BaseColumnHeaderFilterComponent, BaseDataGridTableComponent, BaseInlineCellEditorComponent, BaseOGridComponent, BasePaginationControlsComponent, BasePopoverCellEditorComponent, CELL_PADDING, CHECKBOX_COLUMN_WIDTH, COLUMN_HEADER_MENU_ITEMS, ColumnReorderService, DEFAULT_DEBOUNCE_MS, DEFAULT_MIN_COLUMN_WIDTH, DataGridEditingHelper, DataGridInteractionHelper, DataGridLayoutHelper, DataGridStateService, EmptyStateComponent, GRID_BORDER_RADIUS, GRID_CONTEXT_MENU_ITEMS, GridContextMenuComponent, INLINE_CELL_EDITOR_STYLES, INLINE_CELL_EDITOR_TEMPLATE, MAX_PAGE_BUTTONS, MarchingAntsOverlayComponent, OGRID_THEME_VARS_CSS, OGridLayoutComponent, OGridService, PAGE_SIZE_OPTIONS, PEOPLE_SEARCH_DEBOUNCE_MS, POPOVER_CELL_EDITOR_OVERLAY_STYLES, POPOVER_CELL_EDITOR_TEMPLATE, ROW_NUMBER_COLUMN_WIDTH, SIDEBAR_TRANSITION_MS, SideBarComponent, StatusBarComponent, UndoRedoStack, VirtualScrollService, Z_INDEX, applyCellDeletion, applyCutClear, applyFillValues, applyPastedValues, applyRangeRowSelection, areGridRowPropsEqual, booleanParser, buildCsvHeader, buildCsvRows, buildHeaderRows, buildInlineEditorProps, buildPopoverEditorProps, calculateDropTarget, clampSelectionToBounds, computeAggregations, computeArrowNavigation, computeAutoScrollSpeed, computeNextSortState, computeRowSelectionState, computeTabNavigation, computeTotalHeight, computeVisibleRange, createDebouncedCallback, createDebouncedSignal, createLatestCallback, currencyParser, dateParser, debounce, deriveFilterOptionsFromData, emailParser, escapeCsvValue, exportToCsv, findCtrlArrowTarget, flattenColumns, formatCellValueForTsv, formatSelectionAsTsv, formatShortcut, getCellRenderDescriptor, getCellValue, getColumnHeaderMenuItems, getContextMenuHandlers, getDataGridStatusBarConfig, getFilterField, getHeaderFilterConfig, getMultiSelectFilterFields, getPaginationViewModel, getPinStateForColumn, getScrollTopForRow, getStatusBarParts, injectGlobalStyles, isFilterConfig, isInSelectionRange, isRowInRange, measureColumnContentWidth, measureRange, mergeFilter, normalizeSelectionRange, numberParser, parseTsvClipboard, parseValue, processClientSideData, rangesEqual, reorderColumnArray, resolveCellDisplayContent, resolveCellStyle, toUserLike, triggerCsvDownload, validateColumns, validateRowIds } from '@alaarab/ogrid-angular';
3
+ import { ViewChild, Component, ChangeDetectionStrategy, Input, ViewEncapsulation, signal, computed } from '@angular/core';
4
+ import { MatMenuTrigger, MatMenuModule } from '@angular/material/menu';
5
+ import { MatDividerModule } from '@angular/material/divider';
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __decorateClass = (decorators, target, key, kind) => {
10
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
11
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
+ if (decorator = decorators[i])
13
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
14
+ if (kind && result) __defProp(target, key, result);
15
+ return result;
16
+ };
17
+ var ColumnHeaderFilterComponent = class extends BaseColumnHeaderFilterComponent {
18
+ getHeaderEl() {
19
+ return this.headerEl;
20
+ }
21
+ onDocumentClickWrapper(event) {
22
+ this.onDocumentClick(event, "ogrid-column-header-filter");
23
+ }
24
+ };
25
+ __decorateClass([
26
+ ViewChild("headerEl")
27
+ ], ColumnHeaderFilterComponent.prototype, "headerEl", 2);
28
+ ColumnHeaderFilterComponent = __decorateClass([
29
+ Component({
30
+ selector: "ogrid-column-header-filter",
31
+ standalone: true,
32
+ changeDetection: ChangeDetectionStrategy.OnPush,
33
+ template: `
34
+ <div class="ogrid-header-filter" #headerEl>
35
+ <div class="ogrid-header-filter__label">
36
+ <span class="ogrid-header-filter__name" [title]="columnName" data-header-label>
37
+ {{ columnName }}
38
+ </span>
39
+ </div>
40
+
41
+ <div class="ogrid-header-filter__actions">
42
+ @if (filterType !== 'none') {
43
+ <button
44
+ class="ogrid-header-filter__filter-btn"
45
+ [class.ogrid-header-filter__filter-btn--active]="hasActiveFilter() || isFilterOpen()"
46
+ (click)="toggleFilter($event)"
47
+ [attr.aria-label]="'Filter ' + columnName"
48
+ [title]="'Filter ' + columnName"
49
+ >
50
+ <span class="ogrid-header-filter__funnel"></span>
51
+ @if (hasActiveFilter()) {
52
+ <span class="ogrid-header-filter__dot"></span>
53
+ }
54
+ </button>
55
+ }
56
+ </div>
57
+ </div>
58
+
59
+ @if (isFilterOpen() && filterType !== 'none') {
60
+ <div
61
+ class="ogrid-header-filter__popover"
62
+ [style.top.px]="popoverTop()"
63
+ [style.left.px]="popoverLeft()"
64
+ (click)="$event.stopPropagation()"
65
+ >
66
+ <div class="ogrid-header-filter__popover-header">
67
+ Filter: {{ columnName }}
68
+ </div>
69
+
70
+ @switch (filterType) {
71
+ @case ('text') {
72
+ <div class="ogrid-header-filter__popover-body" style="width: 260px;">
73
+ <div style="padding: 12px;">
74
+ <input
75
+ type="text"
76
+ class="ogrid-header-filter__input"
77
+ placeholder="Enter search term..."
78
+ [value]="tempTextValue()"
79
+ (input)="tempTextValue.set(asInputValue($event))"
80
+ (keydown)="onTextKeydown($event)"
81
+ autocomplete="off"
82
+ />
83
+ </div>
84
+ <div class="ogrid-header-filter__popover-actions">
85
+ <button class="ogrid-header-filter__action-btn" [disabled]="!tempTextValue()" (click)="handleTextClear()">Clear</button>
86
+ <button class="ogrid-header-filter__action-btn ogrid-header-filter__action-btn--primary" (click)="handleTextApply()">Apply</button>
87
+ </div>
88
+ </div>
89
+ }
90
+ @case ('multiSelect') {
91
+ <div class="ogrid-header-filter__popover-body" style="width: 280px;">
92
+ <div style="padding: 12px 12px 4px;">
93
+ <input
94
+ type="text"
95
+ class="ogrid-header-filter__input"
96
+ placeholder="Search..."
97
+ [value]="searchText()"
98
+ (input)="searchText.set(asInputValue($event))"
99
+ (keydown)="$event.stopPropagation()"
100
+ autocomplete="off"
101
+ />
102
+ <div class="ogrid-header-filter__options-info">
103
+ {{ filteredOptions().length }} of {{ (options ?? []).length }} options
104
+ </div>
105
+ </div>
106
+ <div class="ogrid-header-filter__select-actions">
107
+ <button class="ogrid-header-filter__action-btn" (click)="handleSelectAllFiltered()">
108
+ Select All ({{ filteredOptions().length }})
109
+ </button>
110
+ <button class="ogrid-header-filter__action-btn" (click)="handleClearSelection()">Clear</button>
111
+ </div>
112
+ <div class="ogrid-header-filter__options-list">
113
+ @if (isLoadingOptions) {
114
+ <div class="ogrid-header-filter__loading">Loading...</div>
115
+ } @else if (filteredOptions().length === 0) {
116
+ <div class="ogrid-header-filter__empty">No options found</div>
117
+ } @else {
118
+ @for (option of filteredOptions(); track option) {
119
+ <label class="ogrid-header-filter__option">
120
+ <input
121
+ type="checkbox"
122
+ [checked]="tempSelected().has(option)"
123
+ (change)="handleCheckboxChange(option, $event)"
124
+ />
125
+ <span>{{ option }}</span>
126
+ </label>
127
+ }
128
+ }
129
+ </div>
130
+ <div class="ogrid-header-filter__popover-actions" style="border-top: 1px solid rgba(0,0,0,0.12);">
131
+ <button class="ogrid-header-filter__action-btn" (click)="handleClearSelection()">Clear</button>
132
+ <button class="ogrid-header-filter__action-btn ogrid-header-filter__action-btn--primary" (click)="handleApplyMultiSelect()">Apply</button>
133
+ </div>
134
+ </div>
135
+ }
136
+ @case ('people') {
137
+ <div class="ogrid-header-filter__popover-body" style="width: 300px;">
138
+ @if (selectedUser) {
139
+ <div class="ogrid-header-filter__people-selected">
140
+ <div class="ogrid-header-filter__people-info-label">Currently filtered by:</div>
141
+ <div class="ogrid-header-filter__people-card">
142
+ <div class="ogrid-header-filter__people-avatar">{{ selectedUser!.displayName?.[0] ?? '?' }}</div>
143
+ <div class="ogrid-header-filter__people-details">
144
+ <div>{{ selectedUser!.displayName }}</div>
145
+ <div class="ogrid-header-filter__people-email">{{ selectedUser!.email }}</div>
146
+ </div>
147
+ <button class="ogrid-header-filter__btn" (click)="handleClearUser()" aria-label="Remove filter">&times;</button>
148
+ </div>
149
+ </div>
150
+ }
151
+ <div style="padding: 12px 12px 4px;">
152
+ <input
153
+ type="text"
154
+ class="ogrid-header-filter__input"
155
+ placeholder="Search for a person..."
156
+ [value]="peopleSearchText()"
157
+ (input)="onPeopleSearchInput($event)"
158
+ (keydown)="$event.stopPropagation()"
159
+ autocomplete="off"
160
+ />
161
+ </div>
162
+ <div class="ogrid-header-filter__options-list">
163
+ @if (isPeopleLoading() && peopleSearchText().trim()) {
164
+ <div class="ogrid-header-filter__loading">Loading...</div>
165
+ } @else if (peopleSuggestions().length === 0 && peopleSearchText().trim()) {
166
+ <div class="ogrid-header-filter__empty">No results found</div>
167
+ } @else if (peopleSearchText().trim()) {
168
+ @for (user of peopleSuggestions(); track user.id || user.email || user.displayName) {
169
+ <div class="ogrid-header-filter__people-option" (click)="handleUserSelect(user)">
170
+ <div class="ogrid-header-filter__people-avatar">{{ user.displayName?.[0] ?? '?' }}</div>
171
+ <div class="ogrid-header-filter__people-details">
172
+ <div>{{ user.displayName }}</div>
173
+ <div class="ogrid-header-filter__people-email">{{ user.email }}</div>
174
+ </div>
175
+ </div>
176
+ }
177
+ } @else {
178
+ <div class="ogrid-header-filter__empty">Type to search...</div>
179
+ }
180
+ </div>
181
+ @if (selectedUser) {
182
+ <div style="padding: 8px 12px; border-top: 1px solid rgba(0,0,0,0.12);">
183
+ <button class="ogrid-header-filter__action-btn" style="width: 100%;" (click)="handleClearUser()">Clear Filter</button>
184
+ </div>
185
+ }
186
+ </div>
187
+ }
188
+ @case ('date') {
189
+ <div class="ogrid-header-filter__popover-body" style="padding: 12px; display: flex; flex-direction: column; gap: 8px;">
190
+ <div style="display: flex; align-items: center; gap: 8px;">
191
+ <span style="min-width: 36px; font-size: 12px;">From:</span>
192
+ <input type="date" [value]="tempDateFrom()" (input)="tempDateFrom.set(asInputValue($event))" style="flex: 1; padding: 4px 6px;" />
193
+ </div>
194
+ <div style="display: flex; align-items: center; gap: 8px;">
195
+ <span style="min-width: 36px; font-size: 12px;">To:</span>
196
+ <input type="date" [value]="tempDateTo()" (input)="tempDateTo.set(asInputValue($event))" style="flex: 1; padding: 4px 6px;" />
197
+ </div>
198
+ <div class="ogrid-header-filter__popover-actions" style="margin-top: 4px;">
199
+ <button class="ogrid-header-filter__action-btn" [disabled]="!tempDateFrom() && !tempDateTo()" (click)="handleDateClear()">Clear</button>
200
+ <button class="ogrid-header-filter__action-btn ogrid-header-filter__action-btn--primary" (click)="handleDateApply()">Apply</button>
201
+ </div>
202
+ </div>
203
+ }
204
+ }
205
+ </div>
206
+ }
207
+ `,
208
+ styles: [`
209
+ :host { display: flex; align-items: center; flex: 1; min-width: 0; position: relative; }
210
+ .ogrid-header-filter { display: flex; align-items: center; width: 100%; min-width: 0; }
211
+ .ogrid-header-filter__label { flex: 1; min-width: 0; overflow: hidden; }
212
+ .ogrid-header-filter__name {
213
+ display: block; font-weight: 600; font-size: 14px; line-height: 1.4;
214
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
215
+ }
216
+ .ogrid-header-filter__actions { display: flex; align-items: center; margin-left: 4px; flex-shrink: 0; }
217
+ .ogrid-header-filter__btn {
218
+ width: 24px; height: 24px; padding: 2px; border: none; border-radius: 4px;
219
+ background: transparent; cursor: pointer; font-size: 12px; line-height: 1;
220
+ display: inline-flex; align-items: center; justify-content: center; position: relative;
221
+ color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.54));
222
+ }
223
+ .ogrid-header-filter__btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08)); }
224
+ .ogrid-header-filter__btn--active { color: var(--mat-sys-primary, #1976d2); }
225
+ .ogrid-header-filter__filter-btn {
226
+ width: 24px; height: 24px; padding: 2px; border: none; border-radius: 4px;
227
+ background: transparent; cursor: pointer; line-height: 1;
228
+ display: inline-flex; align-items: center; justify-content: center; position: relative;
229
+ opacity: 0.6; transition: opacity 0.15s;
230
+ }
231
+ .ogrid-header-filter:hover .ogrid-header-filter__filter-btn { opacity: 0.8; }
232
+ .ogrid-header-filter__filter-btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08)); opacity: 1 !important; }
233
+ .ogrid-header-filter__filter-btn--active { opacity: 1 !important; }
234
+ .ogrid-header-filter__funnel {
235
+ display: block; width: 0; height: 0;
236
+ border-left: 5px solid transparent; border-right: 5px solid transparent;
237
+ border-top: 6px solid var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.65));
238
+ position: relative;
239
+ }
240
+ .ogrid-header-filter__funnel::after {
241
+ content: ''; display: block; width: 2px; height: 4px;
242
+ background: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.65)); position: absolute;
243
+ top: -1px; left: -1px;
244
+ }
245
+ .ogrid-header-filter__filter-btn--active .ogrid-header-filter__funnel {
246
+ border-top-color: var(--mat-sys-primary, #1976d2);
247
+ }
248
+ .ogrid-header-filter__filter-btn--active .ogrid-header-filter__funnel::after {
249
+ background: var(--mat-sys-primary, #1976d2);
250
+ }
251
+ .ogrid-header-filter__dot {
252
+ position: absolute; top: 2px; right: 2px;
253
+ width: 6px; height: 6px; border-radius: 50%;
254
+ background: var(--mat-sys-primary, #1976d2);
255
+ }
256
+ .ogrid-header-filter__popover {
257
+ position: fixed; z-index: 1000;
258
+ background: var(--ogrid-bg, #ffffff); border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.2));
259
+ border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1);
260
+ margin-top: 4px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
261
+ }
262
+ .ogrid-header-filter__popover-header {
263
+ padding: 8px 12px; font-size: 14px; font-weight: 600;
264
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
265
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
266
+ }
267
+ .ogrid-header-filter__popover-body { }
268
+ .ogrid-header-filter__popover-actions {
269
+ display: flex; justify-content: flex-end; gap: 8px; padding: 8px 12px;
270
+ }
271
+ .ogrid-header-filter__input {
272
+ width: 100%; padding: 8px 12px; border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23));
273
+ border-radius: 4px; font-size: 14px; box-sizing: border-box;
274
+ background: var(--ogrid-bg, #ffffff); color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
275
+ }
276
+ .ogrid-header-filter__input:focus { outline: 2px solid var(--mat-sys-primary, #1976d2); outline-offset: -1px; }
277
+ .ogrid-header-filter__options-info { margin-top: 4px; font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
278
+ .ogrid-header-filter__select-actions {
279
+ display: flex; justify-content: space-between; padding: 4px 12px;
280
+ }
281
+ .ogrid-header-filter__options-list { max-height: 240px; overflow-y: auto; padding: 0 4px; }
282
+ .ogrid-header-filter__option {
283
+ display: flex; align-items: center; gap: 8px;
284
+ padding: 4px 8px; cursor: pointer; font-size: 14px;
285
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
286
+ }
287
+ .ogrid-header-filter__option:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
288
+ .ogrid-header-filter__loading, .ogrid-header-filter__empty {
289
+ padding: 16px; text-align: center; font-size: 14px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6));
290
+ }
291
+ .ogrid-header-filter__action-btn {
292
+ padding: 4px 12px; border: none; border-radius: 4px;
293
+ background: transparent; cursor: pointer; font-size: 13px;
294
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
295
+ }
296
+ .ogrid-header-filter__action-btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
297
+ .ogrid-header-filter__action-btn:disabled { opacity: 0.38; cursor: default; }
298
+ .ogrid-header-filter__action-btn--primary {
299
+ background: var(--mat-sys-primary, #1976d2); color: #fff;
300
+ }
301
+ .ogrid-header-filter__action-btn--primary:hover { opacity: 0.9; }
302
+ .ogrid-header-filter__people-selected {
303
+ padding: 12px; border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
304
+ }
305
+ .ogrid-header-filter__people-info-label { font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
306
+ .ogrid-header-filter__people-card {
307
+ display: flex; align-items: center; gap: 8px; margin-top: 4px;
308
+ }
309
+ .ogrid-header-filter__people-avatar {
310
+ width: 32px; height: 32px; border-radius: 50%; background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08));
311
+ display: flex; align-items: center; justify-content: center;
312
+ font-size: 14px; font-weight: 600; flex-shrink: 0;
313
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
314
+ }
315
+ .ogrid-header-filter__people-details { flex: 1; min-width: 0; font-size: 14px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)); }
316
+ .ogrid-header-filter__people-details > div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
317
+ .ogrid-header-filter__people-email { font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
318
+ .ogrid-header-filter__people-option {
319
+ display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer;
320
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
321
+ }
322
+ .ogrid-header-filter__people-option:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
323
+ `],
324
+ host: {
325
+ "(document:click)": "onDocumentClickWrapper($event)"
326
+ }
327
+ })
328
+ ], ColumnHeaderFilterComponent);
329
+ var ColumnHeaderMenuComponent = class {
330
+ constructor() {
331
+ // Signal-backed inputs so computed() tracks changes reactively
332
+ this._canPinLeft = signal(true);
333
+ this._canPinRight = signal(true);
334
+ this._canUnpin = signal(false);
335
+ this._currentSort = signal(null);
336
+ this._isSortable = signal(true);
337
+ this._isResizable = signal(true);
338
+ this.handlers = {};
339
+ this.menuItems = computed(
340
+ () => getColumnHeaderMenuItems({
341
+ canPinLeft: this._canPinLeft(),
342
+ canPinRight: this._canPinRight(),
343
+ canUnpin: this._canUnpin(),
344
+ currentSort: this._currentSort(),
345
+ isSortable: this._isSortable(),
346
+ isResizable: this._isResizable()
347
+ })
348
+ );
349
+ }
350
+ set canPinLeft(v) {
351
+ this._canPinLeft.set(v);
352
+ }
353
+ set canPinRight(v) {
354
+ this._canPinRight.set(v);
355
+ }
356
+ set canUnpin(v) {
357
+ this._canUnpin.set(v);
358
+ }
359
+ set currentSort(v) {
360
+ this._currentSort.set(v);
361
+ }
362
+ set isSortable(v) {
363
+ this._isSortable.set(v);
364
+ }
365
+ set isResizable(v) {
366
+ this._isResizable.set(v);
367
+ }
368
+ handleMenuItemClick(itemId) {
369
+ const h = this.handlers;
370
+ const actionMap = {
371
+ pinLeft: h.onPinLeft,
372
+ pinRight: h.onPinRight,
373
+ unpin: h.onUnpin,
374
+ sortAsc: h.onSortAsc,
375
+ sortDesc: h.onSortDesc,
376
+ clearSort: h.onClearSort,
377
+ autosizeThis: h.onAutosizeThis,
378
+ autosizeAll: h.onAutosizeAll
379
+ };
380
+ const action = actionMap[itemId];
381
+ if (action) {
382
+ action();
383
+ h.onClose?.();
384
+ }
385
+ }
386
+ };
387
+ __decorateClass([
388
+ Input({ required: true })
389
+ ], ColumnHeaderMenuComponent.prototype, "columnId", 2);
390
+ __decorateClass([
391
+ Input()
392
+ ], ColumnHeaderMenuComponent.prototype, "canPinLeft", 1);
393
+ __decorateClass([
394
+ Input()
395
+ ], ColumnHeaderMenuComponent.prototype, "canPinRight", 1);
396
+ __decorateClass([
397
+ Input()
398
+ ], ColumnHeaderMenuComponent.prototype, "canUnpin", 1);
399
+ __decorateClass([
400
+ Input()
401
+ ], ColumnHeaderMenuComponent.prototype, "currentSort", 1);
402
+ __decorateClass([
403
+ Input()
404
+ ], ColumnHeaderMenuComponent.prototype, "isSortable", 1);
405
+ __decorateClass([
406
+ Input()
407
+ ], ColumnHeaderMenuComponent.prototype, "isResizable", 1);
408
+ __decorateClass([
409
+ Input()
410
+ ], ColumnHeaderMenuComponent.prototype, "handlers", 2);
411
+ __decorateClass([
412
+ ViewChild(MatMenuTrigger)
413
+ ], ColumnHeaderMenuComponent.prototype, "menuTrigger", 2);
414
+ ColumnHeaderMenuComponent = __decorateClass([
415
+ Component({
416
+ selector: "column-header-menu",
417
+ standalone: true,
418
+ changeDetection: ChangeDetectionStrategy.OnPush,
419
+ imports: [MatMenuModule, MatDividerModule],
420
+ template: `
421
+ <button
422
+ [matMenuTriggerFor]="menu"
423
+ class="column-header-menu-trigger"
424
+ [attr.aria-label]="'Column options for ' + columnId"
425
+ >
426
+ &#8942;
427
+ </button>
428
+
429
+ <mat-menu #menu="matMenu">
430
+ @for (item of menuItems(); track item.id) {
431
+ <button
432
+ mat-menu-item
433
+ [disabled]="item.disabled"
434
+ (click)="handleMenuItemClick(item.id)"
435
+ >
436
+ {{ item.label }}
437
+ </button>
438
+ @if (item.divider) {
439
+ <mat-divider></mat-divider>
440
+ }
441
+ }
442
+ </mat-menu>
443
+ `,
444
+ styles: [`
445
+ :host { flex-shrink: 0; }
446
+ .column-header-menu-trigger {
447
+ width: 24px;
448
+ height: 24px;
449
+ padding: 0;
450
+ border: none;
451
+ border-radius: 4px;
452
+ background: transparent;
453
+ cursor: pointer;
454
+ font-size: 16px;
455
+ line-height: 1;
456
+ display: inline-flex;
457
+ align-items: center;
458
+ justify-content: center;
459
+ color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.54));
460
+ }
461
+
462
+ .column-header-menu-trigger:hover {
463
+ background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08));
464
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
465
+ }
466
+ `]
467
+ })
468
+ ], ColumnHeaderMenuComponent);
469
+ var InlineCellEditorComponent = class extends BaseInlineCellEditorComponent {
470
+ };
471
+ InlineCellEditorComponent = __decorateClass([
472
+ Component({
473
+ selector: "ogrid-mat-inline-cell-editor",
474
+ standalone: true,
475
+ changeDetection: ChangeDetectionStrategy.OnPush,
476
+ template: INLINE_CELL_EDITOR_TEMPLATE,
477
+ styles: [INLINE_CELL_EDITOR_STYLES]
478
+ })
479
+ ], InlineCellEditorComponent);
480
+ var PopoverCellEditorComponent = class extends BasePopoverCellEditorComponent {
481
+ };
482
+ PopoverCellEditorComponent = __decorateClass([
483
+ Component({
484
+ selector: "ogrid-mat-popover-cell-editor",
485
+ standalone: true,
486
+ changeDetection: ChangeDetectionStrategy.OnPush,
487
+ template: POPOVER_CELL_EDITOR_TEMPLATE,
488
+ styles: [`
489
+ ${POPOVER_CELL_EDITOR_OVERLAY_STYLES}
490
+ .ogrid-popover-anchor {
491
+ width: 100%; height: 100%; display: flex; align-items: center; min-width: 0;
492
+ padding: 6px 10px; box-sizing: border-box; overflow: hidden;
493
+ text-overflow: ellipsis; white-space: nowrap; user-select: none;
494
+ outline: 2px solid var(--ogrid-selection, #217346); outline-offset: -1px;
495
+ z-index: 2; position: relative;
496
+ }
497
+ `]
498
+ })
499
+ ], PopoverCellEditorComponent);
500
+
501
+ // src/datagrid-table/datagrid-table.component.ts
502
+ var DataGridTableComponent = class extends BaseDataGridTableComponent {
503
+ constructor() {
504
+ super();
505
+ this.propsSignal = signal(void 0);
506
+ this.initBase();
507
+ }
508
+ set propsInput(value) {
509
+ this.propsSignal.set(value);
510
+ }
511
+ getProps() {
512
+ return this.propsSignal();
513
+ }
514
+ getWrapperRef() {
515
+ return this.wrapperRef;
516
+ }
517
+ getTableContainerRef() {
518
+ return this.tableContainerRef;
519
+ }
520
+ };
521
+ __decorateClass([
522
+ Input({ required: true, alias: "props" })
523
+ ], DataGridTableComponent.prototype, "propsInput", 1);
524
+ __decorateClass([
525
+ ViewChild("wrapperEl")
526
+ ], DataGridTableComponent.prototype, "wrapperRef", 2);
527
+ __decorateClass([
528
+ ViewChild("tableContainerElRef")
529
+ ], DataGridTableComponent.prototype, "tableContainerRef", 2);
530
+ DataGridTableComponent = __decorateClass([
531
+ Component({
532
+ selector: "ogrid-datagrid-table",
533
+ standalone: true,
534
+ changeDetection: ChangeDetectionStrategy.OnPush,
535
+ encapsulation: ViewEncapsulation.None,
536
+ imports: [ColumnHeaderFilterComponent, ColumnHeaderMenuComponent, StatusBarComponent, GridContextMenuComponent, MarchingAntsOverlayComponent, EmptyStateComponent, InlineCellEditorComponent, PopoverCellEditorComponent],
537
+ providers: [DataGridStateService, ColumnReorderService, VirtualScrollService],
538
+ template: `
539
+ <div class="ogrid-datagrid-root">
540
+ <div
541
+ #wrapperEl
542
+ class="ogrid-datagrid-wrapper"
543
+ [class.ogrid-datagrid-wrapper--fit]="layoutModeFit()"
544
+ [class.ogrid-datagrid-wrapper--overflow-x]="allowOverflowX()"
545
+ [class.ogrid-datagrid-wrapper--loading-empty]="isLoading() && items().length === 0"
546
+ [style.--ogrid-row-height]="rowHeightCssVar()"
547
+ tabindex="0"
548
+ role="region"
549
+ [attr.aria-label]="ariaLabel()"
550
+ [attr.aria-labelledby]="ariaLabelledBy()"
551
+ (mousedown)="onWrapperMouseDown($event)"
552
+ (keydown)="onGridKeyDown($event)"
553
+ (scroll)="onWrapperScroll($event)"
554
+ (contextmenu)="$event.preventDefault()"
555
+ [attr.data-overflow-x]="allowOverflowX() ? 'true' : 'false'"
556
+ >
557
+ <div class="ogrid-datagrid-scroll-wrapper">
558
+ <div [style.minWidth.px]="allowOverflowX() ? minTableWidth() : undefined">
559
+ <div [class.ogrid-datagrid-table-wrapper--loading]="isLoading() && items().length > 0" #tableContainerElRef>
560
+ <table class="ogrid-datagrid-table" [style.minWidth.px]="minTableWidth()"
561
+ >
562
+ <thead [class]="stickyHeader() ? 'ogrid-datagrid-thead ogrid-sticky-header' : 'ogrid-datagrid-thead'">
563
+ @for (row of headerRows(); track $index; let rowIdx = $index) {
564
+ <tr class="ogrid-datagrid-header-row">
565
+ @if (rowIdx === headerRows().length - 1 && hasCheckboxCol()) {
566
+ <th class="ogrid-datagrid-th ogrid-datagrid-checkbox-col" [attr.rowSpan]="headerRows().length > 1 ? 1 : null">
567
+ <div class="ogrid-datagrid-checkbox-wrapper">
568
+ <input
569
+ type="checkbox"
570
+ [checked]="allSelected()"
571
+ [indeterminate]="someSelected()"
572
+ (change)="onSelectAllChange($event)"
573
+ aria-label="Select all rows"
574
+ />
575
+ </div>
576
+ </th>
577
+ }
578
+ @if (rowIdx === 0 && rowIdx < headerRows().length - 1 && hasCheckboxCol()) {
579
+ <th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th" style="width: 48px; min-width: 48px; padding: 0;"></th>
580
+ }
581
+ @if (rowIdx === headerRows().length - 1 && hasRowNumbersCol()) {
582
+ <th class="ogrid-datagrid-th ogrid-row-number-header" [attr.rowSpan]="headerRows().length > 1 ? 1 : null">
583
+ <div class="ogrid-row-number-header-content">#</div>
584
+ </th>
585
+ }
586
+ @if (rowIdx === 0 && rowIdx < headerRows().length - 1 && hasRowNumbersCol()) {
587
+ <th [attr.rowSpan]="headerRows().length - 1" class="ogrid-datagrid-th" [style.width.px]="50" [style.min-width.px]="50" style="padding: 0;"></th>
588
+ }
589
+ @for (cell of row; track cell.columnDef?.columnId ?? $index; let cellIdx = $index) {
590
+ @if (cell.isGroup) {
591
+ <th [attr.colSpan]="cell.colSpan" scope="colgroup" class="ogrid-datagrid-th ogrid-datagrid-group-header">
592
+ {{ cell.label }}
593
+ </th>
594
+ } @else {
595
+ @let col = asColumnDef(cell.columnDef);
596
+ @let colW = getColumnWidth(col);
597
+ @let pinned = isPinned(col.columnId);
598
+ @let pinnedLeft = pinned === 'left';
599
+ @let pinnedRight = pinned === 'right';
600
+ @let sortState = getSortState(col.columnId);
601
+ @let ariaSort = sortState === 'asc' ? 'ascending' : sortState === 'desc' ? 'descending' : null;
602
+ @let config = getFilterConfig(col);
603
+ <th scope="col"
604
+ class="ogrid-datagrid-th"
605
+ [class.ogrid-datagrid-th--pinned-left]="pinnedLeft"
606
+ [class.ogrid-datagrid-th--pinned-right]="pinnedRight"
607
+ [attr.rowSpan]="headerRows().length > 1 ? headerRows().length - rowIdx : null"
608
+ [attr.data-column-id]="col.columnId"
609
+ [attr.aria-sort]="ariaSort"
610
+ [style.minWidth.px]="getEffectiveMinWidth(col)"
611
+ [style.width.px]="colW"
612
+ [style.maxWidth.px]="colW"
613
+ [style.cursor]="columnReorderService.isDragging() ? 'grabbing' : 'grab'"
614
+ [style.left.px]="pinnedLeft ? getPinnedLeftOffset(col.columnId) : null"
615
+ [style.right.px]="pinnedRight ? getPinnedRightOffset(col.columnId) : null"
616
+ (mousedown)="onHeaderMouseDown(col.columnId, $event)"
617
+ >
618
+ <div style="display:flex;align-items:center;gap:4px;">
619
+ <ogrid-column-header-filter
620
+ [columnKey]="col.columnId"
621
+ [columnName]="col.name"
622
+ [filterType]="config.filterType"
623
+ [isSorted]="config.isSorted"
624
+ [isSortedDescending]="config.isSortedDescending"
625
+ [onSort]="config.onSort"
626
+ [selectedValues]="config.selectedValues"
627
+ [onFilterChange]="config.onFilterChange"
628
+ [options]="config.options"
629
+ [isLoadingOptions]="config.isLoadingOptions ?? false"
630
+ [textValue]="config.textValue ?? ''"
631
+ [onTextChange]="config.onTextChange"
632
+ [selectedUser]="config.selectedUser"
633
+ [onUserChange]="config.onUserChange"
634
+ [peopleSearch]="config.peopleSearch"
635
+ [dateValue]="config.dateValue"
636
+ [onDateChange]="config.onDateChange"
637
+ />
638
+ @let pinState = getPinState(col.columnId);
639
+ <column-header-menu
640
+ [columnId]="col.columnId"
641
+ [canPinLeft]="pinState.canPinLeft"
642
+ [canPinRight]="pinState.canPinRight"
643
+ [canUnpin]="pinState.canUnpin"
644
+ [currentSort]="sortState"
645
+ [isSortable]="col.sortable !== false"
646
+ [isResizable]="col.resizable !== false"
647
+ [handlers]="getColumnMenuHandlersMemoized(col.columnId)"
648
+ />
649
+ </div>
650
+ <div class="ogrid-datagrid-resize-handle" (mousedown)="onResizeStart($event, col)"></div>
651
+ </th>
652
+ }
653
+ }
654
+ </tr>
655
+ }
656
+ </thead>
657
+ @if (!showEmptyInGrid()) {
658
+ <tbody>
659
+ @if (vsEnabled() && vsTopSpacerHeight() > 0) {
660
+ <tr class="ogrid-datagrid-vs-spacer" [style.height.px]="vsTopSpacerHeight()"></tr>
661
+ }
662
+ @for (item of vsVisibleItems(); track getRowId()(item); let localIdx = $index) {
663
+ @let rowIndex = vsStartIndex() + localIdx;
664
+ @let rowId = getRowId()(item);
665
+ @let isSelected = selectedRowIds().has(rowId);
666
+ <tr
667
+ class="ogrid-datagrid-row"
668
+ [class.ogrid-datagrid-row--selected]="isSelected"
669
+ [attr.data-row-id]="rowId"
670
+ (click)="onRowClick($event, rowId)"
671
+ >
672
+ @if (hasCheckboxCol()) {
673
+ <td class="ogrid-datagrid-td ogrid-datagrid-checkbox-col">
674
+ <div
675
+ class="ogrid-datagrid-checkbox-wrapper"
676
+ [attr.data-row-index]="rowIndex"
677
+ [attr.data-col-index]="0"
678
+ (click)="$event.stopPropagation()"
679
+ >
680
+ <input
681
+ type="checkbox"
682
+ [checked]="isSelected"
683
+ (change)="onRowCheckboxChange(rowId, $event, rowIndex)"
684
+ [attr.aria-label]="'Select row ' + (rowIndex + 1)"
685
+ />
686
+ </div>
687
+ </td>
688
+ }
689
+ @if (hasRowNumbersCol()) {
690
+ <td class="ogrid-datagrid-td ogrid-row-number-cell">
691
+ <div class="ogrid-row-number-cell-content">
692
+ {{ rowNumberOffset() + rowIndex + 1 }}
693
+ </div>
694
+ </td>
695
+ }
696
+ @for (colLayout of columnLayouts(); track colLayout.col.columnId; let colIdx = $index) {
697
+ <td
698
+ class="ogrid-datagrid-td"
699
+ [attr.data-column-id]="colLayout.col.columnId"
700
+ [class.ogrid-datagrid-td--pinned-left]="colLayout.pinnedLeft"
701
+ [class.ogrid-datagrid-td--pinned-right]="colLayout.pinnedRight"
702
+ [style.minWidth.px]="colLayout.minWidth"
703
+ [style.width.px]="colLayout.width"
704
+ [style.maxWidth.px]="colLayout.width"
705
+ [style.left.px]="colLayout.pinnedLeft ? getPinnedLeftOffset(colLayout.col.columnId) : null"
706
+ [style.right.px]="colLayout.pinnedRight ? getPinnedRightOffset(colLayout.col.columnId) : null"
707
+ >
708
+ @let descriptor = getCellDescriptor(item, colLayout.col, rowIndex, colIdx);
709
+ @if (descriptor.mode === 'editing-inline') {
710
+ <div class="ogrid-editing-cell">
711
+ <ogrid-mat-inline-cell-editor
712
+ [value]="descriptor.value"
713
+ [item]="item"
714
+ [column]="colLayout.col"
715
+ [rowIndex]="rowIndex"
716
+ [editorType]="descriptor.editorType ?? 'text'"
717
+ (commit)="commitEdit(item, colLayout.col.columnId, descriptor.value, $event, rowIndex, descriptor.globalColIndex)"
718
+ (cancel)="cancelEdit()"
719
+ ></ogrid-mat-inline-cell-editor>
720
+ </div>
721
+ } @else if (descriptor.mode === 'editing-popover') {
722
+ @let editorProps = buildPopoverEditorProps(item, colLayout.col, descriptor);
723
+ <ogrid-mat-popover-cell-editor
724
+ [item]="item"
725
+ [column]="colLayout.col"
726
+ [rowIndex]="rowIndex"
727
+ [globalColIndex]="descriptor.globalColIndex"
728
+ [displayValue]="descriptor.displayValue"
729
+ [editorProps]="editorProps"
730
+ [onCancel]="cancelEdit.bind(this)"
731
+ ></ogrid-mat-popover-cell-editor>
732
+ } @else {
733
+ @let content = resolveCellContent(colLayout.col, item, descriptor.displayValue);
734
+ @let cellStyle = resolveCellStyleFn(colLayout.col, item);
735
+ <div
736
+ class="ogrid-datagrid-cell"
737
+ [class.ogrid-datagrid-cell--active]="descriptor.isActive && !descriptor.isInRange"
738
+ [class.ogrid-datagrid-cell--in-range]="descriptor.isInRange"
739
+ [class.ogrid-datagrid-cell--in-cut-range]="descriptor.isInCutRange"
740
+ [class.ogrid-datagrid-cell--editable]="descriptor.canEditAny"
741
+ [class.ogrid-datagrid-cell--numeric]="colLayout.col.type === 'numeric'"
742
+ [class.ogrid-datagrid-cell--boolean]="colLayout.col.type === 'boolean'"
743
+ [attr.data-row-index]="rowIndex"
744
+ [attr.data-col-index]="descriptor.globalColIndex"
745
+ [attr.data-in-range]="descriptor.isInRange ? 'true' : null"
746
+ [attr.tabindex]="descriptor.isActive ? 0 : -1"
747
+ (mousedown)="onCellMouseDown($event, rowIndex, descriptor.globalColIndex)"
748
+ (click)="onCellClick(rowIndex, descriptor.globalColIndex)"
749
+ (contextmenu)="onCellContextMenu($event)"
750
+ (dblclick)="descriptor.canEditAny ? onCellDblClick(descriptor.rowId, colLayout.col.columnId) : null"
751
+ [attr.role]="descriptor.canEditAny ? 'button' : null"
752
+ [style]="cellStyle ?? undefined"
753
+ >
754
+ {{ content }}
755
+ @if (descriptor.canEditAny && descriptor.isSelectionEndCell) {
756
+ <div
757
+ class="ogrid-datagrid-fill-handle"
758
+ (mousedown)="onFillHandleMouseDown($event)"
759
+ aria-label="Fill handle"
760
+ ></div>
761
+ }
762
+ </div>
763
+ }
764
+ </td>
765
+ }
766
+ </tr>
767
+ }
768
+ @if (vsEnabled() && vsBottomSpacerHeight() > 0) {
769
+ <tr class="ogrid-datagrid-vs-spacer" [style.height.px]="vsBottomSpacerHeight()"></tr>
770
+ }
771
+ </tbody>
772
+ }
773
+ </table>
774
+
775
+ <ogrid-marching-ants-overlay
776
+ [containerEl]="tableContainerEl()"
777
+ [selectionRange]="state().interaction.selectionRange"
778
+ [copyRange]="state().interaction.copyRange"
779
+ [cutRange]="state().interaction.cutRange"
780
+ [colOffset]="state().layout.colOffset"
781
+ [columnSizingVersion]="columnSizingVersion()"
782
+ [items]="items()"
783
+ [visibleColumns]="propsVisibleColumns()"
784
+ [columnOrder]="propsColumnOrder()"
785
+ ></ogrid-marching-ants-overlay>
786
+
787
+ @if (showEmptyInGrid() && emptyState()) {
788
+ <div class="ogrid-datagrid-empty">
789
+ <div class="ogrid-datagrid-empty__title">No results found</div>
790
+ <div class="ogrid-datagrid-empty__message">
791
+ <ogrid-empty-state
792
+ [message]="emptyState()?.message"
793
+ [hasActiveFilters]="emptyState()?.hasActiveFilters ?? false"
794
+ [render]="emptyState()?.render"
795
+ (clearAll)="emptyState()?.onClearAll()"
796
+ ></ogrid-empty-state>
797
+ </div>
798
+ </div>
799
+ }
800
+ </div>
801
+ </div>
802
+ </div>
803
+
804
+ @if (columnReorderService.isDragging() && columnReorderService.dropIndicatorX() !== null) {
805
+ <div class="ogrid-datagrid-drop-indicator" [style.left.px]="columnReorderService.dropIndicatorX()"></div>
806
+ }
807
+
808
+ @if (menuPosition()) {
809
+ <div
810
+ class="ogrid-datagrid-context-menu-overlay"
811
+ (click)="closeContextMenu()"
812
+ (contextmenu)="$event.preventDefault(); closeContextMenu()"
813
+ >
814
+ <ogrid-context-menu
815
+ [x]="menuPosition()!.x"
816
+ [y]="menuPosition()!.y"
817
+ [hasSelection]="hasCellSelection()"
818
+ [canUndoProp]="canUndo()"
819
+ [canRedoProp]="canRedo()"
820
+ (undoAction)="onUndo()"
821
+ (redoAction)="onRedo()"
822
+ (copyAction)="handleCopy()"
823
+ (cutAction)="handleCut()"
824
+ (pasteAction)="handlePaste()"
825
+ (selectAllAction)="handleSelectAllCells()"
826
+ (closeAction)="closeContextMenu()"
827
+ />
828
+ </div>
829
+ }
830
+ </div>
831
+
832
+ @let sbConfig = statusBarConfig();
833
+ @if (sbConfig) {
834
+ <ogrid-status-bar
835
+ [totalCount]="sbConfig.totalCount"
836
+ [filteredCount]="sbConfig.filteredCount"
837
+ [selectedCount]="sbConfig.selectedCount ?? selectedRowIds().size"
838
+ [selectedCellCount]="selectionCellCount()"
839
+ [aggregation]="sbConfig.aggregation"
840
+ [suppressRowCount]="sbConfig.suppressRowCount"
841
+ />
842
+ }
843
+
844
+ @if (isLoading()) {
845
+ <div class="ogrid-datagrid-loading-overlay">
846
+ <div class="ogrid-datagrid-loading-inner">
847
+ <div class="ogrid-datagrid-spinner"></div>
848
+ <span>{{ loadingMessage() }}</span>
849
+ </div>
850
+ </div>
851
+ }
852
+ </div>
853
+ `,
854
+ styles: [OGRID_THEME_VARS_CSS, `
855
+ :host { display: block; }
856
+ .ogrid-datagrid-root { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
857
+ .ogrid-datagrid-wrapper {
858
+ position: relative; flex: 1; min-height: 0; width: 100%; max-width: 100%;
859
+ overflow-x: hidden; overflow-y: auto; background: var(--ogrid-bg, #ffffff);
860
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
861
+ will-change: scroll-position; outline: none;
862
+ }
863
+ .ogrid-datagrid-wrapper [data-drag-range] { background: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important; }
864
+ .ogrid-datagrid-wrapper--fit { width: fit-content; }
865
+ .ogrid-datagrid-wrapper--overflow-x { overflow-x: auto; }
866
+ .ogrid-datagrid-wrapper--loading-empty { min-height: 200px; }
867
+ .ogrid-datagrid-scroll-wrapper { display: flex; flex-direction: column; min-height: 100%; }
868
+ .ogrid-datagrid-table-wrapper--loading { position: relative; opacity: 0.6; }
869
+ .ogrid-datagrid-table {
870
+ width: 100%; border-collapse: collapse; table-layout: fixed;
871
+ }
872
+ .ogrid-datagrid-table tbody tr { height: var(--ogrid-row-height, auto); }
873
+ .ogrid-datagrid-thead {
874
+ z-index: 8; background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
875
+ }
876
+ .ogrid-datagrid-thead th { background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); }
877
+ .ogrid-datagrid-header-row { background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); }
878
+ .ogrid-datagrid-th {
879
+ font-weight: 600; padding: 6px 10px; text-align: left;
880
+ font-size: 14px; border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
881
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); z-index: 8;
882
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
883
+ }
884
+ .ogrid-sticky-header .ogrid-datagrid-th { position: sticky; top: 0; }
885
+ .ogrid-datagrid-th:focus-visible {
886
+ outline: 2px solid var(--mat-sys-primary, #1976d2); outline-offset: -2px; z-index: 11;
887
+ }
888
+ .ogrid-datagrid-th--pinned-left {
889
+ position: sticky; top: 0; left: 0; z-index: 10; background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); will-change: transform;
890
+ border-right: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
891
+ box-shadow: 2px 0 4px -1px rgba(0, 0, 0, 0.1);
892
+ }
893
+ .ogrid-datagrid-th--pinned-right {
894
+ position: sticky; top: 0; right: 0; z-index: 10; background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); will-change: transform;
895
+ border-left: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
896
+ box-shadow: -2px 0 4px -1px rgba(0, 0, 0, 0.1);
897
+ }
898
+ .ogrid-datagrid-group-header {
899
+ text-align: center; font-weight: 600; border-bottom: 2px solid var(--ogrid-border, rgba(0, 0, 0, 0.12)); padding: 6px;
900
+ }
901
+ .ogrid-datagrid-checkbox-col {
902
+ width: ${CHECKBOX_COLUMN_WIDTH}px; min-width: ${CHECKBOX_COLUMN_WIDTH}px;
903
+ max-width: ${CHECKBOX_COLUMN_WIDTH}px; text-align: center;
904
+ }
905
+ .ogrid-datagrid-checkbox-wrapper { display: flex; align-items: center; justify-content: center; }
906
+ .ogrid-row-number-header, .ogrid-row-number-cell {
907
+ width: ${ROW_NUMBER_COLUMN_WIDTH}px; min-width: ${ROW_NUMBER_COLUMN_WIDTH}px;
908
+ max-width: ${ROW_NUMBER_COLUMN_WIDTH}px; text-align: center;
909
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); font-weight: 600;
910
+ font-variant-numeric: tabular-nums; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6));
911
+ position: sticky; left: 0; z-index: 3;
912
+ }
913
+ .ogrid-row-number-header { z-index: 4; }
914
+ .ogrid-row-number-header-content, .ogrid-row-number-cell-content {
915
+ display: flex; align-items: center; justify-content: center;
916
+ }
917
+ .ogrid-datagrid-row { }
918
+ .ogrid-datagrid-row:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
919
+ .ogrid-datagrid-row--selected { background: var(--ogrid-selected-row-bg, #e6f0fb); }
920
+ .ogrid-datagrid-td { position: relative; padding: 0; height: 1px; border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.06)); }
921
+ .ogrid-datagrid-td--pinned-left {
922
+ position: sticky; left: 0; z-index: 6; background: var(--ogrid-bg, #ffffff); will-change: transform;
923
+ border-right: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
924
+ box-shadow: 2px 0 4px -1px rgba(0, 0, 0, 0.1);
925
+ }
926
+ .ogrid-datagrid-td--pinned-right {
927
+ position: sticky; right: 0; z-index: 6; background: var(--ogrid-bg, #ffffff); will-change: transform;
928
+ border-left: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
929
+ box-shadow: -2px 0 4px -1px rgba(0, 0, 0, 0.1);
930
+ }
931
+ .ogrid-datagrid-cell {
932
+ width: 100%; height: 100%; display: flex; align-items: center; min-width: 0;
933
+ padding: 6px 10px; box-sizing: border-box; overflow: hidden;
934
+ text-overflow: ellipsis; white-space: nowrap; user-select: none; outline: none;
935
+ font-size: 14px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
936
+ }
937
+ .ogrid-datagrid-cell:focus-visible {
938
+ outline: 2px solid var(--mat-sys-primary, #1976d2); outline-offset: -2px; z-index: 3;
939
+ }
940
+ .ogrid-datagrid-cell--numeric { justify-content: flex-end; text-align: right; }
941
+ .ogrid-datagrid-cell--boolean { justify-content: center; text-align: center; }
942
+ .ogrid-datagrid-cell--editable { cursor: cell; }
943
+ .ogrid-datagrid-cell--active {
944
+ outline: 2px solid var(--ogrid-selection-color, #217346); outline-offset: -1px;
945
+ z-index: 2; position: relative; overflow: visible;
946
+ }
947
+ .ogrid-datagrid-cell--in-range { background: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)); }
948
+ .ogrid-datagrid-cell--in-cut-range { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); opacity: 0.7; }
949
+ .ogrid-datagrid-cell--editing { padding: 0; }
950
+ .ogrid-editing-cell {
951
+ width: 100%; height: 100%; display: flex; align-items: center; box-sizing: border-box;
952
+ outline: 2px solid var(--ogrid-selection-color, #217346); outline-offset: -1px;
953
+ z-index: 2; position: relative; background: var(--ogrid-bg, #fff); overflow: visible; padding: 0;
954
+ }
955
+ .ogrid-datagrid-editor-input {
956
+ width: 100%; height: 100%; padding: 6px 10px; border: 2px solid var(--ogrid-selection-color, #217346);
957
+ box-sizing: border-box; font-size: 14px; outline: none; font-family: inherit; line-height: inherit;
958
+ background: var(--ogrid-bg, #ffffff); color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
959
+ }
960
+ .ogrid-datagrid-cell--numeric .ogrid-datagrid-editor-input {
961
+ text-align: right;
962
+ }
963
+ .ogrid-datagrid-editor-select {
964
+ width: 100%; height: 100%; padding: 4px 8px; border: 2px solid var(--ogrid-selection-color, #217346);
965
+ box-sizing: border-box; font-size: 14px;
966
+ background: var(--ogrid-bg, #ffffff); color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
967
+ }
968
+ .ogrid-datagrid-fill-handle {
969
+ position: absolute; right: -3px; bottom: -3px; width: 7px; height: 7px;
970
+ background: var(--ogrid-selection-color, #217346);
971
+ border: 1px solid var(--ogrid-bg, #ffffff); border-radius: 1px;
972
+ cursor: crosshair; pointer-events: auto; z-index: 3;
973
+ }
974
+ .ogrid-datagrid-resize-handle {
975
+ position: absolute; top: 0; right: -3px; bottom: 0; width: 8px;
976
+ cursor: col-resize; user-select: none;
977
+ }
978
+ .ogrid-datagrid-resize-handle::after {
979
+ content: ''; position: absolute; top: 4px; right: 3px; bottom: 4px; width: 2px;
980
+ background: var(--ogrid-border, rgba(0, 0, 0, 0.12)); border-radius: 1px; transition: background 0.15s;
981
+ }
982
+ .ogrid-datagrid-resize-handle:hover::after { background: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.4)); }
983
+ .ogrid-datagrid-resize-handle:active::after { background: var(--mat-sys-primary, #1976d2); }
984
+ .ogrid-datagrid-empty {
985
+ padding: 32px 16px; text-align: center; border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
986
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
987
+ }
988
+ .ogrid-datagrid-empty__title { font-size: 18px; font-weight: 600; margin-bottom: 8px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)); }
989
+ .ogrid-datagrid-empty__message { font-size: 14px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
990
+ .ogrid-datagrid-empty__clear {
991
+ background: none; border: none; color: var(--mat-sys-primary, #1976d2);
992
+ cursor: pointer; font-size: inherit; text-decoration: underline; padding: 0;
993
+ }
994
+ .ogrid-datagrid-loading-overlay {
995
+ position: absolute; inset: 0; z-index: 2;
996
+ display: flex; align-items: center; justify-content: center;
997
+ background: var(--ogrid-loading-overlay, rgba(255, 255, 255, 0.7));
998
+ }
999
+ .ogrid-datagrid-loading-inner {
1000
+ display: flex; flex-direction: column; align-items: center; gap: 8px;
1001
+ padding: 16px; background: var(--ogrid-bg, #ffffff); border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12)); border-radius: 4px;
1002
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1003
+ }
1004
+ .ogrid-datagrid-spinner {
1005
+ width: 24px; height: 24px; border: 3px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
1006
+ border-top-color: var(--mat-sys-primary, #1976d2);
1007
+ border-radius: 50%; animation: ogrid-spin 0.8s linear infinite;
1008
+ }
1009
+ @keyframes ogrid-spin { to { transform: rotate(360deg); } }
1010
+ .ogrid-datagrid-drop-indicator {
1011
+ position: absolute; top: 0; bottom: 0; width: 3px;
1012
+ background: var(--ogrid-selection-color, #217346);
1013
+ pointer-events: none; z-index: 100; transition: left 0.05s;
1014
+ }
1015
+ .ogrid-datagrid-context-menu-overlay {
1016
+ position: fixed; inset: 0; z-index: 1000;
1017
+ }
1018
+
1019
+ /* Angular Material Menu popup dark mode overrides */
1020
+ .mat-mdc-menu-panel {
1021
+ background: var(--ogrid-bg, #ffffff) !important;
1022
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)) !important;
1023
+ }
1024
+ .mat-mdc-menu-item {
1025
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)) !important;
1026
+ }
1027
+ .mat-mdc-menu-item:hover:not([disabled]) {
1028
+ background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)) !important;
1029
+ }
1030
+ .mat-mdc-menu-item .mat-mdc-menu-item-text {
1031
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)) !important;
1032
+ }
1033
+ `]
1034
+ })
1035
+ ], DataGridTableComponent);
1036
+ var ColumnChooserComponent = class extends BaseColumnChooserComponent {
1037
+ onDocumentClick(event) {
1038
+ const el = event.target;
1039
+ if (!el.closest("ogrid-column-chooser")) {
1040
+ this.isOpen.set(false);
1041
+ }
1042
+ }
1043
+ };
1044
+ ColumnChooserComponent = __decorateClass([
1045
+ Component({
1046
+ selector: "ogrid-column-chooser",
1047
+ standalone: true,
1048
+ changeDetection: ChangeDetectionStrategy.OnPush,
1049
+ template: `
1050
+ <div class="ogrid-column-chooser">
1051
+ <button
1052
+ class="ogrid-column-chooser__trigger"
1053
+ (click)="toggle()"
1054
+ [attr.aria-expanded]="isOpen()"
1055
+ aria-haspopup="listbox"
1056
+ >
1057
+ &#9638; Column Visibility ({{ visibleCount() }} of {{ totalCount() }})
1058
+ <span class="ogrid-column-chooser__caret">{{ isOpen() ? '&#9650;' : '&#9660;' }}</span>
1059
+ </button>
1060
+
1061
+ @if (isOpen()) {
1062
+ <div class="ogrid-column-chooser__dropdown" (click)="$event.stopPropagation()">
1063
+ <div class="ogrid-column-chooser__header">
1064
+ Select Columns ({{ visibleCount() }} of {{ totalCount() }})
1065
+ </div>
1066
+
1067
+ <div class="ogrid-column-chooser__list">
1068
+ @for (col of columns; track col.columnId) {
1069
+ <label class="ogrid-column-chooser__item">
1070
+ <input
1071
+ type="checkbox"
1072
+ [checked]="visibleColumns.has(col.columnId)"
1073
+ (change)="onCheckboxChange(col.columnId, $event)"
1074
+ />
1075
+ <span>{{ col.name }}</span>
1076
+ </label>
1077
+ }
1078
+ </div>
1079
+
1080
+ <div class="ogrid-column-chooser__footer">
1081
+ <button class="ogrid-column-chooser__btn" (click)="onClearAll()">Clear All</button>
1082
+ <button class="ogrid-column-chooser__btn ogrid-column-chooser__btn--primary" (click)="selectAll()">Select All</button>
1083
+ </div>
1084
+ </div>
1085
+ }
1086
+ </div>
1087
+ `,
1088
+ styles: [`
1089
+ :host { display: inline-flex; position: relative; }
1090
+ .ogrid-column-chooser { position: relative; }
1091
+ .ogrid-column-chooser__trigger {
1092
+ display: inline-flex; align-items: center; gap: 6px;
1093
+ padding: 6px 12px; border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23)); border-radius: 4px;
1094
+ background: transparent; cursor: pointer; font-size: 14px; font-weight: 600;
1095
+ text-transform: none; white-space: nowrap;
1096
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1097
+ }
1098
+ .ogrid-column-chooser__trigger:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
1099
+ .ogrid-column-chooser__caret { font-size: 10px; }
1100
+ .ogrid-column-chooser__dropdown {
1101
+ position: absolute; top: 100%; right: 0; z-index: 1000;
1102
+ min-width: 220px; margin-top: 4px;
1103
+ background: var(--ogrid-bg, #ffffff); border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12)); border-radius: 4px;
1104
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1105
+ }
1106
+ .ogrid-column-chooser__header {
1107
+ padding: 8px 12px; font-size: 14px; font-weight: 600;
1108
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
1109
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
1110
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1111
+ }
1112
+ .ogrid-column-chooser__list {
1113
+ max-height: 320px; overflow-y: auto; padding: 4px 0;
1114
+ }
1115
+ .ogrid-column-chooser__item {
1116
+ display: flex; align-items: center; gap: 8px;
1117
+ padding: 4px 12px; min-height: 32px; cursor: pointer; font-size: 14px;
1118
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1119
+ }
1120
+ .ogrid-column-chooser__item:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
1121
+ .ogrid-column-chooser__footer {
1122
+ display: flex; justify-content: flex-end; gap: 8px;
1123
+ padding: 8px 12px; border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
1124
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
1125
+ }
1126
+ .ogrid-column-chooser__btn {
1127
+ padding: 4px 12px; border: none; border-radius: 4px;
1128
+ background: transparent; cursor: pointer; font-size: 13px; text-transform: none;
1129
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1130
+ }
1131
+ .ogrid-column-chooser__btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
1132
+ .ogrid-column-chooser__btn--primary {
1133
+ background: var(--mat-sys-primary, #1976d2); color: #fff;
1134
+ }
1135
+ .ogrid-column-chooser__btn--primary:hover {
1136
+ opacity: 0.9;
1137
+ }
1138
+ `],
1139
+ host: {
1140
+ "(document:click)": "onDocumentClick($event)"
1141
+ }
1142
+ })
1143
+ ], ColumnChooserComponent);
1144
+ var PaginationControlsComponent = class extends BasePaginationControlsComponent {
1145
+ };
1146
+ PaginationControlsComponent = __decorateClass([
1147
+ Component({
1148
+ selector: "ogrid-pagination-controls",
1149
+ standalone: true,
1150
+ changeDetection: ChangeDetectionStrategy.OnPush,
1151
+ template: `
1152
+ @if (vm(); as vm) {
1153
+ <nav class="ogrid-pagination" role="navigation" aria-label="Pagination">
1154
+ <span class="ogrid-pagination__info">
1155
+ Showing {{ vm.startItem }} to {{ vm.endItem }} of {{ totalCount.toLocaleString() }} {{ entityLabelPlural }}
1156
+ </span>
1157
+
1158
+ <span class="ogrid-pagination__pages">
1159
+ <button
1160
+ class="ogrid-pagination__btn"
1161
+ [disabled]="currentPage === 1"
1162
+ (click)="pageChange.emit(1)"
1163
+ aria-label="First page"
1164
+ >&laquo;</button>
1165
+ <button
1166
+ class="ogrid-pagination__btn"
1167
+ [disabled]="currentPage === 1"
1168
+ (click)="pageChange.emit(currentPage - 1)"
1169
+ aria-label="Previous page"
1170
+ >&lsaquo;</button>
1171
+
1172
+ @if (vm.showStartEllipsis) {
1173
+ <button class="ogrid-pagination__btn" (click)="pageChange.emit(1)" aria-label="Page 1">1</button>
1174
+ <span class="ogrid-pagination__ellipsis" aria-hidden="true">&hellip;</span>
1175
+ }
1176
+
1177
+ @for (pageNum of vm.pageNumbers; track pageNum) {
1178
+ <button
1179
+ class="ogrid-pagination__btn"
1180
+ [class.ogrid-pagination__btn--active]="currentPage === pageNum"
1181
+ (click)="pageChange.emit(pageNum)"
1182
+ [attr.aria-label]="'Page ' + pageNum"
1183
+ [attr.aria-current]="currentPage === pageNum ? 'page' : null"
1184
+ >{{ pageNum }}</button>
1185
+ }
1186
+
1187
+ @if (vm.showEndEllipsis) {
1188
+ <span class="ogrid-pagination__ellipsis" aria-hidden="true">&hellip;</span>
1189
+ <button
1190
+ class="ogrid-pagination__btn"
1191
+ (click)="pageChange.emit(vm.totalPages)"
1192
+ [attr.aria-label]="'Page ' + vm.totalPages"
1193
+ >{{ vm.totalPages }}</button>
1194
+ }
1195
+
1196
+ <button
1197
+ class="ogrid-pagination__btn"
1198
+ [disabled]="currentPage >= vm.totalPages"
1199
+ (click)="pageChange.emit(currentPage + 1)"
1200
+ aria-label="Next page"
1201
+ >&rsaquo;</button>
1202
+ <button
1203
+ class="ogrid-pagination__btn"
1204
+ [disabled]="currentPage >= vm.totalPages"
1205
+ (click)="pageChange.emit(vm.totalPages)"
1206
+ aria-label="Last page"
1207
+ >&raquo;</button>
1208
+ </span>
1209
+
1210
+ <span class="ogrid-pagination__size">
1211
+ <label>Rows
1212
+ <select
1213
+ [value]="pageSize"
1214
+ (change)="onPageSizeSelect($event)"
1215
+ aria-label="Rows per page"
1216
+ >
1217
+ @for (n of vm.pageSizeOptions; track n) {
1218
+ <option [value]="n" [selected]="pageSize === n">{{ n }}</option>
1219
+ }
1220
+ </select>
1221
+ </label>
1222
+ </span>
1223
+ </nav>
1224
+ }
1225
+ `,
1226
+ styles: [`
1227
+ :host { display: block; }
1228
+ .ogrid-pagination {
1229
+ display: flex; align-items: center; justify-content: space-between;
1230
+ flex-wrap: wrap; gap: 8px; padding: 6px 12px; font-size: 14px;
1231
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1232
+ }
1233
+ .ogrid-pagination__info { color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
1234
+ .ogrid-pagination__pages { display: flex; align-items: center; gap: 2px; }
1235
+ .ogrid-pagination__btn {
1236
+ min-width: 32px; height: 32px; padding: 0 6px;
1237
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23)); border-radius: 4px;
1238
+ background: transparent; cursor: pointer; font-size: 14px;
1239
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1240
+ }
1241
+ .ogrid-pagination__btn:hover:not(:disabled) { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
1242
+ .ogrid-pagination__btn:disabled { opacity: 0.38; cursor: default; }
1243
+ .ogrid-pagination__btn--active {
1244
+ background: var(--mat-sys-primary, #1976d2); color: #fff;
1245
+ border-color: var(--mat-sys-primary, #1976d2);
1246
+ }
1247
+ .ogrid-pagination__ellipsis { margin: 0 4px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
1248
+ .ogrid-pagination__size { display: flex; align-items: center; gap: 8px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)); }
1249
+ .ogrid-pagination__size select {
1250
+ min-width: 60px; height: 32px; padding: 4px 8px;
1251
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23)); border-radius: 4px;
1252
+ font-size: 14px; margin-left: 8px;
1253
+ background: var(--ogrid-bg, #ffffff); color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
1254
+ }
1255
+ `]
1256
+ })
1257
+ ], PaginationControlsComponent);
1258
+
1259
+ // src/ogrid/ogrid.component.ts
1260
+ var OGridComponent = class extends BaseOGridComponent {
1261
+ };
1262
+ OGridComponent = __decorateClass([
1263
+ Component({
1264
+ selector: "ogrid",
1265
+ standalone: true,
1266
+ changeDetection: ChangeDetectionStrategy.OnPush,
1267
+ imports: [
1268
+ OGridLayoutComponent,
1269
+ DataGridTableComponent,
1270
+ ColumnChooserComponent,
1271
+ PaginationControlsComponent
1272
+ ],
1273
+ providers: [OGridService],
1274
+ styles: [`:host { display: block; height: 100%; }`],
1275
+ template: `
1276
+ <ogrid-layout
1277
+ [className]="ogridService.className()"
1278
+ [sideBar]="ogridService.sideBarProps()"
1279
+ [hasToolbar]="showToolbar"
1280
+ [hasToolbarBelow]="false"
1281
+ [hasPagination]="true"
1282
+ [fullScreen]="ogridService.fullScreen()"
1283
+ >
1284
+ <ng-container toolbarEnd>
1285
+ @if (ogridService.columnChooserPlacement() === 'toolbar') {
1286
+ <ogrid-column-chooser
1287
+ [columns]="ogridService.columnChooser().columns"
1288
+ [visibleColumns]="ogridService.columnChooser().visibleColumns"
1289
+ (visibilityChange)="ogridService.columnChooser().onVisibilityChange($event.columnKey, $event.visible)"
1290
+ />
1291
+ }
1292
+ </ng-container>
1293
+
1294
+ <ogrid-datagrid-table [props]="ogridService.dataGridProps()" />
1295
+
1296
+ <ng-container pagination>
1297
+ <ogrid-pagination-controls
1298
+ [currentPage]="ogridService.pagination().page"
1299
+ [pageSize]="ogridService.pagination().pageSize"
1300
+ [totalCount]="ogridService.pagination().displayTotalCount"
1301
+ [pageSizeOptions]="ogridService.pagination().pageSizeOptions"
1302
+ [entityLabelPlural]="ogridService.pagination().entityLabelPlural"
1303
+ (pageChange)="ogridService.pagination().setPage($event)"
1304
+ (pageSizeChange)="onPageSizeChange($event)"
1305
+ />
1306
+ </ng-container>
1307
+ </ogrid-layout>
1308
+ `
1309
+ })
1310
+ ], OGridComponent);
1311
+
1312
+ export { ColumnChooserComponent, ColumnHeaderFilterComponent, ColumnHeaderMenuComponent, DataGridTableComponent, InlineCellEditorComponent, OGridComponent, PaginationControlsComponent, PopoverCellEditorComponent };