@alaarab/ogrid-angular 2.0.9 → 2.0.12

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 (28) hide show
  1. package/dist/esm/components/base-column-chooser.component.js +78 -0
  2. package/dist/esm/components/base-column-header-filter.component.js +266 -0
  3. package/dist/esm/components/base-datagrid-table.component.js +106 -6
  4. package/dist/esm/components/base-pagination-controls.component.js +72 -0
  5. package/dist/esm/components/empty-state.component.js +22 -10
  6. package/dist/esm/components/grid-context-menu.component.js +65 -26
  7. package/dist/esm/components/marching-ants-overlay.component.js +78 -69
  8. package/dist/esm/components/ogrid-layout.component.js +94 -35
  9. package/dist/esm/components/sidebar.component.js +58 -55
  10. package/dist/esm/components/status-bar.component.js +43 -23
  11. package/dist/esm/index.js +3 -0
  12. package/dist/esm/services/datagrid-state.service.js +1 -1
  13. package/dist/esm/services/ogrid.service.js +8 -8
  14. package/dist/types/components/base-column-chooser.component.d.ts +37 -0
  15. package/dist/types/components/base-column-header-filter.component.d.ts +90 -0
  16. package/dist/types/components/base-datagrid-table.component.d.ts +19 -1
  17. package/dist/types/components/base-pagination-controls.component.d.ts +34 -0
  18. package/dist/types/components/empty-state.component.d.ts +5 -4
  19. package/dist/types/components/grid-context-menu.component.d.ts +16 -16
  20. package/dist/types/components/marching-ants-overlay.component.d.ts +14 -14
  21. package/dist/types/components/ogrid-layout.component.d.ts +5 -5
  22. package/dist/types/components/sidebar.component.d.ts +1 -1
  23. package/dist/types/components/status-bar.component.d.ts +10 -10
  24. package/dist/types/index.d.ts +5 -0
  25. package/dist/types/services/datagrid-state.service.d.ts +1 -1
  26. package/dist/types/services/ogrid.service.d.ts +2 -1
  27. package/dist/types/types/dataGridTypes.d.ts +3 -1
  28. package/package.json +2 -2
@@ -4,30 +4,27 @@ 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, output, viewChild, DestroyRef, inject } from '@angular/core';
7
+ import { Component, Input, Output, EventEmitter, ViewChild, DestroyRef, inject } from '@angular/core';
8
8
  import { CommonModule } from '@angular/common';
9
9
  import { GRID_CONTEXT_MENU_ITEMS, formatShortcut } from '@alaarab/ogrid-core';
10
10
  let GridContextMenuComponent = class GridContextMenuComponent {
11
11
  constructor() {
12
12
  this.destroyRef = inject(DestroyRef);
13
- this.x = input.required();
14
- this.y = input.required();
15
- this.hasSelection = input(false);
16
- this.canUndoProp = input(false);
17
- this.canRedoProp = input(false);
18
- this.classNames = input(undefined);
19
- this.copy = output();
20
- this.cut = output();
21
- this.paste = output();
22
- this.selectAll = output();
23
- this.undoAction = output();
24
- this.redoAction = output();
25
- this.close = output();
26
- this.menuRef = viewChild('menuRef');
13
+ this.hasSelection = false;
14
+ this.canUndoProp = false;
15
+ this.canRedoProp = false;
16
+ this.classNames = undefined;
17
+ this.copy = new EventEmitter();
18
+ this.cut = new EventEmitter();
19
+ this.paste = new EventEmitter();
20
+ this.selectAll = new EventEmitter();
21
+ this.undoAction = new EventEmitter();
22
+ this.redoAction = new EventEmitter();
23
+ this.close = new EventEmitter();
27
24
  this.menuItems = GRID_CONTEXT_MENU_ITEMS;
28
25
  this.formatShortcutFn = formatShortcut;
29
26
  this.clickOutsideHandler = (e) => {
30
- const el = this.menuRef()?.nativeElement;
27
+ const el = this.menuRef?.nativeElement;
31
28
  if (el && !el.contains(e.target))
32
29
  this.close.emit();
33
30
  };
@@ -44,11 +41,11 @@ let GridContextMenuComponent = class GridContextMenuComponent {
44
41
  });
45
42
  }
46
43
  isDisabled(item) {
47
- if (item.disabledWhenNoSelection && !this.hasSelection())
44
+ if (item.disabledWhenNoSelection && !this.hasSelection)
48
45
  return true;
49
- if (item.id === 'undo' && !this.canUndoProp())
46
+ if (item.id === 'undo' && !this.canUndoProp)
50
47
  return true;
51
- if (item.id === 'redo' && !this.canRedoProp())
48
+ if (item.id === 'redo' && !this.canRedoProp)
52
49
  return true;
53
50
  return false;
54
51
  }
@@ -76,6 +73,48 @@ let GridContextMenuComponent = class GridContextMenuComponent {
76
73
  this.close.emit();
77
74
  }
78
75
  };
76
+ __decorate([
77
+ Input({ required: true })
78
+ ], GridContextMenuComponent.prototype, "x", void 0);
79
+ __decorate([
80
+ Input({ required: true })
81
+ ], GridContextMenuComponent.prototype, "y", void 0);
82
+ __decorate([
83
+ Input()
84
+ ], GridContextMenuComponent.prototype, "hasSelection", void 0);
85
+ __decorate([
86
+ Input()
87
+ ], GridContextMenuComponent.prototype, "canUndoProp", void 0);
88
+ __decorate([
89
+ Input()
90
+ ], GridContextMenuComponent.prototype, "canRedoProp", void 0);
91
+ __decorate([
92
+ Input()
93
+ ], GridContextMenuComponent.prototype, "classNames", void 0);
94
+ __decorate([
95
+ Output()
96
+ ], GridContextMenuComponent.prototype, "copy", void 0);
97
+ __decorate([
98
+ Output()
99
+ ], GridContextMenuComponent.prototype, "cut", void 0);
100
+ __decorate([
101
+ Output()
102
+ ], GridContextMenuComponent.prototype, "paste", void 0);
103
+ __decorate([
104
+ Output()
105
+ ], GridContextMenuComponent.prototype, "selectAll", void 0);
106
+ __decorate([
107
+ Output()
108
+ ], GridContextMenuComponent.prototype, "undoAction", void 0);
109
+ __decorate([
110
+ Output()
111
+ ], GridContextMenuComponent.prototype, "redoAction", void 0);
112
+ __decorate([
113
+ Output()
114
+ ], GridContextMenuComponent.prototype, "close", void 0);
115
+ __decorate([
116
+ ViewChild('menuRef')
117
+ ], GridContextMenuComponent.prototype, "menuRef", void 0);
79
118
  GridContextMenuComponent = __decorate([
80
119
  Component({
81
120
  selector: 'ogrid-context-menu',
@@ -84,25 +123,25 @@ GridContextMenuComponent = __decorate([
84
123
  template: `
85
124
  <div
86
125
  #menuRef
87
- [class]="classNames()?.contextMenu ?? ''"
126
+ [class]="classNames?.contextMenu ?? ''"
88
127
  role="menu"
89
- [style.left.px]="x()"
90
- [style.top.px]="y()"
128
+ [style.left.px]="x"
129
+ [style.top.px]="y"
91
130
  aria-label="Grid context menu"
92
131
  >
93
132
  @for (item of menuItems; track item.id) {
94
133
  @if (item.dividerBefore) {
95
- <div [class]="classNames()?.contextMenuDivider ?? ''"></div>
134
+ <div [class]="classNames?.contextMenuDivider ?? ''"></div>
96
135
  }
97
136
  <button
98
137
  type="button"
99
- [class]="classNames()?.contextMenuItem ?? ''"
138
+ [class]="classNames?.contextMenuItem ?? ''"
100
139
  (click)="onItemClick(item.id)"
101
140
  [disabled]="isDisabled(item)"
102
141
  >
103
- <span [class]="classNames()?.contextMenuItemLabel ?? ''">{{ item.label }}</span>
142
+ <span [class]="classNames?.contextMenuItemLabel ?? ''">{{ item.label }}</span>
104
143
  @if (item.shortcut) {
105
- <span [class]="classNames()?.contextMenuItemShortcut ?? ''">
144
+ <span [class]="classNames?.contextMenuItemShortcut ?? ''">
106
145
  {{ formatShortcutFn(item.shortcut) }}
107
146
  </span>
108
147
  }
@@ -4,81 +4,25 @@ 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, effect, signal, DestroyRef, inject } from '@angular/core';
7
+ import { Component, Input, signal, DestroyRef, inject } from '@angular/core';
8
8
  import { CommonModule } from '@angular/common';
9
- function measureRange(container, range, colOffset) {
10
- const startGlobalCol = range.startCol + colOffset;
11
- const endGlobalCol = range.endCol + colOffset;
12
- const topLeft = container.querySelector(`[data-row-index="${range.startRow}"][data-col-index="${startGlobalCol}"]`);
13
- const bottomRight = container.querySelector(`[data-row-index="${range.endRow}"][data-col-index="${endGlobalCol}"]`);
14
- if (!topLeft || !bottomRight)
15
- return null;
16
- const cRect = container.getBoundingClientRect();
17
- const tlRect = topLeft.getBoundingClientRect();
18
- const brRect = bottomRight.getBoundingClientRect();
19
- return {
20
- top: tlRect.top - cRect.top,
21
- left: tlRect.left - cRect.left,
22
- width: brRect.right - tlRect.left,
23
- height: brRect.bottom - tlRect.top,
24
- };
25
- }
26
- function ensureKeyframes() {
27
- if (typeof document === 'undefined')
28
- return;
29
- if (document.getElementById('ogrid-marching-ants-keyframes'))
30
- return;
31
- const style = document.createElement('style');
32
- style.id = 'ogrid-marching-ants-keyframes';
33
- style.textContent = '@keyframes ogrid-marching-ants{to{stroke-dashoffset:-8}}';
34
- document.head.appendChild(style);
35
- }
9
+ import { measureRange, injectGlobalStyles } from '@alaarab/ogrid-core';
36
10
  let MarchingAntsOverlayComponent = class MarchingAntsOverlayComponent {
37
11
  constructor() {
38
12
  this.destroyRef = inject(DestroyRef);
39
- this.containerEl = input.required();
40
- this.selectionRange = input(null);
41
- this.copyRange = input(null);
42
- this.cutRange = input(null);
43
- this.colOffset = input(0);
44
- this.columnSizingVersion = input(0);
13
+ this.selectionRange = null;
14
+ this.copyRange = null;
15
+ this.cutRange = null;
16
+ this.colOffset = 0;
17
+ this.columnSizingVersion = 0;
18
+ this.items = [];
19
+ this.visibleColumns = undefined;
20
+ this.columnOrder = undefined;
45
21
  this.selRect = signal(null);
46
22
  this.clipRect = signal(null);
47
23
  this.rafId = 0;
48
24
  this.resizeObserver = null;
49
- ensureKeyframes();
50
- effect(() => {
51
- const container = this.containerEl();
52
- const selRange = this.selectionRange();
53
- const clipRange = this.copyRange() ?? this.cutRange();
54
- const colOff = this.colOffset();
55
- void this.columnSizingVersion(); // Track column resize changes
56
- if (this.resizeObserver) {
57
- this.resizeObserver.disconnect();
58
- this.resizeObserver = null;
59
- }
60
- if (!selRange && !clipRange) {
61
- this.selRect.set(null);
62
- this.clipRect.set(null);
63
- return;
64
- }
65
- const measureAll = () => {
66
- if (!container) {
67
- this.selRect.set(null);
68
- this.clipRect.set(null);
69
- return;
70
- }
71
- this.selRect.set(selRange ? measureRange(container, selRange, colOff) : null);
72
- this.clipRect.set(clipRange ? measureRange(container, clipRange, colOff) : null);
73
- };
74
- if (this.rafId)
75
- cancelAnimationFrame(this.rafId);
76
- this.rafId = requestAnimationFrame(measureAll);
77
- if (container) {
78
- this.resizeObserver = new ResizeObserver(measureAll);
79
- this.resizeObserver.observe(container);
80
- }
81
- });
25
+ injectGlobalStyles('ogrid-marching-ants-keyframes', '@keyframes ogrid-marching-ants{to{stroke-dashoffset:-8}}');
82
26
  this.destroyRef.onDestroy(() => {
83
27
  if (this.rafId)
84
28
  cancelAnimationFrame(this.rafId);
@@ -86,9 +30,47 @@ let MarchingAntsOverlayComponent = class MarchingAntsOverlayComponent {
86
30
  this.resizeObserver.disconnect();
87
31
  });
88
32
  }
33
+ ngOnChanges(_changes) {
34
+ this.recalculate();
35
+ }
36
+ recalculate() {
37
+ const container = this.containerEl;
38
+ const selRange = this.selectionRange;
39
+ const clipRange = this.copyRange ?? this.cutRange;
40
+ const colOff = this.colOffset;
41
+ void this.columnSizingVersion; // Track column resize changes
42
+ void this.items; // Track data changes (sorting)
43
+ void this.visibleColumns; // Track column visibility changes
44
+ void this.columnOrder; // Track column reordering
45
+ if (this.resizeObserver) {
46
+ this.resizeObserver.disconnect();
47
+ this.resizeObserver = null;
48
+ }
49
+ if (!selRange && !clipRange) {
50
+ this.selRect.set(null);
51
+ this.clipRect.set(null);
52
+ return;
53
+ }
54
+ const measureAll = () => {
55
+ if (!container) {
56
+ this.selRect.set(null);
57
+ this.clipRect.set(null);
58
+ return;
59
+ }
60
+ this.selRect.set(selRange ? measureRange(container, selRange, colOff) : null);
61
+ this.clipRect.set(clipRange ? measureRange(container, clipRange, colOff) : null);
62
+ };
63
+ if (this.rafId)
64
+ cancelAnimationFrame(this.rafId);
65
+ this.rafId = requestAnimationFrame(measureAll);
66
+ if (container) {
67
+ this.resizeObserver = new ResizeObserver(measureAll);
68
+ this.resizeObserver.observe(container);
69
+ }
70
+ }
89
71
  clipRangeMatchesSel() {
90
- const selRange = this.selectionRange();
91
- const clipRange = this.copyRange() ?? this.cutRange();
72
+ const selRange = this.selectionRange;
73
+ const clipRange = this.copyRange ?? this.cutRange;
92
74
  return selRange != null && clipRange != null &&
93
75
  selRange.startRow === clipRange.startRow &&
94
76
  selRange.startCol === clipRange.startCol &&
@@ -99,6 +81,33 @@ let MarchingAntsOverlayComponent = class MarchingAntsOverlayComponent {
99
81
  return Math.max(0, n);
100
82
  }
101
83
  };
84
+ __decorate([
85
+ Input({ required: true })
86
+ ], MarchingAntsOverlayComponent.prototype, "containerEl", void 0);
87
+ __decorate([
88
+ Input()
89
+ ], MarchingAntsOverlayComponent.prototype, "selectionRange", void 0);
90
+ __decorate([
91
+ Input()
92
+ ], MarchingAntsOverlayComponent.prototype, "copyRange", void 0);
93
+ __decorate([
94
+ Input()
95
+ ], MarchingAntsOverlayComponent.prototype, "cutRange", void 0);
96
+ __decorate([
97
+ Input()
98
+ ], MarchingAntsOverlayComponent.prototype, "colOffset", void 0);
99
+ __decorate([
100
+ Input()
101
+ ], MarchingAntsOverlayComponent.prototype, "columnSizingVersion", void 0);
102
+ __decorate([
103
+ Input()
104
+ ], MarchingAntsOverlayComponent.prototype, "items", void 0);
105
+ __decorate([
106
+ Input()
107
+ ], MarchingAntsOverlayComponent.prototype, "visibleColumns", void 0);
108
+ __decorate([
109
+ Input()
110
+ ], MarchingAntsOverlayComponent.prototype, "columnOrder", void 0);
102
111
  MarchingAntsOverlayComponent = __decorate([
103
112
  Component({
104
113
  selector: 'ogrid-marching-ants-overlay',
@@ -4,61 +4,126 @@ 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 } from '@angular/core';
7
+ import { Component, Input, ViewEncapsulation } from '@angular/core';
8
8
  import { CommonModule } from '@angular/common';
9
9
  import { SideBarComponent } from './sidebar.component';
10
10
  import { GRID_BORDER_RADIUS } from '@alaarab/ogrid-core';
11
11
  let OGridLayoutComponent = class OGridLayoutComponent {
12
12
  constructor() {
13
- this.className = input(undefined);
14
- this.hasToolbar = input(false);
15
- this.hasToolbarBelow = input(false);
16
- this.hasPagination = input(false);
17
- this.sideBar = input(null);
13
+ this.hasToolbar = false;
14
+ this.hasToolbarBelow = false;
15
+ this.hasPagination = false;
16
+ this.sideBar = null;
18
17
  this.borderRadius = GRID_BORDER_RADIUS;
19
18
  }
20
19
  };
20
+ __decorate([
21
+ Input()
22
+ ], OGridLayoutComponent.prototype, "className", void 0);
23
+ __decorate([
24
+ Input()
25
+ ], OGridLayoutComponent.prototype, "hasToolbar", void 0);
26
+ __decorate([
27
+ Input()
28
+ ], OGridLayoutComponent.prototype, "hasToolbarBelow", void 0);
29
+ __decorate([
30
+ Input()
31
+ ], OGridLayoutComponent.prototype, "hasPagination", void 0);
32
+ __decorate([
33
+ Input()
34
+ ], OGridLayoutComponent.prototype, "sideBar", void 0);
21
35
  OGridLayoutComponent = __decorate([
22
36
  Component({
23
37
  selector: 'ogrid-layout',
24
38
  standalone: true,
39
+ encapsulation: ViewEncapsulation.None,
25
40
  imports: [CommonModule, SideBarComponent],
26
41
  styles: [`
42
+ /* ─── OGrid Theme Variables ─── */
43
+ :root {
44
+ --ogrid-bg: #ffffff;
45
+ --ogrid-fg: rgba(0, 0, 0, 0.87);
46
+ --ogrid-fg-secondary: rgba(0, 0, 0, 0.6);
47
+ --ogrid-fg-muted: rgba(0, 0, 0, 0.5);
48
+ --ogrid-border: rgba(0, 0, 0, 0.12);
49
+ --ogrid-header-bg: rgba(0, 0, 0, 0.04);
50
+ --ogrid-hover-bg: rgba(0, 0, 0, 0.04);
51
+ --ogrid-selected-row-bg: #e6f0fb;
52
+ --ogrid-active-cell-bg: rgba(0, 0, 0, 0.02);
53
+ --ogrid-range-bg: rgba(33, 115, 70, 0.12);
54
+ --ogrid-accent: #0078d4;
55
+ --ogrid-selection-color: #217346;
56
+ --ogrid-loading-overlay: rgba(255, 255, 255, 0.7);
57
+ }
58
+ @media (prefers-color-scheme: dark) {
59
+ :root:not([data-theme="light"]) {
60
+ --ogrid-bg: #1e1e1e;
61
+ --ogrid-fg: rgba(255, 255, 255, 0.87);
62
+ --ogrid-fg-secondary: rgba(255, 255, 255, 0.6);
63
+ --ogrid-fg-muted: rgba(255, 255, 255, 0.5);
64
+ --ogrid-border: rgba(255, 255, 255, 0.12);
65
+ --ogrid-header-bg: rgba(255, 255, 255, 0.06);
66
+ --ogrid-hover-bg: rgba(255, 255, 255, 0.08);
67
+ --ogrid-selected-row-bg: #1a3a5c;
68
+ --ogrid-active-cell-bg: rgba(255, 255, 255, 0.06);
69
+ --ogrid-range-bg: rgba(46, 160, 67, 0.15);
70
+ --ogrid-accent: #4da6ff;
71
+ --ogrid-selection-color: #2ea043;
72
+ --ogrid-loading-overlay: rgba(0, 0, 0, 0.7);
73
+ }
74
+ }
75
+ [data-theme="dark"] {
76
+ --ogrid-bg: #1e1e1e;
77
+ --ogrid-fg: rgba(255, 255, 255, 0.87);
78
+ --ogrid-fg-secondary: rgba(255, 255, 255, 0.6);
79
+ --ogrid-fg-muted: rgba(255, 255, 255, 0.5);
80
+ --ogrid-border: rgba(255, 255, 255, 0.12);
81
+ --ogrid-header-bg: rgba(255, 255, 255, 0.06);
82
+ --ogrid-hover-bg: rgba(255, 255, 255, 0.08);
83
+ --ogrid-selected-row-bg: #1a3a5c;
84
+ --ogrid-active-cell-bg: rgba(255, 255, 255, 0.06);
85
+ --ogrid-range-bg: rgba(46, 160, 67, 0.15);
86
+ --ogrid-accent: #4da6ff;
87
+ --ogrid-selection-color: #2ea043;
88
+ --ogrid-loading-overlay: rgba(0, 0, 0, 0.7);
89
+ }
90
+ :host { display: block; height: 100%; }
27
91
  .ogrid-layout-root { display: flex; flex-direction: column; height: 100%; }
28
92
  .ogrid-layout-container {
29
- border: 1px solid var(--ogrid-border, #e0e0e0);
93
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
30
94
  overflow: hidden; display: flex; flex-direction: column;
31
- flex: 1; min-height: 0; background: var(--ogrid-bg, #fff);
95
+ flex: 1; min-height: 0; background: var(--ogrid-bg, #ffffff);
96
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
32
97
  }
33
98
  .ogrid-layout-toolbar {
34
99
  display: flex; justify-content: space-between; align-items: center;
35
- padding: 6px 12px; background: var(--ogrid-header-bg, #f5f5f5);
100
+ padding: 6px 12px; background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
36
101
  gap: 8px; flex-wrap: wrap; min-height: 0;
37
102
  }
38
103
  .ogrid-layout-toolbar--has-below { border-bottom: none; }
39
- .ogrid-layout-toolbar--no-below { border-bottom: 1px solid var(--ogrid-border, #e0e0e0); }
104
+ .ogrid-layout-toolbar--no-below { border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12)); }
40
105
  .ogrid-layout-toolbar-left { display: flex; align-items: center; gap: 8px; }
41
106
  .ogrid-layout-toolbar-right { display: flex; align-items: center; gap: 8px; }
42
107
  .ogrid-layout-toolbar-below {
43
- border-bottom: 1px solid var(--ogrid-border, #e0e0e0);
44
- padding: 6px 12px; background: var(--ogrid-header-bg, #f5f5f5);
108
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
109
+ padding: 6px 12px; background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
45
110
  }
46
111
  .ogrid-layout-grid-area { width: 100%; min-width: 0; min-height: 0; flex: 1; display: flex; }
47
112
  .ogrid-layout-grid-content { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
48
113
  .ogrid-layout-footer {
49
- border-top: 1px solid var(--ogrid-border, #e0e0e0);
50
- background: var(--ogrid-header-bg, #f5f5f5); padding: 6px 12px;
114
+ border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
115
+ background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04)); padding: 6px 12px;
51
116
  }
52
117
  `],
53
118
  template: `
54
- <div [class]="(className() ?? '') + ' ogrid-layout-root'">
119
+ <div [class]="(className ?? '') + ' ogrid-layout-root'">
55
120
  <div class="ogrid-layout-container" [style.border-radius.px]="borderRadius">
56
121
  <!-- Toolbar strip -->
57
- @if (hasToolbar()) {
122
+ @if (hasToolbar) {
58
123
  <div
59
124
  class="ogrid-layout-toolbar"
60
- [class.ogrid-layout-toolbar--has-below]="hasToolbarBelow()"
61
- [class.ogrid-layout-toolbar--no-below]="!hasToolbarBelow()"
125
+ [class.ogrid-layout-toolbar--has-below]="hasToolbarBelow"
126
+ [class.ogrid-layout-toolbar--no-below]="!hasToolbarBelow"
62
127
  >
63
128
  <div class="ogrid-layout-toolbar-left">
64
129
  <ng-content select="[toolbar]"></ng-content>
@@ -70,33 +135,27 @@ OGridLayoutComponent = __decorate([
70
135
  }
71
136
 
72
137
  <!-- Secondary toolbar row -->
73
- @if (hasToolbarBelow()) {
138
+ @if (hasToolbarBelow) {
74
139
  <div class="ogrid-layout-toolbar-below">
75
140
  <ng-content select="[toolbarBelow]"></ng-content>
76
141
  </div>
77
142
  }
78
143
 
79
- <!-- Grid area -->
80
- @if (sideBar()) {
81
- <div class="ogrid-layout-grid-area">
82
- @if (sideBar()?.position === 'left') {
83
- <ogrid-sidebar [sideBarProps]="sideBar()"></ogrid-sidebar>
84
- }
85
- <div class="ogrid-layout-grid-content">
86
- <ng-content></ng-content>
87
- </div>
88
- @if (sideBar()?.position !== 'left') {
89
- <ogrid-sidebar [sideBarProps]="sideBar()"></ogrid-sidebar>
90
- }
91
- </div>
92
- } @else {
144
+ <!-- Grid area (single ng-content to avoid Angular content projection issues) -->
145
+ <div class="ogrid-layout-grid-area">
146
+ @if (sideBar && sideBar.position === 'left') {
147
+ <ogrid-sidebar [sideBarProps]="sideBar"></ogrid-sidebar>
148
+ }
93
149
  <div class="ogrid-layout-grid-content">
94
150
  <ng-content></ng-content>
95
151
  </div>
96
- }
152
+ @if (sideBar && sideBar.position !== 'left') {
153
+ <ogrid-sidebar [sideBarProps]="sideBar"></ogrid-sidebar>
154
+ }
155
+ </div>
97
156
 
98
157
  <!-- Footer strip (pagination) -->
99
- @if (hasPagination()) {
158
+ @if (hasPagination) {
100
159
  <div class="ogrid-layout-footer">
101
160
  <ng-content select="[pagination]"></ng-content>
102
161
  </div>