@alaarab/ogrid-angular-radix 2.0.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.
Files changed (33) hide show
  1. package/README.md +76 -0
  2. package/dist/esm/column-chooser/column-chooser.component.js +199 -0
  3. package/dist/esm/column-header-filter/column-header-filter.component.js +497 -0
  4. package/dist/esm/datagrid-table/datagrid-table.component.js +573 -0
  5. package/dist/esm/index.js +14 -0
  6. package/dist/esm/ogrid/ogrid.component.js +77 -0
  7. package/dist/esm/pagination-controls/pagination-controls.component.js +189 -0
  8. package/dist/types/column-chooser/column-chooser.component.d.ts +26 -0
  9. package/dist/types/column-header-filter/column-header-filter.component.d.ts +67 -0
  10. package/dist/types/datagrid-table/datagrid-table.component.d.ts +131 -0
  11. package/dist/types/index.d.ts +12 -0
  12. package/dist/types/ogrid/ogrid.component.d.ts +14 -0
  13. package/dist/types/pagination-controls/pagination-controls.component.d.ts +15 -0
  14. package/jest-mocks/angular-cdk-overlay.cjs.js +38 -0
  15. package/jest-mocks/style-mock.js +1 -0
  16. package/jest.config.js +43 -0
  17. package/package.json +37 -0
  18. package/scripts/compile-styles.js +53 -0
  19. package/src/__tests__/column-chooser.component.spec.ts.skip +195 -0
  20. package/src/__tests__/column-header-filter.component.spec.ts.skip +401 -0
  21. package/src/__tests__/datagrid-table.component.spec.ts.skip +417 -0
  22. package/src/__tests__/exports.test.ts +54 -0
  23. package/src/__tests__/ogrid.component.spec.ts.skip +236 -0
  24. package/src/__tests__/pagination-controls.component.spec.ts.skip +190 -0
  25. package/src/column-chooser/column-chooser.component.ts +204 -0
  26. package/src/column-header-filter/column-header-filter.component.ts +528 -0
  27. package/src/datagrid-table/datagrid-table.component.scss +289 -0
  28. package/src/datagrid-table/datagrid-table.component.ts +636 -0
  29. package/src/index.ts +16 -0
  30. package/src/ogrid/ogrid.component.ts +78 -0
  31. package/src/pagination-controls/pagination-controls.component.ts +187 -0
  32. package/tsconfig.build.json +9 -0
  33. package/tsconfig.json +21 -0
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @alaarab/ogrid-angular-radix
2
+
3
+ Lightweight Angular data grid with sorting, filtering, pagination, column chooser, and CSV export. Built with Angular CDK for overlays.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @alaarab/ogrid-angular-radix
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - ✅ **Lightweight**: Uses Angular CDK only - no heavy UI framework dependency
14
+ - ✅ **Full-featured**: Sorting, filtering, pagination, column management
15
+ - ✅ **Cell Selection**: Excel-like spreadsheet selection and editing
16
+ - ✅ **Keyboard Navigation**: Arrow keys, Enter, Escape, Tab
17
+ - ✅ **Copy/Paste**: Clipboard integration with Excel-compatible formats
18
+ - ✅ **Fill Handle**: Drag to fill cells like Excel
19
+ - ✅ **Undo/Redo**: Full edit history support
20
+ - ✅ **Context Menu**: Right-click menu for common operations
21
+ - ✅ **Column Resize**: Drag column borders to resize
22
+ - ✅ **Column Reorder**: Drag column headers to reorder
23
+ - ✅ **Customizable**: CSS variables for theming
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import { Component } from '@angular/core';
29
+ import { OGridComponent } from '@alaarab/ogrid-angular-radix';
30
+
31
+ interface Employee {
32
+ id: number;
33
+ name: string;
34
+ department: string;
35
+ salary: number;
36
+ }
37
+
38
+ @Component({
39
+ selector: 'app-root',
40
+ standalone: true,
41
+ imports: [OGridComponent],
42
+ template: `
43
+ <ogrid
44
+ [props]="{
45
+ columns: columns,
46
+ data: data,
47
+ cellSelection: true,
48
+ editable: true,
49
+ statusBar: true
50
+ }"
51
+ />
52
+ `
53
+ })
54
+ export class AppComponent {
55
+ columns = [
56
+ { columnId: 'id', name: 'ID', type: 'numeric' as const },
57
+ { columnId: 'name', name: 'Name', type: 'text' as const },
58
+ { columnId: 'department', name: 'Department', type: 'text' as const, filterable: { type: 'multiSelect' as const } },
59
+ { columnId: 'salary', name: 'Salary', type: 'numeric' as const, editable: true }
60
+ ];
61
+
62
+ data: Employee[] = [
63
+ { id: 1, name: 'Alice', department: 'Engineering', salary: 120000 },
64
+ { id: 2, name: 'Bob', department: 'Marketing', salary: 90000 },
65
+ { id: 3, name: 'Carol', department: 'Engineering', salary: 115000 }
66
+ ];
67
+ }
68
+ ```
69
+
70
+ ## Documentation
71
+
72
+ Full documentation available at: https://alaarab.github.io/ogrid
73
+
74
+ ## License
75
+
76
+ MIT © Ala Arab
@@ -0,0 +1,199 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Component, input, output, signal, computed, ChangeDetectionStrategy } from '@angular/core';
8
+ /**
9
+ * Column visibility chooser dropdown for Angular Radix (lightweight styling).
10
+ * Standalone component with inline template and CSS variables for theming.
11
+ */
12
+ let ColumnChooserComponent = class ColumnChooserComponent {
13
+ constructor() {
14
+ this.columns = input.required();
15
+ this.visibleColumns = input.required();
16
+ this.visibilityChange = output();
17
+ this.isOpen = signal(false);
18
+ this.visibleCount = computed(() => this.visibleColumns().size);
19
+ this.totalCount = computed(() => this.columns().length);
20
+ }
21
+ toggle() {
22
+ this.isOpen.update((v) => !v);
23
+ }
24
+ onCheckboxChange(columnKey, event) {
25
+ const checked = event.target.checked;
26
+ this.visibilityChange.emit({ columnKey, visible: checked });
27
+ }
28
+ selectAll() {
29
+ for (const col of this.columns()) {
30
+ if (!this.visibleColumns().has(col.columnId)) {
31
+ this.visibilityChange.emit({ columnKey: col.columnId, visible: true });
32
+ }
33
+ }
34
+ }
35
+ clearAll() {
36
+ for (const col of this.columns()) {
37
+ if (this.visibleColumns().has(col.columnId)) {
38
+ this.visibilityChange.emit({ columnKey: col.columnId, visible: false });
39
+ }
40
+ }
41
+ }
42
+ onDocumentClick(event) {
43
+ // Close dropdown when clicking outside
44
+ const el = event.target;
45
+ if (!el.closest('ogrid-column-chooser')) {
46
+ this.isOpen.set(false);
47
+ }
48
+ }
49
+ };
50
+ ColumnChooserComponent = __decorate([
51
+ Component({
52
+ selector: 'ogrid-column-chooser',
53
+ standalone: true,
54
+ changeDetection: ChangeDetectionStrategy.OnPush,
55
+ template: `
56
+ <div class="ogrid-column-chooser">
57
+ <button
58
+ class="ogrid-column-chooser__trigger"
59
+ (click)="toggle()"
60
+ [attr.aria-expanded]="isOpen()"
61
+ aria-haspopup="listbox"
62
+ >
63
+ ☰ Columns ({{ visibleCount() }}/{{ totalCount() }})
64
+ <span class="ogrid-column-chooser__caret">{{ isOpen() ? '▲' : '▼' }}</span>
65
+ </button>
66
+
67
+ @if (isOpen()) {
68
+ <div class="ogrid-column-chooser__dropdown" (click)="$event.stopPropagation()">
69
+ <div class="ogrid-column-chooser__header">
70
+ Select Columns ({{ visibleCount() }} of {{ totalCount() }})
71
+ </div>
72
+
73
+ <div class="ogrid-column-chooser__list">
74
+ @for (col of columns(); track col.columnId) {
75
+ <label class="ogrid-column-chooser__item">
76
+ <input
77
+ type="checkbox"
78
+ [checked]="visibleColumns().has(col.columnId)"
79
+ (change)="onCheckboxChange(col.columnId, $event)"
80
+ />
81
+ <span>{{ col.name }}</span>
82
+ </label>
83
+ }
84
+ </div>
85
+
86
+ <div class="ogrid-column-chooser__footer">
87
+ <button class="ogrid-column-chooser__btn" (click)="clearAll()">Clear All</button>
88
+ <button class="ogrid-column-chooser__btn ogrid-column-chooser__btn--primary" (click)="selectAll()">Select All</button>
89
+ </div>
90
+ </div>
91
+ }
92
+ </div>
93
+ `,
94
+ styles: [`
95
+ :host { display: inline-flex; position: relative; }
96
+ .ogrid-column-chooser { position: relative; }
97
+ .ogrid-column-chooser__trigger {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: 6px;
101
+ padding: 6px 12px;
102
+ border: 1px solid var(--ogrid-border, #e0e0e0);
103
+ border-radius: 4px;
104
+ background: var(--ogrid-bg, #ffffff);
105
+ color: var(--ogrid-fg, #242424);
106
+ cursor: pointer;
107
+ font-size: 14px;
108
+ font-weight: 600;
109
+ text-transform: none;
110
+ white-space: nowrap;
111
+ transition: all 0.15s ease;
112
+ }
113
+ .ogrid-column-chooser__trigger:hover {
114
+ background: var(--ogrid-hover-bg, #f0f0f0);
115
+ border-color: var(--ogrid-active-border, #0078d4);
116
+ }
117
+ .ogrid-column-chooser__caret {
118
+ font-size: 10px;
119
+ opacity: 0.7;
120
+ }
121
+ .ogrid-column-chooser__dropdown {
122
+ position: absolute;
123
+ top: 100%;
124
+ right: 0;
125
+ z-index: 1000;
126
+ min-width: 220px;
127
+ margin-top: 4px;
128
+ background: var(--ogrid-bg, #ffffff);
129
+ border: 1px solid var(--ogrid-border, #e0e0e0);
130
+ border-radius: 4px;
131
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
132
+ }
133
+ .ogrid-column-chooser__header {
134
+ padding: 8px 12px;
135
+ font-size: 14px;
136
+ font-weight: 600;
137
+ color: var(--ogrid-fg, #242424);
138
+ border-bottom: 1px solid var(--ogrid-border, #e0e0e0);
139
+ background: var(--ogrid-header-bg, #f5f5f5);
140
+ }
141
+ .ogrid-column-chooser__list {
142
+ max-height: 320px;
143
+ overflow-y: auto;
144
+ padding: 4px 0;
145
+ }
146
+ .ogrid-column-chooser__item {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: 8px;
150
+ padding: 6px 12px;
151
+ min-height: 32px;
152
+ cursor: pointer;
153
+ font-size: 14px;
154
+ color: var(--ogrid-fg, #242424);
155
+ transition: background 0.15s ease;
156
+ }
157
+ .ogrid-column-chooser__item:hover {
158
+ background: var(--ogrid-hover-bg, #f0f0f0);
159
+ }
160
+ .ogrid-column-chooser__item input[type="checkbox"] {
161
+ cursor: pointer;
162
+ }
163
+ .ogrid-column-chooser__footer {
164
+ display: flex;
165
+ justify-content: flex-end;
166
+ gap: 8px;
167
+ padding: 8px 12px;
168
+ border-top: 1px solid var(--ogrid-border, #e0e0e0);
169
+ background: var(--ogrid-header-bg, #f5f5f5);
170
+ }
171
+ .ogrid-column-chooser__btn {
172
+ padding: 6px 12px;
173
+ border: 1px solid var(--ogrid-border, #e0e0e0);
174
+ border-radius: 4px;
175
+ background: var(--ogrid-bg, #ffffff);
176
+ color: var(--ogrid-fg, #242424);
177
+ cursor: pointer;
178
+ font-size: 13px;
179
+ text-transform: none;
180
+ transition: all 0.15s ease;
181
+ }
182
+ .ogrid-column-chooser__btn:hover {
183
+ background: var(--ogrid-hover-bg, #f0f0f0);
184
+ }
185
+ .ogrid-column-chooser__btn--primary {
186
+ background: var(--ogrid-active-border, #0078d4);
187
+ color: #ffffff;
188
+ border-color: var(--ogrid-active-border, #0078d4);
189
+ }
190
+ .ogrid-column-chooser__btn--primary:hover {
191
+ opacity: 0.9;
192
+ }
193
+ `],
194
+ host: {
195
+ '(document:click)': 'onDocumentClick($event)',
196
+ },
197
+ })
198
+ ], ColumnChooserComponent);
199
+ export { ColumnChooserComponent };