argent-grid 0.1.0 → 0.2.0

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 (108) hide show
  1. package/.github/workflows/ci.yml +69 -0
  2. package/.github/workflows/pages.yml +6 -12
  3. package/.storybook/main.ts +20 -0
  4. package/.storybook/preview.ts +18 -0
  5. package/.storybook/tsconfig.json +24 -0
  6. package/AGENTS.md +2 -2
  7. package/README.md +51 -34
  8. package/angular.json +66 -0
  9. package/biome.json +66 -0
  10. package/demo-app/e2e/selection-screenshot.spec.ts +20 -0
  11. package/docs/AG-GRID-COMPARISON.md +725 -0
  12. package/docs/CELL-RENDERER-GUIDE.md +241 -0
  13. package/docs/CONTEXT-MENU-GUIDE.md +371 -0
  14. package/docs/LIVE-DATA-OPTIMIZATIONS.md +497 -0
  15. package/docs/PERFORMANCE-OPTIMIZATIONS-PHASE1.md +162 -0
  16. package/docs/PERFORMANCE-REVIEW.md +571 -0
  17. package/docs/RESEARCH-STATUS.md +234 -0
  18. package/docs/STATE-PERSISTENCE-GUIDE.md +370 -0
  19. package/docs/STORYBOOK-REFACTOR.md +215 -0
  20. package/docs/STORYBOOK-STATUS.md +156 -0
  21. package/docs/TEST-COVERAGE-REPORT.md +276 -0
  22. package/docs/THEME-API-GUIDE.md +445 -0
  23. package/docs/THEME-API-PLAN.md +364 -0
  24. package/e2e/advanced.spec.ts +109 -0
  25. package/e2e/argentgrid.spec.ts +65 -0
  26. package/e2e/benchmark.spec.ts +52 -0
  27. package/e2e/screenshots.spec.ts +52 -0
  28. package/e2e/theming.spec.ts +35 -0
  29. package/e2e/visual.spec.ts +91 -0
  30. package/e2e/visual.spec.ts-snapshots/grid-default.png +0 -0
  31. package/e2e/visual.spec.ts-snapshots/grid-empty-state.png +0 -0
  32. package/e2e/visual.spec.ts-snapshots/grid-filter-popup.png +0 -0
  33. package/e2e/visual.spec.ts-snapshots/grid-scroll-borders.png +0 -0
  34. package/e2e/visual.spec.ts-snapshots/grid-sidebar-buttons.png +0 -0
  35. package/e2e/visual.spec.ts-snapshots/grid-text-filter.png +0 -0
  36. package/e2e/visual.spec.ts-snapshots/grid-with-selection.png +0 -0
  37. package/package.json +20 -6
  38. package/plan.md +50 -18
  39. package/playwright.config.ts +38 -0
  40. package/setup-vitest.ts +10 -13
  41. package/src/lib/argent-grid.module.ts +10 -12
  42. package/src/lib/components/argent-grid.component.css +327 -76
  43. package/src/lib/components/argent-grid.component.html +186 -64
  44. package/src/lib/components/argent-grid.component.spec.ts +120 -160
  45. package/src/lib/components/argent-grid.component.ts +642 -189
  46. package/src/lib/components/argent-grid.selection.spec.ts +132 -0
  47. package/src/lib/components/set-filter/set-filter.component.ts +302 -0
  48. package/src/lib/directives/ag-grid-compatibility.directive.ts +16 -26
  49. package/src/lib/directives/click-outside.directive.ts +19 -0
  50. package/src/lib/rendering/canvas-renderer.spec.ts +366 -0
  51. package/src/lib/rendering/canvas-renderer.ts +418 -305
  52. package/src/lib/rendering/live-data-handler.ts +110 -0
  53. package/src/lib/rendering/live-data-optimizations.ts +133 -0
  54. package/src/lib/rendering/render/blit.spec.ts +16 -27
  55. package/src/lib/rendering/render/blit.ts +48 -36
  56. package/src/lib/rendering/render/cells.spec.ts +132 -0
  57. package/src/lib/rendering/render/cells.ts +46 -24
  58. package/src/lib/rendering/render/column-utils.ts +73 -0
  59. package/src/lib/rendering/render/hit-test.ts +55 -0
  60. package/src/lib/rendering/render/index.ts +79 -76
  61. package/src/lib/rendering/render/lines.ts +43 -43
  62. package/src/lib/rendering/render/primitives.ts +161 -0
  63. package/src/lib/rendering/render/theme.spec.ts +8 -12
  64. package/src/lib/rendering/render/theme.ts +7 -10
  65. package/src/lib/rendering/render/types.ts +2 -2
  66. package/src/lib/rendering/render/walk.spec.ts +35 -38
  67. package/src/lib/rendering/render/walk.ts +60 -50
  68. package/src/lib/rendering/utils/damage-tracker.spec.ts +8 -7
  69. package/src/lib/rendering/utils/damage-tracker.ts +6 -18
  70. package/src/lib/rendering/utils/index.ts +1 -1
  71. package/src/lib/services/grid.service.set-filter.spec.ts +219 -0
  72. package/src/lib/services/grid.service.spec.ts +1165 -201
  73. package/src/lib/services/grid.service.ts +819 -187
  74. package/src/lib/themes/parts/color-schemes.ts +132 -0
  75. package/src/lib/themes/parts/icon-sets.ts +258 -0
  76. package/src/lib/themes/theme-builder.ts +347 -0
  77. package/src/lib/themes/theme-quartz.ts +72 -0
  78. package/src/lib/themes/types.ts +238 -0
  79. package/src/lib/types/ag-grid-types.ts +73 -14
  80. package/src/public-api.ts +39 -9
  81. package/src/stories/Advanced.stories.ts +188 -0
  82. package/src/stories/ArgentGrid.stories.ts +277 -0
  83. package/src/stories/Benchmark.stories.ts +74 -0
  84. package/src/stories/CellRenderers.stories.ts +221 -0
  85. package/src/stories/Filtering.stories.ts +252 -0
  86. package/src/stories/Grouping.stories.ts +217 -0
  87. package/src/stories/Theming.stories.ts +124 -0
  88. package/src/stories/benchmark-wrapper.component.ts +315 -0
  89. package/tsconfig.storybook.json +10 -0
  90. package/vitest.config.ts +9 -9
  91. package/demo-app/README.md +0 -70
  92. package/demo-app/angular.json +0 -78
  93. package/demo-app/e2e/benchmark.spec.ts +0 -53
  94. package/demo-app/e2e/demo-page.spec.ts +0 -77
  95. package/demo-app/e2e/grid-features.spec.ts +0 -269
  96. package/demo-app/package-lock.json +0 -14023
  97. package/demo-app/package.json +0 -36
  98. package/demo-app/playwright-test-menu.js +0 -19
  99. package/demo-app/playwright.config.ts +0 -23
  100. package/demo-app/src/app/app.component.ts +0 -10
  101. package/demo-app/src/app/app.config.ts +0 -13
  102. package/demo-app/src/app/app.routes.ts +0 -7
  103. package/demo-app/src/app/demo-page/demo-page.component.css +0 -313
  104. package/demo-app/src/app/demo-page/demo-page.component.html +0 -124
  105. package/demo-app/src/app/demo-page/demo-page.component.ts +0 -366
  106. package/demo-app/src/index.html +0 -19
  107. package/demo-app/src/main.ts +0 -6
  108. package/demo-app/tsconfig.json +0 -31
@@ -0,0 +1,364 @@
1
+ # ArgentGrid Theme API Implementation Plan
2
+
3
+ ## 📊 AG Grid New Theming API Research
4
+
5
+ **Source:** AG Grid v32.2+ (October 2024), default in v33+
6
+
7
+ ### Key Features of AG Grid's New Theming API
8
+
9
+ 1. **Programmatic Theme Objects**
10
+ - `themeQuartz`, `themeBalham`, `themeAlpine`, `themeMaterial`
11
+ - Import from `@ag-grid-community/theming`
12
+ - Applied via `theme` grid option (not CSS class)
13
+
14
+ 2. **withParams() Method**
15
+ - Customize themes programmatically
16
+ - TypeScript validation & autocomplete
17
+ - Example: `themeQuartz.withParams({ spacing: 12, accentColor: 'red' })`
18
+
19
+ 3. **Parts System**
20
+ - Modular theme components
21
+ - Mix and match: `themeQuartz.withPart(iconSetMaterial).withPart(colorSchemeDark)`
22
+ - Available parts:
23
+ - Color schemes (light, dark, etc.)
24
+ - Icon sets (Material, etc.)
25
+ - Checkbox styles
26
+ - Input styles
27
+ - Tab styles
28
+
29
+ 4. **createPart() API**
30
+ - Create custom reusable parts
31
+ - `withCSS()`, `withAdditionalParams()`, `withParams()`
32
+
33
+ 5. **CSS Layer Support**
34
+ - `themeCssLayer` grid option
35
+ - Proper layer ordering for overrides
36
+
37
+ 6. **Shadow DOM Support**
38
+ - `themeStyleContainer` grid option
39
+ - Automatic detection and style injection
40
+
41
+ 7. **Theme Builder Tool**
42
+ - Visual theme designer
43
+ - Export to code
44
+
45
+ ---
46
+
47
+ ## 🔍 Current ArgentGrid Theme System
48
+
49
+ ### What We Have ✅
50
+
51
+ 1. **Basic Theme Constants**
52
+ - `DEFAULT_THEME` - Default light theme
53
+ - `DARK_THEME` - Dark mode theme
54
+
55
+ 2. **Theme Utilities**
56
+ - `mergeTheme()` - Merge multiple themes
57
+ - `getFontFromTheme()` - Generate font string
58
+ - `getRowTheme()` - Row state-based theming
59
+ - `getCellBackgroundColor()` - Cell background by state
60
+
61
+ 3. **Theme Presets**
62
+ - `default`, `dark`, `compact`, `comfortable`, `blueAccent`, `greenAccent`
63
+ - `createTheme()` - Create theme from preset
64
+
65
+ ### What's Missing ❌
66
+
67
+ | Feature | AG Grid | ArgentGrid | Priority |
68
+ |---------|---------|------------|----------|
69
+ | **Theme Objects** | ✅ themeQuartz, etc. | ❌ | **HIGH** |
70
+ | **withParams()** | ✅ Chainable customization | ❌ | **HIGH** |
71
+ | **Parts System** | ✅ Modular parts | ❌ | **MEDIUM** |
72
+ | **createPart()** | ✅ Custom parts | ❌ | **LOW** |
73
+ | **CSS Layer Support** | ✅ themeCssLayer | ❌ | **MEDIUM** |
74
+ | **Shadow DOM** | ✅ themeStyleContainer | ❌ | **LOW** |
75
+ | **Theme Builder** | ✅ Visual tool | ❌ | **LOW** |
76
+ | **Icon Sets** | ✅ Multiple icon sets | ❌ | **MEDIUM** |
77
+ | **Color Schemes** | ✅ Built-in schemes | ⚠️ Partial | **MEDIUM** |
78
+
79
+ ---
80
+
81
+ ## 🎯 Implementation Plan
82
+
83
+ ### Phase 1: Core Theme API (HIGH Priority)
84
+
85
+ **Goal:** Match AG Grid's core theming API
86
+
87
+ #### 1.1 Theme Objects
88
+ ```typescript
89
+ // New API
90
+ import { themeQuartz, themeBalham } from 'argent-grid';
91
+
92
+ // Apply theme
93
+ gridOptions.theme = themeQuartz;
94
+ ```
95
+
96
+ **Files to create:**
97
+ - `src/lib/themes/theme-quartz.ts`
98
+ - `src/lib/themes/theme-balham.ts`
99
+ - `src/lib/themes/theme-alpine.ts`
100
+
101
+ #### 1.2 withParams() Method
102
+ ```typescript
103
+ // Chainable customization
104
+ const myTheme = themeQuartz
105
+ .withParams({ spacing: 12, accentColor: 'red' })
106
+ .withParams({ fontSize: 14 });
107
+ ```
108
+
109
+ **Files to modify:**
110
+ - `src/lib/themes/theme-builder.ts` (NEW)
111
+ - `src/lib/rendering/render/theme.ts` (Extend)
112
+
113
+ #### 1.3 Theme Parameters Interface
114
+ ```typescript
115
+ interface ThemeParameters {
116
+ // Colors
117
+ accentColor?: string;
118
+ backgroundColor?: string;
119
+ foregroundColor?: string;
120
+
121
+ // Typography
122
+ fontFamily?: string;
123
+ fontSize?: number;
124
+ fontWeight?: string | number;
125
+
126
+ // Spacing
127
+ spacing?: number;
128
+ rowHeight?: number;
129
+ headerHeight?: number;
130
+
131
+ // Borders
132
+ borderColor?: string;
133
+ borderWidth?: number;
134
+ borderRadius?: number;
135
+
136
+ // Density
137
+ compact?: boolean;
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ### Phase 2: Parts System (MEDIUM Priority)
144
+
145
+ **Goal:** Enable modular theme customization
146
+
147
+ #### 2.1 Built-in Parts
148
+ ```typescript
149
+ import {
150
+ themeQuartz,
151
+ colorSchemeDark,
152
+ iconSetMaterial,
153
+ checkboxStyleQuartz
154
+ } from 'argent-grid';
155
+
156
+ const myTheme = themeQuartz
157
+ .withPart(colorSchemeDark)
158
+ .withPart(iconSetMaterial);
159
+ ```
160
+
161
+ **Files to create:**
162
+ - `src/lib/themes/parts/color-schemes.ts`
163
+ - `src/lib/themes/parts/icon-sets.ts`
164
+ - `src/lib/themes/parts/checkbox-styles.ts`
165
+ - `src/lib/themes/parts/input-styles.ts`
166
+
167
+ #### 2.2 createPart() API
168
+ ```typescript
169
+ import { createPart } from 'argent-grid';
170
+
171
+ const myCustomPart = createPart('myPart')
172
+ .withCSS(`
173
+ .ag-checkbox-input {
174
+ color: ${params.checkboxColor};
175
+ }
176
+ `)
177
+ .withAdditionalParams({
178
+ checkboxColor: { ref: 'accentColor', mix: 0.5 },
179
+ });
180
+ ```
181
+
182
+ **Files to create:**
183
+ - `src/lib/themes/part-builder.ts` (NEW)
184
+
185
+ ---
186
+
187
+ ### Phase 3: Advanced Features (LOW Priority)
188
+
189
+ #### 3.1 CSS Layer Support
190
+ ```typescript
191
+ gridOptions.themeCssLayer = 'grid';
192
+ gridOptions.themeStyleContainer = document.body;
193
+ ```
194
+
195
+ #### 3.2 Shadow DOM Support
196
+ ```typescript
197
+ gridOptions.themeStyleContainer = shadowRoot;
198
+ ```
199
+
200
+ #### 3.3 Icon Sets
201
+ ```typescript
202
+ // Multiple icon sets
203
+ import { iconSetMaterial, iconSetQuartz } from 'argent-grid';
204
+
205
+ const myTheme = themeQuartz.withPart(iconSetMaterial);
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 📋 Implementation Checklist
211
+
212
+ ### Phase 1: Core Theme API
213
+
214
+ - [ ] Create theme objects (themeQuartz, themeBalham, themeAlpine)
215
+ - [ ] Implement withParams() method
216
+ - [ ] Create ThemeParameters interface
217
+ - [ ] Add TypeScript autocomplete/validation
218
+ - [ ] Update GridApi to support theme option
219
+ - [ ] Update GridComponent to accept theme
220
+ - [ ] Write unit tests
221
+ - [ ] Write documentation
222
+
223
+ ### Phase 2: Parts System
224
+
225
+ - [ ] Create Parts system architecture
226
+ - [ ] Implement color scheme parts
227
+ - [ ] Implement icon set parts
228
+ - [ ] Implement checkbox style parts
229
+ - [ ] Implement withPart() method
230
+ - [ ] Create createPart() API
231
+ - [ ] Write unit tests
232
+ - [ ] Write documentation
233
+
234
+ ### Phase 3: Advanced Features
235
+
236
+ - [ ] Implement CSS layer support
237
+ - [ ] Implement Shadow DOM support
238
+ - [ ] Create additional icon sets
239
+ - [ ] Create theme presets library
240
+ - [ ] Write documentation
241
+
242
+ ---
243
+
244
+ ## 🎨 Theme Presets to Implement
245
+
246
+ ### Built-in Themes (Phase 1)
247
+
248
+ | Theme | Description | Based On |
249
+ |-------|-------------|----------|
250
+ | **themeQuartz** | Modern, high contrast | AG Grid Quartz |
251
+ | **themeBalham** | Spreadsheet-style, compact | AG Grid Balham |
252
+ | **themeAlpine** | Classic, clean | AG Grid Alpine |
253
+ | **themeMaterial** | Material Design | AG Grid Material |
254
+
255
+ ### Color Schemes (Phase 2)
256
+
257
+ | Scheme | Description |
258
+ |--------|-------------|
259
+ | **colorSchemeLight** | Default light mode |
260
+ | **colorSchemeDark** | Dark mode |
261
+ | **colorSchemeAuto** | System preference |
262
+
263
+ ### Icon Sets (Phase 2)
264
+
265
+ | Icon Set | Description |
266
+ |----------|-------------|
267
+ | **iconSetQuartz** | Default Quartz icons |
268
+ | **iconSetMaterial** | Material Design icons |
269
+ | **iconSetMinimal** | Minimal line icons |
270
+
271
+ ---
272
+
273
+ ## 📊 Timeline Estimate
274
+
275
+ | Phase | Features | Estimated Time |
276
+ |-------|----------|----------------|
277
+ | **Phase 1** | Core Theme API | 2-3 days |
278
+ | **Phase 2** | Parts System | 2-3 days |
279
+ | **Phase 3** | Advanced Features | 1-2 days |
280
+ | **Total** | Complete Theme API | **5-8 days** |
281
+
282
+ ---
283
+
284
+ ## 🎯 Success Criteria
285
+
286
+ ### Phase 1 Complete When:
287
+ - ✅ Can import and use `themeQuartz`, `themeBalham`, etc.
288
+ - ✅ `withParams()` method works with TypeScript validation
289
+ - ✅ Theme parameters are properly typed
290
+ - ✅ Grid renders with applied theme
291
+ - ✅ Unit tests pass
292
+
293
+ ### Phase 2 Complete When:
294
+ - ✅ Can mix and match parts: `themeQuartz.withPart(iconSetMaterial)`
295
+ - ✅ Color schemes work: `themeQuartz.withPart(colorSchemeDark)`
296
+ - ✅ `createPart()` API works for custom parts
297
+ - ✅ Unit tests pass
298
+
299
+ ### Phase 3 Complete When:
300
+ - ✅ CSS layers work properly
301
+ - ✅ Shadow DOM support works
302
+ - ✅ Documentation complete
303
+ - ✅ All tests pass
304
+
305
+ ---
306
+
307
+ ## 📚 Documentation Plan
308
+
309
+ ### Files to Create/Update:
310
+
311
+ 1. **THEMING-API.md** - Main theming API documentation
312
+ 2. **THEME-PRESETS.md** - Built-in theme reference
313
+ 3. **THEME-PARTS.md** - Parts system reference
314
+ 4. **CUSTOM-THEMES.md** - Guide for creating custom themes
315
+ 5. **MIGRATION-GUIDE.md** - Migration from old theme system
316
+
317
+ ### Code Examples:
318
+
319
+ ```typescript
320
+ // Basic usage
321
+ import { themeQuartz } from 'argent-grid';
322
+
323
+ gridOptions.theme = themeQuartz;
324
+
325
+ // Customization
326
+ const myTheme = themeQuartz.withParams({
327
+ spacing: 12,
328
+ accentColor: 'red',
329
+ fontSize: 14,
330
+ });
331
+
332
+ // Mix and match
333
+ import { themeQuartz, colorSchemeDark, iconSetMaterial } from 'argent-grid';
334
+
335
+ const myTheme = themeQuartz
336
+ .withPart(colorSchemeDark)
337
+ .withPart(iconSetMaterial);
338
+
339
+ // Custom part
340
+ import { createPart } from 'argent-grid';
341
+
342
+ const myPart = createPart('myPart')
343
+ .withCSS(`...`)
344
+ .withAdditionalParams({...});
345
+
346
+ const myTheme = themeQuartz.withPart(myPart);
347
+ ```
348
+
349
+ ---
350
+
351
+ ## 🔗 References
352
+
353
+ - [AG Grid Theming API](https://www.ag-grid.com/react-data-grid/theming-api/)
354
+ - [AG Grid Theme Builder](https://www.ag-grid.com/theme-builder/)
355
+ - [AG Grid Themes](https://www.ag-grid.com/react-data-grid/themes/)
356
+ - [AG Grid Theme Parameters](https://www.ag-grid.com/react-data-grid/theming-parameters/)
357
+ - [AG Grid Theme Parts](https://www.ag-grid.com/react-data-grid/theming-parts/)
358
+ - [AG Grid Blog: New Theming API](https://blog.ag-grid.com/introducing-our-new-theming-api/)
359
+
360
+ ---
361
+
362
+ **Status:** Ready to start implementation
363
+ **Priority:** HIGH (Phase 1)
364
+ **Estimated Start:** Immediately
@@ -0,0 +1,109 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test.describe('Grouping Stories', () => {
4
+ test('should load Row Grouping story', async ({ page }) => {
5
+ await page.goto('/iframe.html?id=features-grouping--row-grouping');
6
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
7
+
8
+ const grid = page.locator('argent-grid').first();
9
+ await expect(grid).toBeVisible({ timeout: 10000 });
10
+ });
11
+
12
+ test('should load Multi-Level Grouping story', async ({ page }) => {
13
+ await page.goto('/iframe.html?id=features-grouping--multi-level-grouping');
14
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
15
+
16
+ const grid = page.locator('argent-grid').first();
17
+ await expect(grid).toBeVisible({ timeout: 10000 });
18
+ });
19
+
20
+ test('should load Grouping with Aggregation story', async ({ page }) => {
21
+ await page.goto('/iframe.html?id=features-grouping--grouping-with-aggregation');
22
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
23
+
24
+ const grid = page.locator('argent-grid').first();
25
+ await expect(grid).toBeVisible({ timeout: 10000 });
26
+ });
27
+ });
28
+
29
+ test.describe('Filtering Stories', () => {
30
+ test('should load Text Filter story', async ({ page }) => {
31
+ await page.goto('/iframe.html?id=features-filtering--text-filter');
32
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
33
+
34
+ const grid = page.locator('argent-grid').first();
35
+ await expect(grid).toBeVisible({ timeout: 10000 });
36
+ });
37
+
38
+ test('should load All Filter Types story (with floating filters)', async ({ page }) => {
39
+ await page.goto('/iframe.html?id=features-filtering--all-filter-types');
40
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
41
+
42
+ const grid = page.locator('argent-grid').first();
43
+ await expect(grid).toBeVisible({ timeout: 10000 });
44
+
45
+ // Verify filter inputs are visible (floating filters)
46
+ const filterInputs = grid.locator('input[placeholder*="Filter"]');
47
+ await expect(filterInputs.first()).toBeVisible({ timeout: 5000 });
48
+ });
49
+
50
+ test('should load Set Filter story', async ({ page }) => {
51
+ await page.goto('/iframe.html?id=features-filtering--set-filter');
52
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
53
+
54
+ const grid = page.locator('argent-grid').first();
55
+ await expect(grid).toBeVisible({ timeout: 10000 });
56
+ });
57
+ });
58
+
59
+ test.describe('Advanced Stories', () => {
60
+ test('should load Side Bar story', async ({ page }) => {
61
+ await page.goto('/iframe.html?id=features-advanced--side-bar');
62
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
63
+
64
+ const grid = page.locator('argent-grid').first();
65
+ await expect(grid).toBeVisible({ timeout: 10000 });
66
+ });
67
+
68
+ test('should load Range Selection story', async ({ page }) => {
69
+ await page.goto('/iframe.html?id=features-advanced--range-selection');
70
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
71
+
72
+ const grid = page.locator('argent-grid').first();
73
+ await expect(grid).toBeVisible({ timeout: 10000 });
74
+ });
75
+
76
+ test('should load Full Features story', async ({ page }) => {
77
+ await page.goto('/iframe.html?id=features-advanced--full-features');
78
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
79
+
80
+ const grid = page.locator('argent-grid').first();
81
+ await expect(grid).toBeVisible({ timeout: 10000 });
82
+ });
83
+ });
84
+
85
+ test.describe('Cell Renderers Stories', () => {
86
+ test('should load Sparkline Area story', async ({ page }) => {
87
+ await page.goto('/iframe.html?id=features-cellrenderers--sparkline-area');
88
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
89
+
90
+ const grid = page.locator('argent-grid').first();
91
+ await expect(grid).toBeVisible({ timeout: 10000 });
92
+ });
93
+
94
+ test('should load Custom Cell Renderer story', async ({ page }) => {
95
+ await page.goto('/iframe.html?id=features-cellrenderers--custom-cell-renderer');
96
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
97
+
98
+ const grid = page.locator('argent-grid').first();
99
+ await expect(grid).toBeVisible({ timeout: 10000 });
100
+ });
101
+
102
+ test('should load Status Badge story', async ({ page }) => {
103
+ await page.goto('/iframe.html?id=features-cellrenderers--status-badge');
104
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
105
+
106
+ const grid = page.locator('argent-grid').first();
107
+ await expect(grid).toBeVisible({ timeout: 10000 });
108
+ });
109
+ });
@@ -0,0 +1,65 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test.describe('ArgentGrid Stories', () => {
4
+ test('should load ArgentGrid Default story', async ({ page }) => {
5
+ const errors: string[] = [];
6
+ page.on('console', (msg) => {
7
+ if (msg.type() === 'error') {
8
+ errors.push(msg.text());
9
+ }
10
+ });
11
+
12
+ await page.goto('/iframe.html?id=components-argentgrid--default');
13
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
14
+
15
+ // Check grid container is visible
16
+ const grid = page.locator('argent-grid').first();
17
+ await expect(grid).toBeVisible({ timeout: 10000 });
18
+
19
+ // No critical errors
20
+ const criticalErrors = errors.filter(
21
+ (e) => e.includes('NG0203') || e.includes('NG0201') || e.includes('NullInjectorError')
22
+ );
23
+ expect(criticalErrors).toHaveLength(0);
24
+ });
25
+
26
+ test('should load Large Dataset story', async ({ page }) => {
27
+ await page.goto('/iframe.html?id=components-argentgrid--large-dataset');
28
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
29
+
30
+ const grid = page.locator('argent-grid').first();
31
+ await expect(grid).toBeVisible({ timeout: 10000 });
32
+ });
33
+
34
+ test('should load Empty state story', async ({ page }) => {
35
+ await page.goto('/iframe.html?id=components-argentgrid--empty');
36
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
37
+
38
+ const grid = page.locator('argent-grid').first();
39
+ await expect(grid).toBeVisible({ timeout: 10000 });
40
+ });
41
+
42
+ test('should load With Sorting story', async ({ page }) => {
43
+ await page.goto('/iframe.html?id=components-argentgrid--with-sorting');
44
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
45
+
46
+ const grid = page.locator('argent-grid').first();
47
+ await expect(grid).toBeVisible({ timeout: 10000 });
48
+ });
49
+
50
+ test('should load With Selection story', async ({ page }) => {
51
+ await page.goto('/iframe.html?id=components-argentgrid--with-selection');
52
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
53
+
54
+ const grid = page.locator('argent-grid').first();
55
+ await expect(grid).toBeVisible({ timeout: 10000 });
56
+ });
57
+
58
+ test('should load With Filtering story', async ({ page }) => {
59
+ await page.goto('/iframe.html?id=components-argentgrid--with-filtering');
60
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
61
+
62
+ const grid = page.locator('argent-grid').first();
63
+ await expect(grid).toBeVisible({ timeout: 10000 });
64
+ });
65
+ });
@@ -0,0 +1,52 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test.describe('Benchmark Stories', () => {
4
+ test('should load Benchmark 10K story', async ({ page }) => {
5
+ await page.goto('/iframe.html?id=features-benchmark--benchmark-10-k');
6
+ await page.waitForSelector('app-benchmark-wrapper', { timeout: 15000 });
7
+
8
+ const wrapper = page.locator('app-benchmark-wrapper').first();
9
+ await expect(wrapper).toBeVisible({ timeout: 10000 });
10
+
11
+ // Check buttons exist
12
+ const runButton = page.locator('button:has-text("Run Benchmark")');
13
+ await expect(runButton).toBeVisible();
14
+
15
+ const reloadButton = page.locator('button:has-text("Reload Data")');
16
+ await expect(reloadButton).toBeVisible();
17
+ });
18
+
19
+ test('should load Benchmark 50K story', async ({ page }) => {
20
+ await page.goto('/iframe.html?id=features-benchmark--benchmark-50-k');
21
+ await page.waitForSelector('app-benchmark-wrapper', { timeout: 15000 });
22
+
23
+ const wrapper = page.locator('app-benchmark-wrapper').first();
24
+ await expect(wrapper).toBeVisible({ timeout: 10000 });
25
+ });
26
+
27
+ test('should load Benchmark 100K story', async ({ page }) => {
28
+ await page.goto('/iframe.html?id=features-benchmark--benchmark-100-k');
29
+ await page.waitForSelector('app-benchmark-wrapper', { timeout: 15000 });
30
+
31
+ const wrapper = page.locator('app-benchmark-wrapper').first();
32
+ await expect(wrapper).toBeVisible({ timeout: 10000 });
33
+ });
34
+
35
+ test('should run benchmark and display results', async ({ page }) => {
36
+ await page.goto('/iframe.html?id=features-benchmark--benchmark-10-k');
37
+ await page.waitForSelector('app-benchmark-wrapper', { timeout: 15000 });
38
+
39
+ // Click Run Benchmark
40
+ const runButton = page.locator('button:has-text("Run Benchmark")');
41
+ await runButton.click();
42
+
43
+ // Wait for results to appear
44
+ const results = page.locator('.results');
45
+ await expect(results).toBeVisible({ timeout: 60000 });
46
+
47
+ // Check result items exist
48
+ const resultItems = page.locator('.result-item');
49
+ const count = await resultItems.count();
50
+ expect(count).toBeGreaterThan(0);
51
+ });
52
+ });
@@ -0,0 +1,52 @@
1
+ import { test } from '@playwright/test';
2
+
3
+ test.describe('ArgentGrid Screenshots', () => {
4
+ test.beforeEach(async () => {
5
+ // Skip if not in CI
6
+ test.skip(!process.env.CI, 'Screenshot tests only run in CI');
7
+ });
8
+
9
+ test('capture default grid screenshot', async ({ page }) => {
10
+ await page.goto('/iframe.html?id=components-argentgrid--default');
11
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
12
+ await page.waitForTimeout(2000);
13
+
14
+ await page.screenshot({
15
+ path: 'e2e/screenshots/grid-default.png',
16
+ fullPage: false,
17
+ });
18
+ });
19
+
20
+ test('capture dark mode screenshot', async ({ page }) => {
21
+ await page.goto('/iframe.html?id=features-theming--dark-mode');
22
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
23
+ await page.waitForTimeout(2000);
24
+
25
+ await page.screenshot({
26
+ path: 'e2e/screenshots/grid-dark-mode.png',
27
+ fullPage: false,
28
+ });
29
+ });
30
+
31
+ test('capture grouping screenshot', async ({ page }) => {
32
+ await page.goto('/iframe.html?id=features-grouping--row-grouping');
33
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
34
+ await page.waitForTimeout(2000);
35
+
36
+ await page.screenshot({
37
+ path: 'e2e/screenshots/grid-grouping.png',
38
+ fullPage: false,
39
+ });
40
+ });
41
+
42
+ test('capture benchmark screenshot', async ({ page }) => {
43
+ await page.goto('/iframe.html?id=features-benchmark--benchmark-10-k');
44
+ await page.waitForSelector('app-benchmark-wrapper', { timeout: 15000 });
45
+ await page.waitForTimeout(2000);
46
+
47
+ await page.screenshot({
48
+ path: 'e2e/screenshots/benchmark.png',
49
+ fullPage: false,
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,35 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test.describe('Theming Stories', () => {
4
+ test('should load Light Mode story', async ({ page }) => {
5
+ await page.goto('/iframe.html?id=features-theming--light-mode');
6
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
7
+
8
+ const grid = page.locator('argent-grid').first();
9
+ await expect(grid).toBeVisible({ timeout: 10000 });
10
+ });
11
+
12
+ test('should load Dark Mode story', async ({ page }) => {
13
+ await page.goto('/iframe.html?id=features-theming--dark-mode');
14
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
15
+
16
+ const grid = page.locator('argent-grid').first();
17
+ await expect(grid).toBeVisible({ timeout: 10000 });
18
+ });
19
+
20
+ test('should load Compact Mode story', async ({ page }) => {
21
+ await page.goto('/iframe.html?id=features-theming--compact-mode');
22
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
23
+
24
+ const grid = page.locator('argent-grid').first();
25
+ await expect(grid).toBeVisible({ timeout: 10000 });
26
+ });
27
+
28
+ test('should load Compact Dark Mode story', async ({ page }) => {
29
+ await page.goto('/iframe.html?id=features-theming--compact-dark-mode');
30
+ await page.waitForSelector('argent-grid', { timeout: 15000 });
31
+
32
+ const grid = page.locator('argent-grid').first();
33
+ await expect(grid).toBeVisible({ timeout: 10000 });
34
+ });
35
+ });