@opencorestack/opengridx 0.1.5 → 0.1.7

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 (130) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +9 -0
  3. package/dist/index.d.ts +6 -0
  4. package/dist/opengridx.css +1 -1
  5. package/dist/opengridx.es.js +319 -319
  6. package/dist/opengridx.es.js.map +1 -1
  7. package/dist/opengridx.umd.js +7 -7
  8. package/dist/opengridx.umd.js.map +1 -1
  9. package/docs/API_REFERENCE.md +177 -0
  10. package/docs/README.md +60 -0
  11. package/docs/components/cell.md +44 -0
  12. package/docs/components/column-group-header.md +57 -0
  13. package/docs/components/column-resize.md +63 -0
  14. package/docs/components/column-visibility.md +61 -0
  15. package/docs/components/datagrid.md +70 -0
  16. package/docs/components/filter-panel.md +26 -0
  17. package/docs/components/header.md +39 -0
  18. package/docs/components/pagination.md +34 -0
  19. package/docs/components/row.md +31 -0
  20. package/docs/components/toolbar.md +40 -0
  21. package/docs/components/tooltip.md +68 -0
  22. package/docs/customization/slots-api.md +227 -0
  23. package/docs/customization/theming.md +293 -0
  24. package/docs/features/aggregation-pivot.md +79 -0
  25. package/docs/features/cell-spanning.md +520 -0
  26. package/docs/features/clipboard.md +76 -0
  27. package/docs/features/custom-pagination.md +143 -0
  28. package/docs/features/data-source.md +72 -0
  29. package/docs/features/editing-reordering.md +99 -0
  30. package/docs/features/export-guide.md +434 -0
  31. package/docs/features/filtering.md +83 -0
  32. package/docs/features/infinite-scroll.md +87 -0
  33. package/docs/features/list-view.md +65 -0
  34. package/docs/features/loading-states.md +68 -0
  35. package/docs/features/master-detail.md +46 -0
  36. package/docs/features/pinning.md +67 -0
  37. package/docs/features/selection.md +70 -0
  38. package/docs/features/sorting-pagination.md +66 -0
  39. package/docs/features/state-persistence.md +67 -0
  40. package/docs/features/tree-data-grouping.md +67 -0
  41. package/docs/features/virtualization.md +188 -0
  42. package/docs/roadmap.md +71 -0
  43. package/lib/components/Cell/Cell.css +119 -0
  44. package/lib/components/Cell/Cell.tsx +264 -0
  45. package/lib/components/Cell/GridEditInputCell.css +62 -0
  46. package/lib/components/Cell/GridEditInputCell.tsx +152 -0
  47. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +67 -0
  48. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.tsx +220 -0
  49. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +31 -0
  50. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +85 -0
  51. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +137 -0
  52. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +190 -0
  53. package/lib/components/DataGrid/DataGrid.css +224 -0
  54. package/lib/components/DataGrid/DataGrid.tsx +2253 -0
  55. package/lib/components/DetailPanel/DetailPanel.css +36 -0
  56. package/lib/components/DetailPanel/DetailPanel.tsx +34 -0
  57. package/lib/components/FilterPanel/FilterPanel.css +196 -0
  58. package/lib/components/FilterPanel/FilterPanel.tsx +183 -0
  59. package/lib/components/FilterPanel/index.ts +1 -0
  60. package/lib/components/Header/ColumnMenu.css +68 -0
  61. package/lib/components/Header/ColumnMenu.tsx +249 -0
  62. package/lib/components/Header/Header.css +224 -0
  63. package/lib/components/Header/Header.tsx +516 -0
  64. package/lib/components/ListView/ListView.css +112 -0
  65. package/lib/components/ListView/ListViewRow.tsx +63 -0
  66. package/lib/components/Pagination/Pagination.css +91 -0
  67. package/lib/components/Pagination/Pagination.tsx +151 -0
  68. package/lib/components/QuickFilter/QuickFilter.css +23 -0
  69. package/lib/components/QuickFilter/QuickFilter.tsx +79 -0
  70. package/lib/components/Row/Row.css +126 -0
  71. package/lib/components/Row/Row.tsx +377 -0
  72. package/lib/components/Skeleton/Skeleton.css +55 -0
  73. package/lib/components/Skeleton/Skeleton.tsx +22 -0
  74. package/lib/components/SkeletonRow/SkeletonRow.css +32 -0
  75. package/lib/components/SkeletonRow/SkeletonRow.tsx +89 -0
  76. package/lib/components/SkeletonRow/index.ts +1 -0
  77. package/lib/components/Toolbar/GlobalSearch.css +113 -0
  78. package/lib/components/Toolbar/GlobalSearch.tsx +120 -0
  79. package/lib/components/Toolbar/GridToolbar.css +204 -0
  80. package/lib/components/Toolbar/GridToolbar.tsx +647 -0
  81. package/lib/components/Toolbar/PivotPanel.css +212 -0
  82. package/lib/components/Toolbar/PivotPanel.tsx +239 -0
  83. package/lib/components/Tooltip/Tooltip.css +59 -0
  84. package/lib/components/Tooltip/Tooltip.tsx +106 -0
  85. package/lib/components/ui/Button.css +89 -0
  86. package/lib/components/ui/Button.tsx +39 -0
  87. package/lib/components/ui/Checkbox.css +71 -0
  88. package/lib/components/ui/Checkbox.tsx +66 -0
  89. package/lib/components/ui/DragHandleIcon.css +19 -0
  90. package/lib/components/ui/DragHandleIcon.tsx +18 -0
  91. package/lib/components/ui/ExpandIcon.css +38 -0
  92. package/lib/components/ui/ExpandIcon.tsx +75 -0
  93. package/lib/components/ui/Input.css +59 -0
  94. package/lib/components/ui/Input.tsx +45 -0
  95. package/lib/components/ui/index.ts +15 -0
  96. package/lib/hooks/core/useDataGrid.ts +392 -0
  97. package/lib/hooks/core/useGridApiRef.ts +10 -0
  98. package/lib/hooks/features/useAggregation.ts +143 -0
  99. package/lib/hooks/features/useGridClipboard.ts +133 -0
  100. package/lib/hooks/features/useGridDataSource.ts +190 -0
  101. package/lib/hooks/features/useGridEditing.ts +100 -0
  102. package/lib/hooks/features/useGridSpanning.ts +349 -0
  103. package/lib/hooks/features/usePivot.ts +149 -0
  104. package/lib/hooks/useColumnReorder.ts +114 -0
  105. package/lib/hooks/useRowGrouping.ts +302 -0
  106. package/lib/hooks/useRowReorder.ts +83 -0
  107. package/lib/hooks/useTreeData.ts +323 -0
  108. package/lib/index.ts +106 -0
  109. package/lib/state/index.ts +17 -0
  110. package/lib/state/types.ts +48 -0
  111. package/lib/state/useGridStateStorage.ts +113 -0
  112. package/lib/styles/base/reset.css +21 -0
  113. package/lib/styles/base/variables.css +161 -0
  114. package/lib/styles/opengridx.css +27 -0
  115. package/lib/styles/opengridx.css.d.ts +4 -0
  116. package/lib/theme/DataGridThemeProvider.tsx +276 -0
  117. package/lib/theme/defaultStyles.ts +0 -0
  118. package/lib/theme/index.ts +21 -0
  119. package/lib/theme/presets.ts +148 -0
  120. package/lib/theme/types.ts +155 -0
  121. package/lib/types/index.ts +764 -0
  122. package/lib/utils/export/exportToExcelAdvanced.ts +516 -0
  123. package/lib/utils/export/index.ts +550 -0
  124. package/lib/utils/filtering/index.ts +240 -0
  125. package/lib/utils/pinning/index.ts +282 -0
  126. package/lib/utils/sorting/index.ts +55 -0
  127. package/lib/utils/virtualization/index.ts +106 -0
  128. package/lib/vite-env.d.ts +1 -0
  129. package/llms.txt +12 -2
  130. package/package.json +13 -4
@@ -0,0 +1,40 @@
1
+ # `<Toolbar />`
2
+
3
+ The toolbar is an optional component rendered at the top of the grid. It typically contains global actions like exporting, filtering, and column management.
4
+
5
+ ## 🛠️ Provided Component: `GridToolbar`
6
+
7
+ OpenGridX includes a pre-built `GridToolbar` that bundles common actions.
8
+
9
+ ### Usage
10
+ ```tsx
11
+ import { DataGrid, GridToolbar } from '@opencorestack/opengridx';
12
+
13
+ <DataGrid
14
+ slots={{
15
+ toolbar: GridToolbar
16
+ }}
17
+ />
18
+ ```
19
+
20
+ ### Features
21
+ - **Quick Search**: Search across all visible columns.
22
+ - **Export Menu**: Download data as CSV, Print, or [Advanced Excel](../features/export-guide.md).
23
+ - **Column Visibility**: Toggle which columns are shown via a dropdown [Visibility Panel](column-visibility.md).
24
+ - **Density**: Switch between Compact, Standard, and Comfortable row heights.
25
+
26
+ ## 🎨 Custom Toolbar
27
+
28
+ You can provide your own component to the `toolbar` slot. It will receive props to interact with the grid state.
29
+
30
+ ```tsx
31
+ const MyToolbar = () => {
32
+ return (
33
+ <div className="custom-toolbar">
34
+ <button onClick={...}>Custom Action</button>
35
+ </div>
36
+ );
37
+ };
38
+
39
+ <DataGrid slots={{ toolbar: MyToolbar }} />
40
+ ```
@@ -0,0 +1,68 @@
1
+ # `<GridTooltip />`
2
+
3
+ The `GridTooltip` component provides a lightweight, accessible tooltip for any HTML or React element. It is commonly used within columns, actions, or toolbars to display extra information when a user hovers over a component.
4
+
5
+ ## 📑 Overview
6
+ - **Portal Rendering**: Tooltips are rendered at the end of `document.body` for unobstructed positioning.
7
+ - **Dynamic Calculation**: Tooltips calculate their placement relative to the target element on hover.
8
+ - **Support for React Elements**: It wraps its child element to attach event listeners and calculate position.
9
+ - **Customizable Delays**: Support for `enterDelay` and `leaveDelay`.
10
+
11
+ ---
12
+
13
+ ## 🛠️ Usage
14
+
15
+ ### Tooltip with a Button
16
+ Wrap any React element with the `GridTooltip` and provide a `title`.
17
+
18
+ ```tsx
19
+ import { GridTooltip } from '@opencorestack/opengridx';
20
+
21
+ <GridTooltip title="Click to Export">
22
+ <button onClick={handleExport}>
23
+ Export as Excel
24
+ </button>
25
+ </GridTooltip>
26
+ ```
27
+
28
+ ### Tooltip with Custom Placement
29
+ You can choose from four different placements: `top`, `bottom`, `left`, or `right`.
30
+
31
+ ```tsx
32
+ <GridTooltip title="Top Placement" placement="top">
33
+ <span>Hover me</span>
34
+ </GridTooltip>
35
+
36
+ <GridTooltip title="Bottom Placement" placement="bottom">
37
+ <span>Hover me</span>
38
+ </GridTooltip>
39
+ ```
40
+
41
+ ---
42
+
43
+ ## ⚙️ Properties
44
+
45
+ | Property | Type | Default | Description |
46
+ | :--- | :--- | :--- | :--- |
47
+ | **`title`** | `React.ReactNode` | — | Content (text, JSX, etc.) to show inside the tooltip. |
48
+ | **`children`** | `React.ReactElement` | — | The target element the tooltip is attached to. |
49
+ | **`placement`** | `'top'`, `'bottom'`, `'left'`, `'right'` | `'top'` | Direction where the tooltip appears. |
50
+ | **`enterDelay`** | `number` | `200` | Delay (ms) before showing the tooltip. |
51
+ | **`leaveDelay`** | `number` | `0` | Delay (ms) before hiding the tooltip. |
52
+
53
+ ---
54
+
55
+ ## 🎨 Slot Implementation
56
+ In the DataGrid, specialized components like the Toolbar often use tooltips within their built-in actions. These can be customized or replaced using the slots API.
57
+
58
+ ```tsx
59
+ <DataGrid
60
+ slots={{
61
+ tooltip: GridTooltip
62
+ }}
63
+ />
64
+ ```
65
+
66
+ ## 📝 Accessibility
67
+ - Tooltips are triggered by mouse hover events (`onMouseEnter`/`onMouseLeave`).
68
+ - It is recommended to use descriptive `aria-label` tags on the child element for screen readers, as tooltips are visually focused.
@@ -0,0 +1,227 @@
1
+ # Slots API Reference
2
+
3
+ The Slots API allows you to replace any built-in component in the DataGrid with your own custom implementation.
4
+
5
+ ## Available Slots
6
+
7
+ ### 1. `toolbar`
8
+ Add a custom toolbar above the grid (commonly used for export buttons, filters, actions).
9
+
10
+ **Props received:**
11
+ ```typescript
12
+ {
13
+ // Any props from slotProps.toolbar
14
+ }
15
+ ```
16
+
17
+ **Example:**
18
+ ```tsx
19
+ import { exportToCsv, exportToExcel } from '@opencorestack/opengridx';
20
+
21
+ function CustomToolbar({ rows, columns }) {
22
+ return (
23
+ <div style={{ padding: '12px', display: 'flex', gap: '8px' }}>
24
+ <button onClick={() => exportToCsv(rows, columns)}>
25
+ Export CSV
26
+ </button>
27
+ <button onClick={() => exportToExcel(rows, columns)}>
28
+ Export Excel
29
+ </button>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ <DataGrid
35
+ slots={{ toolbar: CustomToolbar }}
36
+ slotProps={{ toolbar: { rows, columns } }}
37
+ />
38
+ ```
39
+
40
+ ### 2. `pagination`
41
+ Replace the default pagination component.
42
+
43
+ **Props received:**
44
+ ```typescript
45
+ {
46
+ page: number; // Current page (0-based)
47
+ pageSize: number; // Current page size
48
+ rowCount: number; // Total number of rows
49
+ pageSizeOptions: number[]; // Available page sizes
50
+ onPageChange: (page: number) => void;
51
+ onPageSizeChange: (size: number) => void;
52
+ }
53
+ ```
54
+
55
+ **Example:**
56
+ ```tsx
57
+ <DataGrid
58
+ slots={{ pagination: CustomPagination }}
59
+ slotProps={{ pagination: { customProp: 'value' } }}
60
+ />
61
+ ```
62
+
63
+ ### 3. `noRowsOverlay`
64
+ Replace the empty state shown when there are no rows.
65
+
66
+ **Props received:**
67
+ ```typescript
68
+ {
69
+ // Any props from slotProps.noRowsOverlay
70
+ }
71
+ ```
72
+
73
+ **Example:**
74
+ ```tsx
75
+ function CustomNoRows() {
76
+ return (
77
+ <div style={{ padding: '40px', textAlign: 'center' }}>
78
+ <h3>No data available</h3>
79
+ <p>Try adjusting your filters</p>
80
+ </div>
81
+ );
82
+ }
83
+
84
+ <DataGrid
85
+ slots={{ noRowsOverlay: CustomNoRows }}
86
+ />
87
+ ```
88
+
89
+ ### 4. `loadingOverlay`
90
+ Replace the loading state overlay.
91
+
92
+ **Props received:**
93
+ ```typescript
94
+ {
95
+ // Any props from slotProps.loadingOverlay
96
+ }
97
+ ```
98
+
99
+ **Example:**
100
+ ```tsx
101
+ function CustomLoader() {
102
+ return (
103
+ <div style={{ padding: '40px', textAlign: 'center' }}>
104
+ <Spin size="large" /> {/* Ant Design Spinner */}
105
+ <p>Loading data...</p>
106
+ </div>
107
+ );
108
+ }
109
+
110
+ <DataGrid
111
+ slots={{ loadingOverlay: CustomLoader }}
112
+ />
113
+ ```
114
+
115
+ ### 5. `footer`
116
+ Replace the entire footer section (including pagination).
117
+
118
+ **Props received:**
119
+ ```typescript
120
+ {
121
+ // Any props from slotProps.footer
122
+ }
123
+ ```
124
+
125
+ **Example:**
126
+ ```tsx
127
+ function CustomFooter() {
128
+ return (
129
+ <div style={{ padding: '12px', borderTop: '1px solid #e0e0e0' }}>
130
+ <span>Custom footer content</span>
131
+ </div>
132
+ );
133
+ }
134
+
135
+ <DataGrid
136
+ slots={{ footer: CustomFooter }}
137
+ />
138
+ ```
139
+
140
+ ## Complete Example
141
+
142
+ ```tsx
143
+ import { Select, Pagination, Spin, Empty } from 'antd';
144
+ import { DataGrid } from '@opencorestack/opengridx';
145
+
146
+ function AntdPagination(props) {
147
+ const { page, pageSize, rowCount, pageSizeOptions, onPageChange, onPageSizeChange } = props;
148
+
149
+ return (
150
+ <div style={{ display: 'flex', gap: '16px', padding: '12px 16px', justifyContent: 'flex-end' }}>
151
+ <Select
152
+ value={pageSize}
153
+ onChange={onPageSizeChange}
154
+ options={pageSizeOptions.map(s => ({ value: s, label: s }))}
155
+ />
156
+ <Pagination
157
+ current={page + 1}
158
+ total={rowCount}
159
+ pageSize={pageSize}
160
+ onChange={(p) => onPageChange(p - 1)}
161
+ />
162
+ </div>
163
+ );
164
+ }
165
+
166
+ function AntdNoRows() {
167
+ return <Empty description="No data available" />;
168
+ }
169
+
170
+ function AntdLoader() {
171
+ return (
172
+ <div style={{ padding: '40px', textAlign: 'center' }}>
173
+ <Spin size="large" />
174
+ </div>
175
+ );
176
+ }
177
+
178
+ function MyApp() {
179
+ return (
180
+ <DataGrid
181
+ rows={rows}
182
+ columns={columns}
183
+ pagination
184
+ loading={isLoading}
185
+ slots={{
186
+ pagination: AntdPagination,
187
+ noRowsOverlay: AntdNoRows,
188
+ loadingOverlay: AntdLoader
189
+ }}
190
+ slotProps={{
191
+ pagination: {
192
+ // Additional custom props if needed
193
+ }
194
+ }}
195
+ />
196
+ );
197
+ }
198
+ ```
199
+
200
+ ## TypeScript Support
201
+
202
+ For full type safety, define your component props:
203
+
204
+ ```typescript
205
+ import type { PaginationProps } from '@opencorestack/opengridx';
206
+
207
+ interface CustomPaginationProps extends PaginationProps {
208
+ customProp?: string;
209
+ }
210
+
211
+ const CustomPagination: React.FC<CustomPaginationProps> = (props) => {
212
+ // Your implementation
213
+ };
214
+ ```
215
+
216
+ ## Best Practices
217
+
218
+ 1. **Maintain Functionality**: Ensure your custom component provides the same core functionality as the default.
219
+ 2. **Accessibility**: Include proper ARIA labels and keyboard navigation.
220
+ 3. **Responsive Design**: Make sure your component works on different screen sizes.
221
+ 4. **Performance**: Avoid expensive operations in render; use memoization where appropriate.
222
+ 5. **Consistent Styling**: Match your app's design system while maintaining usability.
223
+
224
+ ## See Also
225
+
226
+ - [Custom Pagination Guide](./CUSTOM_PAGINATION.md) - Detailed examples with Ant Design and MUI
227
+ - [DataGrid Props](../src/OpenGridX/types/index.ts) - Full TypeScript definitions
@@ -0,0 +1,293 @@
1
+ # OpenGridX Theming Guide
2
+
3
+ OpenGridX ships with a complete design-token system built on CSS custom properties (`--ogx-*`). You can theme the grid in two ways:
4
+
5
+ 1. **`DataGridThemeProvider`** — the recommended React API (maps a typed `GridTheme` object → CSS variables)
6
+ 2. **Raw CSS override** — set any `--ogx-*` variable yourself on a wrapper element or `:root`
7
+
8
+ ---
9
+
10
+ ## Quick Start — `DataGridThemeProvider`
11
+
12
+ ```tsx
13
+ import { DataGrid, DataGridThemeProvider } from '@opencorestack/opengridx';
14
+
15
+ const myTheme = {
16
+ colors: {
17
+ primary: '#7c3aed',
18
+ primaryDark: '#5b21b6',
19
+ primaryLight: '#ede9fe',
20
+ },
21
+ grid: {
22
+ background: '#fff',
23
+ headerBackground: '#f5f3ff',
24
+ rowHoverBackground: '#faf5ff',
25
+ rowSelectedBackground: '#ede9fe',
26
+ cellFocusBorder: '#7c3aed',
27
+ },
28
+ };
29
+
30
+ export default function App() {
31
+ return (
32
+ <DataGridThemeProvider theme={myTheme}>
33
+ <DataGrid rows={rows} columns={columns} />
34
+ </DataGridThemeProvider>
35
+ );
36
+ }
37
+ ```
38
+
39
+ The `DataGridThemeProvider` resolves each key in the `GridTheme` object to its corresponding `--ogx-*` CSS variable and applies it as an inline style on a wrapper `div`. **No CSS-in-JS, no runtime overhead.**
40
+
41
+ ---
42
+
43
+ ## Dark Mode
44
+
45
+ The grid automatically switches to its dark palette via `@media (prefers-color-scheme: dark)`. If your app manages dark mode manually (e.g. via a `data-theme` attribute), override the dark tokens with:
46
+
47
+ ```css
48
+ [data-theme="dark"] {
49
+ --ogx-grid-background: #0f172a;
50
+ --ogx-grid-header-background: #1e293b;
51
+ --ogx-grid-row-text: #cbd5e1;
52
+ --ogx-grid-border-color: #334155;
53
+ /* … etc */
54
+ }
55
+ ```
56
+
57
+ ---
58
+
59
+ ## `GridTheme` Interface Reference
60
+
61
+ ```ts
62
+ interface GridTheme {
63
+ colors?: GridThemeColors;
64
+ typography?: GridThemeTypography;
65
+ spacing?: GridThemeSpacing;
66
+ borders?: GridThemeBorders;
67
+ shadows?: GridThemeShadows;
68
+ grid?: GridThemeGrid;
69
+ toolbar?: GridThemeToolbar;
70
+ overlays?: GridThemeOverlays;
71
+ scrollbar?: GridThemeScrollbar;
72
+ skeleton?: GridThemeSkeleton;
73
+ transitions?: GridThemeTransitions;
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## All CSS Tokens
80
+
81
+ ### Colors
82
+
83
+ | Token | Default (light) | Dark override | Description |
84
+ |---|---|---|---|
85
+ | `--ogx-color-primary` | `#3b82f6` | `#60a5fa` | Brand / accent color |
86
+ | `--ogx-color-primary-dark` | `#2563eb` | `#3b82f6` | Hover / pressed primary |
87
+ | `--ogx-color-primary-light` | `#eff6ff` | `#1e3a5f` | Tinted backgrounds |
88
+ | `--ogx-color-primary-focus` | `rgba(59,130,246,0.5)` | `rgba(96,165,250,0.4)` | Focus ring color |
89
+ | `--ogx-color-secondary` | `#8b5cf6` | — | Secondary accent |
90
+ | `--ogx-color-secondary-dark` | `#7c3aed` | — | Hover secondary |
91
+ | `--ogx-color-secondary-light` | `#f5f3ff` | — | Tinted secondary backgrounds |
92
+ | `--ogx-color-success` | `#10b981` | — | Positive indicators |
93
+ | `--ogx-color-warning` | `#f59e0b` | — | Warning indicators |
94
+ | `--ogx-color-error` | `#ef4444` | — | Error / destructive |
95
+ | `--ogx-color-info` | `#0ea5e9` | — | Informational |
96
+ | `--ogx-color-white` | `#ffffff` | `#0f172a` | Pure white (inverted in dark) |
97
+ | `--ogx-color-black` | `#0f172a` | `#f8fafc` | Pure black (inverted in dark) |
98
+ | `--ogx-color-gray-50` | `#f8fafc` | `#1e293b` | Lightest gray |
99
+ | `--ogx-color-gray-100` | `#f1f5f9` | `#334155` | |
100
+ | `--ogx-color-gray-200` | `#e2e8f0` | `#475569` | Default borders |
101
+ | `--ogx-color-gray-300` | `#cbd5e1` | `#64748b` | |
102
+ | `--ogx-color-gray-400` | `#94a3b8` | `#94a3b8` | Muted text |
103
+ | `--ogx-color-gray-500` | `#64748b` | `#cbd5e1` | |
104
+ | `--ogx-color-gray-600` | `#475569` | `#e2e8f0` | |
105
+ | `--ogx-color-gray-700` | `#334155` | `#e2e8f0` | Header text default |
106
+ | `--ogx-color-gray-800` | `#1e293b` | `#f1f5f9` | Body text default |
107
+ | `--ogx-color-gray-900` | `#0f172a` | `#f8fafc` | Darkest gray |
108
+
109
+ ### Typography
110
+
111
+ | Token | Default | Description |
112
+ |---|---|---|
113
+ | `--ogx-font-family` | `'Inter', system-ui, sans-serif` | Primary UI font |
114
+ | `--ogx-font-family-mono` | `'JetBrains Mono', 'Fira Code', monospace` | Monospace (code cells, IDs) |
115
+ | `--ogx-font-size-xs` | `0.75rem` (12px) | Extra-small |
116
+ | `--ogx-font-size-sm` | `0.875rem` (14px) | Small |
117
+ | `--ogx-font-size-md` | `1rem` (16px) | Medium |
118
+ | `--ogx-font-size-lg` | `1.125rem` (18px) | Large |
119
+ | `--ogx-font-size-xl` | `1.25rem` (20px) | Extra-large |
120
+ | `--ogx-font-weight-light` | `300` | |
121
+ | `--ogx-font-weight-regular` | `400` | |
122
+ | `--ogx-font-weight-medium` | `500` | |
123
+ | `--ogx-font-weight-semibold` | `600` | |
124
+ | `--ogx-font-weight-bold` | `700` | |
125
+ | `--ogx-line-height-tight` | `1.2` | |
126
+ | `--ogx-line-height-normal` | `1.5` | |
127
+ | `--ogx-line-height-relaxed` | `1.75` | |
128
+
129
+ ### Spacing
130
+
131
+ | Token | Default | Description |
132
+ |---|---|---|
133
+ | `--ogx-spacing-xs` | `0.25rem` (4px) | |
134
+ | `--ogx-spacing-sm` | `0.5rem` (8px) | |
135
+ | `--ogx-spacing-md` | `1rem` (16px) | |
136
+ | `--ogx-spacing-lg` | `1.5rem` (24px) | |
137
+ | `--ogx-spacing-xl` | `2rem` (32px) | |
138
+ | `--ogx-spacing-xxl` | `3rem` (48px) | |
139
+
140
+ ### Borders
141
+
142
+ | Token | Default | Description |
143
+ |---|---|---|
144
+ | `--ogx-border-width-thin` | `1px` | |
145
+ | `--ogx-border-width-medium` | `2px` | |
146
+ | `--ogx-border-width-thick` | `3px` | |
147
+ | `--ogx-border-radius-sm` | `4px` | |
148
+ | `--ogx-border-radius-md` | `8px` | |
149
+ | `--ogx-border-radius-lg` | `12px` | |
150
+ | `--ogx-border-radius-xl` | `16px` | |
151
+ | `--ogx-border-radius-round` | `50%` | Circular |
152
+ | `--ogx-border-color` | `var(--ogx-color-gray-200)` | Default border color |
153
+ | `--ogx-border-color-hover` | `var(--ogx-color-gray-300)` | Border on hover |
154
+
155
+ ### Shadows
156
+
157
+ | Token | Default | Description |
158
+ |---|---|---|
159
+ | `--ogx-shadow-sm` | `0 1px 2px rgba(0,0,0,.05)` | Subtle lift |
160
+ | `--ogx-shadow-md` | `0 4px 6px -1px ...` | Card-level |
161
+ | `--ogx-shadow-lg` | `0 10px 15px -3px ...` | Overlay |
162
+ | `--ogx-shadow-xl` | `0 20px 25px -5px ...` | Modal |
163
+
164
+ ### Grid Layout
165
+
166
+ | Token | Default | Description |
167
+ |---|---|---|
168
+ | `--ogx-row-height` | `52px` | Default row height |
169
+ | `--ogx-header-height` | `56px` | Column header row height |
170
+ | `--ogx-grid-row-height-compact` | `32px` | Compact density preset |
171
+ | `--ogx-grid-row-height-standard` | `52px` | Standard density preset |
172
+ | `--ogx-grid-row-height-comfortable` | `72px` | Comfortable density preset |
173
+ | `--ogx-grid-header-height` | `56px` | Header height (grid-specific) |
174
+ | `--ogx-grid-cell-padding-x` | `10px` | Horizontal cell padding |
175
+ | `--ogx-grid-cell-padding-y` | `8px` | Vertical cell padding |
176
+ | `--ogx-grid-cell-font-size` | `13px` | Body cell font size |
177
+ | `--ogx-grid-header-font-size` | `13px` | Header cell font size |
178
+ | `--ogx-grid-line-height` | `var(--ogx-line-height-normal)` | Row line height |
179
+
180
+ ### Grid Colors
181
+
182
+ | Token | Default (light) | Dark override | Description |
183
+ |---|---|---|---|
184
+ | `--ogx-grid-background` | `#ffffff` | `#0f172a` | Grid body background |
185
+ | `--ogx-grid-border-color` | `#e2e8f0` | `#334155` | Cell border lines |
186
+ | `--ogx-grid-header-background` | `#f8fafc` | `#1e293b` | Header row background |
187
+ | `--ogx-grid-header-text` | `#334155` | `#e2e8f0` | Header label color |
188
+ | `--ogx-grid-header-hover-background` | `#f1f5f9` | `#334155` | Header hover state |
189
+ | `--ogx-grid-header-sorted-background` | `#f8fafc` | `#1e3a5f` | Sorted column header tint |
190
+ | `--ogx-grid-row-text` | `#1e293b` | `#cbd5e1` | Default body cell text |
191
+ | `--ogx-grid-row-hover-background` | `#f8fafc` | `#1e293b` | Row hover highlight |
192
+ | `--ogx-grid-row-alternate-background` | `var(--ogx-grid-background)` | `#162032` | Striped row alternate |
193
+ | `--ogx-grid-row-selected-background` | `#eff6ff` | `#1e3a5f` | Selected row fill |
194
+ | `--ogx-grid-row-selected-hover-background` | `#dbeafe` | `#1d4ed8` | Selected row hover |
195
+ | `--ogx-grid-cell-focus-border` | `#3b82f6` | `#60a5fa` | Keyboard focus ring |
196
+ | `--ogx-grid-pinned-left-shadow` | `4px 0 24px...` | (darker) | Shadow on left-pinned columns |
197
+ | `--ogx-grid-pinned-right-shadow` | `-4px 0 24px...` | (darker) | Shadow on right-pinned columns |
198
+ | `--ogx-checkbox-bg` | — | `#1e293b` | Checkbox background (dark only) |
199
+ | `--ogx-checkbox-border` | — | `#64748b` | Checkbox border (dark only) |
200
+
201
+ ### Transitions
202
+
203
+ | Token | Default | Description |
204
+ |---|---|---|
205
+ | `--ogx-transition-duration-fast` | `150ms` | Quick micro-interactions |
206
+ | `--ogx-transition-duration-normal` | `250ms` | Standard UI transitions |
207
+ | `--ogx-transition-duration-slow` | `350ms` | Deliberate animations |
208
+ | `--ogx-transition-easing` | `cubic-bezier(0.4,0,0.2,1)` | Material easing curve |
209
+
210
+ ### Z-index Scale
211
+
212
+ | Token | Default | Use |
213
+ |---|---|---|
214
+ | `--ogx-z-index-base` | `0` | |
215
+ | `--ogx-z-index-sticky` | `1020` | Sticky/pinned columns |
216
+ | `--ogx-z-index-fixed` | `1030` | Fixed elements |
217
+ | `--ogx-z-index-dropdown` | `1000` | Inline dropdowns |
218
+ | `--ogx-z-index-modal-backdrop` | `1040` | |
219
+ | `--ogx-z-index-modal` | `1050` | |
220
+ | `--ogx-z-index-popover` | `1060` | Column menus |
221
+ | `--ogx-z-index-tooltip` | `1070` | Tooltips |
222
+
223
+ ---
224
+
225
+ ## CSS-Only Override (no React)
226
+
227
+ You can theme the grid without the `DataGridThemeProvider` by overriding variables on any ancestor element:
228
+
229
+ ```css
230
+ /* App-level override */
231
+ .my-grid-container {
232
+ --ogx-color-primary: #059669;
233
+ --ogx-color-primary-light: #d1fae5;
234
+ --ogx-grid-header-background: #f0fdf4;
235
+ --ogx-grid-row-selected-background: #d1fae5;
236
+ --ogx-grid-cell-focus-border: #059669;
237
+ }
238
+ ```
239
+
240
+ ```tsx
241
+ <div className="my-grid-container">
242
+ <DataGrid rows={rows} columns={columns} />
243
+ </div>
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Built-in Presets
249
+
250
+ OpenGridX ships with two presets accessible from `'opengridx'`:
251
+
252
+ ```tsx
253
+ import { DataGridThemeProvider, themes } from '@opencorestack/opengridx';
254
+
255
+ // Available: themes.light, themes.dark, themes.compact, themes.comfortable
256
+ <DataGridThemeProvider theme={themes.dark}>
257
+ <DataGrid ... />
258
+ </DataGridThemeProvider>
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Example: Custom Purple Theme
264
+
265
+ ```tsx
266
+ const purpleTheme: GridTheme = {
267
+ colors: {
268
+ primary: '#7c3aed',
269
+ primaryDark: '#5b21b6',
270
+ primaryLight: '#ede9fe',
271
+ primaryFocus: 'rgba(124,58,237,0.4)',
272
+ },
273
+ grid: {
274
+ headerBackground: '#f5f3ff',
275
+ headerText: '#4c1d95',
276
+ headerHoverBackground: '#ede9fe',
277
+ headerSortedBackground: '#ddd6fe',
278
+ rowSelectedBackground: '#ede9fe',
279
+ rowSelectedHoverBackground: '#ddd6fe',
280
+ cellFocusBorder: '#7c3aed',
281
+ },
282
+ };
283
+ ```
284
+
285
+ ---
286
+
287
+ ## CSS Architecture Notes
288
+
289
+ - All tokens are defined in `lib/styles/base/variables.css`
290
+ - The dark mode overrides are in the same file under `@media (prefers-color-scheme: dark)`
291
+ - The CSS entry point for the entire library is `lib/styles/opengridx.css` (single barrel import)
292
+ - BEM class prefix: `ogx__` (e.g. `ogx__cell`, `ogx__header-cell`)
293
+ - Variable prefix: `--ogx-` (e.g. `--ogx-color-primary`)
@@ -0,0 +1,79 @@
1
+ # 📊 Aggregation & Pivot Mode
2
+
3
+ Transform raw data into meaningful insights with advanced grouping and summary features.
4
+
5
+ ---
6
+
7
+ ## 📈 Row Aggregation
8
+
9
+ Aggregation allows you to calculate summary values (Sum, Avg, etc.) for groups or the entire dataset.
10
+
11
+ ### Usage
12
+ ```tsx
13
+ <DataGrid
14
+ rows={rows}
15
+ columns={columns}
16
+ aggregationModel={{
17
+ salary: 'sum',
18
+ age: 'avg',
19
+ department: 'count'
20
+ }}
21
+ />
22
+ ```
23
+
24
+ ### Configuration
25
+ You can control where the aggregation results appear:
26
+ - **`footer`**: A sticky row at the bottom of the grid.
27
+ - **`inline`**: Values displayed within group headers (when Row Grouping is active).
28
+ - **`both`**: Display in both locations.
29
+
30
+ ```tsx
31
+ <DataGrid
32
+ aggregationModel={model}
33
+ getAggregationPosition={(groupNode) => 'both'}
34
+ />
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 🔄 Pivot Mode
40
+
41
+ Pivot mode rotates your data, turning row values into dynamically generated columns.
42
+
43
+ ### Defining a Pivot
44
+ ```tsx
45
+ const pivotModel: GridPivotModel = {
46
+ rowFields: ['office'], // Dimensions on the Left
47
+ columnFields: ['year'], // Dimensions on the Top
48
+ valueFields: [ // Values to compute
49
+ { field: 'revenue', aggFn: 'sum', headerName: 'Total Revenue' }
50
+ ]
51
+ };
52
+
53
+ <DataGrid
54
+ pivotMode={true}
55
+ pivotModel={pivotModel}
56
+ />
57
+ ```
58
+
59
+ ### Key Concepts
60
+ - **Row Fields**: These become the static vertical axis of your pivot table.
61
+ - **Column Fields**: Unique values in these fields become new columns.
62
+ - **Value Fields**: The data that gets summarized at the intersection of row and column fields.
63
+
64
+ ---
65
+
66
+ ## ⚙️ Aggregation Functions
67
+
68
+ Built-in functions available:
69
+ - `sum`: Total of numeric values.
70
+ - `avg`: Arithmetic mean.
71
+ - `min`: Smallest value.
72
+ - `max`: Largest value.
73
+ - `count`: Number of items.
74
+ - `unique`: Number of unique items.
75
+
76
+ ---
77
+
78
+ ## 🎨 Formatting Totals
79
+ Aggregation results automatically inherit the `valueFormatter` from their respective column definitions. If you need a specific format for aggregates only, use the `formatAggregationValue` utility.