@alaarab/ogrid-angular 2.6.0 → 2.6.1

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.
Files changed (62) hide show
  1. package/dist/esm/components/base-column-chooser.component.js +77 -0
  2. package/dist/esm/components/base-column-header-filter.component.js +267 -0
  3. package/dist/esm/components/base-column-header-menu.component.js +80 -0
  4. package/dist/esm/components/base-datagrid-table.component.js +768 -0
  5. package/dist/esm/components/base-inline-cell-editor.component.js +380 -0
  6. package/dist/esm/components/base-ogrid.component.js +36 -0
  7. package/dist/esm/components/base-pagination-controls.component.js +68 -0
  8. package/dist/esm/components/base-popover-cell-editor.component.js +122 -0
  9. package/dist/esm/components/empty-state.component.js +68 -0
  10. package/dist/esm/components/formula-bar.component.js +99 -0
  11. package/dist/esm/components/formula-ref-overlay.component.js +115 -0
  12. package/dist/esm/components/grid-context-menu.component.js +197 -0
  13. package/dist/esm/components/inline-cell-editor-template.js +134 -0
  14. package/dist/esm/components/marching-ants-overlay.component.js +177 -0
  15. package/dist/esm/components/ogrid-layout.component.js +302 -0
  16. package/dist/esm/components/sheet-tabs.component.js +83 -0
  17. package/dist/esm/components/sidebar.component.js +431 -0
  18. package/dist/esm/components/status-bar.component.js +92 -0
  19. package/dist/esm/index.js +39 -819
  20. package/dist/esm/services/column-reorder.service.js +176 -0
  21. package/dist/esm/services/datagrid-editing.service.js +59 -0
  22. package/dist/esm/services/datagrid-interaction.service.js +744 -0
  23. package/dist/esm/services/datagrid-layout.service.js +157 -0
  24. package/dist/esm/services/datagrid-state.service.js +636 -0
  25. package/dist/esm/services/formula-engine.service.js +223 -0
  26. package/dist/esm/services/ogrid.service.js +1094 -0
  27. package/dist/esm/services/virtual-scroll.service.js +114 -0
  28. package/dist/esm/styles/ogrid-theme-vars.js +112 -0
  29. package/dist/esm/types/columnTypes.js +1 -0
  30. package/dist/esm/types/dataGridTypes.js +1 -0
  31. package/dist/esm/types/index.js +1 -0
  32. package/dist/esm/utils/dataGridViewModel.js +6 -0
  33. package/dist/esm/utils/debounce.js +68 -0
  34. package/dist/esm/utils/index.js +8 -0
  35. package/dist/esm/utils/latestRef.js +41 -0
  36. package/dist/types/components/base-column-chooser.component.d.ts +3 -0
  37. package/dist/types/components/base-column-header-filter.component.d.ts +3 -0
  38. package/dist/types/components/base-column-header-menu.component.d.ts +3 -0
  39. package/dist/types/components/base-datagrid-table.component.d.ts +4 -19
  40. package/dist/types/components/base-inline-cell-editor.component.d.ts +7 -0
  41. package/dist/types/components/base-ogrid.component.d.ts +3 -0
  42. package/dist/types/components/base-pagination-controls.component.d.ts +3 -0
  43. package/dist/types/components/base-popover-cell-editor.component.d.ts +3 -0
  44. package/dist/types/components/empty-state.component.d.ts +3 -0
  45. package/dist/types/components/formula-bar.component.d.ts +3 -8
  46. package/dist/types/components/formula-ref-overlay.component.d.ts +3 -6
  47. package/dist/types/components/grid-context-menu.component.d.ts +3 -0
  48. package/dist/types/components/inline-cell-editor-template.d.ts +2 -2
  49. package/dist/types/components/marching-ants-overlay.component.d.ts +3 -0
  50. package/dist/types/components/ogrid-layout.component.d.ts +3 -0
  51. package/dist/types/components/sheet-tabs.component.d.ts +3 -8
  52. package/dist/types/components/sidebar.component.d.ts +3 -0
  53. package/dist/types/components/status-bar.component.d.ts +3 -0
  54. package/dist/types/index.d.ts +0 -2
  55. package/dist/types/services/column-reorder.service.d.ts +3 -0
  56. package/dist/types/services/datagrid-interaction.service.d.ts +1 -0
  57. package/dist/types/services/datagrid-state.service.d.ts +5 -0
  58. package/dist/types/services/formula-engine.service.d.ts +3 -9
  59. package/dist/types/services/ogrid.service.d.ts +8 -11
  60. package/dist/types/services/virtual-scroll.service.d.ts +3 -0
  61. package/dist/types/types/dataGridTypes.d.ts +0 -4
  62. package/package.json +4 -3
@@ -0,0 +1,157 @@
1
+ import { signal, computed, effect } from '@angular/core';
2
+ import { flattenColumns, CHECKBOX_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, resolveResponsiveConfig, applyResponsiveHiding, } from '@alaarab/ogrid-core';
3
+ /**
4
+ * Manages column layout, visibility, sizing, and container measurement.
5
+ * Extracted from DataGridStateService for modularity.
6
+ *
7
+ * Not @Injectable - instantiated and owned by DataGridStateService.
8
+ */
9
+ export class DataGridLayoutHelper {
10
+ constructor(props, wrapperEl, ngZone) {
11
+ // --- Internal state ---
12
+ this.containerWidthSig = signal(0, ...(ngDevMode ? [{ debugName: "containerWidthSig" }] : []));
13
+ this.columnSizingOverridesSig = signal({}, ...(ngDevMode ? [{ debugName: "columnSizingOverridesSig" }] : []));
14
+ // ResizeObserver
15
+ this.resizeObserver = null;
16
+ this.props = props;
17
+ this.wrapperEl = wrapperEl;
18
+ this.initialColumnWidthsSig = computed(() => this.props()?.initialColumnWidths, ...(ngDevMode ? [{ debugName: "initialColumnWidthsSig" }] : []));
19
+ this.flatColumnsRaw = computed(() => {
20
+ const p = this.props();
21
+ if (!p)
22
+ return [];
23
+ return flattenColumns(p.columns);
24
+ }, ...(ngDevMode ? [{ debugName: "flatColumnsRaw" }] : []));
25
+ this.flatColumns = computed(() => {
26
+ const raw = this.flatColumnsRaw();
27
+ const p = this.props();
28
+ const pinnedColumns = p?.pinnedColumns;
29
+ if (!pinnedColumns || Object.keys(pinnedColumns).length === 0)
30
+ return raw;
31
+ return raw.map((col) => {
32
+ const override = pinnedColumns[col.columnId];
33
+ if (override && col.pinned !== override)
34
+ return { ...col, pinned: override };
35
+ return col;
36
+ });
37
+ }, ...(ngDevMode ? [{ debugName: "flatColumns" }] : []));
38
+ this.visibleCols = computed(() => {
39
+ const p = this.props();
40
+ if (!p)
41
+ return [];
42
+ const flatCols = this.flatColumns();
43
+ const filtered = p.visibleColumns
44
+ ? flatCols.filter((c) => p.visibleColumns.has(c.columnId))
45
+ : flatCols;
46
+ let ordered;
47
+ const order = p.columnOrder;
48
+ if (!order?.length) {
49
+ ordered = filtered;
50
+ }
51
+ else {
52
+ const orderMap = new Map();
53
+ for (let i = 0; i < order.length; i++) {
54
+ orderMap.set(order[i], i);
55
+ }
56
+ ordered = [...filtered].sort((a, b) => {
57
+ const ia = orderMap.get(a.columnId) ?? -1;
58
+ const ib = orderMap.get(b.columnId) ?? -1;
59
+ if (ia === -1 && ib === -1)
60
+ return 0;
61
+ if (ia === -1)
62
+ return 1;
63
+ if (ib === -1)
64
+ return -1;
65
+ return ia - ib;
66
+ });
67
+ }
68
+ // Responsive column hiding
69
+ return applyResponsiveHiding(ordered, this.containerWidthSig(), resolveResponsiveConfig(p.responsiveColumns));
70
+ }, ...(ngDevMode ? [{ debugName: "visibleCols" }] : []));
71
+ this.visibleColumnCount = computed(() => this.visibleCols().length, ...(ngDevMode ? [{ debugName: "visibleColumnCount" }] : []));
72
+ this.hasCheckboxCol = computed(() => (this.props()?.rowSelection ?? 'none') === 'multiple', ...(ngDevMode ? [{ debugName: "hasCheckboxCol" }] : []));
73
+ this.hasRowNumbersCol = computed(() => !!this.props()?.showRowNumbers, ...(ngDevMode ? [{ debugName: "hasRowNumbersCol" }] : []));
74
+ this.specialColsCount = computed(() => (this.hasCheckboxCol() ? 1 : 0) + (this.hasRowNumbersCol() ? 1 : 0), ...(ngDevMode ? [{ debugName: "specialColsCount" }] : []));
75
+ this.totalColCount = computed(() => this.visibleColumnCount() + this.specialColsCount(), ...(ngDevMode ? [{ debugName: "totalColCount" }] : []));
76
+ this.colOffset = computed(() => this.specialColsCount(), ...(ngDevMode ? [{ debugName: "colOffset" }] : []));
77
+ this.rowIndexByRowId = computed(() => {
78
+ const p = this.props();
79
+ if (!p)
80
+ return new Map();
81
+ const m = new Map();
82
+ p.items.forEach((item, idx) => m.set(p.getRowId(item), idx));
83
+ return m;
84
+ }, ...(ngDevMode ? [{ debugName: "rowIndexByRowId" }] : []));
85
+ this.minTableWidth = computed(() => {
86
+ const checkboxW = this.hasCheckboxCol() ? CHECKBOX_COLUMN_WIDTH : 0;
87
+ return this.visibleCols().reduce((sum, c) => sum + (c.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH) + CELL_PADDING, checkboxW);
88
+ }, ...(ngDevMode ? [{ debugName: "minTableWidth" }] : []));
89
+ this.desiredTableWidth = computed(() => {
90
+ const checkboxW = this.hasCheckboxCol() ? CHECKBOX_COLUMN_WIDTH : 0;
91
+ const overrides = this.columnSizingOverridesSig();
92
+ return this.visibleCols().reduce((sum, c) => {
93
+ const override = overrides[c.columnId];
94
+ const w = override
95
+ ? override.widthPx
96
+ : (c.idealWidth ?? c.defaultWidth ?? c.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH);
97
+ return sum + Math.max(c.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH, w) + CELL_PADDING;
98
+ }, checkboxW);
99
+ }, ...(ngDevMode ? [{ debugName: "desiredTableWidth" }] : []));
100
+ // Initialize column sizing overrides from initial widths
101
+ effect(() => {
102
+ const widths = this.initialColumnWidthsSig();
103
+ if (widths) {
104
+ const result = {};
105
+ for (const [id, width] of Object.entries(widths)) {
106
+ result[id] = { widthPx: width };
107
+ }
108
+ this.columnSizingOverridesSig.set(result);
109
+ }
110
+ });
111
+ // Container width measurement via ResizeObserver
112
+ effect(() => {
113
+ const el = this.wrapperEl();
114
+ if (this.resizeObserver) {
115
+ this.resizeObserver.disconnect();
116
+ this.resizeObserver = null;
117
+ }
118
+ if (!el)
119
+ return;
120
+ const measure = () => {
121
+ const rect = el.getBoundingClientRect();
122
+ const cs = window.getComputedStyle(el);
123
+ const borderX = (parseFloat(cs.borderLeftWidth || '0') || 0) +
124
+ (parseFloat(cs.borderRightWidth || '0') || 0);
125
+ this.containerWidthSig.set(Math.max(0, rect.width - borderX));
126
+ };
127
+ ngZone.runOutsideAngular(() => {
128
+ this.resizeObserver = new ResizeObserver(measure);
129
+ this.resizeObserver.observe(el);
130
+ });
131
+ measure();
132
+ });
133
+ // Clean up column sizing overrides for removed columns
134
+ effect(() => {
135
+ const colIds = new Set(this.flatColumns().map((c) => c.columnId));
136
+ this.columnSizingOverridesSig.update((prev) => {
137
+ const next = {};
138
+ let changed = false;
139
+ for (const [id, value] of Object.entries(prev)) {
140
+ if (colIds.has(id)) {
141
+ next[id] = value;
142
+ }
143
+ else {
144
+ changed = true;
145
+ }
146
+ }
147
+ return changed ? next : prev;
148
+ });
149
+ });
150
+ }
151
+ destroy() {
152
+ if (this.resizeObserver) {
153
+ this.resizeObserver.disconnect();
154
+ this.resizeObserver = null;
155
+ }
156
+ }
157
+ }