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,74 @@
1
+ import type { Meta, StoryObj } from '@storybook/angular';
2
+ import { moduleMetadata } from '@storybook/angular';
3
+ import { BenchmarkWrapperComponent } from './benchmark-wrapper.component';
4
+
5
+ const meta: Meta<BenchmarkWrapperComponent> = {
6
+ title: 'Features/Benchmark',
7
+ component: BenchmarkWrapperComponent,
8
+ decorators: [
9
+ moduleMetadata({
10
+ imports: [BenchmarkWrapperComponent],
11
+ }),
12
+ ],
13
+ parameters: {
14
+ layout: 'fullscreen',
15
+ },
16
+ };
17
+
18
+ export default meta;
19
+ type Story = StoryObj<BenchmarkWrapperComponent>;
20
+
21
+ export const Benchmark10K: Story = {
22
+ args: {
23
+ // Default 10K rows
24
+ },
25
+ render: (args) => ({
26
+ props: args,
27
+ template: `<app-benchmark-wrapper />`,
28
+ }),
29
+ parameters: {
30
+ docs: {
31
+ description: {
32
+ story:
33
+ 'Benchmark with ~10,000 rows. Click "Run Benchmark" to test selection, grouping, and scroll performance.',
34
+ },
35
+ },
36
+ },
37
+ };
38
+
39
+ export const Benchmark50K: Story = {
40
+ args: {},
41
+ render: (args) => ({
42
+ props: {
43
+ ...args,
44
+ rowCount: 50000,
45
+ } as any,
46
+ template: `<app-benchmark-wrapper [rowCount]="50000" />`,
47
+ }),
48
+ parameters: {
49
+ docs: {
50
+ description: {
51
+ story: 'Benchmark with ~50,000 rows. Stress tests virtual scrolling with large datasets.',
52
+ },
53
+ },
54
+ },
55
+ };
56
+
57
+ export const Benchmark100K: Story = {
58
+ args: {},
59
+ render: (args) => ({
60
+ props: {
61
+ ...args,
62
+ rowCount: 100000,
63
+ } as any,
64
+ template: `<app-benchmark-wrapper [rowCount]="100000" />`,
65
+ }),
66
+ parameters: {
67
+ docs: {
68
+ description: {
69
+ story:
70
+ 'Benchmark with ~100,000 rows. High-performance stress test. Expect longer initial render but smooth scrolling.',
71
+ },
72
+ },
73
+ },
74
+ };
@@ -0,0 +1,221 @@
1
+ import { BrowserModule } from '@angular/platform-browser';
2
+ import type { Meta, StoryObj } from '@storybook/angular';
3
+ import { moduleMetadata } from '@storybook/angular';
4
+ import { ArgentGridComponent, ArgentGridModule, themeQuartz } from '../public-api';
5
+
6
+ interface Employee {
7
+ id: number;
8
+ name: string;
9
+ department: string;
10
+ role: string;
11
+ salary: number;
12
+ salaryTrend: number[];
13
+ location: string;
14
+ performance: number;
15
+ status: string;
16
+ }
17
+
18
+ const meta: Meta<ArgentGridComponent<Employee>> = {
19
+ title: 'Features/CellRenderers',
20
+ component: ArgentGridComponent,
21
+ decorators: [
22
+ moduleMetadata({
23
+ imports: [ArgentGridModule, BrowserModule],
24
+ }),
25
+ ],
26
+ parameters: {
27
+ layout: 'fullscreen',
28
+ },
29
+ };
30
+
31
+ export default meta;
32
+ type Story = StoryObj<ArgentGridComponent<Employee>>;
33
+
34
+ function generateStaticData(count: number): Employee[] {
35
+ const departments = ['Engineering', 'Sales', 'Marketing', 'HR', 'Finance'];
36
+ const roles = ['Engineer', 'Manager', 'Director', 'VP', 'Intern'];
37
+ const locations = ['New York', 'San Francisco', 'London', 'Singapore', 'Remote'];
38
+ const statuses = ['Active', 'On Leave', 'Remote', 'Travel'];
39
+
40
+ return Array.from({ length: count }, (_, i) => ({
41
+ id: i + 1,
42
+ name: `Employee ${i + 1}`,
43
+ department: departments[i % departments.length],
44
+ role: roles[i % roles.length],
45
+ salary: 50000 + i * 1000,
46
+ salaryTrend: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((v) => (v + i * 5) % 100),
47
+ location: locations[i % locations.length],
48
+ performance: 60 + (i % 40),
49
+ status: statuses[i % statuses.length],
50
+ }));
51
+ }
52
+
53
+ export const SparklineArea: Story = {
54
+ args: {
55
+ columnDefs: [
56
+ { field: 'id', headerName: 'ID', width: 80 },
57
+ { field: 'name', headerName: 'Name', width: 200 },
58
+ { field: 'department', headerName: 'Department', width: 180 },
59
+ {
60
+ field: 'salaryTrend',
61
+ headerName: 'Salary Trend',
62
+ width: 200,
63
+ cellRenderer: 'sparkline',
64
+ sparklineOptions: {
65
+ type: 'area',
66
+ area: {
67
+ fill: 'rgba(74, 222, 128, 0.2)',
68
+ stroke: '#4ade80',
69
+ strokeWidth: 2,
70
+ },
71
+ },
72
+ },
73
+ ],
74
+ rowData: generateStaticData(50),
75
+ height: '400px',
76
+ width: '100%',
77
+ theme: themeQuartz,
78
+ },
79
+ parameters: {
80
+ docs: {
81
+ description: {
82
+ story: 'Area sparkline showing salary trend data over time.',
83
+ },
84
+ },
85
+ },
86
+ };
87
+
88
+ export const SparklineLine: Story = {
89
+ args: {
90
+ columnDefs: [
91
+ { field: 'id', headerName: 'ID', width: 80 },
92
+ { field: 'name', headerName: 'Name', width: 200 },
93
+ { field: 'department', headerName: 'Department', width: 180 },
94
+ {
95
+ field: 'salaryTrend',
96
+ headerName: 'Trend',
97
+ width: 150,
98
+ cellRenderer: 'sparkline',
99
+ sparklineOptions: {
100
+ type: 'line',
101
+ line: {
102
+ stroke: '#3b82f6',
103
+ strokeWidth: 2,
104
+ },
105
+ },
106
+ },
107
+ ],
108
+ rowData: generateStaticData(50),
109
+ height: '400px',
110
+ width: '100%',
111
+ theme: themeQuartz,
112
+ },
113
+ parameters: {
114
+ docs: {
115
+ description: {
116
+ story: 'Line sparkline showing trend data.',
117
+ },
118
+ },
119
+ },
120
+ };
121
+
122
+ export const CustomCellRenderer: Story = {
123
+ args: {
124
+ columnDefs: [
125
+ { field: 'id', headerName: 'ID', width: 80 },
126
+ { field: 'name', headerName: 'Name', width: 200 },
127
+ { field: 'department', headerName: 'Department', width: 180 },
128
+ {
129
+ field: 'performance',
130
+ headerName: 'Performance',
131
+ width: 150,
132
+ cellRenderer: (params: any) => {
133
+ const value = params.value;
134
+ const color = value >= 80 ? '#22c55e' : value >= 60 ? '#eab308' : '#ef4444';
135
+ return `<div style="display: flex; align-items: center; gap: 8px;">
136
+ <div style="flex: 1; height: 8px; background: #e5e7eb; border-radius: 4px; overflow: hidden;">
137
+ <div style="width: ${value}%; height: 100%; background: ${color}; border-radius: 4px;"></div>
138
+ </div>
139
+ <span style="color: ${color}; font-weight: 600; min-width: 40px;">${value}%</span>
140
+ </div>`;
141
+ },
142
+ },
143
+ ],
144
+ rowData: generateStaticData(50),
145
+ height: '400px',
146
+ width: '100%',
147
+ theme: themeQuartz,
148
+ },
149
+ parameters: {
150
+ docs: {
151
+ description: {
152
+ story: 'Custom cell renderer showing performance as a progress bar with color coding.',
153
+ },
154
+ },
155
+ },
156
+ };
157
+
158
+ export const StatusBadge: Story = {
159
+ args: {
160
+ columnDefs: [
161
+ { field: 'id', headerName: 'ID', width: 80 },
162
+ { field: 'name', headerName: 'Name', width: 200 },
163
+ { field: 'department', headerName: 'Department', width: 180 },
164
+ {
165
+ field: 'status',
166
+ headerName: 'Status',
167
+ width: 120,
168
+ cellRenderer: (params: any) => {
169
+ const status = params.value;
170
+ const colors: Record<string, { bg: string; text: string }> = {
171
+ Active: { bg: '#dcfce7', text: '#16a34a' },
172
+ 'On Leave': { bg: '#fef3c7', text: '#d97706' },
173
+ Remote: { bg: '#dbeafe', text: '#2563eb' },
174
+ Travel: { bg: '#f3e8ff', text: '#9333ea' },
175
+ };
176
+ const { bg, text } = colors[status] || { bg: '#f3f4f6', text: '#6b7280' };
177
+ return `<span style="padding: 4px 12px; background: ${bg}; color: ${text}; border-radius: 9999px; font-size: 12px; font-weight: 500;">${status}</span>`;
178
+ },
179
+ },
180
+ { field: 'salary', headerName: 'Salary', width: 120 },
181
+ ],
182
+ rowData: generateStaticData(50),
183
+ height: '400px',
184
+ width: '100%',
185
+ theme: themeQuartz,
186
+ },
187
+ parameters: {
188
+ docs: {
189
+ description: {
190
+ story: 'Custom status badge cell renderer with different colors for each status type.',
191
+ },
192
+ },
193
+ },
194
+ };
195
+
196
+ export const CurrencyFormatter: Story = {
197
+ args: {
198
+ columnDefs: [
199
+ { field: 'id', headerName: 'ID', width: 80 },
200
+ { field: 'name', headerName: 'Name', width: 200 },
201
+ { field: 'department', headerName: 'Department', width: 180 },
202
+ {
203
+ field: 'salary',
204
+ headerName: 'Salary',
205
+ width: 130,
206
+ valueFormatter: (params: any) => (params.value ? `$${params.value.toLocaleString()}` : ''),
207
+ },
208
+ ],
209
+ rowData: generateStaticData(50),
210
+ height: '400px',
211
+ width: '100%',
212
+ theme: themeQuartz,
213
+ },
214
+ parameters: {
215
+ docs: {
216
+ description: {
217
+ story: 'Currency formatter showing salary with dollar sign and comma separators.',
218
+ },
219
+ },
220
+ },
221
+ };
@@ -0,0 +1,252 @@
1
+ import { BrowserModule } from '@angular/platform-browser';
2
+ import type { Meta, StoryObj } from '@storybook/angular';
3
+ import { moduleMetadata } from '@storybook/angular';
4
+ import { ArgentGridComponent, ArgentGridModule, themeQuartz } from '../public-api';
5
+
6
+ interface Employee {
7
+ id: number;
8
+ name: string;
9
+ department: string;
10
+ role: string;
11
+ salary: number;
12
+ location: string;
13
+ startDate: string;
14
+ }
15
+
16
+ const meta: Meta<ArgentGridComponent<Employee>> = {
17
+ title: 'Features/Filtering',
18
+ component: ArgentGridComponent,
19
+ decorators: [
20
+ moduleMetadata({
21
+ imports: [ArgentGridModule, BrowserModule],
22
+ }),
23
+ ],
24
+ parameters: {
25
+ layout: 'fullscreen',
26
+ },
27
+ };
28
+
29
+ export default meta;
30
+ type Story = StoryObj<ArgentGridComponent<Employee>>;
31
+
32
+ function generateStaticData(count: number): Employee[] {
33
+ const departments = ['Engineering', 'Sales', 'Marketing'];
34
+ const roles = ['Engineer', 'Manager', 'Analyst'];
35
+ const locations = ['New York', 'London', 'Berlin'];
36
+
37
+ return Array.from({ length: count }, (_, i) => ({
38
+ id: i + 1,
39
+ name: `Employee ${i + 1}`,
40
+ department: departments[i % departments.length],
41
+ role: roles[i % roles.length],
42
+ salary: 50000 + i * 1000,
43
+ location: locations[i % locations.length],
44
+ startDate: '2020-01-01',
45
+ }));
46
+ }
47
+
48
+ export const TextFilter: Story = {
49
+ args: {
50
+ columnDefs: [
51
+ { field: 'id', headerName: 'ID', width: 80 },
52
+ {
53
+ field: 'name',
54
+ headerName: 'Name 🔤',
55
+ width: 200,
56
+ filter: 'text',
57
+ floatingFilter: true,
58
+ headerComponentParams: { filterIcon: '🔤' },
59
+ },
60
+ {
61
+ field: 'department',
62
+ headerName: 'Department 🔤',
63
+ width: 180,
64
+ filter: 'text',
65
+ floatingFilter: true,
66
+ headerComponentParams: { filterIcon: '🔤' },
67
+ },
68
+ {
69
+ field: 'role',
70
+ headerName: 'Role 🔤',
71
+ width: 250,
72
+ filter: 'text',
73
+ floatingFilter: true,
74
+ headerComponentParams: { filterIcon: '🔤' },
75
+ },
76
+ { field: 'salary', headerName: 'Salary', width: 120 },
77
+ { field: 'location', headerName: 'Location', width: 150 },
78
+ ],
79
+ rowData: generateStaticData(50),
80
+ height: '500px',
81
+ width: '100%',
82
+ theme: themeQuartz,
83
+ },
84
+ parameters: {
85
+ docs: {
86
+ description: {
87
+ story:
88
+ 'Text filters on Name, Department, and Role columns. **Filter inputs are visible in the header row** (floating filters). Type to filter results.',
89
+ },
90
+ },
91
+ },
92
+ };
93
+
94
+ export const NumberFilter: Story = {
95
+ args: {
96
+ columnDefs: [
97
+ {
98
+ field: 'id',
99
+ headerName: 'ID 🔢',
100
+ width: 80,
101
+ filter: 'number',
102
+ floatingFilter: true,
103
+ headerComponentParams: { filterIcon: '🔢' },
104
+ },
105
+ { field: 'name', headerName: 'Name', width: 200 },
106
+ { field: 'department', headerName: 'Department', width: 180 },
107
+ {
108
+ field: 'salary',
109
+ headerName: 'Salary 🔢',
110
+ width: 120,
111
+ filter: 'number',
112
+ floatingFilter: true,
113
+ headerComponentParams: { filterIcon: '🔢' },
114
+ },
115
+ { field: 'location', headerName: 'Location', width: 150 },
116
+ ],
117
+ rowData: generateStaticData(50),
118
+ height: '500px',
119
+ width: '100%',
120
+ theme: themeQuartz,
121
+ },
122
+ parameters: {
123
+ docs: {
124
+ description: {
125
+ story:
126
+ 'Number filters on ID and Salary columns. **Filter inputs visible in header**. Supports equals, greater than, less than, etc. Try typing "> 100000" in Salary filter.',
127
+ },
128
+ },
129
+ },
130
+ };
131
+
132
+ export const SetFilter: Story = {
133
+ args: {
134
+ columnDefs: [
135
+ { field: 'id', headerName: 'ID', width: 80 },
136
+ { field: 'name', headerName: 'Name', width: 200 },
137
+ {
138
+ field: 'department',
139
+ headerName: 'Department ☑️',
140
+ width: 180,
141
+ filter: 'set',
142
+ floatingFilter: true,
143
+ headerComponentParams: { filterIcon: '☑️' },
144
+ },
145
+ { field: 'role', headerName: 'Role', width: 250 },
146
+ { field: 'salary', headerName: 'Salary', width: 120 },
147
+ {
148
+ field: 'location',
149
+ headerName: 'Location ☑️',
150
+ width: 150,
151
+ filter: 'set',
152
+ floatingFilter: true,
153
+ headerComponentParams: { filterIcon: '☑️' },
154
+ },
155
+ ],
156
+ rowData: generateStaticData(50),
157
+ height: '500px',
158
+ width: '100%',
159
+ theme: themeQuartz,
160
+ },
161
+ parameters: {
162
+ docs: {
163
+ description: {
164
+ story:
165
+ 'Set filters on Department and Location columns. **Filter inputs visible in header**. Click the filter input to see a dropdown list of unique values with checkboxes for multi-select.',
166
+ },
167
+ },
168
+ },
169
+ };
170
+
171
+ export const HiddenFloatingFilters: Story = {
172
+ args: {
173
+ columnDefs: [
174
+ { field: 'id', headerName: 'ID', width: 80 },
175
+ { field: 'name', headerName: 'Name', width: 200, filter: 'text' },
176
+ { field: 'department', headerName: 'Department', width: 180, filter: 'text' },
177
+ { field: 'role', headerName: 'Role', width: 250, filter: 'text' },
178
+ { field: 'salary', headerName: 'Salary', width: 120, filter: 'number' },
179
+ ],
180
+ rowData: generateStaticData(50),
181
+ height: '500px',
182
+ width: '100%',
183
+ theme: themeQuartz,
184
+ },
185
+ parameters: {
186
+ docs: {
187
+ description: {
188
+ story:
189
+ 'Filtering enabled but **floating filters are hidden**. Use the column header menu (3 dots) to change filter types and values.',
190
+ },
191
+ },
192
+ },
193
+ };
194
+
195
+ export const AllFilterTypes: Story = {
196
+ args: {
197
+ columnDefs: [
198
+ {
199
+ field: 'id',
200
+ headerName: 'ID 🔢',
201
+ width: 80,
202
+ filter: 'number',
203
+ floatingFilter: true,
204
+ headerComponentParams: { filterIcon: '🔢' },
205
+ },
206
+ {
207
+ field: 'name',
208
+ headerName: 'Name 🔤',
209
+ width: 200,
210
+ filter: 'text',
211
+ floatingFilter: true,
212
+ headerComponentParams: { filterIcon: '🔤' },
213
+ },
214
+ {
215
+ field: 'department',
216
+ headerName: 'Department ☑️',
217
+ width: 180,
218
+ filter: 'set',
219
+ floatingFilter: true,
220
+ headerComponentParams: { filterIcon: '☑️' },
221
+ },
222
+ {
223
+ field: 'startDate',
224
+ headerName: 'Start Date 📅',
225
+ width: 150,
226
+ filter: 'date',
227
+ floatingFilter: true,
228
+ headerComponentParams: { filterIcon: '📅' },
229
+ },
230
+ {
231
+ field: 'salary',
232
+ headerName: 'Salary 🔢',
233
+ width: 120,
234
+ filter: 'number',
235
+ floatingFilter: true,
236
+ headerComponentParams: { filterIcon: '🔢' },
237
+ },
238
+ ],
239
+ rowData: generateStaticData(50),
240
+ height: '500px',
241
+ width: '100%',
242
+ theme: themeQuartz,
243
+ },
244
+ parameters: {
245
+ docs: {
246
+ description: {
247
+ story:
248
+ '**All filter types in one grid** with floating filters enabled. Each column shows its filter type with an emoji indicator (🔤 Text, 🔢 Number, ☑️ Set, 📅 Date). Filter inputs are visible in the header row for easy access.',
249
+ },
250
+ },
251
+ },
252
+ };