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,347 @@
1
+ /**
2
+ * Theme Builder - Create and customize themes programmatically
3
+ *
4
+ * Inspired by AG Grid's new Theming API (v32.2+)
5
+ */
6
+
7
+ import type {
8
+ PartialThemeParameters,
9
+ GridThemeObject as Theme,
10
+ ThemeBuilder,
11
+ ThemeParameters,
12
+ ThemePart,
13
+ } from './types';
14
+
15
+ // ============================================================================
16
+ // THEME BUILDER CLASS
17
+ // ============================================================================
18
+
19
+ /**
20
+ * Theme builder class for creating and customizing themes
21
+ */
22
+ class ThemeBuilderImpl implements ThemeBuilder {
23
+ public readonly name: string;
24
+ public readonly description?: string;
25
+ public readonly parameters: ThemeParameters;
26
+ public readonly parts: ThemePart[];
27
+
28
+ constructor(config: {
29
+ name: string;
30
+ description?: string;
31
+ parameters: ThemeParameters;
32
+ parts?: ThemePart[];
33
+ }) {
34
+ this.name = config.name;
35
+ this.description = config.description;
36
+ this.parameters = config.parameters;
37
+ this.parts = config.parts || [];
38
+ }
39
+
40
+ /**
41
+ * Create a new theme with overridden parameters
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const myTheme = themeQuartz.withParams({
46
+ * spacing: 12,
47
+ * accentColor: 'red',
48
+ * fontSize: 14,
49
+ * });
50
+ * ```
51
+ */
52
+ withParams(params: PartialThemeParameters): ThemeBuilder {
53
+ const mergedParams = {
54
+ ...this.parameters,
55
+ ...params,
56
+ };
57
+
58
+ return new ThemeBuilderImpl({
59
+ name: this.name,
60
+ description: this.description,
61
+ parameters: mergedParams,
62
+ parts: this.parts,
63
+ });
64
+ }
65
+
66
+ /**
67
+ * Add a theme part to the theme
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const myTheme = themeQuartz
72
+ * .withPart(colorSchemeDark)
73
+ * .withPart(iconSetMaterial);
74
+ * ```
75
+ */
76
+ withPart(part: ThemePart): ThemeBuilder {
77
+ return new ThemeBuilderImpl({
78
+ name: this.name,
79
+ description: this.description,
80
+ parameters: this.parameters,
81
+ parts: [...this.parts, part],
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Get the final theme object with all parts applied
87
+ */
88
+ build(): Theme {
89
+ return {
90
+ name: this.name,
91
+ description: this.description,
92
+ parameters: this.parameters,
93
+ parts: this.parts,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Convert theme to CSS custom properties
99
+ */
100
+ toCSS(): string {
101
+ const cssVars: string[] = [];
102
+
103
+ // Convert parameters to CSS custom properties
104
+ Object.entries(this.parameters).forEach(([key, value]) => {
105
+ const cssVarName = camelToKebab(key);
106
+ cssVars.push(` --ag-${cssVarName}: ${value};`);
107
+ });
108
+
109
+ // Add parts CSS
110
+ this.parts.forEach((part) => {
111
+ if (part.css) {
112
+ cssVars.push(part.css);
113
+ }
114
+ });
115
+
116
+ return `:root {\n${cssVars.join('\n')}\n}`;
117
+ }
118
+ }
119
+
120
+ // ============================================================================
121
+ // THEME CREATION FUNCTIONS
122
+ // ============================================================================
123
+
124
+ /**
125
+ * Create a new theme
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * const myTheme = createTheme({
130
+ * name: 'my-theme',
131
+ * description: 'My custom theme',
132
+ * parameters: {
133
+ * accentColor: 'blue',
134
+ * spacing: 12,
135
+ * },
136
+ * });
137
+ * ```
138
+ */
139
+ export function createTheme(config: {
140
+ name: string;
141
+ description?: string;
142
+ parameters: ThemeParameters;
143
+ parts?: ThemePart[];
144
+ }): ThemeBuilder {
145
+ return new ThemeBuilderImpl(config);
146
+ }
147
+
148
+ /**
149
+ * Create a theme by extending an existing theme
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const myTheme = extendTheme(themeQuartz, {
154
+ * accentColor: 'red',
155
+ * spacing: 12,
156
+ * });
157
+ * ```
158
+ */
159
+ export function extendTheme(baseTheme: ThemeBuilder, params: PartialThemeParameters): ThemeBuilder {
160
+ return baseTheme.withParams(params);
161
+ }
162
+
163
+ /**
164
+ * Merge multiple themes together
165
+ * Later themes override earlier ones
166
+ */
167
+ export function mergeThemes(...themes: ThemeBuilder[]): ThemeBuilder {
168
+ if (themes.length === 0) {
169
+ throw new Error('At least one theme is required');
170
+ }
171
+
172
+ const baseTheme = themes[0];
173
+ const mergedParams = { ...baseTheme.parameters };
174
+ const mergedParts = [...baseTheme.parts];
175
+
176
+ for (let i = 1; i < themes.length; i++) {
177
+ const theme = themes[i];
178
+ Object.assign(mergedParams, theme.parameters);
179
+ mergedParts.push(...theme.parts);
180
+ }
181
+
182
+ return new ThemeBuilderImpl({
183
+ name: 'merged',
184
+ parameters: mergedParams,
185
+ parts: mergedParts,
186
+ });
187
+ }
188
+
189
+ // ============================================================================
190
+ // UTILITIES
191
+ // ============================================================================
192
+
193
+ /**
194
+ * Convert camelCase to kebab-case
195
+ */
196
+ function camelToKebab(str: string): string {
197
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
198
+ }
199
+
200
+ /**
201
+ * Get CSS variables from theme as a map
202
+ * Returns CSS custom properties that can be applied to an element's style
203
+ */
204
+ export function getThemeCSSVariables(theme: ThemeBuilder): Record<string, string> {
205
+ const params = theme.parameters;
206
+ const parts = theme.parts;
207
+
208
+ // Collect all parameters from theme and parts
209
+ let allParams = { ...params };
210
+
211
+ // Merge parameters from all parts (later parts override earlier ones)
212
+ for (const part of parts) {
213
+ if (part.params) {
214
+ allParams = { ...allParams, ...part.params };
215
+ }
216
+ }
217
+
218
+ // Map to CSS variables
219
+ return {
220
+ '--ag-background-color': allParams.backgroundColor || allParams.rowBackgroundColor || '#ffffff',
221
+ '--ag-foreground-color': allParams.foregroundColor || '#181d1f',
222
+ '--ag-secondary-foreground-color': allParams.secondaryForegroundColor || '#666666',
223
+ '--ag-header-background-color': allParams.headerBackgroundColor || '#f8f9fa',
224
+ '--ag-header-foreground-color': allParams.foregroundColor || '#181d1f',
225
+ '--ag-odd-row-background-color': allParams.rowEvenBackgroundColor || '#f8f9fa',
226
+ '--ag-row-hover-color':
227
+ allParams.rowHoverBackgroundColor || allParams.cellHoverBackgroundColor || '#f0f2f5',
228
+ '--ag-selected-row-background-color': allParams.rowSelectedBackgroundColor || '#e3f2fd',
229
+ '--ag-border-color': allParams.borderColor || '#babed1',
230
+ '--ag-cell-horizontal-padding': `${String(allParams.cellPadding || allParams.spacing || 8)}px`,
231
+ '--ag-header-height': `${String(allParams.headerHeight || 48)}px`,
232
+ '--ag-row-height': `${String(allParams.rowHeight || 32)}px`,
233
+ '--ag-font-size': `${String(allParams.fontSize || 14)}px`,
234
+ '--ag-font-family':
235
+ allParams.fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
236
+ };
237
+ }
238
+
239
+ /**
240
+ * Apply theme CSS variables to a specific element
241
+ * This updates both the element's inline styles and any CSS that uses these variables
242
+ */
243
+ export function applyThemeCSSVariables(theme: ThemeBuilder, element: HTMLElement): void {
244
+ const cssVars = getThemeCSSVariables(theme);
245
+
246
+ Object.entries(cssVars).forEach(([key, value]) => {
247
+ element.style.setProperty(key, value);
248
+ });
249
+ }
250
+
251
+ /**
252
+ * Apply theme to a container element
253
+ * Injects CSS custom properties
254
+ */
255
+ export function applyTheme(
256
+ theme: ThemeBuilder,
257
+ container: HTMLElement | ShadowRoot = document.documentElement
258
+ ): void {
259
+ const css = theme.toCSS();
260
+
261
+ // Remove existing theme styles
262
+ const existingStyle = container.querySelector('style[data-ag-theme]');
263
+ if (existingStyle) {
264
+ existingStyle.remove();
265
+ }
266
+
267
+ // Create new style element
268
+ const style = document.createElement('style');
269
+ style.setAttribute('data-ag-theme', theme.name);
270
+ style.textContent = css;
271
+
272
+ // Append to container
273
+ container.appendChild(style);
274
+ }
275
+
276
+ /**
277
+ * Remove theme from a container element
278
+ */
279
+ export function removeTheme(
280
+ theme: ThemeBuilder,
281
+ container: HTMLElement | ShadowRoot = document.documentElement
282
+ ): void {
283
+ const existingStyle = container.querySelector(`style[data-ag-theme="${theme.name}"]`);
284
+ if (existingStyle) {
285
+ existingStyle.remove();
286
+ }
287
+ }
288
+
289
+ // ============================================================================
290
+ // THEME CONVERTER - Convert ThemeBuilder to Canvas Renderer format
291
+ // ============================================================================
292
+
293
+ /**
294
+ * Convert ThemeBuilder parameters to internal GridTheme format
295
+ * This allows the new Theming API to work with the canvas renderer
296
+ */
297
+ export function convertThemeToGridTheme(theme: ThemeBuilder): Record<string, any> {
298
+ const params = theme.parameters;
299
+ const parts = theme.parts;
300
+
301
+ // Collect all parameters from theme and parts
302
+ let allParams = { ...params };
303
+
304
+ // Merge parameters from all parts (later parts override earlier ones)
305
+ for (const part of parts) {
306
+ if (part.params) {
307
+ allParams = { ...allParams, ...part.params };
308
+ }
309
+ }
310
+
311
+ // Map ThemeParameters to internal GridTheme format
312
+ const gridTheme: Record<string, any> = {
313
+ // Background colors
314
+ bgCell: allParams.backgroundColor || allParams.rowBackgroundColor || '#ffffff',
315
+ bgCellEven: allParams.rowEvenBackgroundColor || '#f8f9fa',
316
+ bgHeader: allParams.headerBackgroundColor || '#f8f9fa',
317
+ bgSelection: allParams.rowSelectedBackgroundColor || '#e3f2fd',
318
+ bgHover: allParams.rowHoverBackgroundColor || allParams.cellHoverBackgroundColor || '#f0f2f5',
319
+ bgGroupRow: allParams.groupRowBackgroundColor || '#f5f5f5',
320
+
321
+ // Text colors
322
+ textCell: allParams.foregroundColor || '#181d1f',
323
+ textHeader: allParams.foregroundColor || '#181d1f',
324
+
325
+ // Typography
326
+ fontFamily:
327
+ allParams.fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
328
+ fontSize: allParams.fontSize || 14,
329
+ fontWeight: allParams.fontWeight || 'normal',
330
+
331
+ // Borders
332
+ borderColor: allParams.borderColor || '#babed1',
333
+ headerBorderColor: allParams.borderColor || '#babed1',
334
+ gridLineColor: allParams.borderColor || '#babed1',
335
+
336
+ // Spacing
337
+ cellPadding: allParams.cellPadding || allParams.spacing || 8,
338
+ headerHeight: allParams.headerHeight || 48,
339
+ rowHeight: allParams.rowHeight || 32,
340
+
341
+ // Group/Tree
342
+ groupIndentWidth: allParams.groupRowIndentWidth || 24,
343
+ groupIndicatorSize: allParams.iconSize || 12,
344
+ };
345
+
346
+ return gridTheme;
347
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Quartz Theme - Modern, high-contrast theme
3
+ * Recommended for most applications
4
+ */
5
+
6
+ import { createTheme } from './theme-builder';
7
+ import type { ThemeParameters } from './types';
8
+
9
+ // Default Quartz theme parameters
10
+ const QUARTZ_DEFAULTS: ThemeParameters = {
11
+ // Colors
12
+ accentColor: '#1976d2',
13
+ backgroundColor: '#ffffff',
14
+ foregroundColor: '#181d1f',
15
+ secondaryForegroundColor: '#666666',
16
+
17
+ // Typography
18
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
19
+ fontSize: 14,
20
+ fontWeight: 400,
21
+ headerFontWeight: 600,
22
+
23
+ // Spacing
24
+ spacing: 8,
25
+ rowHeight: 48,
26
+ headerHeight: 48,
27
+ cellPadding: 12,
28
+
29
+ // Borders
30
+ borderColor: '#dcdcdc',
31
+ borderWidth: 1,
32
+ borderRadius: 0,
33
+
34
+ // Specific colors
35
+ headerBackgroundColor: '#f5f5f5',
36
+ rowBackgroundColor: '#ffffff',
37
+ rowEvenBackgroundColor: '#fafafa',
38
+ rowHoverBackgroundColor: '#f0f0f0',
39
+ rowSelectedBackgroundColor: '#e3f2fd',
40
+ cellHoverBackgroundColor: '#f5f5f5',
41
+
42
+ // Group row
43
+ groupRowBackgroundColor: '#fafafa',
44
+ groupRowIndentWidth: 24,
45
+ };
46
+
47
+ /**
48
+ * Quartz theme object
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { themeQuartz } from 'argent-grid';
53
+ *
54
+ * // Basic usage
55
+ * gridOptions.theme = themeQuartz;
56
+ *
57
+ * // Customization
58
+ * const myTheme = themeQuartz.withParams({
59
+ * spacing: 12,
60
+ * accentColor: 'red',
61
+ * });
62
+ *
63
+ * // Mix with parts
64
+ * import { colorSchemeDark } from 'argent-grid';
65
+ * const myTheme = themeQuartz.withPart(colorSchemeDark);
66
+ * ```
67
+ */
68
+ export const themeQuartz = createTheme({
69
+ name: 'quartz',
70
+ description: 'Modern, high-contrast theme recommended for most applications',
71
+ parameters: QUARTZ_DEFAULTS,
72
+ });
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Theme System Type Definitions
3
+ *
4
+ * Compatible with AG Grid's Theming API structure
5
+ */
6
+
7
+ // ============================================================================
8
+ // THEME PARAMETERS
9
+ // ============================================================================
10
+
11
+ /**
12
+ * Theme configuration parameters
13
+ *
14
+ * All parameters are optional and can be overridden via withParams()
15
+ */
16
+ export interface ThemeParameters {
17
+ // === Colors ===
18
+ /** Primary accent color for selections, highlights, etc. */
19
+ accentColor?: string;
20
+ /** Main background color */
21
+ backgroundColor?: string;
22
+ /** Main text/foreground color */
23
+ foregroundColor?: string;
24
+ /** Secondary text color (muted text) */
25
+ secondaryForegroundColor?: string;
26
+
27
+ // === Typography ===
28
+ /** Font family stack */
29
+ fontFamily?: string;
30
+ /** Base font size in pixels */
31
+ fontSize?: number;
32
+ /** Base font weight */
33
+ fontWeight?: number | 'normal' | 'bold' | 'lighter' | 'bolder';
34
+ /** Header font weight */
35
+ headerFontWeight?: number | 'normal' | 'bold' | 'lighter' | 'bolder';
36
+
37
+ // === Spacing ===
38
+ /** Base spacing unit in pixels */
39
+ spacing?: number;
40
+ /** Row height in pixels */
41
+ rowHeight?: number;
42
+ /** Header row height in pixels */
43
+ headerHeight?: number;
44
+ /** Cell padding in pixels */
45
+ cellPadding?: number;
46
+
47
+ // === Borders ===
48
+ /** Border color */
49
+ borderColor?: string;
50
+ /** Border width in pixels */
51
+ borderWidth?: number;
52
+ /** Border radius in pixels */
53
+ borderRadius?: number;
54
+
55
+ // === Specific Colors ===
56
+ /** Header background color */
57
+ headerBackgroundColor?: string;
58
+ /** Default row background color */
59
+ rowBackgroundColor?: string;
60
+ /** Even row background color (for striping) */
61
+ rowEvenBackgroundColor?: string;
62
+ /** Row background on hover */
63
+ rowHoverBackgroundColor?: string;
64
+ /** Row background when selected */
65
+ rowSelectedBackgroundColor?: string;
66
+ /** Cell background on hover */
67
+ cellHoverBackgroundColor?: string;
68
+
69
+ // === Group Row ===
70
+ /** Group row background color */
71
+ groupRowBackgroundColor?: string;
72
+ /** Group row indent width in pixels */
73
+ groupRowIndentWidth?: number;
74
+
75
+ // === Icons ===
76
+ /** Icon color */
77
+ iconColor?: string;
78
+ /** Icon size in pixels */
79
+ iconSize?: number;
80
+
81
+ // === Focus ===
82
+ /** Focus border color */
83
+ focusBorderColor?: string;
84
+ /** Focus border width */
85
+ focusBorderWidth?: number;
86
+ }
87
+
88
+ /**
89
+ * Partial theme parameters for overrides
90
+ */
91
+ export type PartialThemeParameters = Partial<ThemeParameters>;
92
+
93
+ // ============================================================================
94
+ // THEME PARTS
95
+ // ============================================================================
96
+
97
+ /**
98
+ * Theme part type
99
+ * Parts are modular theme components that can be mixed and matched
100
+ */
101
+ export type ThemePartType =
102
+ | 'color-scheme'
103
+ | 'icon-set'
104
+ | 'checkbox-style'
105
+ | 'input-style'
106
+ | 'tab-style'
107
+ | 'custom';
108
+
109
+ /**
110
+ * Theme part configuration
111
+ */
112
+ export interface ThemePart {
113
+ /** Part name/identifier */
114
+ name: string;
115
+ /** Part type */
116
+ type: ThemePartType;
117
+ /** CSS rules for this part */
118
+ css?: string;
119
+ /** Additional parameters this part uses */
120
+ additionalParams?: Record<string, any>;
121
+ /** Parameters this part overrides */
122
+ params?: PartialThemeParameters;
123
+ }
124
+
125
+ // ============================================================================
126
+ // THEME OBJECT
127
+ // ============================================================================
128
+
129
+ /**
130
+ * Complete theme object
131
+ */
132
+ export interface GridThemeObject {
133
+ /** Theme name */
134
+ name: string;
135
+ /** Theme description */
136
+ description?: string;
137
+ /** Theme parameters */
138
+ parameters: ThemeParameters;
139
+ /** Theme parts */
140
+ parts: ThemePart[];
141
+ }
142
+
143
+ /**
144
+ * Theme builder interface
145
+ * Used for chainable theme customization
146
+ */
147
+ export interface ThemeBuilder {
148
+ /** Theme name */
149
+ readonly name: string;
150
+ /** Theme description */
151
+ readonly description?: string;
152
+ /** Theme parameters */
153
+ readonly parameters: ThemeParameters;
154
+ /** Theme parts */
155
+ readonly parts: ThemePart[];
156
+
157
+ /**
158
+ * Create a new theme with overridden parameters
159
+ */
160
+ withParams(params: PartialThemeParameters): ThemeBuilder;
161
+
162
+ /**
163
+ * Add a theme part to the theme
164
+ */
165
+ withPart(part: ThemePart): ThemeBuilder;
166
+
167
+ /**
168
+ * Get the final theme object
169
+ */
170
+ build(): GridThemeObject;
171
+
172
+ /**
173
+ * Convert theme to CSS custom properties
174
+ */
175
+ toCSS(): string;
176
+ }
177
+
178
+ // ============================================================================
179
+ // COLOR SCHEMES
180
+ // ============================================================================
181
+
182
+ /**
183
+ * Predefined color scheme types
184
+ */
185
+ export type ColorSchemeType = 'light' | 'dark' | 'auto';
186
+
187
+ /**
188
+ * Color scheme part
189
+ */
190
+ export interface ColorSchemePart extends ThemePart {
191
+ type: 'color-scheme';
192
+ scheme: ColorSchemeType;
193
+ }
194
+
195
+ // ============================================================================
196
+ // ICON SETS
197
+ // ============================================================================
198
+
199
+ /**
200
+ * Predefined icon set types
201
+ */
202
+ export type IconSetType = 'quartz' | 'material' | 'minimal' | 'custom';
203
+
204
+ /**
205
+ * Icon definition
206
+ */
207
+ export interface IconDefinition {
208
+ /** Icon name */
209
+ name: string;
210
+ /** Icon SVG path or URL */
211
+ path: string;
212
+ /** Icon viewBox */
213
+ viewBox?: string;
214
+ }
215
+
216
+ /**
217
+ * Icon set part
218
+ */
219
+ export interface IconSetPart extends ThemePart {
220
+ type: 'icon-set';
221
+ icons: Record<string, IconDefinition>;
222
+ }
223
+
224
+ // ============================================================================
225
+ // GRID OPTIONS INTEGRATION
226
+ // ============================================================================
227
+
228
+ /**
229
+ * Grid options theme configuration
230
+ */
231
+ export interface ThemeGridOptions {
232
+ /** Theme object */
233
+ theme?: ThemeBuilder;
234
+ /** CSS layer name for theme styles */
235
+ themeCssLayer?: string;
236
+ /** Container element for theme styles */
237
+ themeStyleContainer?: HTMLElement | ShadowRoot | (() => HTMLElement | ShadowRoot);
238
+ }