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.
- package/.github/workflows/ci.yml +69 -0
- package/.github/workflows/pages.yml +6 -12
- package/.storybook/main.ts +20 -0
- package/.storybook/preview.ts +18 -0
- package/.storybook/tsconfig.json +24 -0
- package/AGENTS.md +2 -2
- package/README.md +51 -34
- package/angular.json +66 -0
- package/biome.json +66 -0
- package/demo-app/e2e/selection-screenshot.spec.ts +20 -0
- package/docs/AG-GRID-COMPARISON.md +725 -0
- package/docs/CELL-RENDERER-GUIDE.md +241 -0
- package/docs/CONTEXT-MENU-GUIDE.md +371 -0
- package/docs/LIVE-DATA-OPTIMIZATIONS.md +497 -0
- package/docs/PERFORMANCE-OPTIMIZATIONS-PHASE1.md +162 -0
- package/docs/PERFORMANCE-REVIEW.md +571 -0
- package/docs/RESEARCH-STATUS.md +234 -0
- package/docs/STATE-PERSISTENCE-GUIDE.md +370 -0
- package/docs/STORYBOOK-REFACTOR.md +215 -0
- package/docs/STORYBOOK-STATUS.md +156 -0
- package/docs/TEST-COVERAGE-REPORT.md +276 -0
- package/docs/THEME-API-GUIDE.md +445 -0
- package/docs/THEME-API-PLAN.md +364 -0
- package/e2e/advanced.spec.ts +109 -0
- package/e2e/argentgrid.spec.ts +65 -0
- package/e2e/benchmark.spec.ts +52 -0
- package/e2e/screenshots.spec.ts +52 -0
- package/e2e/theming.spec.ts +35 -0
- package/e2e/visual.spec.ts +91 -0
- package/e2e/visual.spec.ts-snapshots/grid-default.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-empty-state.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-filter-popup.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-scroll-borders.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-sidebar-buttons.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-text-filter.png +0 -0
- package/e2e/visual.spec.ts-snapshots/grid-with-selection.png +0 -0
- package/package.json +20 -6
- package/plan.md +50 -18
- package/playwright.config.ts +38 -0
- package/setup-vitest.ts +10 -13
- package/src/lib/argent-grid.module.ts +10 -12
- package/src/lib/components/argent-grid.component.css +327 -76
- package/src/lib/components/argent-grid.component.html +186 -64
- package/src/lib/components/argent-grid.component.spec.ts +120 -160
- package/src/lib/components/argent-grid.component.ts +642 -189
- package/src/lib/components/argent-grid.selection.spec.ts +132 -0
- package/src/lib/components/set-filter/set-filter.component.ts +302 -0
- package/src/lib/directives/ag-grid-compatibility.directive.ts +16 -26
- package/src/lib/directives/click-outside.directive.ts +19 -0
- package/src/lib/rendering/canvas-renderer.spec.ts +366 -0
- package/src/lib/rendering/canvas-renderer.ts +418 -305
- package/src/lib/rendering/live-data-handler.ts +110 -0
- package/src/lib/rendering/live-data-optimizations.ts +133 -0
- package/src/lib/rendering/render/blit.spec.ts +16 -27
- package/src/lib/rendering/render/blit.ts +48 -36
- package/src/lib/rendering/render/cells.spec.ts +132 -0
- package/src/lib/rendering/render/cells.ts +46 -24
- package/src/lib/rendering/render/column-utils.ts +73 -0
- package/src/lib/rendering/render/hit-test.ts +55 -0
- package/src/lib/rendering/render/index.ts +79 -76
- package/src/lib/rendering/render/lines.ts +43 -43
- package/src/lib/rendering/render/primitives.ts +161 -0
- package/src/lib/rendering/render/theme.spec.ts +8 -12
- package/src/lib/rendering/render/theme.ts +7 -10
- package/src/lib/rendering/render/types.ts +2 -2
- package/src/lib/rendering/render/walk.spec.ts +35 -38
- package/src/lib/rendering/render/walk.ts +60 -50
- package/src/lib/rendering/utils/damage-tracker.spec.ts +8 -7
- package/src/lib/rendering/utils/damage-tracker.ts +6 -18
- package/src/lib/rendering/utils/index.ts +1 -1
- package/src/lib/services/grid.service.set-filter.spec.ts +219 -0
- package/src/lib/services/grid.service.spec.ts +1165 -201
- package/src/lib/services/grid.service.ts +819 -187
- package/src/lib/themes/parts/color-schemes.ts +132 -0
- package/src/lib/themes/parts/icon-sets.ts +258 -0
- package/src/lib/themes/theme-builder.ts +347 -0
- package/src/lib/themes/theme-quartz.ts +72 -0
- package/src/lib/themes/types.ts +238 -0
- package/src/lib/types/ag-grid-types.ts +73 -14
- package/src/public-api.ts +39 -9
- package/src/stories/Advanced.stories.ts +188 -0
- package/src/stories/ArgentGrid.stories.ts +277 -0
- package/src/stories/Benchmark.stories.ts +74 -0
- package/src/stories/CellRenderers.stories.ts +221 -0
- package/src/stories/Filtering.stories.ts +252 -0
- package/src/stories/Grouping.stories.ts +217 -0
- package/src/stories/Theming.stories.ts +124 -0
- package/src/stories/benchmark-wrapper.component.ts +315 -0
- package/tsconfig.storybook.json +10 -0
- package/vitest.config.ts +9 -9
- package/demo-app/README.md +0 -70
- package/demo-app/angular.json +0 -78
- package/demo-app/e2e/benchmark.spec.ts +0 -53
- package/demo-app/e2e/demo-page.spec.ts +0 -77
- package/demo-app/e2e/grid-features.spec.ts +0 -269
- package/demo-app/package-lock.json +0 -14023
- package/demo-app/package.json +0 -36
- package/demo-app/playwright-test-menu.js +0 -19
- package/demo-app/playwright.config.ts +0 -23
- package/demo-app/src/app/app.component.ts +0 -10
- package/demo-app/src/app/app.config.ts +0 -13
- package/demo-app/src/app/app.routes.ts +0 -7
- package/demo-app/src/app/demo-page/demo-page.component.css +0 -313
- package/demo-app/src/app/demo-page/demo-page.component.html +0 -124
- package/demo-app/src/app/demo-page/demo-page.component.ts +0 -366
- package/demo-app/src/index.html +0 -19
- package/demo-app/src/main.ts +0 -6
- package/demo-app/tsconfig.json +0 -31
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ArgentGrid - AG Grid Compatible Type Definitions
|
|
3
3
|
* A free, high-performance alternative to AG Grid Enterprise
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* This file provides 1:1 TypeScript definitions compatible with AG Grid API
|
|
6
6
|
* to ensure users can switch to ArgentGrid by simply changing their import.
|
|
7
7
|
*/
|
|
@@ -147,7 +147,9 @@ export interface GridOptions<TData = any> {
|
|
|
147
147
|
// === CALLBACKS ===
|
|
148
148
|
processCellForClipboard?: (params: ProcessCellForClipboardParams<TData>) => any;
|
|
149
149
|
processCellFromClipboard?: (params: ProcessCellFromClipboardParams<TData>) => any;
|
|
150
|
-
getContextMenuItems?: (
|
|
150
|
+
getContextMenuItems?: (
|
|
151
|
+
params: GetContextMenuItemsParams<TData>
|
|
152
|
+
) => (DefaultMenuItem | MenuItemDef)[];
|
|
151
153
|
getMainMenuItems?: (params: GetMainMenuItemsParams<TData>) => (DefaultMenuItem | MenuItemDef)[];
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -174,7 +176,9 @@ export interface ColDef<TData = any, TValue = any> {
|
|
|
174
176
|
suppressKeyboardEvent?: (params: SuppressKeyboardEventParams<TData>) => boolean;
|
|
175
177
|
suppressPaste?: boolean | ((params: SuppressPasteParams<TData>) => boolean);
|
|
176
178
|
suppressFillHandle?: boolean;
|
|
177
|
-
contextMenuItems?:
|
|
179
|
+
contextMenuItems?:
|
|
180
|
+
| (DefaultMenuItem | MenuItemDef)[]
|
|
181
|
+
| ((params: any) => (DefaultMenuItem | MenuItemDef)[]);
|
|
178
182
|
context?: any;
|
|
179
183
|
|
|
180
184
|
// === SELECTION ===
|
|
@@ -255,7 +259,9 @@ export interface ColDef<TData = any, TValue = any> {
|
|
|
255
259
|
enablePivot?: boolean;
|
|
256
260
|
|
|
257
261
|
// === RENDERING AND STYLING ===
|
|
258
|
-
cellStyle?:
|
|
262
|
+
cellStyle?:
|
|
263
|
+
| { [key: string]: any }
|
|
264
|
+
| ((params: CellStyleParams<TData, TValue>) => { [key: string]: any });
|
|
259
265
|
cellClass?: string | string[] | ((params: CellClassParams<TData, TValue>) => string | string[]);
|
|
260
266
|
cellClassRules?: { [key: string]: (params: CellClassParams<TData, TValue>) => boolean };
|
|
261
267
|
cellRenderer?: any;
|
|
@@ -349,6 +355,7 @@ export interface GridApi<TData = any> {
|
|
|
349
355
|
setRowData(rowData: TData[]): void;
|
|
350
356
|
applyTransaction(transaction: RowDataTransaction<TData>): RowDataTransactionResult | null;
|
|
351
357
|
getDisplayedRowCount(): number;
|
|
358
|
+
getRowY(index: number): number;
|
|
352
359
|
getAggregations(): { [field: string]: any };
|
|
353
360
|
getRowNode(id: string): IRowNode<TData> | null;
|
|
354
361
|
|
|
@@ -386,6 +393,15 @@ export interface GridApi<TData = any> {
|
|
|
386
393
|
// === CLIPBOARD API ===
|
|
387
394
|
copyToClipboard(): void;
|
|
388
395
|
cutToClipboard(): void;
|
|
396
|
+
|
|
397
|
+
// === STATE PERSISTENCE API ===
|
|
398
|
+
getState(): GridState;
|
|
399
|
+
setState(state: GridState): void;
|
|
400
|
+
saveState(key?: string): void;
|
|
401
|
+
restoreState(key?: string): boolean;
|
|
402
|
+
clearState(key?: string): void;
|
|
403
|
+
hasState(key?: string): boolean;
|
|
404
|
+
getUniqueValues(field: string): any[];
|
|
389
405
|
pasteFromClipboard(): void;
|
|
390
406
|
|
|
391
407
|
// === GRID STATE API ===
|
|
@@ -447,6 +463,9 @@ export interface Column {
|
|
|
447
463
|
sort?: SortDirection;
|
|
448
464
|
sortIndex?: number;
|
|
449
465
|
aggFunc?: string | null;
|
|
466
|
+
checkboxSelection?: boolean;
|
|
467
|
+
headerCheckboxSelection?: boolean;
|
|
468
|
+
filter?: any;
|
|
450
469
|
}
|
|
451
470
|
|
|
452
471
|
export interface IRowNode<TData = any> {
|
|
@@ -471,6 +490,7 @@ export interface IRowNode<TData = any> {
|
|
|
471
490
|
lastChild: boolean;
|
|
472
491
|
rowIndex: number | null;
|
|
473
492
|
displayedRowIndex: number;
|
|
493
|
+
setSelected(selected: boolean, clearSelection?: boolean): void;
|
|
474
494
|
}
|
|
475
495
|
|
|
476
496
|
export interface GroupRowNode<TData = any> {
|
|
@@ -573,7 +593,7 @@ export interface CellRange {
|
|
|
573
593
|
startRow: number;
|
|
574
594
|
endRow: number;
|
|
575
595
|
startColumn: string; // colId
|
|
576
|
-
endColumn: string;
|
|
596
|
+
endColumn: string; // colId
|
|
577
597
|
columns: Column[];
|
|
578
598
|
}
|
|
579
599
|
|
|
@@ -650,9 +670,7 @@ export interface RowSelectionOptions {
|
|
|
650
670
|
enableSelectionWithoutKeys?: boolean;
|
|
651
671
|
}
|
|
652
672
|
|
|
653
|
-
export
|
|
654
|
-
// Cell selection configuration
|
|
655
|
-
}
|
|
673
|
+
export type CellSelectionOptions = {};
|
|
656
674
|
|
|
657
675
|
export interface SelectionColumnDef {
|
|
658
676
|
headerCheckbox?: boolean;
|
|
@@ -869,7 +887,34 @@ export type DomLayoutType = 'normal' | 'autoHeight' | 'print';
|
|
|
869
887
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
870
888
|
export type RowGroupingDisplayType = 'singleColumn' | 'multipleColumns' | 'groupRows' | 'custom';
|
|
871
889
|
export type ColumnMenuTab = 'filterMenu' | 'mainMenu' | 'columnsMenu' | 'chartMenu';
|
|
872
|
-
export type DefaultMenuItem =
|
|
890
|
+
export type DefaultMenuItem =
|
|
891
|
+
| 'pinMenu'
|
|
892
|
+
| 'valueMenu'
|
|
893
|
+
| 'columnMenu'
|
|
894
|
+
| 'expandable'
|
|
895
|
+
| 'separator'
|
|
896
|
+
| 'copy'
|
|
897
|
+
| 'copyWithHeaders'
|
|
898
|
+
| 'copyWithGroupHeaders'
|
|
899
|
+
| 'cut'
|
|
900
|
+
| 'paste'
|
|
901
|
+
| 'export'
|
|
902
|
+
| 'chartRange'
|
|
903
|
+
| 'pivot'
|
|
904
|
+
| 'resetColumns'
|
|
905
|
+
| 'deselectAll'
|
|
906
|
+
| 'selectAll'
|
|
907
|
+
| 'selectAllOtherColumns'
|
|
908
|
+
| 'autoSizeAll'
|
|
909
|
+
| 'autoSizeThisColumn'
|
|
910
|
+
| 'resetColumns'
|
|
911
|
+
| 'expandAll'
|
|
912
|
+
| 'collapseAll'
|
|
913
|
+
| 'rowGroupingGroup'
|
|
914
|
+
| 'rowGroupingUnGroup'
|
|
915
|
+
| 'pivotMenu'
|
|
916
|
+
| 'aggFuncMenu'
|
|
917
|
+
| 'sideBar';
|
|
873
918
|
|
|
874
919
|
export interface MenuItemDef {
|
|
875
920
|
name: string;
|
|
@@ -885,14 +930,28 @@ export interface MenuItemDef {
|
|
|
885
930
|
// FUNCTION TYPE DEFINITIONS
|
|
886
931
|
// ============================================================================
|
|
887
932
|
|
|
888
|
-
export type ValueGetterFunc<TData = any, TValue = any> = (
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
export type
|
|
933
|
+
export type ValueGetterFunc<TData = any, TValue = any> = (
|
|
934
|
+
params: ValueGetterParams<TData>
|
|
935
|
+
) => TValue;
|
|
936
|
+
export type ValueFormatterFunc<TData = any, TValue = any> = (
|
|
937
|
+
params: ValueFormatterParams<TData, TValue>
|
|
938
|
+
) => string;
|
|
939
|
+
export type ValueSetterFunc<TData = any, TValue = any> = (
|
|
940
|
+
params: ValueSetterParams<TData, TValue>
|
|
941
|
+
) => boolean;
|
|
942
|
+
export type ValueParserFunc<TData = any, TValue = any> = (
|
|
943
|
+
params: ValueParserParams<TData, TValue>
|
|
944
|
+
) => TValue;
|
|
892
945
|
export type KeyCreatorFunc<TValue = any> = (params: KeyCreatorParams<TValue>) => string;
|
|
893
946
|
export type EqualsFunc<TValue = any> = (params: EqualsParams<TValue>) => boolean;
|
|
894
947
|
export type HeaderValueGetterFunc<TData = any> = (params: HeaderValueGetterParams<TData>) => string;
|
|
895
|
-
export type SortComparatorFn<TValue = any> = (
|
|
948
|
+
export type SortComparatorFn<TValue = any> = (
|
|
949
|
+
valueA: TValue,
|
|
950
|
+
valueB: TValue,
|
|
951
|
+
nodeA: IRowNode,
|
|
952
|
+
nodeB: IRowNode,
|
|
953
|
+
isDescending: boolean
|
|
954
|
+
) => number;
|
|
896
955
|
export type GetRowIdFunc<TData = any> = (params: GetRowIdParams<TData>) => string;
|
|
897
956
|
export type IAggFunc<TData = any> = (params: IAggFuncParams<TData>) => any;
|
|
898
957
|
|
package/src/public-api.ts
CHANGED
|
@@ -3,20 +3,50 @@
|
|
|
3
3
|
* A free, high-performance alternative to AG Grid Enterprise
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
export
|
|
6
|
+
// Modules
|
|
7
|
+
export { ArgentGridModule } from './lib/argent-grid.module';
|
|
8
8
|
|
|
9
9
|
// Main grid component
|
|
10
10
|
export { ArgentGridComponent } from './lib/components/argent-grid.component';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export { CanvasRenderer } from './lib/rendering/canvas-renderer';
|
|
11
|
+
// Components
|
|
12
|
+
export { SetFilterComponent } from './lib/components/set-filter/set-filter.component';
|
|
14
13
|
|
|
15
14
|
// Directives
|
|
16
15
|
export { AgGridCompatibilityDirective } from './lib/directives/ag-grid-compatibility.directive';
|
|
17
|
-
|
|
16
|
+
export { ClickOutsideDirective } from './lib/directives/click-outside.directive';
|
|
17
|
+
// Canvas renderer
|
|
18
|
+
export { CanvasRenderer } from './lib/rendering/canvas-renderer';
|
|
19
|
+
// Live Data Optimizations
|
|
20
|
+
export { LiveDataOptimizations } from './lib/rendering/live-data-optimizations';
|
|
18
21
|
// Services
|
|
19
22
|
export { GridService } from './lib/services/grid.service';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export {
|
|
24
|
+
COLOR_SCHEMES,
|
|
25
|
+
colorSchemeAuto,
|
|
26
|
+
colorSchemeDark,
|
|
27
|
+
colorSchemeLight,
|
|
28
|
+
getColorScheme,
|
|
29
|
+
} from './lib/themes/parts/color-schemes';
|
|
30
|
+
export {
|
|
31
|
+
getIconSet,
|
|
32
|
+
getIconSvg,
|
|
33
|
+
ICON_SETS,
|
|
34
|
+
iconSetMaterial,
|
|
35
|
+
iconSetMinimal,
|
|
36
|
+
iconSetQuartz,
|
|
37
|
+
} from './lib/themes/parts/icon-sets';
|
|
38
|
+
export {
|
|
39
|
+
applyTheme,
|
|
40
|
+
applyThemeCSSVariables,
|
|
41
|
+
convertThemeToGridTheme,
|
|
42
|
+
createTheme,
|
|
43
|
+
extendTheme,
|
|
44
|
+
getThemeCSSVariables,
|
|
45
|
+
mergeThemes,
|
|
46
|
+
removeTheme,
|
|
47
|
+
} from './lib/themes/theme-builder';
|
|
48
|
+
export { themeQuartz } from './lib/themes/theme-quartz';
|
|
49
|
+
// Theme System - New Theming API (AG Grid v32.2+ compatible)
|
|
50
|
+
export * from './lib/themes/types';
|
|
51
|
+
// Core types - AG Grid compatible
|
|
52
|
+
export * from './lib/types/ag-grid-types';
|
|
@@ -0,0 +1,188 @@
|
|
|
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
|
+
performance: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const meta: Meta<ArgentGridComponent<Employee>> = {
|
|
17
|
+
title: 'Features/Advanced',
|
|
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', 'HR', 'Finance'];
|
|
34
|
+
const roles = ['Engineer', 'Manager', 'Director', 'VP', 'Intern'];
|
|
35
|
+
const locations = ['New York', 'San Francisco', 'London', 'Singapore', 'Remote'];
|
|
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
|
+
performance: 80,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const SideBar: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
columnDefs: [
|
|
51
|
+
{ field: 'id', headerName: 'ID', width: 80, filter: true },
|
|
52
|
+
{ field: 'name', headerName: 'Name', width: 200, filter: true },
|
|
53
|
+
{ field: 'department', headerName: 'Department', width: 180, filter: 'set' },
|
|
54
|
+
{ field: 'role', headerName: 'Role', width: 250, filter: true },
|
|
55
|
+
{ field: 'salary', headerName: 'Salary', width: 120, filter: 'number' },
|
|
56
|
+
{ field: 'location', headerName: 'Location', width: 150, filter: 'set' },
|
|
57
|
+
{ field: 'performance', headerName: 'Performance', width: 120, filter: 'number' },
|
|
58
|
+
],
|
|
59
|
+
rowData: generateStaticData(50),
|
|
60
|
+
height: '500px',
|
|
61
|
+
width: '100%',
|
|
62
|
+
theme: themeQuartz,
|
|
63
|
+
gridOptions: {
|
|
64
|
+
sideBar: {
|
|
65
|
+
toolPanels: [
|
|
66
|
+
{
|
|
67
|
+
id: 'columns',
|
|
68
|
+
labelDefault: 'Columns',
|
|
69
|
+
labelKey: 'columns',
|
|
70
|
+
iconKey: 'columns',
|
|
71
|
+
toolPanel: 'agColumnsToolPanel',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'filters',
|
|
75
|
+
labelDefault: 'Filters',
|
|
76
|
+
labelKey: 'filters',
|
|
77
|
+
iconKey: 'filter',
|
|
78
|
+
toolPanel: 'agFiltersToolPanel',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
parameters: {
|
|
85
|
+
docs: {
|
|
86
|
+
description: {
|
|
87
|
+
story:
|
|
88
|
+
'Side bar with Columns and Filters panels. Click the sidebar toggle button in the grid toolbar to show/hide.',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const SideBarDefault: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
columnDefs: [
|
|
97
|
+
{ field: 'id', headerName: 'ID', width: 80, filter: true },
|
|
98
|
+
{ field: 'name', headerName: 'Name', width: 200, filter: true },
|
|
99
|
+
{ field: 'department', headerName: 'Department', width: 180, filter: 'set' },
|
|
100
|
+
{ field: 'role', headerName: 'Role', width: 250, filter: true },
|
|
101
|
+
{ field: 'salary', headerName: 'Salary', width: 120, filter: 'number' },
|
|
102
|
+
],
|
|
103
|
+
rowData: generateStaticData(50),
|
|
104
|
+
height: '500px',
|
|
105
|
+
width: '100%',
|
|
106
|
+
theme: themeQuartz,
|
|
107
|
+
gridOptions: {
|
|
108
|
+
sideBar: true,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
parameters: {
|
|
112
|
+
docs: {
|
|
113
|
+
description: {
|
|
114
|
+
story: 'Side bar with default configuration (Columns and Filters tool panels).',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const RangeSelection: Story = {
|
|
121
|
+
args: {
|
|
122
|
+
columnDefs: [
|
|
123
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
124
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
125
|
+
{ field: 'department', headerName: 'Department', width: 180 },
|
|
126
|
+
{ field: 'role', headerName: 'Role', width: 250 },
|
|
127
|
+
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
128
|
+
{ field: 'location', headerName: 'Location', width: 150 },
|
|
129
|
+
],
|
|
130
|
+
rowData: generateStaticData(50),
|
|
131
|
+
height: '400px',
|
|
132
|
+
width: '100%',
|
|
133
|
+
theme: themeQuartz,
|
|
134
|
+
gridOptions: {
|
|
135
|
+
enableRangeSelection: true,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
parameters: {
|
|
139
|
+
docs: {
|
|
140
|
+
description: {
|
|
141
|
+
story:
|
|
142
|
+
'Enable range selection to select multiple cells by clicking and dragging. Use Ctrl+C to copy selected range.',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const FullFeatures: Story = {
|
|
149
|
+
args: {
|
|
150
|
+
columnDefs: [
|
|
151
|
+
{ field: 'id', headerName: 'ID', width: 80, filter: true, sortable: true },
|
|
152
|
+
{ field: 'name', headerName: 'Name', width: 200, filter: true, sortable: true },
|
|
153
|
+
{
|
|
154
|
+
field: 'department',
|
|
155
|
+
headerName: 'Department',
|
|
156
|
+
width: 180,
|
|
157
|
+
filter: 'set',
|
|
158
|
+
sortable: true,
|
|
159
|
+
rowGroup: true,
|
|
160
|
+
},
|
|
161
|
+
{ field: 'role', headerName: 'Role', width: 250, filter: true },
|
|
162
|
+
{ field: 'salary', headerName: 'Salary', width: 120, filter: 'number', sortable: true },
|
|
163
|
+
{ field: 'location', headerName: 'Location', width: 150, filter: 'set' },
|
|
164
|
+
],
|
|
165
|
+
rowData: generateStaticData(100),
|
|
166
|
+
height: '500px',
|
|
167
|
+
width: '100%',
|
|
168
|
+
theme: themeQuartz,
|
|
169
|
+
gridOptions: {
|
|
170
|
+
floatingFilter: true,
|
|
171
|
+
enableRangeSelection: true,
|
|
172
|
+
sideBar: true,
|
|
173
|
+
autoGroupColumnDef: {
|
|
174
|
+
headerName: 'Organization',
|
|
175
|
+
width: 250,
|
|
176
|
+
pinned: 'left',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
parameters: {
|
|
181
|
+
docs: {
|
|
182
|
+
description: {
|
|
183
|
+
story:
|
|
184
|
+
'Full-featured grid with sorting, filtering, floating filters, range selection, side bar, and row grouping.',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { moduleMetadata } from '@storybook/angular';
|
|
3
|
+
import { ArgentGridComponent, ArgentGridModule, themeQuartz } from '../public-api';
|
|
4
|
+
|
|
5
|
+
interface Employee {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
department: string;
|
|
9
|
+
role: string;
|
|
10
|
+
salary: number;
|
|
11
|
+
location: string;
|
|
12
|
+
startDate: string;
|
|
13
|
+
performance: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const meta: Meta<ArgentGridComponent<Employee>> = {
|
|
17
|
+
title: 'Components/ArgentGrid',
|
|
18
|
+
component: ArgentGridComponent,
|
|
19
|
+
decorators: [
|
|
20
|
+
moduleMetadata({
|
|
21
|
+
imports: [ArgentGridModule],
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
parameters: {
|
|
25
|
+
layout: 'fullscreen',
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
height: { control: 'text' },
|
|
29
|
+
width: { control: 'text' },
|
|
30
|
+
rowHeight: { control: 'number' },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
type Story = StoryObj<ArgentGridComponent<Employee>>;
|
|
36
|
+
|
|
37
|
+
function generateStaticData(count: number): Employee[] {
|
|
38
|
+
const departments = ['Engineering', 'Sales', 'Marketing', 'HR', 'Finance'];
|
|
39
|
+
const roles = ['Engineer', 'Manager', 'Director', 'VP', 'Intern'];
|
|
40
|
+
const locations = ['New York', 'San Francisco', 'London', 'Singapore', 'Remote'];
|
|
41
|
+
|
|
42
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
43
|
+
id: i + 1,
|
|
44
|
+
name: `Employee ${i + 1}`,
|
|
45
|
+
department: departments[i % departments.length],
|
|
46
|
+
role: roles[i % roles.length],
|
|
47
|
+
salary: 50000 + i * 1000,
|
|
48
|
+
location: locations[i % locations.length],
|
|
49
|
+
startDate: '2020-01-01',
|
|
50
|
+
performance: 80,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
columnDefs: [
|
|
57
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
58
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
59
|
+
{ field: 'department', headerName: 'Department', width: 180 },
|
|
60
|
+
{ field: 'role', headerName: 'Role', width: 250 },
|
|
61
|
+
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
62
|
+
{ field: 'location', headerName: 'Location', width: 150 },
|
|
63
|
+
{ field: 'startDate', headerName: 'Start Date', width: 130 },
|
|
64
|
+
{ field: 'performance', headerName: 'Performance', width: 120 },
|
|
65
|
+
],
|
|
66
|
+
rowData: generateStaticData(100),
|
|
67
|
+
height: '500px',
|
|
68
|
+
width: '100%',
|
|
69
|
+
theme: themeQuartz,
|
|
70
|
+
},
|
|
71
|
+
parameters: {
|
|
72
|
+
docs: {
|
|
73
|
+
description: {
|
|
74
|
+
story: '**Basic grid** with 100 rows. Default theme (Quartz). No special features enabled.',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const LargeDataset: Story = {
|
|
81
|
+
args: {
|
|
82
|
+
columnDefs: [
|
|
83
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
84
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
85
|
+
{ field: 'department', headerName: 'Department', width: 180 },
|
|
86
|
+
{ field: 'role', headerName: 'Role', width: 250 },
|
|
87
|
+
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
88
|
+
],
|
|
89
|
+
rowData: generateStaticData(100000),
|
|
90
|
+
height: '500px',
|
|
91
|
+
width: '100%',
|
|
92
|
+
theme: themeQuartz,
|
|
93
|
+
},
|
|
94
|
+
parameters: {
|
|
95
|
+
docs: {
|
|
96
|
+
description: {
|
|
97
|
+
story:
|
|
98
|
+
'**Performance demo with 100K rows**. Scroll smoothly at 60fps thanks to canvas rendering and virtual scrolling. Try scrolling to the bottom!',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const WithSorting: Story = {
|
|
105
|
+
args: {
|
|
106
|
+
columnDefs: [
|
|
107
|
+
{
|
|
108
|
+
field: 'id',
|
|
109
|
+
headerName: 'ID ↕️',
|
|
110
|
+
width: 80,
|
|
111
|
+
sortable: true,
|
|
112
|
+
headerComponentParams: { sortIcon: '↕️' },
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
field: 'name',
|
|
116
|
+
headerName: 'Name ↕️',
|
|
117
|
+
width: 200,
|
|
118
|
+
sortable: true,
|
|
119
|
+
headerComponentParams: { sortIcon: '↕️' },
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
field: 'department',
|
|
123
|
+
headerName: 'Department ↕️',
|
|
124
|
+
width: 180,
|
|
125
|
+
sortable: true,
|
|
126
|
+
headerComponentParams: { sortIcon: '↕️' },
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
field: 'salary',
|
|
130
|
+
headerName: 'Salary ↕️',
|
|
131
|
+
width: 120,
|
|
132
|
+
sortable: true,
|
|
133
|
+
headerComponentParams: { sortIcon: '↕️' },
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
rowData: generateStaticData(50),
|
|
137
|
+
height: '400px',
|
|
138
|
+
width: '100%',
|
|
139
|
+
theme: themeQuartz,
|
|
140
|
+
},
|
|
141
|
+
parameters: {
|
|
142
|
+
docs: {
|
|
143
|
+
description: {
|
|
144
|
+
story:
|
|
145
|
+
'**Sortable columns** with ↕️ indicators. **Click column headers** to sort ascending/descending. Look for the **▲/▼ arrows** that appear when sorted.',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const WithSelection: Story = {
|
|
152
|
+
args: {
|
|
153
|
+
columnDefs: [
|
|
154
|
+
{
|
|
155
|
+
field: 'id',
|
|
156
|
+
headerName: 'ID ☑️',
|
|
157
|
+
width: 80,
|
|
158
|
+
checkboxSelection: true,
|
|
159
|
+
headerComponentParams: { selectionIcon: '☑️' },
|
|
160
|
+
},
|
|
161
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
162
|
+
{ field: 'department', headerName: 'Department', width: 180 },
|
|
163
|
+
{ field: 'role', headerName: 'Role', width: 250 },
|
|
164
|
+
],
|
|
165
|
+
rowData: generateStaticData(50),
|
|
166
|
+
rowSelection: 'multiple',
|
|
167
|
+
height: '400px',
|
|
168
|
+
width: '100%',
|
|
169
|
+
theme: themeQuartz,
|
|
170
|
+
},
|
|
171
|
+
parameters: {
|
|
172
|
+
docs: {
|
|
173
|
+
description: {
|
|
174
|
+
story:
|
|
175
|
+
'**Row selection with checkboxes**. The first column shows **☑️ checkboxes** in every row. **Click checkboxes** to select/deselect rows. **Header checkbox** selects/deselects all visible rows.',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const WithFiltering: Story = {
|
|
182
|
+
args: {
|
|
183
|
+
columnDefs: [
|
|
184
|
+
{
|
|
185
|
+
field: 'id',
|
|
186
|
+
headerName: 'ID 🔢',
|
|
187
|
+
width: 80,
|
|
188
|
+
filter: 'number',
|
|
189
|
+
floatingFilter: true,
|
|
190
|
+
headerComponentParams: { filterIcon: '🔢' },
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
field: 'name',
|
|
194
|
+
headerName: 'Name 🔤',
|
|
195
|
+
width: 200,
|
|
196
|
+
filter: 'text',
|
|
197
|
+
floatingFilter: true,
|
|
198
|
+
headerComponentParams: { filterIcon: '🔤' },
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
field: 'department',
|
|
202
|
+
headerName: 'Department ☑️',
|
|
203
|
+
width: 180,
|
|
204
|
+
filter: 'set',
|
|
205
|
+
floatingFilter: true,
|
|
206
|
+
headerComponentParams: { filterIcon: '☑️' },
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
field: 'role',
|
|
210
|
+
headerName: 'Role 🔤',
|
|
211
|
+
width: 250,
|
|
212
|
+
filter: 'text',
|
|
213
|
+
floatingFilter: true,
|
|
214
|
+
headerComponentParams: { filterIcon: '🔤' },
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
rowData: generateStaticData(50),
|
|
218
|
+
height: '500px',
|
|
219
|
+
width: '100%',
|
|
220
|
+
theme: themeQuartz,
|
|
221
|
+
},
|
|
222
|
+
parameters: {
|
|
223
|
+
docs: {
|
|
224
|
+
description: {
|
|
225
|
+
story:
|
|
226
|
+
'**Filtering with visible filter inputs**. Each filterable column shows an icon (🔢 Number, 🔤 Text, ☑️ Set). **Filter inputs are visible in the header row** - type to filter. Department uses a set filter (dropdown with checkboxes).',
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export const Empty: Story = {
|
|
233
|
+
args: {
|
|
234
|
+
columnDefs: [
|
|
235
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
236
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
237
|
+
],
|
|
238
|
+
rowData: [],
|
|
239
|
+
height: '300px',
|
|
240
|
+
width: '100%',
|
|
241
|
+
theme: themeQuartz,
|
|
242
|
+
},
|
|
243
|
+
parameters: {
|
|
244
|
+
docs: {
|
|
245
|
+
description: {
|
|
246
|
+
story: '**Empty grid** with no rows. Shows overlay message "No rows to show".',
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export const WithCustomTheme: Story = {
|
|
253
|
+
args: {
|
|
254
|
+
columnDefs: [
|
|
255
|
+
{ field: 'id', headerName: 'ID', width: 80 },
|
|
256
|
+
{ field: 'name', headerName: 'Name', width: 200 },
|
|
257
|
+
{ field: 'department', headerName: 'Department', width: 180 },
|
|
258
|
+
{ field: 'salary', headerName: 'Salary', width: 120 },
|
|
259
|
+
],
|
|
260
|
+
rowData: generateStaticData(50),
|
|
261
|
+
height: '400px',
|
|
262
|
+
width: '100%',
|
|
263
|
+
theme: themeQuartz.withParams({
|
|
264
|
+
accentColor: '#ff5722', // Orange accent
|
|
265
|
+
rowHeight: 48,
|
|
266
|
+
fontSize: 14,
|
|
267
|
+
}),
|
|
268
|
+
},
|
|
269
|
+
parameters: {
|
|
270
|
+
docs: {
|
|
271
|
+
description: {
|
|
272
|
+
story:
|
|
273
|
+
'**Custom theme** with orange accent color, larger row height (48px), and larger font (14px). See Theming stories for more theme options.',
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
};
|